diff --git a/sdk/perfetto.cc b/sdk/perfetto.cc
new file mode 100644
index 0000000..2ac9f80
--- /dev/null
+++ b/sdk/perfetto.cc
@@ -0,0 +1,64965 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// This file is automatically generated by gen_amalgamated. Do not edit.
+
+// gen_amalgamated: predefined macros
+#if !defined(PERFETTO_IMPLEMENTATION)
+#define PERFETTO_IMPLEMENTATION
+#endif
+#include "perfetto.h"
+// gen_amalgamated begin source: src/base/default_platform.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/platform.h
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_PLATFORM_H_
+#define INCLUDE_PERFETTO_EXT_BASE_PLATFORM_H_
+
+namespace perfetto {
+namespace base {
+namespace platform {
+
+// Executed before entering a syscall (e.g. poll, read, write etc) which might
+// block.
+// This is overridden in Google internal builds for dealing with userspace
+// scheduling.
+void BeforeMaybeBlockingSyscall();
+
+// Executed after entering a syscall (e.g. poll, read, write etc) which might
+// block.
+// This is overridden in Google internal builds for dealing with userspace
+// scheduling.
+void AfterMaybeBlockingSyscall();
+
+}  // namespace platform
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_PLATFORM_H_
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/platform.h"
+
+namespace perfetto {
+namespace base {
+namespace platform {
+
+// This is a no-op outside of Google3 where we have some custom logic to deal
+// with the userspace scheduler.
+void BeforeMaybeBlockingSyscall() {}
+
+// This is a no-op outside of Google3 where we have some custom logic to deal
+// with the userspace scheduler.
+void AfterMaybeBlockingSyscall() {}
+
+}  // namespace platform
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/android_utils.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/android_utils.h
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_ANDROID_UTILS_H_
+#define INCLUDE_PERFETTO_EXT_BASE_ANDROID_UTILS_H_
+
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+namespace perfetto {
+namespace base {
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+
+// Returns the value of the Android system property named `name`. If the
+// property does not exist, returns an empty string (a non-existing property is
+// the same as a property with an empty value for this API).
+std::string GetAndroidProp(const char* name);
+
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_ANDROID_UTILS_H_
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/android_utils.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+#include <string>
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#include <sys/system_properties.h>
+#endif
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+
+namespace perfetto {
+namespace base {
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+
+std::string GetAndroidProp(const char* name) {
+  std::string ret;
+#if __ANDROID_API__ >= 26
+  const prop_info* pi = __system_property_find(name);
+  if (!pi) {
+    return ret;
+  }
+  __system_property_read_callback(
+      pi,
+      [](void* dst_void, const char*, const char* value, uint32_t) {
+        std::string& dst = *static_cast<std::string*>(dst_void);
+        dst = value;
+      },
+      &ret);
+#else  // __ANDROID_API__ < 26
+  char value_buf[PROP_VALUE_MAX];
+  int len = __system_property_get(name, value_buf);
+  if (len > 0 && static_cast<size_t>(len) < sizeof(value_buf)) {
+    ret = std::string(value_buf, static_cast<size_t>(len));
+  }
+#endif
+  return ret;
+}
+
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/base64.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/base64.h
+// gen_amalgamated begin header: include/perfetto/ext/base/string_view.h
+// gen_amalgamated begin header: include/perfetto/ext/base/hash.h
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_HASH_H_
+#define INCLUDE_PERFETTO_EXT_BASE_HASH_H_
+
+#include <stddef.h>
+#include <stdint.h>
+#include <string>
+#include <type_traits>
+#include <utility>
+
+namespace perfetto {
+namespace base {
+
+// A helper class which computes a 64-bit hash of the input data.
+// The algorithm used is FNV-1a as it is fast and easy to implement and has
+// relatively few collisions.
+// WARNING: This hash function should not be used for any cryptographic purpose.
+class Hasher {
+ public:
+  // Creates an empty hash object
+  Hasher() {}
+
+  // Hashes a numeric value.
+  template <
+      typename T,
+      typename std::enable_if<std::is_arithmetic<T>::value, bool>::type = true>
+  void Update(T data) {
+    Update(reinterpret_cast<const char*>(&data), sizeof(data));
+  }
+
+  // Using the loop instead of "Update(str, strlen(str))" to avoid looping twice
+  void Update(const char* str) {
+    for (const auto* p = str; *p; ++p)
+      Update(*p);
+  }
+
+  // Hashes a byte array.
+  void Update(const char* data, size_t size) {
+    for (size_t i = 0; i < size; i++) {
+      result_ ^= static_cast<uint8_t>(data[i]);
+      // Note: Arithmetic overflow of unsigned integers is well defined in C++
+      // standard unlike signed integers.
+      // https://stackoverflow.com/a/41280273
+      result_ *= kFnv1a64Prime;
+    }
+  }
+
+  // Allow hashing anything that has a |data| field, a |size| field,
+  // and has the kHashable trait (e.g., base::StringView).
+  template <typename T, typename = std::enable_if_t<T::kHashable>>
+  void Update(const T& t) {
+    Update(t.data(), t.size());
+  }
+
+  void Update(const std::string& s) { Update(s.data(), s.size()); }
+
+  uint64_t digest() const { return result_; }
+
+  // Usage:
+  // uint64_t hashed_value = Hash::Combine(33, false, "ABC", 458L, 3u, 'x');
+  template <typename... Ts>
+  static uint64_t Combine(Ts&&... args) {
+    Hasher hasher;
+    hasher.UpdateAll(std::forward<Ts>(args)...);
+    return hasher.digest();
+  }
+
+  // `hasher.UpdateAll(33, false, "ABC")` is shorthand for:
+  // `hasher.Update(33); hasher.Update(false); hasher.Update("ABC");`
+  void UpdateAll() {}
+
+  template <typename T, typename... Ts>
+  void UpdateAll(T&& arg, Ts&&... args) {
+    Update(arg);
+    UpdateAll(std::forward<Ts>(args)...);
+  }
+
+ private:
+  static constexpr uint64_t kFnv1a64OffsetBasis = 0xcbf29ce484222325;
+  static constexpr uint64_t kFnv1a64Prime = 0x100000001b3;
+
+  uint64_t result_ = kFnv1a64OffsetBasis;
+};
+
+// This is for using already-hashed key into std::unordered_map and avoid the
+// cost of re-hashing. Example:
+// unordered_map<uint64_t, Value, AlreadyHashed> my_map.
+template <typename T>
+struct AlreadyHashed {
+  size_t operator()(const T& x) const { return static_cast<size_t>(x); }
+};
+
+// base::Hash uses base::Hasher for integer values and falls base to std::hash
+// for other types. This is needed as std::hash for integers is just the
+// identity function and Perfetto uses open-addressing hash table, which are
+// very sensitive to hash quality and are known to degrade in performance
+// when using std::hash.
+template <typename T>
+struct Hash {
+  // Version for ints, using base::Hasher.
+  template <typename U = T>
+  auto operator()(const U& x) ->
+      typename std::enable_if<std::is_arithmetic<U>::value, size_t>::type
+      const {
+    Hasher hash;
+    hash.Update(x);
+    return static_cast<size_t>(hash.digest());
+  }
+
+  // Version for non-ints, falling back to std::hash.
+  template <typename U = T>
+  auto operator()(const U& x) ->
+      typename std::enable_if<!std::is_arithmetic<U>::value, size_t>::type
+      const {
+    return std::hash<U>()(x);
+  }
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_HASH_H_
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_STRING_VIEW_H_
+#define INCLUDE_PERFETTO_EXT_BASE_STRING_VIEW_H_
+
+#include <string.h>
+
+#include <algorithm>
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
+
+namespace perfetto {
+namespace base {
+
+// A string-like object that refers to a non-owned piece of memory.
+// Strings are internally NOT null terminated.
+class StringView {
+ public:
+  // Allow hashing with base::Hash.
+  static constexpr bool kHashable = true;
+  static constexpr size_t npos = static_cast<size_t>(-1);
+
+  StringView() : data_(nullptr), size_(0) {}
+  StringView(const StringView&) = default;
+  StringView& operator=(const StringView&) = default;
+  StringView(const char* data, size_t size) : data_(data), size_(size) {
+    PERFETTO_DCHECK(size == 0 || data != nullptr);
+  }
+
+  // Allow implicit conversion from any class that has a |data| and |size| field
+  // and has the kConvertibleToStringView trait (e.g., protozero::ConstChars).
+  template <typename T, typename = std::enable_if<T::kConvertibleToStringView>>
+  StringView(const T& x) : StringView(x.data, x.size) {
+    PERFETTO_DCHECK(x.size == 0 || x.data != nullptr);
+  }
+
+  // Creates a StringView from a null-terminated C string.
+  // Deliberately not "explicit".
+  StringView(const char* cstr) : data_(cstr), size_(strlen(cstr)) {
+    PERFETTO_DCHECK(cstr != nullptr);
+  }
+
+  // This instead has to be explicit, as creating a StringView out of a
+  // std::string can be subtle.
+  explicit StringView(const std::string& str)
+      : data_(str.data()), size_(str.size()) {}
+
+  bool empty() const { return size_ == 0; }
+  size_t size() const { return size_; }
+  const char* data() const { return data_; }
+  const char* begin() const { return data_; }
+  const char* end() const { return data_ + size_; }
+
+  char at(size_t pos) const {
+    PERFETTO_DCHECK(pos < size_);
+    return data_[pos];
+  }
+
+  size_t find(char c, size_t start_pos = 0) const {
+    for (size_t i = start_pos; i < size_; ++i) {
+      if (data_[i] == c)
+        return i;
+    }
+    return npos;
+  }
+
+  size_t find(const StringView& str, size_t start_pos = 0) const {
+    if (start_pos > size())
+      return npos;
+    auto it = std::search(begin() + start_pos, end(), str.begin(), str.end());
+    size_t pos = static_cast<size_t>(it - begin());
+    return pos + str.size() <= size() ? pos : npos;
+  }
+
+  size_t find(const char* str, size_t start_pos = 0) const {
+    return find(StringView(str), start_pos);
+  }
+
+  size_t rfind(char c) const {
+    for (size_t i = size_; i > 0; --i) {
+      if (data_[i - 1] == c)
+        return i - 1;
+    }
+    return npos;
+  }
+
+  StringView substr(size_t pos, size_t count = npos) const {
+    if (pos >= size_)
+      return StringView("", 0);
+    size_t rcount = std::min(count, size_ - pos);
+    return StringView(data_ + pos, rcount);
+  }
+
+  bool CaseInsensitiveEq(const StringView& other) const {
+    if (size() != other.size())
+      return false;
+    if (size() == 0)
+      return true;
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    return _strnicmp(data(), other.data(), size()) == 0;
+#else
+    return strncasecmp(data(), other.data(), size()) == 0;
+#endif
+  }
+
+  bool StartsWith(const StringView& other) const {
+    if (other.size() == 0)
+      return true;
+    if (size() == 0)
+      return false;
+    if (other.size() > size())
+      return false;
+    return memcmp(data(), other.data(), other.size()) == 0;
+  }
+
+  bool EndsWith(const StringView& other) const {
+    if (other.size() == 0)
+      return true;
+    if (size() == 0)
+      return false;
+    if (other.size() > size())
+      return false;
+    size_t off = size() - other.size();
+    return memcmp(data() + off, other.data(), other.size()) == 0;
+  }
+
+  std::string ToStdString() const {
+    return size_ == 0 ? "" : std::string(data_, size_);
+  }
+
+  uint64_t Hash() const {
+    base::Hasher hasher;
+    hasher.Update(data_, size_);
+    return hasher.digest();
+  }
+
+ private:
+  const char* data_ = nullptr;
+  size_t size_ = 0;
+};
+
+inline bool operator==(const StringView& x, const StringView& y) {
+  if (x.size() != y.size())
+    return false;
+  if (x.size() == 0)
+    return true;
+  return memcmp(x.data(), y.data(), x.size()) == 0;
+}
+
+inline bool operator!=(const StringView& x, const StringView& y) {
+  return !(x == y);
+}
+
+inline bool operator<(const StringView& x, const StringView& y) {
+  auto size = std::min(x.size(), y.size());
+  if (size == 0)
+    return x.size() < y.size();
+  int result = memcmp(x.data(), y.data(), size);
+  return result < 0 || (result == 0 && x.size() < y.size());
+}
+
+inline bool operator>=(const StringView& x, const StringView& y) {
+  return !(x < y);
+}
+
+inline bool operator>(const StringView& x, const StringView& y) {
+  return y < x;
+}
+
+inline bool operator<=(const StringView& x, const StringView& y) {
+  return !(y < x);
+}
+
+}  // namespace base
+}  // namespace perfetto
+
+template <>
+struct std::hash<::perfetto::base::StringView> {
+  size_t operator()(const ::perfetto::base::StringView& sv) const {
+    return static_cast<size_t>(sv.Hash());
+  }
+};
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_STRING_VIEW_H_
+// gen_amalgamated begin header: include/perfetto/ext/base/utils.h
+// gen_amalgamated begin header: include/perfetto/ext/base/sys_types.h
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_SYS_TYPES_H_
+#define INCLUDE_PERFETTO_EXT_BASE_SYS_TYPES_H_
+
+// This headers deals with sys types commonly used in the codebase that are
+// missing on Windows.
+
+#include <sys/types.h>
+#include <cstdint>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_COMPILER_GCC)
+// MinGW has these. clang-cl and MSVC, which use just the Windows SDK, don't.
+using uid_t = int;
+using pid_t = int;
+#endif  // !GCC
+
+#if defined(_WIN64)
+using ssize_t = int64_t;
+#else
+using ssize_t = long;
+#endif  // _WIN64
+
+#endif  // OS_WIN
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && !defined(AID_SHELL)
+// From libcutils' android_filesystem_config.h .
+#define AID_SHELL 2000
+#endif
+
+namespace perfetto {
+namespace base {
+
+// The machine ID used in the tracing core.
+using MachineID = uint32_t;
+// The default value reserved for the host trace.
+constexpr MachineID kDefaultMachineID = 0;
+
+constexpr uid_t kInvalidUid = static_cast<uid_t>(-1);
+constexpr pid_t kInvalidPid = static_cast<pid_t>(-1);
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_SYS_TYPES_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_UTILS_H_
+#define INCLUDE_PERFETTO_EXT_BASE_UTILS_H_
+
+#include <errno.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <atomic>
+#include <functional>
+#include <memory>
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/sys_types.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+// Even if Windows has errno.h, the all syscall-restart behavior does not apply.
+// Trying to handle EINTR can cause more harm than good if errno is left stale.
+// Chromium does the same.
+#define PERFETTO_EINTR(x) (x)
+#else
+#define PERFETTO_EINTR(x)                                   \
+  ([&] {                                                    \
+    decltype(x) eintr_wrapper_result;                       \
+    do {                                                    \
+      eintr_wrapper_result = (x);                           \
+    } while (eintr_wrapper_result == -1 && errno == EINTR); \
+    return eintr_wrapper_result;                            \
+  }())
+#endif
+
+namespace perfetto {
+namespace base {
+
+namespace internal {
+extern std::atomic<uint32_t> g_cached_page_size;
+uint32_t GetSysPageSizeSlowpath();
+}  // namespace internal
+
+// Returns the system's page size. Use this when dealing with mmap, madvise and
+// similar mm-related syscalls.
+// This function might be called in hot paths. Avoid calling getpagesize() all
+// the times, in many implementations getpagesize() calls sysconf() which is
+// not cheap.
+inline uint32_t GetSysPageSize() {
+  const uint32_t page_size =
+      internal::g_cached_page_size.load(std::memory_order_relaxed);
+  return page_size != 0 ? page_size : internal::GetSysPageSizeSlowpath();
+}
+
+template <typename T, size_t TSize>
+constexpr size_t ArraySize(const T (&)[TSize]) {
+  return TSize;
+}
+
+// Function object which invokes 'free' on its parameter, which must be
+// a pointer. Can be used to store malloc-allocated pointers in std::unique_ptr:
+//
+// std::unique_ptr<int, base::FreeDeleter> foo_ptr(
+//     static_cast<int*>(malloc(sizeof(int))));
+struct FreeDeleter {
+  inline void operator()(void* ptr) const { free(ptr); }
+};
+
+template <typename T>
+constexpr T AssumeLittleEndian(T value) {
+#if !PERFETTO_IS_LITTLE_ENDIAN()
+  static_assert(false, "Unimplemented on big-endian archs");
+#endif
+  return value;
+}
+
+// Round up |size| to a multiple of |alignment| (must be a power of two).
+inline constexpr size_t AlignUp(size_t size, size_t alignment) {
+  return (size + alignment - 1) & ~(alignment - 1);
+}
+
+// TODO(primiano): clean this up and move all existing usages to the constexpr
+// version above.
+template <size_t alignment>
+constexpr size_t AlignUp(size_t size) {
+  static_assert((alignment & (alignment - 1)) == 0, "alignment must be a pow2");
+  return AlignUp(size, alignment);
+}
+
+inline bool IsAgain(int err) {
+  return err == EAGAIN || err == EWOULDBLOCK;
+}
+
+// setenv(2)-equivalent. Deals with Windows vs Posix discrepancies.
+void SetEnv(const std::string& key, const std::string& value);
+
+// unsetenv(2)-equivalent. Deals with Windows vs Posix discrepancies.
+void UnsetEnv(const std::string& key);
+
+// Calls mallopt(M_PURGE, 0) on Android. Does nothing on other platforms.
+// This forces the allocator to release freed memory. This is used to work
+// around various Scudo inefficiencies. See b/170217718.
+void MaybeReleaseAllocatorMemToOS();
+
+// geteuid() on POSIX OSes, returns 0 on Windows (See comment in utils.cc).
+uid_t GetCurrentUserId();
+
+// Forks the process.
+// Parent: prints the PID of the child, calls |parent_cb| and exits from the
+//         process with its return value.
+// Child: redirects stdio onto /dev/null, chdirs into / and returns.
+void Daemonize(std::function<int()> parent_cb);
+
+// Returns the path of the current executable, e.g. /foo/bar/exe.
+std::string GetCurExecutablePath();
+
+// Returns the directory where the current executable lives in, e.g. /foo/bar.
+// This is independent of cwd().
+std::string GetCurExecutableDir();
+
+// Memory returned by AlignedAlloc() must be freed via AlignedFree() not just
+// free. It makes a difference on Windows where _aligned_malloc() and
+// _aligned_free() must be paired.
+// Prefer using the AlignedAllocTyped() below which takes care of the pairing.
+void* AlignedAlloc(size_t alignment, size_t size);
+void AlignedFree(void*);
+
+// A RAII version of the above, which takes care of pairing Aligned{Alloc,Free}.
+template <typename T>
+struct AlignedDeleter {
+  inline void operator()(T* ptr) const { AlignedFree(ptr); }
+};
+
+// The remove_extent<T> here and below is to allow defining unique_ptr<T[]>.
+// As per https://en.cppreference.com/w/cpp/memory/unique_ptr the Deleter takes
+// always a T*, not a T[]*.
+template <typename T>
+using AlignedUniquePtr =
+    std::unique_ptr<T, AlignedDeleter<typename std::remove_extent<T>::type>>;
+
+template <typename T>
+AlignedUniquePtr<T> AlignedAllocTyped(size_t n_membs) {
+  using TU = typename std::remove_extent<T>::type;
+  return AlignedUniquePtr<T>(
+      static_cast<TU*>(AlignedAlloc(alignof(TU), sizeof(TU) * n_membs)));
+}
+
+// A RAII wrapper to invoke a function when leaving a function/scope.
+template <typename Func>
+class OnScopeExitWrapper {
+ public:
+  explicit OnScopeExitWrapper(Func f) : f_(std::move(f)), active_(true) {}
+  OnScopeExitWrapper(OnScopeExitWrapper&& other) noexcept
+      : f_(std::move(other.f_)), active_(other.active_) {
+    other.active_ = false;
+  }
+  ~OnScopeExitWrapper() {
+    if (active_)
+      f_();
+  }
+
+ private:
+  Func f_;
+  bool active_;
+};
+
+template <typename Func>
+PERFETTO_WARN_UNUSED_RESULT OnScopeExitWrapper<Func> OnScopeExit(Func f) {
+  return OnScopeExitWrapper<Func>(std::move(f));
+}
+
+// Returns a xxd-style hex dump (hex + ascii chars) of the input data.
+std::string HexDump(const void* data, size_t len, size_t bytes_per_line = 16);
+inline std::string HexDump(const std::string& data,
+                           size_t bytes_per_line = 16) {
+  return HexDump(data.data(), data.size(), bytes_per_line);
+}
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_UTILS_H_
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_BASE64_H_
+#define INCLUDE_PERFETTO_EXT_BASE_BASE64_H_
+
+#include <optional>
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"  // For ssize_t.
+
+namespace perfetto {
+namespace base {
+
+// Returns the length of the destination string (included '=' padding).
+// Does NOT include the size of the string null terminator.
+inline size_t Base64EncSize(size_t src_size) {
+  return (src_size + 2) / 3 * 4;
+}
+
+// Returns the upper bound on the length of the destination buffer.
+// The actual decoded length might be <= the number returned here.
+inline size_t Base64DecSize(size_t src_size) {
+  return (src_size + 3) / 4 * 3;
+}
+
+// Does NOT null-terminate |dst|.
+ssize_t Base64Encode(const void* src,
+                     size_t src_size,
+                     char* dst,
+                     size_t dst_size);
+
+std::string Base64Encode(const void* src, size_t src_size);
+
+inline std::string Base64Encode(StringView sv) {
+  return Base64Encode(sv.data(), sv.size());
+}
+
+// Returns -1 in case of failure.
+ssize_t Base64Decode(const char* src,
+                     size_t src_size,
+                     uint8_t* dst,
+                     size_t dst_size);
+
+std::optional<std::string> Base64Decode(const char* src, size_t src_size);
+
+inline std::optional<std::string> Base64Decode(StringView sv) {
+  return Base64Decode(sv.data(), sv.size());
+}
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_BASE64_H_
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/base64.h"
+
+namespace perfetto {
+namespace base {
+
+namespace {
+
+constexpr char kPadding = '=';
+
+constexpr char kEncTable[] =
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+static_assert(sizeof(kEncTable) == (1u << 6) + sizeof('\0'), "Bad table size");
+
+// Maps an ASCII character to its 6-bit value. It only contains translations
+// from '+' to 'z'. Supports the standard (+/) and URL-safe (-_) alphabets.
+constexpr uint8_t kX = 0xff;  // Value used for invalid characters
+constexpr uint8_t kDecTable[] = {
+    62, kX, 62, kX, 63, 52, 53, 54, 55, 56,  // 00 - 09
+    57, 58, 59, 60, 61, kX, kX, kX, 0,  kX,  // 10 - 19
+    kX, kX, 0,  1,  2,  3,  4,  5,  6,  7,   // 20 - 29
+    8,  9,  10, 11, 12, 13, 14, 15, 16, 17,  // 30 - 39
+    18, 19, 20, 21, 22, 23, 24, 25, kX, kX,  // 40 - 49
+    kX, kX, 63, kX, 26, 27, 28, 29, 30, 31,  // 50 - 59
+    32, 33, 34, 35, 36, 37, 38, 39, 40, 41,  // 60 - 69
+    42, 43, 44, 45, 46, 47, 48, 49, 50, 51,  // 70 - 79
+};
+constexpr char kMinDecChar = '+';
+constexpr char kMaxDecChar = 'z';
+static_assert(kMaxDecChar - kMinDecChar <= sizeof(kDecTable), "Bad table size");
+
+inline uint8_t DecodeChar(char c) {
+  if (c < kMinDecChar || c > kMaxDecChar)
+    return kX;
+  return kDecTable[c - kMinDecChar];
+}
+
+}  // namespace
+
+ssize_t Base64Encode(const void* src,
+                     size_t src_size,
+                     char* dst,
+                     size_t dst_size) {
+  const size_t padded_dst_size = Base64EncSize(src_size);
+  if (dst_size < padded_dst_size)
+    return -1;  // Not enough space in output.
+
+  const uint8_t* rd = static_cast<const uint8_t*>(src);
+  const uint8_t* const end = rd + src_size;
+  size_t wr_size = 0;
+  while (rd < end) {
+    uint8_t s[3]{};
+    s[0] = *(rd++);
+    dst[wr_size++] = kEncTable[s[0] >> 2];
+
+    uint8_t carry0 = static_cast<uint8_t>((s[0] & 0x03) << 4);
+    if (PERFETTO_LIKELY(rd < end)) {
+      s[1] = *(rd++);
+      dst[wr_size++] = kEncTable[carry0 | (s[1] >> 4)];
+    } else {
+      dst[wr_size++] = kEncTable[carry0];
+      dst[wr_size++] = kPadding;
+      dst[wr_size++] = kPadding;
+      break;
+    }
+
+    uint8_t carry1 = static_cast<uint8_t>((s[1] & 0x0f) << 2);
+    if (PERFETTO_LIKELY(rd < end)) {
+      s[2] = *(rd++);
+      dst[wr_size++] = kEncTable[carry1 | (s[2] >> 6)];
+    } else {
+      dst[wr_size++] = kEncTable[carry1];
+      dst[wr_size++] = kPadding;
+      break;
+    }
+
+    dst[wr_size++] = kEncTable[s[2] & 0x3f];
+  }
+  PERFETTO_DCHECK(wr_size == padded_dst_size);
+  return static_cast<ssize_t>(padded_dst_size);
+}
+
+std::string Base64Encode(const void* src, size_t src_size) {
+  std::string dst;
+  dst.resize(Base64EncSize(src_size));
+  auto res = Base64Encode(src, src_size, &dst[0], dst.size());
+  PERFETTO_CHECK(res == static_cast<ssize_t>(dst.size()));
+  return dst;
+}
+
+ssize_t Base64Decode(const char* src,
+                     size_t src_size,
+                     uint8_t* dst,
+                     size_t dst_size) {
+  const size_t min_dst_size = Base64DecSize(src_size);
+  if (dst_size < min_dst_size)
+    return -1;
+
+  const char* rd = src;
+  const char* const end = src + src_size;
+  size_t wr_size = 0;
+
+  char s[4]{};
+  while (rd < end) {
+    uint8_t d[4];
+    for (uint32_t j = 0; j < 4; j++) {
+      // Padding is only feasible for the last 2 chars of each group of 4.
+      s[j] = rd < end ? *(rd++) : (j < 2 ? '\0' : kPadding);
+      d[j] = DecodeChar(s[j]);
+      if (d[j] == kX)
+        return -1;  // Invalid input char.
+    }
+    dst[wr_size] = static_cast<uint8_t>((d[0] << 2) | (d[1] >> 4));
+    dst[wr_size + 1] = static_cast<uint8_t>((d[1] << 4) | (d[2] >> 2));
+    dst[wr_size + 2] = static_cast<uint8_t>((d[2] << 6) | (d[3]));
+    wr_size += 3;
+  }
+
+  PERFETTO_CHECK(wr_size <= dst_size);
+  wr_size -= (s[3] == kPadding ? 1 : 0) + (s[2] == kPadding ? 1 : 0);
+  return static_cast<ssize_t>(wr_size);
+}
+
+std::optional<std::string> Base64Decode(const char* src, size_t src_size) {
+  std::string dst;
+  dst.resize(Base64DecSize(src_size));
+  auto res = Base64Decode(src, src_size, reinterpret_cast<uint8_t*>(&dst[0]),
+                          dst.size());
+  if (res < 0)
+    return std::nullopt;  // Decoding error.
+
+  PERFETTO_CHECK(res <= static_cast<ssize_t>(dst.size()));
+  dst.resize(static_cast<size_t>(res));
+  return std::make_optional(dst);
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/crash_keys.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/crash_keys.h
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_CRASH_KEYS_H_
+#define INCLUDE_PERFETTO_EXT_BASE_CRASH_KEYS_H_
+
+#include <algorithm>
+#include <atomic>
+
+#include <stdint.h>
+#include <string.h>
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
+
+// Crash keys are very simple global variables with static-storage that
+// are reported on crash time for managed crashes (CHECK/FATAL/Watchdog).
+// - Translation units can define a CrashKey and register it at some point
+//   during initialization.
+// - CrashKey instances must be long-lived. They should really be just global
+//   static variable in the anonymous namespace.
+// Example:
+// subsystem_1.cc
+//   CrashKey g_client_id("ipc_client_id");
+//   ...
+//   OnIpcReceived(client_id) {
+//      g_client_id.Set(client_id);
+//      ... // Process the IPC
+//      g_client_id.Clear();
+//   }
+//   Or equivalently:
+//   OnIpcReceived(client_id) {
+//      auto scoped_key = g_client_id.SetScoped(client_id);
+//      ... // Process the IPC
+//   }
+//
+// If a crash happens while processing the IPC, the crash report will
+// have a line "ipc_client_id: 42".
+//
+// Thread safety considerations:
+// CrashKeys can be registered and set/cleared from any thread.
+// There is no compelling use-case to have full acquire/release consistency when
+// setting a key. This means that if a thread crashes immediately after a
+// crash key has been set on another thread, the value printed on the crash
+// report could be incomplete. The code guarantees defined behavior and does
+// not rely on null-terminated string (in the worst case 32 bytes of random
+// garbage will be printed out).
+
+// The tests live in logging_unittest.cc.
+
+namespace perfetto {
+namespace base {
+
+constexpr size_t kCrashKeyMaxStrSize = 32;
+
+// CrashKey instances must be long lived
+class CrashKey {
+ public:
+  class ScopedClear {
+   public:
+    explicit ScopedClear(CrashKey* k) : key_(k) {}
+    ~ScopedClear() {
+      if (key_)
+        key_->Clear();
+    }
+    ScopedClear(const ScopedClear&) = delete;
+    ScopedClear& operator=(const ScopedClear&) = delete;
+    ScopedClear& operator=(ScopedClear&&) = delete;
+    ScopedClear(ScopedClear&& other) noexcept : key_(other.key_) {
+      other.key_ = nullptr;
+    }
+
+   private:
+    CrashKey* key_;
+  };
+
+  // constexpr so it can be used in the anon namespace without requiring a
+  // global constructor.
+  // |name| must be a long-lived string.
+  constexpr explicit CrashKey(const char* name)
+      : registered_{}, type_(Type::kUnset), name_(name), str_value_{} {}
+  CrashKey(const CrashKey&) = delete;
+  CrashKey& operator=(const CrashKey&) = delete;
+  CrashKey(CrashKey&&) = delete;
+  CrashKey& operator=(CrashKey&&) = delete;
+
+  enum class Type : uint8_t { kUnset = 0, kInt, kStr };
+
+  void Clear() {
+    int_value_.store(0, std::memory_order_relaxed);
+    type_.store(Type::kUnset, std::memory_order_relaxed);
+  }
+
+  void Set(int64_t value) {
+    int_value_.store(value, std::memory_order_relaxed);
+    type_.store(Type::kInt, std::memory_order_relaxed);
+    if (PERFETTO_UNLIKELY(!registered_.load(std::memory_order_relaxed)))
+      Register();
+  }
+
+  void Set(StringView sv) {
+    size_t len = std::min(sv.size(), sizeof(str_value_) - 1);
+    for (size_t i = 0; i < len; ++i)
+      str_value_[i].store(sv.data()[i], std::memory_order_relaxed);
+    str_value_[len].store('\0', std::memory_order_relaxed);
+    type_.store(Type::kStr, std::memory_order_relaxed);
+    if (PERFETTO_UNLIKELY(!registered_.load(std::memory_order_relaxed)))
+      Register();
+  }
+
+  ScopedClear SetScoped(int64_t value) PERFETTO_WARN_UNUSED_RESULT {
+    Set(value);
+    return ScopedClear(this);
+  }
+
+  ScopedClear SetScoped(StringView sv) PERFETTO_WARN_UNUSED_RESULT {
+    Set(sv);
+    return ScopedClear(this);
+  }
+
+  void Register();
+
+  int64_t int_value() const {
+    return int_value_.load(std::memory_order_relaxed);
+  }
+  size_t ToString(char* dst, size_t len);
+
+ private:
+  std::atomic<bool> registered_;
+  std::atomic<Type> type_;
+  const char* const name_;
+  union {
+    std::atomic<char> str_value_[kCrashKeyMaxStrSize];
+    std::atomic<int64_t> int_value_;
+  };
+};
+
+// Fills |dst| with a string containing one line for each crash key
+// (excluding the unset ones).
+// Returns number of chars written, without counting the NUL terminator.
+// This is used in logging.cc when emitting the crash report abort message.
+size_t SerializeCrashKeys(char* dst, size_t len);
+
+void UnregisterAllCrashKeysForTesting();
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_CRASH_KEYS_H_
+// gen_amalgamated begin header: include/perfetto/ext/base/string_utils.h
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_STRING_UTILS_H_
+#define INCLUDE_PERFETTO_EXT_BASE_STRING_UTILS_H_
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <cinttypes>
+#include <optional>
+#include <string>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
+
+namespace perfetto {
+namespace base {
+
+inline char Lowercase(char c) {
+  return ('A' <= c && c <= 'Z') ? static_cast<char>(c - ('A' - 'a')) : c;
+}
+
+inline char Uppercase(char c) {
+  return ('a' <= c && c <= 'z') ? static_cast<char>(c + ('A' - 'a')) : c;
+}
+
+inline std::optional<uint32_t> CStringToUInt32(const char* s, int base = 10) {
+  char* endptr = nullptr;
+  auto value = static_cast<uint32_t>(strtoul(s, &endptr, base));
+  return (*s && !*endptr) ? std::make_optional(value) : std::nullopt;
+}
+
+inline std::optional<int32_t> CStringToInt32(const char* s, int base = 10) {
+  char* endptr = nullptr;
+  auto value = static_cast<int32_t>(strtol(s, &endptr, base));
+  return (*s && !*endptr) ? std::make_optional(value) : std::nullopt;
+}
+
+// Note: it saturates to 7fffffffffffffff if parsing a hex number >= 0x8000...
+inline std::optional<int64_t> CStringToInt64(const char* s, int base = 10) {
+  char* endptr = nullptr;
+  auto value = static_cast<int64_t>(strtoll(s, &endptr, base));
+  return (*s && !*endptr) ? std::make_optional(value) : std::nullopt;
+}
+
+inline std::optional<uint64_t> CStringToUInt64(const char* s, int base = 10) {
+  char* endptr = nullptr;
+  auto value = static_cast<uint64_t>(strtoull(s, &endptr, base));
+  return (*s && !*endptr) ? std::make_optional(value) : std::nullopt;
+}
+
+double StrToD(const char* nptr, char** endptr);
+
+inline std::optional<double> CStringToDouble(const char* s) {
+  char* endptr = nullptr;
+  double value = StrToD(s, &endptr);
+  std::optional<double> result(std::nullopt);
+  if (*s != '\0' && *endptr == '\0')
+    result = value;
+  return result;
+}
+
+inline std::optional<uint32_t> StringToUInt32(const std::string& s,
+                                              int base = 10) {
+  return CStringToUInt32(s.c_str(), base);
+}
+
+inline std::optional<int32_t> StringToInt32(const std::string& s,
+                                            int base = 10) {
+  return CStringToInt32(s.c_str(), base);
+}
+
+inline std::optional<uint64_t> StringToUInt64(const std::string& s,
+                                              int base = 10) {
+  return CStringToUInt64(s.c_str(), base);
+}
+
+inline std::optional<int64_t> StringToInt64(const std::string& s,
+                                            int base = 10) {
+  return CStringToInt64(s.c_str(), base);
+}
+
+inline std::optional<double> StringToDouble(const std::string& s) {
+  return CStringToDouble(s.c_str());
+}
+
+bool StartsWith(const std::string& str, const std::string& prefix);
+bool EndsWith(const std::string& str, const std::string& suffix);
+bool StartsWithAny(const std::string& str,
+                   const std::vector<std::string>& prefixes);
+bool Contains(const std::string& haystack, const std::string& needle);
+bool Contains(const std::string& haystack, char needle);
+size_t Find(const StringView& needle, const StringView& haystack);
+bool CaseInsensitiveEqual(const std::string& first, const std::string& second);
+std::string Join(const std::vector<std::string>& parts,
+                 const std::string& delim);
+std::vector<std::string> SplitString(const std::string& text,
+                                     const std::string& delimiter);
+std::string StripPrefix(const std::string& str, const std::string& prefix);
+std::string StripSuffix(const std::string& str, const std::string& suffix);
+std::string TrimWhitespace(const std::string& str);
+std::string ToLower(const std::string& str);
+std::string ToUpper(const std::string& str);
+std::string StripChars(const std::string& str,
+                       const std::string& chars,
+                       char replacement);
+std::string ToHex(const char* data, size_t size);
+inline std::string ToHex(const std::string& s) {
+  return ToHex(s.c_str(), s.size());
+}
+std::string IntToHexString(uint32_t number);
+std::string Uint64ToHexString(uint64_t number);
+std::string Uint64ToHexStringNoPrefix(uint64_t number);
+std::string ReplaceAll(std::string str,
+                       const std::string& to_replace,
+                       const std::string& replacement);
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+bool WideToUTF8(const std::wstring& source, std::string& output);
+bool UTF8ToWide(const std::string& source, std::wstring& output);
+#endif // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+// A BSD-style strlcpy without the return value.
+// Copies at most |dst_size|-1 characters. Unlike strncpy, it always \0
+// terminates |dst|, as long as |dst_size| is not 0.
+// Unlike strncpy and like strlcpy it does not zero-pad the rest of |dst|.
+// Returns nothing. The BSD strlcpy returns the size of |src|, which might
+// be > |dst_size|. Anecdotal experience suggests people assume the return value
+// is the number of bytes written in |dst|. That assumption can lead to
+// dangerous bugs.
+// In order to avoid being subtly uncompliant with strlcpy AND avoid misuse,
+// the choice here is to return nothing.
+inline void StringCopy(char* dst, const char* src, size_t dst_size) {
+  for (size_t i = 0; i < dst_size; ++i) {
+    if ((dst[i] = src[i]) == '\0') {
+      return;  // We hit and copied the null terminator.
+    }
+  }
+
+  // We were left off at dst_size. We over copied 1 byte. Null terminate.
+  if (PERFETTO_LIKELY(dst_size > 0))
+    dst[dst_size - 1] = 0;
+}
+
+// Like snprintf() but returns the number of chars *actually* written (without
+// counting the null terminator) NOT "the number of chars which would have been
+// written to the final string if enough  space had been available".
+// This should be used in almost all cases when the caller uses the return value
+// of snprintf(). If the return value is not used, there is no benefit in using
+// this wrapper, as this just calls snprintf() and mangles the return value.
+// It always null-terminates |dst| (even in case of errors), unless
+// |dst_size| == 0.
+// Examples:
+//   SprintfTrunc(x, 4, "123whatever"): returns 3 and writes "123\0".
+//   SprintfTrunc(x, 4, "123"): returns 3 and writes "123\0".
+//   SprintfTrunc(x, 3, "123"): returns 2 and writes "12\0".
+//   SprintfTrunc(x, 2, "123"): returns 1 and writes "1\0".
+//   SprintfTrunc(x, 1, "123"): returns 0 and writes "\0".
+//   SprintfTrunc(x, 0, "123"): returns 0 and writes nothing.
+// NOTE: This means that the caller has no way to tell when truncation happens
+//   vs the edge case of *just* fitting in the buffer.
+size_t SprintfTrunc(char* dst, size_t dst_size, const char* fmt, ...)
+    PERFETTO_PRINTF_FORMAT(3, 4);
+
+// Line number starts from 1
+struct LineWithOffset {
+  base::StringView line;
+  uint32_t line_offset;
+  uint32_t line_num;
+};
+
+// For given string and offset Pfinds a line with character for
+// which offset points, what number is this line (starts from 1), and the offset
+// inside this line. returns std::nullopt if the offset points to
+// line break character or exceeds string length.
+std::optional<LineWithOffset> FindLineWithOffset(base::StringView str,
+                                                 uint32_t offset);
+
+// A helper class to facilitate construction and usage of write-once stack
+// strings.
+// Example usage:
+//   StackString<32> x("format %d %s", 42, string_arg);
+//   TakeString(x.c_str() | x.string_view() | x.ToStdString());
+// Rather than char x[32] + sprintf.
+// Advantages:
+// - Avoids useless zero-fills caused by people doing `char buf[32] {}` (mainly
+//   by fearing unknown snprintf failure modes).
+// - Makes the code more robust in case of snprintf truncations (len() and
+//  string_view() will return the truncated length, unlike snprintf).
+template <size_t N>
+class StackString {
+ public:
+  explicit PERFETTO_PRINTF_FORMAT(/* 1=this */ 2, 3)
+      StackString(const char* fmt, ...) {
+    buf_[0] = '\0';
+    va_list args;
+    va_start(args, fmt);
+    int res = vsnprintf(buf_, sizeof(buf_), fmt, args);
+    va_end(args);
+    buf_[sizeof(buf_) - 1] = '\0';
+    len_ = res < 0 ? 0 : std::min(static_cast<size_t>(res), sizeof(buf_) - 1);
+  }
+
+  StringView string_view() const { return StringView(buf_, len_); }
+  std::string ToStdString() const { return std::string(buf_, len_); }
+  const char* c_str() const { return buf_; }
+  size_t len() const { return len_; }
+  char* mutable_data() { return buf_; }
+
+ private:
+  char buf_[N];
+  size_t len_ = 0;  // Does not include the \0.
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_STRING_UTILS_H_
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/crash_keys.h"
+
+#include <string.h>
+
+#include <atomic>
+#include <cinttypes>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
+
+namespace perfetto {
+namespace base {
+
+namespace {
+
+constexpr size_t kMaxKeys = 32;
+
+std::atomic<CrashKey*> g_keys[kMaxKeys]{};
+std::atomic<uint32_t> g_num_keys{};
+}  // namespace
+
+void CrashKey::Register() {
+  // If doesn't matter if we fail below. If there are no slots left, don't
+  // keep trying re-registering on every Set(), the outcome won't change.
+
+  // If two threads raced on the Register(), avoid registering the key twice.
+  if (registered_.exchange(true))
+    return;
+
+  uint32_t slot = g_num_keys.fetch_add(1);
+  if (slot >= kMaxKeys) {
+    PERFETTO_LOG("Too many crash keys registered");
+    return;
+  }
+  g_keys[slot].store(this);
+}
+
+// Returns the number of chars written, without counting the \0.
+size_t CrashKey::ToString(char* dst, size_t len) {
+  if (len > 0)
+    *dst = '\0';
+  switch (type_.load(std::memory_order_relaxed)) {
+    case Type::kUnset:
+      break;
+    case Type::kInt:
+      return SprintfTrunc(dst, len, "%s: %" PRId64 "\n", name_,
+                          int_value_.load(std::memory_order_relaxed));
+    case Type::kStr:
+      char buf[sizeof(str_value_)];
+      for (size_t i = 0; i < sizeof(str_value_); i++)
+        buf[i] = str_value_[i].load(std::memory_order_relaxed);
+
+      // Don't assume |str_value_| is properly null-terminated.
+      return SprintfTrunc(dst, len, "%s: %.*s\n", name_, int(sizeof(buf)), buf);
+  }
+  return 0;
+}
+
+void UnregisterAllCrashKeysForTesting() {
+  g_num_keys.store(0);
+  for (auto& key : g_keys)
+    key.store(nullptr);
+}
+
+size_t SerializeCrashKeys(char* dst, size_t len) {
+  size_t written = 0;
+  uint32_t num_keys = g_num_keys.load();
+  if (len > 0)
+    *dst = '\0';
+  for (uint32_t i = 0; i < num_keys && written < len; i++) {
+    CrashKey* key = g_keys[i].load();
+    if (!key)
+      continue;  // Can happen if we hit this between the add and the store.
+    written += key->ToString(dst + written, len - written);
+  }
+  PERFETTO_DCHECK(written <= len);
+  PERFETTO_DCHECK(len == 0 || dst[written] == '\0');
+  return written;
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/ctrl_c_handler.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/ctrl_c_handler.h
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_CTRL_C_HANDLER_H_
+#define INCLUDE_PERFETTO_EXT_BASE_CTRL_C_HANDLER_H_
+
+namespace perfetto {
+namespace base {
+
+// On Linux/Android/Mac: installs SIGINT + SIGTERM signal handlers.
+// On Windows: installs a SetConsoleCtrlHandler() handler.
+// The passed handler must be async safe.
+using CtrlCHandlerFunction = void (*)();
+void InstallCtrlCHandler(CtrlCHandlerFunction);
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_CTRL_C_HANDLER_H_
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/ctrl_c_handler.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <Windows.h>
+#include <io.h>
+#else
+#include <signal.h>
+#include <unistd.h>
+#endif
+
+namespace perfetto {
+namespace base {
+
+namespace {
+CtrlCHandlerFunction g_handler = nullptr;
+}
+
+void InstallCtrlCHandler(CtrlCHandlerFunction handler) {
+  PERFETTO_CHECK(g_handler == nullptr);
+  g_handler = handler;
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  auto trampoline = [](DWORD type) -> int {
+    if (type == CTRL_C_EVENT) {
+      g_handler();
+      return true;
+    }
+    return false;
+  };
+  ::SetConsoleCtrlHandler(trampoline, true);
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+  // Setup signal handler.
+  struct sigaction sa {};
+
+// Glibc headers for sa_sigaction trigger this.
+#pragma GCC diagnostic push
+#if defined(__clang__)
+#pragma GCC diagnostic ignored "-Wdisabled-macro-expansion"
+#endif
+  sa.sa_handler = [](int) { g_handler(); };
+  sa.sa_flags = static_cast<decltype(sa.sa_flags)>(SA_RESETHAND | SA_RESTART);
+#pragma GCC diagnostic pop
+  sigaction(SIGINT, &sa, nullptr);
+  sigaction(SIGTERM, &sa, nullptr);
+#else
+  // Do nothing on NaCL and Fuchsia.
+  ignore_result(handler);
+#endif
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/event_fd.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/event_fd.h
+// gen_amalgamated begin header: include/perfetto/ext/base/scoped_file.h
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_SCOPED_FILE_H_
+#define INCLUDE_PERFETTO_EXT_BASE_SCOPED_FILE_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+#include <stdio.h>
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <dirent.h>  // For DIR* / opendir().
+#endif
+
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
+
+namespace perfetto {
+namespace base {
+
+namespace internal {
+// Used for the most common cases of ScopedResource where there is only one
+// invalid value.
+template <typename T, T InvalidValue>
+struct DefaultValidityChecker {
+  static bool IsValid(T t) { return t != InvalidValue; }
+};
+}  // namespace internal
+
+// RAII classes for auto-releasing fds and dirs.
+// if T is a pointer type, InvalidValue must be nullptr. Doing otherwise
+// causes weird unexpected behaviors (See https://godbolt.org/z/5nGMW4).
+template <typename T,
+          int (*CloseFunction)(T),
+          T InvalidValue,
+          bool CheckClose = true,
+          class Checker = internal::DefaultValidityChecker<T, InvalidValue>>
+class ScopedResource {
+ public:
+  using ValidityChecker = Checker;
+  static constexpr T kInvalid = InvalidValue;
+
+  explicit ScopedResource(T t = InvalidValue) : t_(t) {}
+  ScopedResource(ScopedResource&& other) noexcept {
+    t_ = other.t_;
+    other.t_ = InvalidValue;
+  }
+  ScopedResource& operator=(ScopedResource&& other) {
+    reset(other.t_);
+    other.t_ = InvalidValue;
+    return *this;
+  }
+  T get() const { return t_; }
+  T operator*() const { return t_; }
+  explicit operator bool() const { return Checker::IsValid(t_); }
+  void reset(T r = InvalidValue) {
+    if (Checker::IsValid(t_)) {
+      int res = CloseFunction(t_);
+      if (CheckClose)
+        PERFETTO_CHECK(res == 0);
+    }
+    t_ = r;
+  }
+  T release() {
+    T t = t_;
+    t_ = InvalidValue;
+    return t;
+  }
+  ~ScopedResource() { reset(InvalidValue); }
+
+ private:
+  ScopedResource(const ScopedResource&) = delete;
+  ScopedResource& operator=(const ScopedResource&) = delete;
+  T t_;
+};
+
+// Declared in file_utils.h. Forward declared to avoid #include cycles.
+int PERFETTO_EXPORT_COMPONENT CloseFile(int fd);
+
+// Use this for file resources obtained via open() and similar APIs.
+using ScopedFile = ScopedResource<int, CloseFile, -1>;
+using ScopedFstream = ScopedResource<FILE*, fclose, nullptr>;
+
+// Use this for resources that are HANDLE on Windows. See comments in
+// platform_handle.h
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+using ScopedPlatformHandle = ScopedResource<PlatformHandle,
+                                            ClosePlatformHandle,
+                                            /*InvalidValue=*/nullptr,
+                                            /*CheckClose=*/true,
+                                            PlatformHandleChecker>;
+#else
+// On non-windows systems we alias ScopedPlatformHandle to ScopedFile because
+// they are really the same. This is to allow assignments between the two in
+// Linux-specific code paths that predate ScopedPlatformHandle.
+static_assert(std::is_same<int, PlatformHandle>::value, "");
+using ScopedPlatformHandle = ScopedFile;
+
+// DIR* does not exist on Windows.
+using ScopedDir = ScopedResource<DIR*, closedir, nullptr>;
+#endif
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_SCOPED_FILE_H_
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_EVENT_FD_H_
+#define INCLUDE_PERFETTO_EXT_BASE_EVENT_FD_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+
+namespace perfetto {
+namespace base {
+
+// A waitable event that can be used with poll/select.
+// This is really a wrapper around eventfd_create with a pipe-based fallback
+// for other platforms where eventfd is not supported.
+class EventFd {
+ public:
+  EventFd();
+  ~EventFd();
+  EventFd(EventFd&&) noexcept = default;
+  EventFd& operator=(EventFd&&) = default;
+
+  // The non-blocking file descriptor that can be polled to wait for the event.
+  PlatformHandle fd() const { return event_handle_.get(); }
+
+  // Can be called from any thread.
+  void Notify();
+
+  // Can be called from any thread. If more Notify() are queued a Clear() call
+  // can clear all of them (up to 16 per call).
+  void Clear();
+
+ private:
+  // The eventfd, when eventfd is supported, otherwise this is the read end of
+  // the pipe for fallback mode.
+  ScopedPlatformHandle event_handle_;
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) &&   \
+    !PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
+    !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  // On Mac and other non-Linux UNIX platforms a pipe-based fallback is used.
+  // The write end of the wakeup pipe.
+  ScopedFile write_fd_;
+#endif
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_EVENT_FD_H_
+// gen_amalgamated begin header: include/perfetto/ext/base/pipe.h
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_PIPE_H_
+#define INCLUDE_PERFETTO_EXT_BASE_PIPE_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+
+namespace perfetto {
+namespace base {
+
+class Pipe {
+ public:
+  enum Flags {
+    kBothBlock = 0,
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    kBothNonBlock,
+    kRdNonBlock,
+    kWrNonBlock,
+#endif
+  };
+
+  static Pipe Create(Flags = kBothBlock);
+
+  Pipe();
+  Pipe(Pipe&&) noexcept;
+  Pipe& operator=(Pipe&&);
+
+  ScopedPlatformHandle rd;
+  ScopedPlatformHandle wr;
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_PIPE_H_
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+#include <errno.h>
+#include <stdint.h>
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <Windows.h>
+#include <synchapi.h>
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#include <sys/eventfd.h>
+#include <unistd.h>
+#else  // Mac, Fuchsia and other non-Linux UNIXes
+#include <unistd.h>
+#endif
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/event_fd.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+
+namespace perfetto {
+namespace base {
+
+EventFd::~EventFd() = default;
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+EventFd::EventFd() {
+  event_handle_.reset(
+      CreateEventA(/*lpEventAttributes=*/nullptr, /*bManualReset=*/true,
+                   /*bInitialState=*/false, /*bInitialState=*/nullptr));
+}
+
+void EventFd::Notify() {
+  if (!SetEvent(event_handle_.get()))  // 0: fail, !0: success, unlike UNIX.
+    PERFETTO_DFATAL("EventFd::Notify()");
+}
+
+void EventFd::Clear() {
+  if (!ResetEvent(event_handle_.get()))  // 0: fail, !0: success, unlike UNIX.
+    PERFETTO_DFATAL("EventFd::Clear()");
+}
+
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+
+EventFd::EventFd() {
+  event_handle_.reset(eventfd(/*initval=*/0, EFD_CLOEXEC | EFD_NONBLOCK));
+  PERFETTO_CHECK(event_handle_);
+}
+
+void EventFd::Notify() {
+  const uint64_t value = 1;
+  ssize_t ret = write(event_handle_.get(), &value, sizeof(value));
+  if (ret <= 0 && errno != EAGAIN)
+    PERFETTO_DFATAL("EventFd::Notify()");
+}
+
+void EventFd::Clear() {
+  uint64_t value;
+  ssize_t ret =
+      PERFETTO_EINTR(read(event_handle_.get(), &value, sizeof(value)));
+  if (ret <= 0 && errno != EAGAIN)
+    PERFETTO_DFATAL("EventFd::Clear()");
+}
+
+#else
+
+EventFd::EventFd() {
+  // Make the pipe non-blocking so that we never block the waking thread (either
+  // the main thread or another one) when scheduling a wake-up.
+  Pipe pipe = Pipe::Create(Pipe::kBothNonBlock);
+  event_handle_ = ScopedPlatformHandle(std::move(pipe.rd).release());
+  write_fd_ = std::move(pipe.wr);
+}
+
+void EventFd::Notify() {
+  const uint64_t value = 1;
+  ssize_t ret = write(write_fd_.get(), &value, sizeof(uint8_t));
+  if (ret <= 0 && errno != EAGAIN)
+    PERFETTO_DFATAL("EventFd::Notify()");
+}
+
+void EventFd::Clear() {
+  // Drain the byte(s) written to the wake-up pipe. We can potentially read
+  // more than one byte if several wake-ups have been scheduled.
+  char buffer[16];
+  ssize_t ret =
+      PERFETTO_EINTR(read(event_handle_.get(), &buffer[0], sizeof(buffer)));
+  if (ret <= 0 && errno != EAGAIN)
+    PERFETTO_DFATAL("EventFd::Clear()");
+}
+#endif
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/file_utils.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/file_utils.h
+// gen_amalgamated begin header: include/perfetto/base/status.h
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_BASE_STATUS_H_
+#define INCLUDE_PERFETTO_BASE_STATUS_H_
+
+#include <optional>
+#include <string>
+#include <string_view>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+
+namespace perfetto {
+namespace base {
+
+// Represents either the success or the failure message of a function.
+// This can used as the return type of functions which would usually return an
+// bool for success or int for errno but also wants to add some string context
+// (ususally for logging).
+//
+// Similar to absl::Status, an optional "payload" can also be included with more
+// context about the error. This allows passing additional metadata about the
+// error (e.g. location of errors, potential mitigations etc).
+class PERFETTO_EXPORT_COMPONENT Status {
+ public:
+  Status() : ok_(true) {}
+  explicit Status(std::string msg) : ok_(false), message_(std::move(msg)) {
+    PERFETTO_CHECK(!message_.empty());
+  }
+
+  // Copy operations.
+  Status(const Status&) = default;
+  Status& operator=(const Status&) = default;
+
+  // Move operations. The moved-from state is valid but unspecified.
+  Status(Status&&) noexcept = default;
+  Status& operator=(Status&&) = default;
+
+  bool ok() const { return ok_; }
+
+  // When ok() is false this returns the error message. Returns the empty string
+  // otherwise.
+  const std::string& message() const { return message_; }
+  const char* c_message() const { return message_.c_str(); }
+
+  //////////////////////////////////////////////////////////////////////////////
+  // Payload Management APIs
+  //////////////////////////////////////////////////////////////////////////////
+
+  // Payloads can be attached to error statuses to provide additional context.
+  //
+  // Payloads are (key, value) pairs, where the key is a string acting as a
+  // unique "type URL" and the value is an opaque string. The "type URL" should
+  // be unique, follow the format of a URL and, ideally, documentation on how to
+  // interpret its associated data should be available.
+  //
+  // To attach a payload to a status object, call `Status::SetPayload()`.
+  // Similarly, to extract the payload from a status, call
+  // `Status::GetPayload()`.
+  //
+  // Note: the payload APIs are only meaningful to call when the status is an
+  // error. Otherwise, all methods are noops.
+
+  // Gets the payload for the given |type_url| if one exists.
+  //
+  // Will always return std::nullopt if |ok()|.
+  std::optional<std::string_view> GetPayload(std::string_view type_url) const;
+
+  // Sets the payload for the given key. The key should
+  //
+  // Will always do nothing if |ok()|.
+  void SetPayload(std::string_view type_url, std::string value);
+
+  // Erases the payload for the given string and returns true if the payload
+  // existed and was erased.
+  //
+  // Will always do nothing if |ok()|.
+  bool ErasePayload(std::string_view type_url);
+
+ private:
+  struct Payload {
+    std::string type_url;
+    std::string payload;
+  };
+
+  bool ok_ = false;
+  std::string message_;
+  std::vector<Payload> payloads_;
+};
+
+// Returns a status object which represents the Ok status.
+inline Status OkStatus() {
+  return Status();
+}
+
+PERFETTO_PRINTF_FORMAT(1, 2) Status ErrStatus(const char* format, ...);
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_BASE_STATUS_H_
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_FILE_UTILS_H_
+#define INCLUDE_PERFETTO_EXT_BASE_FILE_UTILS_H_
+
+#include <fcntl.h>  // For mode_t & O_RDONLY/RDWR. Exists also on Windows.
+#include <stddef.h>
+
+#include <optional>
+#include <string>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/status.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+
+namespace perfetto {
+namespace base {
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+using FileOpenMode = int;
+inline constexpr char kDevNull[] = "NUL";
+#else
+using FileOpenMode = mode_t;
+inline constexpr char kDevNull[] = "/dev/null";
+#endif
+
+constexpr FileOpenMode kFileModeInvalid = static_cast<FileOpenMode>(-1);
+
+bool ReadPlatformHandle(PlatformHandle, std::string* out);
+bool ReadFileDescriptor(int fd, std::string* out);
+bool ReadFileStream(FILE* f, std::string* out);
+bool ReadFile(const std::string& path, std::string* out);
+
+// A wrapper around read(2). It deals with Linux vs Windows includes. It also
+// deals with handling EINTR. Has the same semantics of UNIX's read(2).
+ssize_t Read(int fd, void* dst, size_t dst_size);
+
+// Call write until all data is written or an error is detected.
+//
+// man 2 write:
+//   If a write() is interrupted by a signal handler before any bytes are
+//   written, then the call fails with the error EINTR; if it is
+//   interrupted after at least one byte has been written, the call
+//   succeeds, and returns the number of bytes written.
+ssize_t WriteAll(int fd, const void* buf, size_t count);
+
+ssize_t WriteAllHandle(PlatformHandle, const void* buf, size_t count);
+
+ScopedFile OpenFile(const std::string& path,
+                    int flags,
+                    FileOpenMode = kFileModeInvalid);
+ScopedFstream OpenFstream(const char* path, const char* mode);
+
+// This is an alias for close(). It's to avoid leaking Windows.h in headers.
+// Exported because ScopedFile is used in the /include/ext API by Chromium
+// component builds.
+int PERFETTO_EXPORT_COMPONENT CloseFile(int fd);
+
+bool FlushFile(int fd);
+
+// Returns true if mkdir succeeds, false if it fails (see errno in that case).
+bool Mkdir(const std::string& path);
+
+// Calls rmdir() on UNIX, _rmdir() on Windows.
+bool Rmdir(const std::string& path);
+
+// Wrapper around access(path, F_OK).
+bool FileExists(const std::string& path);
+
+// Gets the extension for a filename. If the file has two extensions, returns
+// only the last one (foo.pb.gz => .gz). Returns empty string if there is no
+// extension.
+std::string GetFileExtension(const std::string& filename);
+
+// Puts the path to all files under |dir_path| in |output|, recursively walking
+// subdirectories. File paths are relative to |dir_path|. Only files are
+// included, not directories. Path separator is always '/', even on windows (not
+// '\').
+base::Status ListFilesRecursive(const std::string& dir_path,
+                                std::vector<std::string>& output);
+
+// Sets |path|'s owner group to |group_name| and permission mode bits to
+// |mode_bits|.
+base::Status SetFilePermissions(const std::string& path,
+                                const std::string& group_name,
+                                const std::string& mode_bits);
+
+// Returns the size of the file located at |path|, or nullopt in case of error.
+std::optional<uint64_t> GetFileSize(const std::string& path);
+
+// Returns the size of the open file |fd|, or nullopt in case of error.
+std::optional<uint64_t> GetFileSize(PlatformHandle fd);
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_FILE_UTILS_H_
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
+
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <algorithm>
+#include <deque>
+#include <optional>
+#include <string>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
+// gen_amalgamated expanded: #include "perfetto/base/status.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/platform.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <Windows.h>
+#include <direct.h>
+#include <io.h>
+#include <stringapiset.h>
+#else
+#include <dirent.h>
+#include <unistd.h>
+#endif
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+#define PERFETTO_SET_FILE_PERMISSIONS
+#include <fcntl.h>
+#include <grp.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#endif
+
+namespace perfetto {
+namespace base {
+namespace {
+constexpr size_t kBufSize = 2048;
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+// Wrap FindClose to: (1) make the return unix-style; (2) deal with stdcall.
+int CloseFindHandle(HANDLE h) {
+  return FindClose(h) ? 0 : -1;
+}
+
+std::optional<std::wstring> ToUtf16(const std::string str) {
+  int len = MultiByteToWideChar(CP_UTF8, 0, str.data(),
+                                static_cast<int>(str.size()), nullptr, 0);
+  if (len < 0) {
+    return std::nullopt;
+  }
+  std::vector<wchar_t> tmp;
+  tmp.resize(static_cast<std::vector<wchar_t>::size_type>(len));
+  len =
+      MultiByteToWideChar(CP_UTF8, 0, str.data(), static_cast<int>(str.size()),
+                          tmp.data(), static_cast<int>(tmp.size()));
+  if (len < 0) {
+    return std::nullopt;
+  }
+  PERFETTO_CHECK(static_cast<std::vector<wchar_t>::size_type>(len) ==
+                 tmp.size());
+  return std::wstring(tmp.data(), tmp.size());
+}
+
+#endif
+
+}  // namespace
+
+ssize_t Read(int fd, void* dst, size_t dst_size) {
+  ssize_t ret;
+  platform::BeforeMaybeBlockingSyscall();
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  ret = _read(fd, dst, static_cast<unsigned>(dst_size));
+#else
+  ret = PERFETTO_EINTR(read(fd, dst, dst_size));
+#endif
+  platform::AfterMaybeBlockingSyscall();
+  return ret;
+}
+
+bool ReadFileDescriptor(int fd, std::string* out) {
+  // Do not override existing data in string.
+  size_t i = out->size();
+
+  struct stat buf {};
+  if (fstat(fd, &buf) != -1) {
+    if (buf.st_size > 0)
+      out->resize(i + static_cast<size_t>(buf.st_size));
+  }
+
+  ssize_t bytes_read;
+  for (;;) {
+    if (out->size() < i + kBufSize)
+      out->resize(out->size() + kBufSize);
+
+    bytes_read = Read(fd, &((*out)[i]), kBufSize);
+    if (bytes_read > 0) {
+      i += static_cast<size_t>(bytes_read);
+    } else {
+      out->resize(i);
+      return bytes_read == 0;
+    }
+  }
+}
+
+bool ReadPlatformHandle(PlatformHandle h, std::string* out) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  // Do not override existing data in string.
+  size_t i = out->size();
+
+  for (;;) {
+    if (out->size() < i + kBufSize)
+      out->resize(out->size() + kBufSize);
+    DWORD bytes_read = 0;
+    auto res = ::ReadFile(h, &((*out)[i]), kBufSize, &bytes_read, nullptr);
+    if (res && bytes_read > 0) {
+      i += static_cast<size_t>(bytes_read);
+    } else {
+      out->resize(i);
+      const bool is_eof = res && bytes_read == 0;
+      auto err = res ? 0 : GetLastError();
+      // The "Broken pipe" error on Windows is slighly different than Unix:
+      // On Unix: a "broken pipe" error can happen only on the writer side. On
+      // the reader there is no broken pipe, just a EOF.
+      // On windows: the reader also sees a broken pipe error.
+      // Here we normalize on the Unix behavior, treating broken pipe as EOF.
+      return is_eof || err == ERROR_BROKEN_PIPE;
+    }
+  }
+#else
+  return ReadFileDescriptor(h, out);
+#endif
+}
+
+bool ReadFileStream(FILE* f, std::string* out) {
+  return ReadFileDescriptor(fileno(f), out);
+}
+
+bool ReadFile(const std::string& path, std::string* out) {
+  base::ScopedFile fd = base::OpenFile(path, O_RDONLY);
+  if (!fd)
+    return false;
+
+  return ReadFileDescriptor(*fd, out);
+}
+
+ssize_t WriteAll(int fd, const void* buf, size_t count) {
+  size_t written = 0;
+  while (written < count) {
+    // write() on windows takes an unsigned int size.
+    uint32_t bytes_left = static_cast<uint32_t>(
+        std::min(count - written, static_cast<size_t>(UINT32_MAX)));
+    platform::BeforeMaybeBlockingSyscall();
+    ssize_t wr = PERFETTO_EINTR(
+        write(fd, static_cast<const char*>(buf) + written, bytes_left));
+    platform::AfterMaybeBlockingSyscall();
+    if (wr == 0)
+      break;
+    if (wr < 0)
+      return wr;
+    written += static_cast<size_t>(wr);
+  }
+  return static_cast<ssize_t>(written);
+}
+
+ssize_t WriteAllHandle(PlatformHandle h, const void* buf, size_t count) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  DWORD wsize = 0;
+  if (::WriteFile(h, buf, static_cast<DWORD>(count), &wsize, nullptr)) {
+    return wsize;
+  } else {
+    return -1;
+  }
+#else
+  return WriteAll(h, buf, count);
+#endif
+}
+
+bool FlushFile(int fd) {
+  PERFETTO_DCHECK(fd != 0);
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  return !PERFETTO_EINTR(fdatasync(fd));
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  return !PERFETTO_EINTR(_commit(fd));
+#else
+  return !PERFETTO_EINTR(fsync(fd));
+#endif
+}
+
+bool Mkdir(const std::string& path) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  return _mkdir(path.c_str()) == 0;
+#else
+  return mkdir(path.c_str(), 0755) == 0;
+#endif
+}
+
+bool Rmdir(const std::string& path) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  return _rmdir(path.c_str()) == 0;
+#else
+  return rmdir(path.c_str()) == 0;
+#endif
+}
+
+int CloseFile(int fd) {
+  return close(fd);
+}
+
+ScopedFile OpenFile(const std::string& path, int flags, FileOpenMode mode) {
+  // If a new file might be created, ensure that the permissions for the new
+  // file are explicitly specified.
+  PERFETTO_CHECK((flags & O_CREAT) == 0 || mode != kFileModeInvalid);
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  // Always use O_BINARY on Windows, to avoid silly EOL translations.
+  ScopedFile fd(_open(path.c_str(), flags | O_BINARY, mode));
+#else
+  // Always open a ScopedFile with O_CLOEXEC so we can safely fork and exec.
+  ScopedFile fd(open(path.c_str(), flags | O_CLOEXEC, mode));
+#endif
+  return fd;
+}
+
+ScopedFstream OpenFstream(const char* path, const char* mode) {
+  ScopedFstream file;
+// On Windows fopen interprets filename using the ANSI or OEM codepage but
+// sqlite3_value_text returns a UTF-8 string. To make sure we interpret the
+// filename correctly we use _wfopen and a UTF-16 string on windows.
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  auto w_path = ToUtf16(path);
+  auto w_mode = ToUtf16(mode);
+  if (w_path && w_mode) {
+    file.reset(_wfopen(w_path->c_str(), w_mode->c_str()));
+  }
+#else
+  file.reset(fopen(path, mode));
+#endif
+  return file;
+}
+
+bool FileExists(const std::string& path) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  return _access(path.c_str(), 0) == 0;
+#else
+  return access(path.c_str(), F_OK) == 0;
+#endif
+}
+
+// Declared in base/platform_handle.h.
+int ClosePlatformHandle(PlatformHandle handle) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  // Make the return value UNIX-style.
+  return CloseHandle(handle) ? 0 : -1;
+#else
+  return close(handle);
+#endif
+}
+
+base::Status ListFilesRecursive(const std::string& dir_path,
+                                std::vector<std::string>& output) {
+  std::string root_dir_path = dir_path;
+  if (root_dir_path.back() == '\\') {
+    root_dir_path.back() = '/';
+  } else if (root_dir_path.back() != '/') {
+    root_dir_path.push_back('/');
+  }
+
+  // dir_queue contains full paths to the directories. The paths include the
+  // root_dir_path at the beginning and the trailing slash at the end.
+  std::deque<std::string> dir_queue;
+  dir_queue.push_back(root_dir_path);
+
+  while (!dir_queue.empty()) {
+    const std::string cur_dir = std::move(dir_queue.front());
+    dir_queue.pop_front();
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
+    return base::ErrStatus("ListFilesRecursive not supported yet");
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    std::string glob_path = cur_dir + "*";
+    // + 1 because we also have to count the NULL terminator.
+    if (glob_path.length() + 1 > MAX_PATH)
+      return base::ErrStatus("Directory path %s is too long", dir_path.c_str());
+    WIN32_FIND_DATAA ffd;
+
+    base::ScopedResource<HANDLE, CloseFindHandle, nullptr, false,
+                         base::PlatformHandleChecker>
+        hFind(FindFirstFileA(glob_path.c_str(), &ffd));
+    if (!hFind) {
+      // For empty directories, there should be at least one entry '.'.
+      // If FindFirstFileA returns INVALID_HANDLE_VALUE, this means directory
+      // couldn't be accessed.
+      return base::ErrStatus("Failed to open directory %s", cur_dir.c_str());
+    }
+    do {
+      if (strcmp(ffd.cFileName, ".") == 0 || strcmp(ffd.cFileName, "..") == 0)
+        continue;
+      if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+        std::string subdir_path = cur_dir + ffd.cFileName + '/';
+        dir_queue.push_back(subdir_path);
+      } else {
+        const std::string full_path = cur_dir + ffd.cFileName;
+        PERFETTO_CHECK(full_path.length() > root_dir_path.length());
+        output.push_back(full_path.substr(root_dir_path.length()));
+      }
+    } while (FindNextFileA(*hFind, &ffd));
+#else
+    ScopedDir dir = ScopedDir(opendir(cur_dir.c_str()));
+    if (!dir) {
+      return base::ErrStatus("Failed to open directory %s", cur_dir.c_str());
+    }
+    for (auto* dirent = readdir(dir.get()); dirent != nullptr;
+         dirent = readdir(dir.get())) {
+      if (strcmp(dirent->d_name, ".") == 0 ||
+          strcmp(dirent->d_name, "..") == 0) {
+        continue;
+      }
+      if (dirent->d_type == DT_DIR) {
+        dir_queue.push_back(cur_dir + dirent->d_name + '/');
+      } else if (dirent->d_type == DT_REG) {
+        const std::string full_path = cur_dir + dirent->d_name;
+        PERFETTO_CHECK(full_path.length() > root_dir_path.length());
+        output.push_back(full_path.substr(root_dir_path.length()));
+      }
+    }
+#endif
+  }
+  return base::OkStatus();
+}
+
+std::string GetFileExtension(const std::string& filename) {
+  auto ext_idx = filename.rfind('.');
+  if (ext_idx == std::string::npos)
+    return std::string();
+  return filename.substr(ext_idx);
+}
+
+base::Status SetFilePermissions(const std::string& file_path,
+                                const std::string& group_name_or_id,
+                                const std::string& mode_bits) {
+#ifdef PERFETTO_SET_FILE_PERMISSIONS
+  PERFETTO_CHECK(!file_path.empty());
+  PERFETTO_CHECK(!group_name_or_id.empty());
+
+  // Default |group_id| to -1 for not changing the group ownership.
+  gid_t group_id = static_cast<gid_t>(-1);
+  auto maybe_group_id = base::StringToUInt32(group_name_or_id);
+  if (maybe_group_id) {  // A numerical group ID.
+    group_id = *maybe_group_id;
+  } else {  // A group name.
+    struct group* file_group = nullptr;
+    // Query the group ID of |group|.
+    do {
+      file_group = getgrnam(group_name_or_id.c_str());
+    } while (file_group == nullptr && errno == EINTR);
+    if (file_group == nullptr) {
+      return base::ErrStatus("Failed to get group information of %s ",
+                             group_name_or_id.c_str());
+    }
+    group_id = file_group->gr_gid;
+  }
+
+  if (PERFETTO_EINTR(chown(file_path.c_str(), geteuid(), group_id))) {
+    return base::ErrStatus("Failed to chown %s ", file_path.c_str());
+  }
+
+  // |mode| accepts values like "0660" as "rw-rw----" mode bits.
+  auto mode_value = base::StringToInt32(mode_bits, 8);
+  if (!(mode_bits.size() == 4 && mode_value.has_value())) {
+    return base::ErrStatus(
+        "The chmod mode bits must be a 4-digit octal number, e.g. 0660");
+  }
+  if (PERFETTO_EINTR(
+          chmod(file_path.c_str(), static_cast<mode_t>(mode_value.value())))) {
+    return base::ErrStatus("Failed to chmod %s", file_path.c_str());
+  }
+  return base::OkStatus();
+#else
+  base::ignore_result(file_path);
+  base::ignore_result(group_name_or_id);
+  base::ignore_result(mode_bits);
+  return base::ErrStatus(
+      "Setting file permissions is not supported on this platform");
+#endif
+}
+
+std::optional<uint64_t> GetFileSize(const std::string& file_path) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  // This does not use base::OpenFile to avoid getting an exclusive lock.
+  base::ScopedPlatformHandle fd(
+      CreateFileA(file_path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr,
+                  OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr));
+#else
+  base::ScopedFile fd(base::OpenFile(file_path, O_RDONLY | O_CLOEXEC));
+#endif
+  if (!fd) {
+    return std::nullopt;
+  }
+  return GetFileSize(*fd);
+}
+
+std::optional<uint64_t> GetFileSize(PlatformHandle fd) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  LARGE_INTEGER file_size;
+  file_size.QuadPart = 0;
+  if (!GetFileSizeEx(fd, &file_size)) {
+    return std::nullopt;
+  }
+  static_assert(sizeof(decltype(file_size.QuadPart)) <= sizeof(uint64_t));
+  return static_cast<uint64_t>(file_size.QuadPart);
+#else
+  struct stat buf {};
+  if (fstat(fd, &buf) == -1) {
+    return std::nullopt;
+  }
+  static_assert(sizeof(decltype(buf.st_size)) <= sizeof(uint64_t));
+  return static_cast<uint64_t>(buf.st_size);
+#endif
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/getopt_compat.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/getopt_compat.h
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_GETOPT_COMPAT_H_
+#define INCLUDE_PERFETTO_EXT_BASE_GETOPT_COMPAT_H_
+
+#include <cstddef>  // For std::nullptr_t
+
+// No translation units other than base/getopt.h and getopt_compat_unittest.cc
+// should directly include this file. Use base/getopt.h instead.
+
+namespace perfetto {
+namespace base {
+namespace getopt_compat {
+
+// A tiny getopt() replacement for Windows, which doesn't have <getopt.h>.
+// This implementation is based on the subset of features that we use in the
+// Perfetto codebase. It doesn't even try to deal with the full surface of GNU's
+// getopt().
+// Limitations:
+// - getopt_long_only() is not supported.
+// - optional_argument is not supported. That is extremely subtle and caused us
+//   problems in the past with GNU's getopt.
+// - It does not reorder non-option arguments. It behaves like MacOS getopt, or
+//   GNU's when POSIXLY_CORRECT=1.
+// - Doesn't expose optopt or opterr.
+// - option.flag and longindex are not supported and must be nullptr.
+
+enum {
+  no_argument = 0,
+  required_argument = 1,
+};
+
+struct option {
+  const char* name;
+  int has_arg;
+  std::nullptr_t flag;  // Only nullptr is supported.
+  int val;
+};
+
+extern char* optarg;
+extern int optind;
+extern int optopt;
+extern int opterr;
+
+int getopt_long(int argc,
+                char** argv,
+                const char* shortopts,
+                const option* longopts,
+                std::nullptr_t /*longindex is not supported*/);
+
+int getopt(int argc, char** argv, const char* shortopts);
+
+}  // namespace getopt_compat
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_GETOPT_COMPAT_H_
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/getopt_compat.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+
+namespace perfetto {
+namespace base {
+namespace getopt_compat {
+
+char* optarg = nullptr;
+int optind = 0;
+int optopt = 0;
+int opterr = 1;
+
+namespace {
+
+char* nextchar = nullptr;
+
+const option* LookupLongOpt(const std::vector<option>& opts,
+                            const char* name,
+                            size_t len) {
+  for (const option& opt : opts) {
+    if (strncmp(opt.name, name, len) == 0 && strlen(opt.name) == len)
+      return &opt;
+  }
+  return nullptr;
+}
+
+const option* LookupShortOpt(const std::vector<option>& opts, char c) {
+  for (const option& opt : opts) {
+    if (!*opt.name && opt.val == c)
+      return &opt;
+  }
+  return nullptr;
+}
+
+bool ParseOpts(const char* shortopts,
+               const option* longopts,
+               std::vector<option>* res) {
+  // Parse long options first.
+  for (const option* lopt = longopts; lopt && lopt->name; lopt++) {
+    PERFETTO_CHECK(lopt->flag == nullptr);
+    PERFETTO_CHECK(lopt->has_arg == no_argument ||
+                   lopt->has_arg == required_argument);
+    res->emplace_back(*lopt);
+  }
+
+  // Merge short options.
+  for (const char* sopt = shortopts; sopt && *sopt;) {
+    const size_t idx = static_cast<size_t>(sopt - shortopts);
+    char c = *sopt++;
+    bool valid = (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
+                 (c >= '0' && c <= '9');
+    if (!valid) {
+      fprintf(stderr,
+              "Error parsing shortopts. Unexpected char '%c' at offset %zu\n",
+              c, idx);
+      return false;
+    }
+    res->emplace_back();
+    option& opt = res->back();
+    opt.name = "";
+    opt.val = c;
+    opt.has_arg = no_argument;
+    if (*sopt == ':') {
+      opt.has_arg = required_argument;
+      ++sopt;
+    }
+  }
+  return true;
+}
+
+}  // namespace
+
+int getopt_long(int argc,
+                char** argv,
+                const char* shortopts,
+                const option* longopts,
+                std::nullptr_t /*longind*/) {
+  std::vector<option> opts;
+  optarg = nullptr;
+
+  if (optind == 0)
+    optind = 1;
+
+  if (optind >= argc)
+    return -1;
+
+  if (!ParseOpts(shortopts, longopts, &opts))
+    return '?';
+
+  char* arg = argv[optind];
+  optopt = 0;
+
+  if (!nextchar) {
+    // If |nextchar| is null we are NOT in the middle of a short option and we
+    // should parse the next argv.
+    if (strncmp(arg, "--", 2) == 0 && strlen(arg) > 2) {
+      // A --long option.
+      arg += 2;
+      char* sep = strchr(arg, '=');
+      optind++;
+
+      size_t len = sep ? static_cast<size_t>(sep - arg) : strlen(arg);
+      const option* opt = LookupLongOpt(opts, arg, len);
+
+      if (!opt) {
+        if (opterr)
+          fprintf(stderr, "unrecognized option '--%s'\n", arg);
+        return '?';
+      }
+
+      optopt = opt->val;
+      if (opt->has_arg == no_argument) {
+        if (sep) {
+          fprintf(stderr, "option '--%s' doesn't allow an argument\n", arg);
+          return '?';
+        } else {
+          return opt->val;
+        }
+      } else if (opt->has_arg == required_argument) {
+        if (sep) {
+          optarg = sep + 1;
+          return opt->val;
+        } else if (optind >= argc) {
+          if (opterr)
+            fprintf(stderr, "option '--%s' requires an argument\n", arg);
+          return '?';
+        } else {
+          optarg = argv[optind++];
+          return opt->val;
+        }
+      }
+      // has_arg must be either |no_argument| or |required_argument|. We
+      // shoulnd't get here unless the check in ParseOpts() has a bug.
+      PERFETTO_CHECK(false);
+    }  // if (arg ~= "--*").
+
+    if (strlen(arg) > 1 && arg[0] == '-' && arg[1] != '-') {
+      // A sequence of short options. Parsing logic continues below.
+      nextchar = &arg[1];
+    }
+  }  // if(!nextchar)
+
+  if (nextchar) {
+    // At this point either:
+    // 1. This is the first char of a sequence of short options, and we fell
+    //    through here from the lines above.
+    // 2. This is the N (>1) char of a sequence of short options, and we got
+    //    here from a new getopt() call to getopt().
+    const char cur_char = *nextchar;
+    PERFETTO_CHECK(cur_char != '\0');
+
+    // Advance the option char in any case, before we start reasoning on them.
+    // if we got to the end of the "-abc" sequence, increment optind so the next
+    // getopt() call resumes from the next argv argument.
+    if (*(++nextchar) == '\0') {
+      nextchar = nullptr;
+      ++optind;
+    }
+
+    const option* opt = LookupShortOpt(opts, cur_char);
+    optopt = cur_char;
+    if (!opt) {
+      if (opterr)
+        fprintf(stderr, "invalid option -- '%c'\n", cur_char);
+      return '?';
+    }
+    if (opt->has_arg == no_argument) {
+      return cur_char;
+    } else if (opt->has_arg == required_argument) {
+      // This is a subtle getopt behavior. Say you call `tar -fx`, there are
+      // two cases:
+      // 1. If 'f' is no_argument then 'x' (and anything else after) is
+      //    interpreted as an independent argument (like `tar -f -x`).
+      // 2. If 'f' is required_argument, than everything else after the 'f'
+      //    is interpreted as the option argument (like `tar -f x`)
+      if (!nextchar) {
+        // Case 1.
+        if (optind >= argc) {
+          if (opterr)
+            fprintf(stderr, "option requires an argument -- '%c'\n", cur_char);
+          return '?';
+        } else {
+          optarg = argv[optind++];
+          return cur_char;
+        }
+      } else {
+        // Case 2.
+        optarg = nextchar;
+        nextchar = nullptr;
+        optind++;
+        return cur_char;
+      }
+    }
+    PERFETTO_CHECK(false);
+  }  // if (nextchar)
+
+  // If we get here, we found the first non-option argument. Stop here.
+
+  if (strcmp(arg, "--") == 0)
+    optind++;
+
+  return -1;
+}
+
+int getopt(int argc, char** argv, const char* shortopts) {
+  return getopt_long(argc, argv, shortopts, nullptr, nullptr);
+}
+
+}  // namespace getopt_compat
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/logging.cc
+// gen_amalgamated begin header: src/base/log_ring_buffer.h
+// gen_amalgamated begin header: include/perfetto/ext/base/thread_annotations.h
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_ANNOTATIONS_H_
+#define INCLUDE_PERFETTO_EXT_BASE_THREAD_ANNOTATIONS_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+// Windows TSAN doesn't currently support these annotations.
+#if defined(THREAD_SANITIZER) && !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+extern "C" {
+void AnnotateBenignRaceSized(const char* file,
+                             int line,
+                             const volatile void* address,
+                             size_t size,
+                             const char* description);
+}
+
+#define PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(pointer, size, description) \
+  AnnotateBenignRaceSized(__FILE__, __LINE__, pointer, size, description);
+#else  // defined(ADDRESS_SANITIZER)
+#define PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(pointer, size, description)
+#endif  // defined(ADDRESS_SANITIZER)
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_THREAD_ANNOTATIONS_H_
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_BASE_LOG_RING_BUFFER_H_
+#define SRC_BASE_LOG_RING_BUFFER_H_
+
+#include <stddef.h>
+#include <stdio.h>
+
+#include <array>
+#include <atomic>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_annotations.h"
+
+namespace perfetto {
+namespace base {
+
+// Defined out of line because a static constexpr requires static storage if
+// ODR-used, not worth adding a .cc file just for tests.
+constexpr size_t kLogRingBufEntries = 8;
+constexpr size_t kLogRingBufMsgLen = 256;
+
+// A static non-allocating ring-buffer to hold the most recent log events.
+// This class is really an implementation detail of logging.cc. The only reason
+// why is fully defined in a dedicated header is for allowing unittesting,
+// without leaking extra headers into logging.h (which is a high-fanout header).
+// This is used to report the last logs in a crash report when a CHECK/FATAL
+// is encountered.
+// This class has just an Append() method to insert events into the buffer and
+// a Read() to read the events in FIFO order. Read() is non-destructive.
+//
+// Thread safety considerations:
+// - The Append() method can be called concurrently by several threads, unless
+//   there are > kLogRingBufEntries concurrent threads. Even if that happens,
+//   case some events will contain a mix of strings but the behavior of
+//   futher Append() and Read() is still defined.
+// - The Read() method is not thread safe but it's fine in practice. Even if
+//   it's called concurrently with other Append(), it only causes some partial
+//   events to be emitted in output.
+// In both cases, we never rely purely on \0, all operations are size-bound.
+//
+// See logging_unittest.cc for tests.
+class LogRingBuffer {
+ public:
+  LogRingBuffer() = default;
+  LogRingBuffer(const LogRingBuffer&) = delete;
+  LogRingBuffer& operator=(const LogRingBuffer&) = delete;
+  LogRingBuffer(LogRingBuffer&&) = delete;
+  LogRingBuffer& operator=(LogRingBuffer&&) = delete;
+
+  // This takes three arguments because it fits its only caller (logging.cc).
+  // The args are just concatenated together (plus one space before the msg).
+  void Append(StringView tstamp, StringView source, StringView log_msg) {
+    // Reserve atomically a slot in the ring buffer, so any concurrent Append()
+    // won't overlap (unless too many concurrent Append() happen together).
+    // There is no strict synchronization here, |event_slot_| is atomic only for
+    // the sake of avoiding colliding on the same slot but does NOT guarantee
+    // full consistency and integrity of the log messages written in each slot.
+    // A release-store (or acq+rel) won't be enough for full consistency. Two
+    // threads that race on Append() and take the N+1 and N+2 slots could finish
+    // the write in reverse order. So Read() would need to synchronize with
+    // something else (either a per-slot atomic flag or with a second atomic
+    // counter which is incremented after the snprintf). Both options increase
+    // the cost of Append() with no huge benefits (90% of the perfetto services
+    // where we use it is single thread, and the log ring buffer is disabled
+    // on non-standalone builds like the SDK).
+    uint32_t slot = event_slot_.fetch_add(1, std::memory_order_relaxed);
+    slot = slot % kLogRingBufEntries;
+
+    char* const msg = events_[slot];
+    PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(msg, kLogRingBufMsgLen,
+                                        "see comments in log_ring_buffer.h")
+    snprintf(msg, kLogRingBufMsgLen, "%.*s%.*s %.*s",
+             static_cast<int>(tstamp.size()), tstamp.data(),
+             static_cast<int>(source.size()), source.data(),
+             static_cast<int>(log_msg.size()), log_msg.data());
+  }
+
+  // Reads back the buffer in FIFO order, up to |len - 1| characters at most
+  // (the -1 is because a NUL terminator is always appended, unless |len| == 0).
+  // The string written in |dst| is guaranteed to be NUL-terminated, even if
+  // |len| < buffer contents length.
+  // Returns the number of bytes written in output, excluding the \0 terminator.
+  size_t Read(char* dst, size_t len) {
+    if (len == 0)
+      return 0;
+    // This is a relaxed-load because we don't need to fully synchronize on the
+    // writing path for the reasons described in the fetch_add() above.
+    const uint32_t event_slot = event_slot_.load(std::memory_order_relaxed);
+    size_t dst_written = 0;
+    for (uint32_t pos = 0; pos < kLogRingBufEntries; ++pos) {
+      const uint32_t slot = (event_slot + pos) % kLogRingBufEntries;
+      const char* src = events_[slot];
+      if (*src == '\0')
+        continue;  // Empty slot. Skip.
+      char* const wptr = dst + dst_written;
+      // |src| might not be null terminated. This can happen if some
+      // thread-race happened. Limit the copy length.
+      const size_t limit = std::min(len - dst_written, kLogRingBufMsgLen);
+      for (size_t i = 0; i < limit; ++i) {
+        const char c = src[i];
+        ++dst_written;
+        if (c == '\0' || i == limit - 1) {
+          wptr[i] = '\n';
+          break;
+        }
+        // Skip non-printable ASCII characters to avoid confusing crash reports.
+        // Note that this deliberately mangles \n. Log messages should not have
+        // a \n in the middle and are NOT \n terminated. The trailing \n between
+        // each line is appended by the if () branch above.
+        const bool is_printable = c >= ' ' && c <= '~';
+        wptr[i] = is_printable ? c : '?';
+      }
+    }
+    // Ensure that the output string is null-terminated.
+    PERFETTO_DCHECK(dst_written <= len);
+    if (dst_written == len) {
+      // In case of truncation we replace the last char with \0. But the return
+      // value is the number of chars without \0, hence the --.
+      dst[--dst_written] = '\0';
+    } else {
+      dst[dst_written] = '\0';
+    }
+    return dst_written;
+  }
+
+ private:
+  using EventBuf = char[kLogRingBufMsgLen];
+  EventBuf events_[kLogRingBufEntries]{};
+
+  static_assert((kLogRingBufEntries & (kLogRingBufEntries - 1)) == 0,
+                "kLogRingBufEntries must be a power of two");
+
+  // A monotonically increasing counter incremented on each event written.
+  // It determines which of the kLogRingBufEntries indexes in |events_| should
+  // be used next.
+  // It grows >> kLogRingBufEntries, it's supposed to be always used
+  // mod(kLogRingBufEntries). A static_assert in the .cc file ensures that
+  // kLogRingBufEntries is a power of two so wraps are aligned.
+  std::atomic<uint32_t> event_slot_{};
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // SRC_BASE_LOG_RING_BUFFER_H_
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <unistd.h>  // For isatty()
+#endif
+
+#include <atomic>
+#include <memory>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/crash_keys.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
+// gen_amalgamated expanded: #include "src/base/log_ring_buffer.h"
+
+#if PERFETTO_ENABLE_LOG_RING_BUFFER() && PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#include <android/set_abort_message.h>
+#endif
+
+namespace perfetto {
+namespace base {
+
+namespace {
+const char kReset[] = "\x1b[0m";
+const char kDefault[] = "\x1b[39m";
+const char kDim[] = "\x1b[2m";
+const char kRed[] = "\x1b[31m";
+const char kBoldGreen[] = "\x1b[1m\x1b[32m";
+const char kLightGray[] = "\x1b[90m";
+
+std::atomic<LogMessageCallback> g_log_callback{};
+
+#if PERFETTO_BUILDFLAG(PERFETTO_STDERR_CRASH_DUMP)
+// __attribute__((constructor)) causes a static initializer that automagically
+// early runs this function before the main().
+void PERFETTO_EXPORT_COMPONENT __attribute__((constructor))
+InitDebugCrashReporter() {
+  // This function is defined in debug_crash_stack_trace.cc.
+  // The dynamic initializer is in logging.cc because logging.cc is included
+  // in virtually any target that depends on base. Having it in
+  // debug_crash_stack_trace.cc would require figuring out -Wl,whole-archive
+  // which is not worth it.
+  EnableStacktraceOnCrashForDebug();
+}
+#endif
+
+#if PERFETTO_ENABLE_LOG_RING_BUFFER()
+LogRingBuffer g_log_ring_buffer{};
+
+// This is global to avoid allocating memory or growing too much the stack
+// in MaybeSerializeLastLogsForCrashReporting(), which is called from
+// arbitrary code paths hitting PERFETTO_CHECK()/FATAL().
+char g_crash_buf[kLogRingBufEntries * kLogRingBufMsgLen];
+#endif
+
+}  // namespace
+
+void SetLogMessageCallback(LogMessageCallback callback) {
+  g_log_callback.store(callback, std::memory_order_relaxed);
+}
+
+void LogMessage(LogLev level,
+                const char* fname,
+                int line,
+                const char* fmt,
+                ...) {
+  char stack_buf[512];
+  std::unique_ptr<char[]> large_buf;
+  char* log_msg = &stack_buf[0];
+  size_t log_msg_len = 0;
+
+  // By default use a stack allocated buffer because most log messages are quite
+  // short. In rare cases they can be larger (e.g. --help). In those cases we
+  // pay the cost of allocating the buffer on the heap.
+  for (size_t max_len = sizeof(stack_buf);;) {
+    va_list args;
+    va_start(args, fmt);
+    int res = vsnprintf(log_msg, max_len, fmt, args);
+    va_end(args);
+
+    // If for any reason the print fails, overwrite the message but still print
+    // it. The code below will attach the filename and line, which is still
+    // useful.
+    if (res < 0) {
+      snprintf(log_msg, max_len, "%s", "[printf format error]");
+      break;
+    }
+
+    // if res == max_len, vsnprintf saturated the input buffer. Retry with a
+    // larger buffer in that case (within reasonable limits).
+    if (res < static_cast<int>(max_len) || max_len >= 128 * 1024) {
+      // In case of truncation vsnprintf returns the len that "would have been
+      // written if the string was longer", not the actual chars written.
+      log_msg_len = std::min(static_cast<size_t>(res), max_len - 1);
+      break;
+    }
+    max_len *= 4;
+    large_buf.reset(new char[max_len]);
+    log_msg = &large_buf[0];
+  }
+
+  LogMessageCallback cb = g_log_callback.load(std::memory_order_relaxed);
+  if (cb) {
+    cb({level, line, fname, log_msg});
+    return;
+  }
+
+  const char* color = kDefault;
+  switch (level) {
+    case kLogDebug:
+      color = kDim;
+      break;
+    case kLogInfo:
+      color = kDefault;
+      break;
+    case kLogImportant:
+      color = kBoldGreen;
+      break;
+    case kLogError:
+      color = kRed;
+      break;
+  }
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) &&  \
+    !PERFETTO_BUILDFLAG(PERFETTO_OS_WASM) && \
+    !PERFETTO_BUILDFLAG(PERFETTO_CHROMIUM_BUILD)
+  static const bool use_colors = isatty(STDERR_FILENO);
+#else
+  static const bool use_colors = false;
+#endif
+
+  // Formats file.cc:line as a space-padded fixed width string. If the file name
+  // |fname| is too long, truncate it on the left-hand side.
+  StackString<10> line_str("%d", line);
+
+  // 24 will be the width of the file.cc:line column in the log event.
+  static constexpr size_t kMaxNameAndLine = 24;
+  size_t fname_len = strlen(fname);
+  size_t fname_max = kMaxNameAndLine - line_str.len() - 2;  // 2 = ':' + '\0'.
+  size_t fname_offset = fname_len <= fname_max ? 0 : fname_len - fname_max;
+  StackString<kMaxNameAndLine> file_and_line(
+      "%*s:%s", static_cast<int>(fname_max), &fname[fname_offset],
+      line_str.c_str());
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  // Logcat has already timestamping, don't re-emit it.
+  __android_log_print(int{ANDROID_LOG_DEBUG} + level, "perfetto", "%s %s",
+                      file_and_line.c_str(), log_msg);
+#endif
+
+  // When printing on stderr, print also the timestamp. We don't really care
+  // about the actual time. We just need some reference clock that can be used
+  // to correlated events across differrent processses (e.g. traced and
+  // traced_probes). The wall time % 1000 is good enough.
+  uint32_t t_ms = static_cast<uint32_t>(GetWallTimeMs().count());
+  uint32_t t_sec = t_ms / 1000;
+  t_ms -= t_sec * 1000;
+  t_sec = t_sec % 1000;
+  StackString<32> timestamp("[%03u.%03u] ", t_sec, t_ms);
+
+  if (use_colors) {
+    fprintf(stderr, "%s%s%s%s %s%s%s\n", kLightGray, timestamp.c_str(),
+            file_and_line.c_str(), kReset, color, log_msg, kReset);
+  } else {
+    fprintf(stderr, "%s%s %s\n", timestamp.c_str(), file_and_line.c_str(),
+            log_msg);
+  }
+
+#if PERFETTO_ENABLE_LOG_RING_BUFFER()
+  // Append the message to the ring buffer for crash reporting postmortems.
+  StringView timestamp_sv = timestamp.string_view();
+  StringView file_and_line_sv = file_and_line.string_view();
+  StringView log_msg_sv(log_msg, static_cast<size_t>(log_msg_len));
+  g_log_ring_buffer.Append(timestamp_sv, file_and_line_sv, log_msg_sv);
+#else
+  ignore_result(log_msg_len);
+#endif
+}
+
+#if PERFETTO_ENABLE_LOG_RING_BUFFER()
+void MaybeSerializeLastLogsForCrashReporting() {
+  // Keep this function minimal. This is called from the watchdog thread, often
+  // when the system is thrashing.
+
+  // This is racy because two threads could hit a CHECK/FATAL at the same time.
+  // But if that happens we have bigger problems, not worth designing around it.
+  // The behaviour is still defined in the race case (the string attached to
+  // the crash report will contain a mixture of log strings).
+  size_t wr = 0;
+  wr += SerializeCrashKeys(&g_crash_buf[wr], sizeof(g_crash_buf) - wr);
+  wr += g_log_ring_buffer.Read(&g_crash_buf[wr], sizeof(g_crash_buf) - wr);
+
+  // Read() null-terminates the string properly. This is just to avoid UB when
+  // two threads race on each other (T1 writes a shorter string, T2
+  // overwrites the \0 writing a longer string. T1 continues here before T2
+  // finishes writing the longer string with the \0 -> boom.
+  g_crash_buf[sizeof(g_crash_buf) - 1] = '\0';
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  // android_set_abort_message() will cause debuggerd to report the message
+  // in the tombstone and in the crash log in logcat.
+  // NOTE: android_set_abort_message() can be called only once. This should
+  // be called only when we are sure we are about to crash.
+  android_set_abort_message(g_crash_buf);
+#else
+  // Print out the message on stderr on Linux/Mac/Win.
+  fputs("\n-----BEGIN PERFETTO PRE-CRASH LOG-----\n", stderr);
+  fputs(g_crash_buf, stderr);
+  fputs("\n-----END PERFETTO PRE-CRASH LOG-----\n", stderr);
+#endif
+}
+#endif  // PERFETTO_ENABLE_LOG_RING_BUFFER
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/metatrace.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/metatrace.h
+// gen_amalgamated begin header: include/perfetto/ext/base/metatrace_events.h
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_METATRACE_EVENTS_H_
+#define INCLUDE_PERFETTO_EXT_BASE_METATRACE_EVENTS_H_
+
+#include <stdint.h>
+
+namespace perfetto {
+namespace metatrace {
+
+enum Tags : uint32_t {
+  TAG_NONE = 0,
+  TAG_ANY = uint32_t(-1),
+  TAG_FTRACE = 1 << 0,
+  TAG_PROC_POLLERS = 1 << 1,
+  TAG_TRACE_WRITER = 1 << 2,
+  TAG_TRACE_SERVICE = 1 << 3,
+  TAG_PRODUCER = 1 << 4,
+};
+
+// The macros below generate matching enums and arrays of string literals.
+// This is to avoid maintaining string maps manually.
+
+// clang-format off
+
+// DO NOT remove or reshuffle items in this list, only append. The ID of these
+// events are an ABI, the trace processor relies on these to open old traces.
+#define PERFETTO_METATRACE_EVENTS(F) \
+  F(EVENT_ZERO_UNUSED), \
+  F(FTRACE_CPU_READER_READ), /*unused*/ \
+  F(FTRACE_DRAIN_CPUS), /*unused*/ \
+  F(FTRACE_UNBLOCK_READERS), /*unused*/ \
+  F(FTRACE_CPU_READ_NONBLOCK), /*unused*/ \
+  F(FTRACE_CPU_READ_BLOCK), /*unused*/ \
+  F(FTRACE_CPU_SPLICE_NONBLOCK), /*unused*/ \
+  F(FTRACE_CPU_SPLICE_BLOCK), /*unused*/ \
+  F(FTRACE_CPU_WAIT_CMD), /*unused*/ \
+  F(FTRACE_CPU_RUN_CYCLE), /*unused*/ \
+  F(FTRACE_CPU_FLUSH), \
+  F(FTRACE_CPU_BUFFER_WATERMARK), \
+  F(READ_SYS_STATS), \
+  F(PS_WRITE_ALL_PROCESSES), \
+  F(PS_ON_PIDS), \
+  F(PS_ON_RENAME_PIDS), \
+  F(PS_WRITE_ALL_PROCESS_STATS), \
+  F(TRACE_WRITER_COMMIT_STARTUP_WRITER_BATCH), \
+  F(FTRACE_READ_TICK), \
+  F(FTRACE_CPU_READ_CYCLE), \
+  F(FTRACE_CPU_READ_BATCH), \
+  F(KALLSYMS_PARSE), \
+  F(PROFILER_READ_TICK), \
+  F(PROFILER_READ_CPU), \
+  F(PROFILER_UNWIND_TICK), \
+  F(PROFILER_UNWIND_SAMPLE), \
+  F(PROFILER_UNWIND_INITIAL_ATTEMPT), \
+  F(PROFILER_UNWIND_ATTEMPT), \
+  F(PROFILER_MAPS_PARSE), \
+  F(PROFILER_MAPS_REPARSE), \
+  F(PROFILER_UNWIND_CACHE_CLEAR)
+
+// Append only, see above.
+//
+// Values that aren't used as counters:
+// * FTRACE_SERVICE_COMMIT_DATA is a bit-packed representation of an event, see
+//   tracing_service_impl.cc for the format.
+// * PROFILER_UNWIND_CURRENT_PID represents the PID that is being unwound.
+//
+#define PERFETTO_METATRACE_COUNTERS(F) \
+  F(COUNTER_ZERO_UNUSED),\
+  F(FTRACE_PAGES_DRAINED), \
+  F(PS_PIDS_SCANNED), \
+  F(TRACE_SERVICE_COMMIT_DATA), \
+  F(PROFILER_UNWIND_QUEUE_SZ), \
+  F(PROFILER_UNWIND_CURRENT_PID)
+
+// clang-format on
+
+#define PERFETTO_METATRACE_IDENTITY(name) name
+#define PERFETTO_METATRACE_TOSTRING(name) #name
+
+enum Events : uint16_t {
+  PERFETTO_METATRACE_EVENTS(PERFETTO_METATRACE_IDENTITY),
+  EVENTS_MAX
+};
+constexpr char const* kEventNames[] = {
+    PERFETTO_METATRACE_EVENTS(PERFETTO_METATRACE_TOSTRING)};
+
+enum Counters : uint16_t {
+  PERFETTO_METATRACE_COUNTERS(PERFETTO_METATRACE_IDENTITY),
+  COUNTERS_MAX
+};
+constexpr char const* kCounterNames[] = {
+    PERFETTO_METATRACE_COUNTERS(PERFETTO_METATRACE_TOSTRING)};
+
+inline void SuppressUnusedVarsInAmalgamatedBuild() {
+  (void)kCounterNames;
+  (void)kEventNames;
+}
+
+}  // namespace metatrace
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_METATRACE_EVENTS_H_
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_METATRACE_H_
+#define INCLUDE_PERFETTO_EXT_BASE_METATRACE_H_
+
+#include <array>
+#include <atomic>
+#include <functional>
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/thread_utils.h"
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/metatrace_events.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+
+// A facility to trace execution of the perfetto codebase itself.
+// The meta-tracing framework is organized into three layers:
+//
+// 1. A static ring-buffer in base/ (this file) that supports concurrent writes
+//    and a single reader.
+//    The responsibility of this layer is to store events and counters as
+//    efficiently as possible without re-entering any tracing code.
+//    This is really a static-storage-based ring-buffer based on a POD array.
+//    This layer does NOT deal with serializing the meta-trace buffer.
+//    It posts a task when it's half full and expects something outside of
+//    base/ to drain the ring-buffer and serialize it, eventually writing it
+//    into the trace itself, before it gets 100% full.
+//
+// 2. A class in tracing/core which takes care of serializing the meta-trace
+//    buffer into the trace using a TraceWriter. See metatrace_writer.h .
+//
+// 3. A data source in traced_probes that, when be enabled via the trace config,
+//    injects metatrace events into the trace. See metatrace_data_source.h .
+//
+// The available events and tags are defined in metatrace_events.h .
+
+namespace perfetto {
+
+namespace base {
+class TaskRunner;
+}  // namespace base
+
+namespace metatrace {
+
+// Meta-tracing is organized in "tags" that can be selectively enabled. This is
+// to enable meta-tracing only of one sub-system. This word has one "enabled"
+// bit for each tag. 0 -> meta-tracing off.
+extern std::atomic<uint32_t> g_enabled_tags;
+
+// Time of the Enable() call. Used as a reference for keeping delta timestmaps
+// in Record.
+extern std::atomic<uint64_t> g_enabled_timestamp;
+
+// Enables meta-tracing for one or more tags. Once enabled it will discard any
+// further Enable() calls and return false until disabled,
+// |read_task| is a closure that will be called enqueued |task_runner| when the
+// meta-tracing ring buffer is half full. The task is expected to read the ring
+// buffer using RingBuffer::GetReadIterator() and serialize the contents onto a
+// file or into the trace itself.
+// Must be called on the |task_runner| passed.
+// |task_runner| must have static lifetime.
+bool Enable(std::function<void()> read_task, base::TaskRunner*, uint32_t tags);
+
+// Disables meta-tracing.
+// Must be called on the same |task_runner| as Enable().
+void Disable();
+
+inline uint64_t TraceTimeNowNs() {
+  return static_cast<uint64_t>(base::GetBootTimeNs().count());
+}
+
+// Returns a relaxed view of whether metatracing is enabled for the given tag.
+// Useful for skipping unnecessary argument computation if metatracing is off.
+inline bool IsEnabled(uint32_t tag) {
+  auto enabled_tags = g_enabled_tags.load(std::memory_order_relaxed);
+  return PERFETTO_UNLIKELY((enabled_tags & tag) != 0);
+}
+
+// Holds the data for a metatrace event or counter.
+struct Record {
+  static constexpr uint16_t kTypeMask = 0x8000;
+  static constexpr uint16_t kTypeCounter = 0x8000;
+  static constexpr uint16_t kTypeEvent = 0;
+
+  uint64_t timestamp_ns() const {
+    auto base_ns = g_enabled_timestamp.load(std::memory_order_relaxed);
+    PERFETTO_DCHECK(base_ns);
+    return base_ns + ((static_cast<uint64_t>(timestamp_ns_high) << 32) |
+                      timestamp_ns_low);
+  }
+
+  void set_timestamp(uint64_t ts) {
+    auto t_start = g_enabled_timestamp.load(std::memory_order_relaxed);
+    uint64_t diff = ts - t_start;
+    PERFETTO_DCHECK(diff < (1ull << 48));
+    timestamp_ns_low = static_cast<uint32_t>(diff);
+    timestamp_ns_high = static_cast<uint16_t>(diff >> 32);
+  }
+
+  // We can't just memset() this class because on MSVC std::atomic<> is not
+  // trivially constructible anymore. Also std::atomic<> has a deleted copy
+  // constructor so we cant just do "*this = Record()" either.
+  // See http://bit.ly/339Jlzd .
+  void clear() {
+    this->~Record();
+    new (this) Record();
+  }
+
+  // This field holds the type (counter vs event) in the MSB and event ID (as
+  // defined in metatrace_events.h) in the lowest 15 bits. It is also used also
+  // as a linearization point: this is always written after all the other
+  // fields with a release-store. This is so the reader can determine whether it
+  // can safely process the other event fields after a load-acquire.
+  std::atomic<uint16_t> type_and_id{};
+
+  // Timestamp is stored as a 48-bits value diffed against g_enabled_timestamp.
+  // This gives us 78 hours from Enabled().
+  uint16_t timestamp_ns_high = 0;
+  uint32_t timestamp_ns_low = 0;
+
+  uint32_t thread_id = 0;
+
+  union {
+    // Only one of the two elements can be zero initialized, clang complains
+    // about "initializing multiple members of union" otherwise.
+    uint32_t duration_ns = 0;  // If type == event.
+    int32_t counter_value;     // If type == counter.
+  };
+};
+
+// Hold the meta-tracing data into a statically allocated array.
+// This class uses static storage (as opposite to being a singleton) to:
+// - Have the guarantee of always valid storage, so that meta-tracing can be
+//   safely used in any part of the codebase, including base/ itself.
+// - Avoid barriers that thread-safe static locals would require.
+class RingBuffer {
+ public:
+  static constexpr size_t kCapacity = 4096;  // 4096 * 16 bytes = 64K.
+
+  // This iterator is not idempotent and will bump the read index in the buffer
+  // at the end of the reads. There can be only one reader at any time.
+  // Usage: for (auto it = RingBuffer::GetReadIterator(); it; ++it) { it->... }
+  class ReadIterator {
+   public:
+    ReadIterator(ReadIterator&& other) {
+      PERFETTO_DCHECK(other.valid_);
+      cur_ = other.cur_;
+      end_ = other.end_;
+      valid_ = other.valid_;
+      other.valid_ = false;
+    }
+
+    ~ReadIterator() {
+      if (!valid_)
+        return;
+      PERFETTO_DCHECK(cur_ >= RingBuffer::rd_index_);
+      PERFETTO_DCHECK(cur_ <= RingBuffer::wr_index_);
+      RingBuffer::rd_index_.store(cur_, std::memory_order_release);
+    }
+
+    explicit operator bool() const { return cur_ < end_; }
+    const Record* operator->() const { return RingBuffer::At(cur_); }
+    const Record& operator*() const { return *operator->(); }
+
+    // This is for ++it. it++ is deliberately not supported.
+    ReadIterator& operator++() {
+      PERFETTO_DCHECK(cur_ < end_);
+      // Once a record has been read, mark it as free clearing its type_and_id,
+      // so if we encounter it in another read iteration while being written
+      // we know it's not fully written yet.
+      // The memory_order_relaxed below is enough because:
+      // - The reader is single-threaded and doesn't re-read the same records.
+      // - Before starting a read batch, the reader has an acquire barrier on
+      //   |rd_index_|.
+      // - After terminating a read batch, the ~ReadIterator dtor updates the
+      //   |rd_index_| with a release-store.
+      // - Reader and writer are typically kCapacity/2 apart. So unless an
+      //   overrun happens a writer won't reuse a newly released record any time
+      //   soon. If an overrun happens, everything is busted regardless.
+      At(cur_)->type_and_id.store(0, std::memory_order_relaxed);
+      ++cur_;
+      return *this;
+    }
+
+   private:
+    friend class RingBuffer;
+    ReadIterator(uint64_t begin, uint64_t end)
+        : cur_(begin), end_(end), valid_(true) {}
+    ReadIterator& operator=(const ReadIterator&) = delete;
+    ReadIterator(const ReadIterator&) = delete;
+
+    uint64_t cur_;
+    uint64_t end_;
+    bool valid_;
+  };
+
+  static Record* At(uint64_t index) {
+    // Doesn't really have to be pow2, but if not the compiler will emit
+    // arithmetic operations to compute the modulo instead of a bitwise AND.
+    static_assert(!(kCapacity & (kCapacity - 1)), "kCapacity must be pow2");
+    PERFETTO_DCHECK(index >= rd_index_);
+    PERFETTO_DCHECK(index <= wr_index_);
+    return &records_[index % kCapacity];
+  }
+
+  // Must be called on the same task runner passed to Enable()
+  static ReadIterator GetReadIterator() {
+    PERFETTO_DCHECK(RingBuffer::IsOnValidTaskRunner());
+    return ReadIterator(rd_index_.load(std::memory_order_acquire),
+                        wr_index_.load(std::memory_order_acquire));
+  }
+
+  static Record* AppendNewRecord();
+  static void Reset();
+
+  static bool has_overruns() {
+    return has_overruns_.load(std::memory_order_acquire);
+  }
+
+  // Can temporarily return a value >= kCapacity but is eventually consistent.
+  // This would happen in case of overruns until threads hit the --wr_index_
+  // in AppendNewRecord().
+  static uint64_t GetSizeForTesting() {
+    auto wr_index = wr_index_.load(std::memory_order_relaxed);
+    auto rd_index = rd_index_.load(std::memory_order_relaxed);
+    PERFETTO_DCHECK(wr_index >= rd_index);
+    return wr_index - rd_index;
+  }
+
+ private:
+  friend class ReadIterator;
+
+  // Returns true if the caller is on the task runner passed to Enable().
+  // Used only for DCHECKs.
+  static bool IsOnValidTaskRunner();
+
+  static std::array<Record, kCapacity> records_;
+  static std::atomic<bool> read_task_queued_;
+  static std::atomic<uint64_t> wr_index_;
+  static std::atomic<uint64_t> rd_index_;
+  static std::atomic<bool> has_overruns_;
+  static Record bankruptcy_record_;  // Used in case of overruns.
+};
+
+inline void TraceCounter(uint32_t tag, uint16_t id, int32_t value) {
+  // memory_order_relaxed is okay because the storage has static lifetime.
+  // It is safe to accidentally log an event soon after disabling.
+  auto enabled_tags = g_enabled_tags.load(std::memory_order_relaxed);
+  if (PERFETTO_LIKELY((enabled_tags & tag) == 0))
+    return;
+  Record* record = RingBuffer::AppendNewRecord();
+  record->thread_id = static_cast<uint32_t>(base::GetThreadId());
+  record->set_timestamp(TraceTimeNowNs());
+  record->counter_value = value;
+  record->type_and_id.store(Record::kTypeCounter | id,
+                            std::memory_order_release);
+}
+
+class ScopedEvent {
+ public:
+  ScopedEvent(uint32_t tag, uint16_t event_id) {
+    auto enabled_tags = g_enabled_tags.load(std::memory_order_relaxed);
+    if (PERFETTO_LIKELY((enabled_tags & tag) == 0))
+      return;
+    event_id_ = event_id;
+    record_ = RingBuffer::AppendNewRecord();
+    record_->thread_id = static_cast<uint32_t>(base::GetThreadId());
+    record_->set_timestamp(TraceTimeNowNs());
+  }
+
+  ~ScopedEvent() {
+    if (PERFETTO_LIKELY(!record_))
+      return;
+    auto now = TraceTimeNowNs();
+    record_->duration_ns = static_cast<uint32_t>(now - record_->timestamp_ns());
+    record_->type_and_id.store(Record::kTypeEvent | event_id_,
+                               std::memory_order_release);
+  }
+
+ private:
+  Record* record_ = nullptr;
+  uint16_t event_id_ = 0;
+  ScopedEvent(const ScopedEvent&) = delete;
+  ScopedEvent& operator=(const ScopedEvent&) = delete;
+};
+
+// Boilerplate to derive a unique variable name for the event.
+#define PERFETTO_METATRACE_UID2(a, b) a##b
+#define PERFETTO_METATRACE_UID(x) PERFETTO_METATRACE_UID2(metatrace_, x)
+
+#define PERFETTO_METATRACE_SCOPED(TAG, ID)                                \
+  ::perfetto::metatrace::ScopedEvent PERFETTO_METATRACE_UID(__COUNTER__)( \
+      ::perfetto::metatrace::TAG, ::perfetto::metatrace::ID)
+
+#define PERFETTO_METATRACE_COUNTER(TAG, ID, VALUE)                \
+  ::perfetto::metatrace::TraceCounter(::perfetto::metatrace::TAG, \
+                                      ::perfetto::metatrace::ID,  \
+                                      static_cast<int32_t>(VALUE))
+
+}  // namespace metatrace
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_METATRACE_H_
+// gen_amalgamated begin header: include/perfetto/base/task_runner.h
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_BASE_TASK_RUNNER_H_
+#define INCLUDE_PERFETTO_BASE_TASK_RUNNER_H_
+
+#include <stdint.h>
+
+#include <functional>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
+
+namespace perfetto {
+namespace base {
+
+// A generic interface to allow the library clients to interleave the execution
+// of the tracing internals in their runtime environment.
+// The expectation is that all tasks, which are queued either via PostTask() or
+// AddFileDescriptorWatch(), are executed on the same sequence (either on the
+// same thread, or on a thread pool that gives sequencing guarantees).
+//
+// Tasks are never executed synchronously inside PostTask and there is a full
+// memory barrier between tasks.
+//
+// All methods of this interface can be called from any thread.
+class PERFETTO_EXPORT_COMPONENT TaskRunner {
+ public:
+  virtual ~TaskRunner();
+
+  // Schedule a task for immediate execution. Immediate tasks are always
+  // executed in the order they are posted. Can be called from any thread.
+  virtual void PostTask(std::function<void()>) = 0;
+
+  // Schedule a task for execution after |delay_ms|. Note that there is no
+  // strict ordering guarantee between immediate and delayed tasks. Can be
+  // called from any thread.
+  virtual void PostDelayedTask(std::function<void()>, uint32_t delay_ms) = 0;
+
+  // Schedule a task to run when the handle becomes readable. The same handle
+  // can only be monitored by one function. Note that this function only needs
+  // to be implemented on platforms where the built-in ipc framework is used.
+  // Can be called from any thread.
+  // TODO(skyostil): Refactor this out of the shared interface.
+  virtual void AddFileDescriptorWatch(PlatformHandle,
+                                      std::function<void()>) = 0;
+
+  // Remove a previously scheduled watch for the handle. If this is run on the
+  // target thread of this TaskRunner, guarantees that the task registered to
+  // this handle will not be executed after this function call.
+  // Can be called from any thread.
+  virtual void RemoveFileDescriptorWatch(PlatformHandle) = 0;
+
+  // Checks if the current thread is the same thread where the TaskRunner's task
+  // run. This allows single threaded task runners (like the ones used in
+  // perfetto) to inform the caller that anything posted will run on the same
+  // thread/sequence. This can allow some callers to skip PostTask and instead
+  // directly execute the code. Can be called from any thread.
+  virtual bool RunsTasksOnCurrentThread() const = 0;
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_BASE_TASK_RUNNER_H_
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/metatrace.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_annotations.h"
+
+namespace perfetto {
+namespace metatrace {
+
+std::atomic<uint32_t> g_enabled_tags{0};
+std::atomic<uint64_t> g_enabled_timestamp{0};
+
+// static members
+std::array<Record, RingBuffer::kCapacity> RingBuffer::records_;
+std::atomic<bool> RingBuffer::read_task_queued_;
+std::atomic<uint64_t> RingBuffer::wr_index_;
+std::atomic<uint64_t> RingBuffer::rd_index_;
+std::atomic<bool> RingBuffer::has_overruns_;
+Record RingBuffer::bankruptcy_record_;
+
+namespace {
+
+// std::function<> is not trivially de/constructible. This struct wraps it in a
+// heap-allocated struct to avoid static initializers.
+struct Delegate {
+  static Delegate* GetInstance() {
+    static Delegate* instance = new Delegate();
+    return instance;
+  }
+
+  base::TaskRunner* task_runner = nullptr;
+  std::function<void()> read_task;
+};
+
+}  // namespace
+
+bool Enable(std::function<void()> read_task,
+            base::TaskRunner* task_runner,
+            uint32_t tags) {
+  PERFETTO_DCHECK(read_task);
+  PERFETTO_DCHECK(task_runner->RunsTasksOnCurrentThread());
+  if (g_enabled_tags.load(std::memory_order_acquire))
+    return false;
+
+  Delegate* dg = Delegate::GetInstance();
+  dg->task_runner = task_runner;
+  dg->read_task = std::move(read_task);
+  RingBuffer::Reset();
+  g_enabled_timestamp.store(TraceTimeNowNs(), std::memory_order_relaxed);
+  g_enabled_tags.store(tags, std::memory_order_release);
+  return true;
+}
+
+void Disable() {
+  g_enabled_tags.store(0, std::memory_order_release);
+  Delegate* dg = Delegate::GetInstance();
+  PERFETTO_DCHECK(!dg->task_runner ||
+                  dg->task_runner->RunsTasksOnCurrentThread());
+  dg->task_runner = nullptr;
+  dg->read_task = nullptr;
+}
+
+// static
+void RingBuffer::Reset() {
+  bankruptcy_record_.clear();
+  for (Record& record : records_)
+    record.clear();
+  wr_index_ = 0;
+  rd_index_ = 0;
+  has_overruns_ = false;
+  read_task_queued_ = false;
+}
+
+// static
+Record* RingBuffer::AppendNewRecord() {
+  auto wr_index = wr_index_.fetch_add(1, std::memory_order_acq_rel);
+
+  // rd_index can only monotonically increase, we don't care if we read an
+  // older value, we'll just hit the slow-path a bit earlier if it happens.
+  auto rd_index = rd_index_.load(std::memory_order_relaxed);
+
+  PERFETTO_DCHECK(wr_index >= rd_index);
+  auto size = wr_index - rd_index;
+  if (PERFETTO_LIKELY(size < kCapacity / 2))
+    return At(wr_index);
+
+  // Slow-path: Enqueue the read task and handle overruns.
+  bool expected = false;
+  if (RingBuffer::read_task_queued_.compare_exchange_strong(expected, true)) {
+    Delegate* dg = Delegate::GetInstance();
+    if (dg->task_runner) {
+      dg->task_runner->PostTask([] {
+        // Meta-tracing might have been disabled in the meantime.
+        auto read_task = Delegate::GetInstance()->read_task;
+        if (read_task)
+          read_task();
+        RingBuffer::read_task_queued_ = false;
+      });
+    }
+  }
+
+  if (PERFETTO_LIKELY(size < kCapacity))
+    return At(wr_index);
+
+  has_overruns_.store(true, std::memory_order_release);
+  wr_index_.fetch_sub(1, std::memory_order_acq_rel);
+
+  // In the case of overflows, threads will race writing on the same memory
+  // location and TSan will rightly complain. This is fine though because nobody
+  // will read the bankruptcy record and it's designed to contain garbage.
+  PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(&bankruptcy_record_, sizeof(Record),
+                                      "nothing reads bankruptcy_record_")
+  return &bankruptcy_record_;
+}
+
+// static
+bool RingBuffer::IsOnValidTaskRunner() {
+  auto* task_runner = Delegate::GetInstance()->task_runner;
+  return task_runner && task_runner->RunsTasksOnCurrentThread();
+}
+
+}  // namespace metatrace
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/paged_memory.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/paged_memory.h
+// gen_amalgamated begin header: include/perfetto/ext/base/container_annotations.h
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_CONTAINER_ANNOTATIONS_H_
+#define INCLUDE_PERFETTO_EXT_BASE_CONTAINER_ANNOTATIONS_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+// Windows ASAN doesn't currently support these annotations.
+#if defined(ADDRESS_SANITIZER) && !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
+    !defined(ADDRESS_SANITIZER_WITHOUT_INSTRUMENTATION)
+
+#include <sanitizer/common_interface_defs.h>
+
+#define ANNOTATE_NEW_BUFFER(buffer, capacity, new_size)                      \
+  if (buffer) {                                                              \
+    __sanitizer_annotate_contiguous_container(buffer, (buffer) + (capacity), \
+                                              (buffer) + (capacity),         \
+                                              (buffer) + (new_size));        \
+  }
+#define ANNOTATE_DELETE_BUFFER(buffer, capacity, old_size)                   \
+  if (buffer) {                                                              \
+    __sanitizer_annotate_contiguous_container(buffer, (buffer) + (capacity), \
+                                              (buffer) + (old_size),         \
+                                              (buffer) + (capacity));        \
+  }
+#define ANNOTATE_CHANGE_SIZE(buffer, capacity, old_size, new_size)           \
+  if (buffer) {                                                              \
+    __sanitizer_annotate_contiguous_container(buffer, (buffer) + (capacity), \
+                                              (buffer) + (old_size),         \
+                                              (buffer) + (new_size));        \
+  }
+#define ANNOTATE_CHANGE_CAPACITY(buffer, old_capacity, buffer_size, \
+                                 new_capacity)                      \
+  ANNOTATE_DELETE_BUFFER(buffer, old_capacity, buffer_size);        \
+  ANNOTATE_NEW_BUFFER(buffer, new_capacity, buffer_size);
+// Annotations require buffers to begin on an 8-byte boundary.
+#else  // defined(ADDRESS_SANITIZER)
+#define ANNOTATE_NEW_BUFFER(buffer, capacity, new_size)
+#define ANNOTATE_DELETE_BUFFER(buffer, capacity, old_size)
+#define ANNOTATE_CHANGE_SIZE(buffer, capacity, old_size, new_size)
+#define ANNOTATE_CHANGE_CAPACITY(buffer, old_capacity, buffer_size, \
+                                 new_capacity)
+#endif  // defined(ADDRESS_SANITIZER)
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_CONTAINER_ANNOTATIONS_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_PAGED_MEMORY_H_
+#define INCLUDE_PERFETTO_EXT_BASE_PAGED_MEMORY_H_
+
+#include <cstddef>
+#include <memory>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/container_annotations.h"
+
+// We need to track the committed size on windows and when ASAN is enabled.
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) || defined(ADDRESS_SANITIZER)
+#define TRACK_COMMITTED_SIZE() 1
+#else
+#define TRACK_COMMITTED_SIZE() 0
+#endif
+
+namespace perfetto {
+namespace base {
+
+class PagedMemory {
+ public:
+  // Initializes an invalid PagedMemory pointing to nullptr.
+  PagedMemory();
+
+  ~PagedMemory();
+
+  PagedMemory(PagedMemory&& other) noexcept;
+  PagedMemory& operator=(PagedMemory&& other);
+
+  enum AllocationFlags {
+    // By default, Allocate() crashes if the underlying mmap fails (e.g., if out
+    // of virtual address space). When this flag is provided, an invalid
+    // PagedMemory pointing to nullptr is returned in this case instead.
+    kMayFail = 1 << 0,
+
+    // By default, Allocate() commits the allocated memory immediately. When
+    // this flag is provided, the memory virtual address space may only be
+    // reserved and the user should call EnsureCommitted() before writing to
+    // memory addresses.
+    kDontCommit = 1 << 1,
+  };
+
+  // Allocates |size| bytes using mmap(MAP_ANONYMOUS). The returned memory is
+  // guaranteed to be page-aligned and guaranteed to be zeroed.
+  // For |flags|, see the AllocationFlags enum above.
+  static PagedMemory Allocate(size_t size, int flags = 0);
+
+  // Hint to the OS that the memory range is not needed and can be discarded.
+  // The memory remains accessible and its contents may be retained, or they
+  // may be zeroed. This function may be a NOP on some platforms. Returns true
+  // if implemented.
+  bool AdviseDontNeed(void* p, size_t size);
+
+  // Ensures that at least the first |committed_size| bytes of the allocated
+  // memory region are committed. The implementation may commit memory in larger
+  // chunks above |committed_size|. Crashes if the memory couldn't be committed.
+#if TRACK_COMMITTED_SIZE()
+  void EnsureCommitted(size_t committed_size);
+#else   // TRACK_COMMITTED_SIZE()
+  void EnsureCommitted(size_t /*committed_size*/) {}
+#endif  // TRACK_COMMITTED_SIZE()
+
+  inline void* Get() const noexcept { return p_; }
+  inline bool IsValid() const noexcept { return !!p_; }
+  inline size_t size() const noexcept { return size_; }
+
+ private:
+  PagedMemory(char* p, size_t size);
+
+  PagedMemory(const PagedMemory&) = delete;
+  // Defaulted for implementation of move constructor + assignment.
+  PagedMemory& operator=(const PagedMemory&) = default;
+
+  char* p_ = nullptr;
+
+  // The size originally passed to Allocate(). The actual virtual memory
+  // reservation will be larger due to: (i) guard pages; (ii) rounding up to
+  // the system page size.
+  size_t size_ = 0;
+
+#if TRACK_COMMITTED_SIZE()
+  size_t committed_size_ = 0u;
+#endif  // TRACK_COMMITTED_SIZE()
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_PAGED_MEMORY_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/paged_memory.h"
+
+#include <algorithm>
+#include <cmath>
+#include <cstddef>
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <Windows.h>
+#else  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <sys/mman.h>
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/container_annotations.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+
+namespace perfetto {
+namespace base {
+
+namespace {
+
+#if TRACK_COMMITTED_SIZE()
+constexpr size_t kCommitChunkSize = 4 * 1024 * 1024;  // 4MB
+#endif
+
+size_t RoundUpToSysPageSize(size_t req_size) {
+  const size_t page_size = GetSysPageSize();
+  return (req_size + page_size - 1) & ~(page_size - 1);
+}
+
+size_t GuardSize() {
+  return GetSysPageSize();
+}
+
+}  // namespace
+
+// static
+PagedMemory PagedMemory::Allocate(size_t req_size, int flags) {
+  size_t rounded_up_size = RoundUpToSysPageSize(req_size);
+  PERFETTO_CHECK(rounded_up_size >= req_size);
+  size_t outer_size = rounded_up_size + GuardSize() * 2;
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  void* ptr = VirtualAlloc(nullptr, outer_size, MEM_RESERVE, PAGE_NOACCESS);
+  if (!ptr && (flags & kMayFail))
+    return PagedMemory();
+  PERFETTO_CHECK(ptr);
+  char* usable_region = reinterpret_cast<char*>(ptr) + GuardSize();
+#else   // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  void* ptr = mmap(nullptr, outer_size, PROT_READ | PROT_WRITE,
+                   MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+  if (ptr == MAP_FAILED && (flags & kMayFail))
+    return PagedMemory();
+  PERFETTO_CHECK(ptr && ptr != MAP_FAILED);
+  char* usable_region = reinterpret_cast<char*>(ptr) + GuardSize();
+  int res = mprotect(ptr, GuardSize(), PROT_NONE);
+  res |= mprotect(usable_region + rounded_up_size, GuardSize(), PROT_NONE);
+  PERFETTO_CHECK(res == 0);
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+  auto memory = PagedMemory(usable_region, req_size);
+#if TRACK_COMMITTED_SIZE()
+  size_t initial_commit = req_size;
+  if (flags & kDontCommit)
+    initial_commit = std::min(initial_commit, kCommitChunkSize);
+  memory.EnsureCommitted(initial_commit);
+#endif  // TRACK_COMMITTED_SIZE()
+  return memory;
+}
+
+PagedMemory::PagedMemory() {}
+
+// clang-format off
+PagedMemory::PagedMemory(char* p, size_t size) : p_(p), size_(size) {
+  ANNOTATE_NEW_BUFFER(p_, size_, committed_size_)
+}
+
+PagedMemory::PagedMemory(PagedMemory&& other) noexcept {
+  *this = other;
+  other.p_ = nullptr;
+}
+// clang-format on
+
+PagedMemory& PagedMemory::operator=(PagedMemory&& other) {
+  this->~PagedMemory();
+  new (this) PagedMemory(std::move(other));
+  return *this;
+}
+
+PagedMemory::~PagedMemory() {
+  if (!p_)
+    return;
+  PERFETTO_CHECK(size_);
+  char* start = p_ - GuardSize();
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  BOOL res = VirtualFree(start, 0, MEM_RELEASE);
+  PERFETTO_CHECK(res != 0);
+#else   // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  const size_t outer_size = RoundUpToSysPageSize(size_) + GuardSize() * 2;
+  int res = munmap(start, outer_size);
+  PERFETTO_CHECK(res == 0);
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  ANNOTATE_DELETE_BUFFER(p_, size_, committed_size_)
+}
+
+bool PagedMemory::AdviseDontNeed(void* p, size_t size) {
+  PERFETTO_DCHECK(p_);
+  PERFETTO_DCHECK(p >= p_);
+  PERFETTO_DCHECK(static_cast<char*>(p) + size <= p_ + size_);
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) || PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
+  // Discarding pages on Windows has more CPU cost than is justified for the
+  // possible memory savings.
+  return false;
+#else   // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) ||
+        // PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
+  // http://man7.org/linux/man-pages/man2/madvise.2.html
+  int res = madvise(p, size, MADV_DONTNEED);
+  PERFETTO_DCHECK(res == 0);
+  return true;
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) ||
+        // PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
+}
+
+#if TRACK_COMMITTED_SIZE()
+void PagedMemory::EnsureCommitted(size_t committed_size) {
+  PERFETTO_DCHECK(committed_size <= size_);
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  if (committed_size_ >= committed_size)
+    return;
+  // Rounding up.
+  size_t delta = committed_size - committed_size_;
+  size_t num_additional_chunks =
+      (delta + kCommitChunkSize - 1) / kCommitChunkSize;
+  PERFETTO_DCHECK(num_additional_chunks * kCommitChunkSize >= delta);
+  // Don't commit more than the total size.
+  size_t commit_size = std::min(num_additional_chunks * kCommitChunkSize,
+                                size_ - committed_size_);
+  void* res = VirtualAlloc(p_ + committed_size_, commit_size, MEM_COMMIT,
+                           PAGE_READWRITE);
+  PERFETTO_CHECK(res);
+  ANNOTATE_CHANGE_SIZE(p_, size_, committed_size_,
+                       committed_size_ + commit_size)
+  committed_size_ += commit_size;
+#else   // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  // mmap commits automatically as needed, so we only track here for ASAN.
+  committed_size = std::max(committed_size_, committed_size);
+  ANNOTATE_CHANGE_SIZE(p_, size_, committed_size_, committed_size)
+  committed_size_ = committed_size;
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+}
+#endif  // TRACK_COMMITTED_SIZE()
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/periodic_task.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/periodic_task.h
+// gen_amalgamated begin header: include/perfetto/ext/base/thread_checker.h
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_CHECKER_H_
+#define INCLUDE_PERFETTO_EXT_BASE_THREAD_CHECKER_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <pthread.h>
+#endif
+#include <atomic>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+
+namespace perfetto {
+namespace base {
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+using ThreadID = unsigned long;
+#else
+using ThreadID = pthread_t;
+#endif
+
+class PERFETTO_EXPORT_COMPONENT ThreadChecker {
+ public:
+  ThreadChecker();
+  ~ThreadChecker();
+  ThreadChecker(const ThreadChecker&);
+  ThreadChecker& operator=(const ThreadChecker&);
+  bool CalledOnValidThread() const PERFETTO_WARN_UNUSED_RESULT;
+  void DetachFromThread();
+
+ private:
+  mutable std::atomic<ThreadID> thread_id_;
+};
+
+#if PERFETTO_DCHECK_IS_ON() && !PERFETTO_BUILDFLAG(PERFETTO_CHROMIUM_BUILD)
+// TODO(primiano) Use Chromium's thread checker in Chromium.
+#define PERFETTO_THREAD_CHECKER(name) base::ThreadChecker name;
+#define PERFETTO_DCHECK_THREAD(name) \
+  PERFETTO_DCHECK((name).CalledOnValidThread())
+#define PERFETTO_DETACH_FROM_THREAD(name) (name).DetachFromThread()
+#else
+#define PERFETTO_THREAD_CHECKER(name)
+#define PERFETTO_DCHECK_THREAD(name)
+#define PERFETTO_DETACH_FROM_THREAD(name)
+#endif  // PERFETTO_DCHECK_IS_ON()
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_THREAD_CHECKER_H_
+// gen_amalgamated begin header: include/perfetto/ext/base/weak_ptr.h
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_WEAK_PTR_H_
+#define INCLUDE_PERFETTO_EXT_BASE_WEAK_PTR_H_
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
+
+#include <memory>
+
+namespace perfetto {
+namespace base {
+
+// A simple WeakPtr for single-threaded cases.
+// Generally keep the WeakPtrFactory as last fields in classes: it makes the
+// WeakPtr(s) invalidate as first thing in the class dtor.
+// Usage:
+// class MyClass {
+//  MyClass() : weak_factory_(this) {}
+//  WeakPtr<MyClass> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
+//
+// private:
+//  WeakPtrFactory<MyClass> weak_factory_;
+// }
+//
+// int main() {
+//  std::unique_ptr<MyClass> foo(new MyClass);
+//  auto wptr = foo.GetWeakPtr();
+//  ASSERT_TRUE(wptr);
+//  ASSERT_EQ(foo.get(), wptr->get());
+//  foo.reset();
+//  ASSERT_FALSE(wptr);
+//  ASSERT_EQ(nullptr, wptr->get());
+// }
+
+template <typename T>
+class WeakPtrFactory;  // Forward declaration, defined below.
+
+template <typename T>
+class WeakPtr {
+ public:
+  WeakPtr() {}
+  WeakPtr(const WeakPtr&) = default;
+  WeakPtr& operator=(const WeakPtr&) = default;
+  WeakPtr(WeakPtr&&) = default;
+  WeakPtr& operator=(WeakPtr&&) = default;
+
+  T* get() const {
+    PERFETTO_DCHECK_THREAD(thread_checker);
+    return handle_ ? *handle_.get() : nullptr;
+  }
+  T* operator->() const { return get(); }
+  T& operator*() const { return *get(); }
+
+  explicit operator bool() const { return !!get(); }
+
+ private:
+  friend class WeakPtrFactory<T>;
+  explicit WeakPtr(const std::shared_ptr<T*>& handle) : handle_(handle) {}
+
+  std::shared_ptr<T*> handle_;
+  PERFETTO_THREAD_CHECKER(thread_checker)
+};
+
+template <typename T>
+class WeakPtrFactory {
+ public:
+  explicit WeakPtrFactory(T* owner) : weak_ptr_(std::make_shared<T*>(owner)) {
+    PERFETTO_DCHECK_THREAD(thread_checker);
+  }
+
+  ~WeakPtrFactory() {
+    PERFETTO_DCHECK_THREAD(thread_checker);
+    *(weak_ptr_.handle_.get()) = nullptr;
+  }
+
+  // Can be safely called on any thread, since it simply copies |weak_ptr_|.
+  // Note that any accesses to the returned pointer need to be made on the
+  // thread that created/reset the factory.
+  WeakPtr<T> GetWeakPtr() const { return weak_ptr_; }
+
+  // Reset the factory to a new owner & thread. May only be called before any
+  // weak pointers were passed out. Future weak pointers will be valid on the
+  // calling thread.
+  void Reset(T* owner) {
+    // Reset thread checker to current thread.
+    PERFETTO_DETACH_FROM_THREAD(thread_checker);
+    PERFETTO_DCHECK_THREAD(thread_checker);
+
+    // We should not have passed out any weak pointers yet at this point.
+    PERFETTO_DCHECK(weak_ptr_.handle_.use_count() == 1);
+
+    weak_ptr_ = WeakPtr<T>(std::make_shared<T*>(owner));
+  }
+
+ private:
+  WeakPtrFactory(const WeakPtrFactory&) = delete;
+  WeakPtrFactory& operator=(const WeakPtrFactory&) = delete;
+
+  WeakPtr<T> weak_ptr_;
+  PERFETTO_THREAD_CHECKER(thread_checker)
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_WEAK_PTR_H_
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_PERIODIC_TASK_H_
+#define INCLUDE_PERFETTO_EXT_BASE_PERIODIC_TASK_H_
+
+#include <functional>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
+
+namespace perfetto {
+namespace base {
+
+class TaskRunner;
+
+// A periodic task utility class. It wraps the logic necessary to do periodic
+// tasks using a TaskRunner, taking care of subtleties like ensuring that
+// outstanding tasks are cancelled after reset/dtor.
+// Tasks are aligned on wall time (unless they are |one_shot|). This is to
+// ensure that when using multiple periodic tasks, they happen at the same time,
+// minimizing context switches.
+// On Linux/Android it also supports suspend-aware mode (via timerfd). On other
+// operating systems it falls back to PostDelayedTask, which is not
+// suspend-aware.
+// TODO(primiano): this should probably become a periodic timer scheduler, so we
+// can use one FD for everything rather than one FD per task. For now we take
+// the hit of a FD-per-task to keep this low-risk.
+// TODO(primiano): consider renaming this class to TimerTask. When |one_shot|
+// is set, the "Periodic" part of the class name becomes a lie.
+class PeriodicTask {
+ public:
+  explicit PeriodicTask(base::TaskRunner*);
+  ~PeriodicTask();  // Calls Reset().
+
+  struct Args {
+    uint32_t period_ms = 0;
+    std::function<void()> task = nullptr;
+    bool start_first_task_immediately = false;
+    bool use_suspend_aware_timer = false;
+    bool one_shot = false;
+  };
+
+  void Start(Args);
+
+  // Safe to be called multiple times, even without calling Start():
+  void Reset();
+
+  // No copy or move. WeakPtr-wrapped pointers to |this| are posted on the
+  // task runner, this class is not easily movable.
+  PeriodicTask(const PeriodicTask&) = delete;
+  PeriodicTask& operator=(const PeriodicTask&) = delete;
+  PeriodicTask(PeriodicTask&&) = delete;
+  PeriodicTask& operator=(PeriodicTask&&) = delete;
+
+  base::PlatformHandle timer_fd_for_testing() { return *timer_fd_; }
+
+ private:
+  static void RunTaskAndPostNext(base::WeakPtr<PeriodicTask>,
+                                 uint32_t generation);
+  void PostNextTask();
+  void ResetTimerFd();
+
+  base::TaskRunner* const task_runner_;
+  Args args_;
+  uint32_t generation_ = 0;
+  base::ScopedPlatformHandle timer_fd_;
+
+  PERFETTO_THREAD_CHECKER(thread_checker_)
+  base::WeakPtrFactory<PeriodicTask> weak_ptr_factory_;  // Keep last.
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_PERIODIC_TASK_H_
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/periodic_task.h"
+
+#include <limits>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    (PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && __ANDROID_API__ >= 19)
+#include <sys/timerfd.h>
+#endif
+
+namespace perfetto {
+namespace base {
+
+namespace {
+
+uint32_t GetNextDelayMs(const TimeMillis& now_ms,
+                        const PeriodicTask::Args& args) {
+  if (args.one_shot)
+    return args.period_ms;
+
+  return args.period_ms -
+         static_cast<uint32_t>(now_ms.count() % args.period_ms);
+}
+
+ScopedPlatformHandle CreateTimerFd(const PeriodicTask::Args& args) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    (PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && __ANDROID_API__ >= 19)
+  ScopedPlatformHandle tfd(
+      timerfd_create(CLOCK_BOOTTIME, TFD_CLOEXEC | TFD_NONBLOCK));
+  uint32_t phase_ms = GetNextDelayMs(GetBootTimeMs(), args);
+
+  struct itimerspec its {};
+  // The "1 +" is to make sure that we never pass a zero it_value in the
+  // unlikely case of phase_ms being 0. That would cause the timer to be
+  // considered disarmed by timerfd_settime.
+  its.it_value.tv_sec = static_cast<time_t>(phase_ms / 1000u);
+  its.it_value.tv_nsec = 1 + static_cast<long>((phase_ms % 1000u) * 1000000u);
+  if (args.one_shot) {
+    its.it_interval.tv_sec = 0;
+    its.it_interval.tv_nsec = 0;
+  } else {
+    const uint32_t period_ms = args.period_ms;
+    its.it_interval.tv_sec = static_cast<time_t>(period_ms / 1000u);
+    its.it_interval.tv_nsec = static_cast<long>((period_ms % 1000u) * 1000000u);
+  }
+  if (timerfd_settime(*tfd, 0, &its, nullptr) < 0)
+    return ScopedPlatformHandle();
+  return tfd;
+#else
+  ignore_result(args);
+  return ScopedPlatformHandle();
+#endif
+}
+
+}  // namespace
+
+PeriodicTask::PeriodicTask(TaskRunner* task_runner)
+    : task_runner_(task_runner), weak_ptr_factory_(this) {}
+
+PeriodicTask::~PeriodicTask() {
+  Reset();
+}
+
+void PeriodicTask::Start(Args args) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  Reset();
+  if (args.period_ms == 0 || !args.task) {
+    PERFETTO_DCHECK(args.period_ms > 0);
+    PERFETTO_DCHECK(args.task);
+    return;
+  }
+  args_ = std::move(args);
+  if (args_.use_suspend_aware_timer) {
+    timer_fd_ = CreateTimerFd(args_);
+    if (timer_fd_) {
+      auto weak_this = weak_ptr_factory_.GetWeakPtr();
+      task_runner_->AddFileDescriptorWatch(
+          *timer_fd_,
+          std::bind(PeriodicTask::RunTaskAndPostNext, weak_this, generation_));
+    } else {
+      PERFETTO_DPLOG("timerfd not supported, falling back on PostDelayedTask");
+    }
+  }  // if (use_suspend_aware_timer).
+
+  if (!timer_fd_)
+    PostNextTask();
+
+  if (args_.start_first_task_immediately)
+    args_.task();
+}
+
+void PeriodicTask::PostNextTask() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DCHECK(args_.period_ms > 0);
+  PERFETTO_DCHECK(!timer_fd_);
+  uint32_t delay_ms = GetNextDelayMs(GetWallTimeMs(), args_);
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostDelayedTask(
+      std::bind(PeriodicTask::RunTaskAndPostNext, weak_this, generation_),
+      delay_ms);
+}
+
+// static
+// This function can be called in two ways (both from the TaskRunner):
+// 1. When using a timerfd, this task is registered as a FD watch.
+// 2. When using PostDelayedTask, this is the task posted on the TaskRunner.
+void PeriodicTask::RunTaskAndPostNext(WeakPtr<PeriodicTask> thiz,
+                                      uint32_t generation) {
+  if (!thiz || !thiz->args_.task || generation != thiz->generation_)
+    return;  // Destroyed or Reset() in the meanwhile.
+  PERFETTO_DCHECK_THREAD(thiz->thread_checker_);
+  if (thiz->timer_fd_) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    PERFETTO_FATAL("timerfd for periodic tasks unsupported on Windows");
+#else
+    // If we are using a timerfd there is no need to repeatedly call
+    // PostDelayedTask(). The kernel will wakeup the timer fd periodically. We
+    // just need to read() it.
+    uint64_t ignored = 0;
+    errno = 0;
+    auto rsize = Read(*thiz->timer_fd_, &ignored, sizeof(&ignored));
+    if (rsize != sizeof(uint64_t)) {
+      if (errno == EAGAIN)
+        return;  // A spurious wakeup. Rare, but can happen, just ignore.
+      PERFETTO_PLOG("read(timerfd) failed, falling back on PostDelayedTask");
+      thiz->ResetTimerFd();
+    }
+#endif
+  }
+
+  // Create a copy of the task to deal with either:
+  // 1. one_shot causing a Reset().
+  // 2. task() invoking internally Reset().
+  // That would cause a reset of the args_.task itself, which would invalidate
+  // the task bind state while we are invoking it.
+  auto task = thiz->args_.task;
+
+  // The repetition of the if() is to deal with the ResetTimerFd() case above.
+  if (thiz->args_.one_shot) {
+    thiz->Reset();
+  } else if (!thiz->timer_fd_) {
+    thiz->PostNextTask();
+  }
+
+  task();
+}
+
+void PeriodicTask::Reset() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  ++generation_;
+  args_ = Args();
+  PERFETTO_DCHECK(!args_.task);
+  ResetTimerFd();
+}
+
+void PeriodicTask::ResetTimerFd() {
+  if (!timer_fd_)
+    return;
+  task_runner_->RemoveFileDescriptorWatch(*timer_fd_);
+  timer_fd_.reset();
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/pipe.cc
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+#include <fcntl.h>  // For O_BINARY (Windows) and F_SETxx (UNIX)
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <Windows.h>
+#include <namedpipeapi.h>
+#else
+#include <sys/types.h>
+#include <unistd.h>
+#endif
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+
+namespace perfetto {
+namespace base {
+
+Pipe::Pipe() = default;
+Pipe::Pipe(Pipe&&) noexcept = default;
+Pipe& Pipe::operator=(Pipe&&) = default;
+
+Pipe Pipe::Create(Flags flags) {
+  PlatformHandle fds[2];
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  PERFETTO_CHECK(::CreatePipe(&fds[0], &fds[1], /*lpPipeAttributes=*/nullptr,
+                              0 /*default size*/));
+#else
+  PERFETTO_CHECK(pipe(fds) == 0);
+  PERFETTO_CHECK(fcntl(fds[0], F_SETFD, FD_CLOEXEC) == 0);
+  PERFETTO_CHECK(fcntl(fds[1], F_SETFD, FD_CLOEXEC) == 0);
+#endif
+  Pipe p;
+  p.rd.reset(fds[0]);
+  p.wr.reset(fds[1]);
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  if (flags == kBothNonBlock || flags == kRdNonBlock) {
+    int cur_flags = fcntl(*p.rd, F_GETFL, 0);
+    PERFETTO_CHECK(cur_flags >= 0);
+    PERFETTO_CHECK(fcntl(*p.rd, F_SETFL, cur_flags | O_NONBLOCK) == 0);
+  }
+
+  if (flags == kBothNonBlock || flags == kWrNonBlock) {
+    int cur_flags = fcntl(*p.wr, F_GETFL, 0);
+    PERFETTO_CHECK(cur_flags >= 0);
+    PERFETTO_CHECK(fcntl(*p.wr, F_SETFL, cur_flags | O_NONBLOCK) == 0);
+  }
+#else
+  PERFETTO_CHECK(flags == kBothBlock);
+#endif
+  return p;
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/scoped_mmap.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/scoped_mmap.h
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_SCOPED_MMAP_H_
+#define INCLUDE_PERFETTO_EXT_BASE_SCOPED_MMAP_H_
+
+#include <cstddef>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#define PERFETTO_HAS_MMAP() 1
+#else
+#define PERFETTO_HAS_MMAP() 0
+#endif
+
+namespace perfetto::base {
+
+// RAII wrapper that holds ownership of an mmap()d area and of a file. Calls
+// unmap() and close() on destruction.
+class ScopedMmap {
+ public:
+  // Creates a memory mapping for the first `length` bytes of `file`.
+  static ScopedMmap FromHandle(base::ScopedPlatformHandle file, size_t length);
+
+  ScopedMmap() {}
+  ~ScopedMmap();
+  ScopedMmap(ScopedMmap&& other) noexcept;
+
+  ScopedMmap& operator=(ScopedMmap&& other) noexcept;
+
+  // Returns a pointer to the mapped memory area. Only valid if `IsValid()` is
+  // true.
+  void* data() const { return ptr_; }
+
+  // Returns true if this object contains a successfully mapped area.
+  bool IsValid() const { return ptr_ != nullptr; }
+
+  // Returns the length of the mapped area.
+  size_t length() const { return length_; }
+
+  // Unmaps the area and closes the file. Returns false if this held a mmap()d
+  // area and unmapping failed. In any case, after this method, `IsValid()` will
+  // return false.
+  bool reset() noexcept;
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+  // Takes ownership of an mmap()d area that starts at `data`, `size` bytes
+  // long. `data` should not be MAP_FAILED.
+  static ScopedMmap InheritMmappedRange(void* data, size_t size);
+#endif
+
+ private:
+  ScopedMmap(const ScopedMmap&) = delete;
+  ScopedMmap& operator=(const ScopedMmap&) = delete;
+
+  size_t length_ = 0;
+  void* ptr_ = nullptr;
+  ScopedPlatformHandle file_;
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  ScopedPlatformHandle map_;
+#endif
+};
+
+// Tries to open `fname` and maps its first `length` bytes in memory.
+ScopedMmap ReadMmapFilePart(const char* fname, size_t length);
+
+// Tries to open `fname` and maps the whole file into memory.
+ScopedMmap ReadMmapWholeFile(const char* fname);
+
+}  // namespace perfetto::base
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_SCOPED_MMAP_H_
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_mmap.h"
+
+#include <utility>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+#include <sys/mman.h>
+#include <unistd.h>
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <Windows.h>
+#endif
+
+namespace perfetto::base {
+namespace {
+
+ScopedPlatformHandle OpenFileForMmap(const char* fname) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+  return OpenFile(fname, O_RDONLY);
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  // This does not use base::OpenFile to avoid getting an exclusive lock.
+  return ScopedPlatformHandle(CreateFileA(fname, GENERIC_READ, FILE_SHARE_READ,
+                                          nullptr, OPEN_EXISTING,
+                                          FILE_ATTRIBUTE_NORMAL, nullptr));
+#else
+  // mmap is not supported. Do not even open the file.
+  base::ignore_result(fname);
+  return ScopedPlatformHandle();
+#endif
+}
+
+}  // namespace
+
+ScopedMmap::ScopedMmap(ScopedMmap&& other) noexcept {
+  *this = std::move(other);
+}
+
+ScopedMmap& ScopedMmap::operator=(ScopedMmap&& other) noexcept {
+  if (this == &other) {
+    return *this;
+  }
+  reset();
+  std::swap(ptr_, other.ptr_);
+  std::swap(length_, other.length_);
+  std::swap(file_, other.file_);
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  std::swap(map_, other.map_);
+#endif
+  return *this;
+}
+
+ScopedMmap::~ScopedMmap() {
+  reset();
+}
+
+// static
+ScopedMmap ScopedMmap::FromHandle(base::ScopedPlatformHandle file,
+                                  size_t length) {
+  ScopedMmap ret;
+  if (!file) {
+    return ret;
+  }
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+  void* ptr = mmap(nullptr, length, PROT_READ, MAP_PRIVATE, *file, 0);
+  if (ptr != MAP_FAILED) {
+    ret.ptr_ = ptr;
+    ret.length_ = length;
+    ret.file_ = std::move(file);
+  }
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  ScopedPlatformHandle map(
+      CreateFileMapping(*file, nullptr, PAGE_READONLY, 0, 0, nullptr));
+  if (!map) {
+    return ret;
+  }
+  void* ptr = MapViewOfFile(*map, FILE_MAP_READ, 0, 0, length);
+  if (ptr != nullptr) {
+    ret.ptr_ = ptr;
+    ret.length_ = length;
+    ret.file_ = std::move(file);
+    ret.map_ = std::move(map);
+  }
+#else
+  base::ignore_result(length);
+#endif
+  return ret;
+}
+
+bool ScopedMmap::reset() noexcept {
+  bool ret = true;
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+  if (ptr_ != nullptr) {
+    ret = munmap(ptr_, length_) == 0;
+  }
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  if (ptr_ != nullptr) {
+    ret = UnmapViewOfFile(ptr_);
+  }
+  map_.reset();
+#endif
+  ptr_ = nullptr;
+  length_ = 0;
+  file_.reset();
+  return ret;
+}
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+// static
+ScopedMmap ScopedMmap::InheritMmappedRange(void* data, size_t size) {
+  ScopedMmap ret;
+  ret.ptr_ = data;
+  ret.length_ = size;
+  return ret;
+}
+#endif
+
+ScopedMmap ReadMmapFilePart(const char* fname, size_t length) {
+  return ScopedMmap::FromHandle(OpenFileForMmap(fname), length);
+}
+
+ScopedMmap ReadMmapWholeFile(const char* fname) {
+  ScopedPlatformHandle file = OpenFileForMmap(fname);
+  if (!file) {
+    return ScopedMmap();
+  }
+  std::optional<uint64_t> file_size = GetFileSize(file.get());
+  if (!file_size.has_value()) {
+    return ScopedMmap();
+  }
+  size_t size = static_cast<size_t>(*file_size);
+  if (static_cast<uint64_t>(size) != *file_size) {
+    return ScopedMmap();
+  }
+  return ScopedMmap::FromHandle(std::move(file), size);
+}
+
+}  // namespace perfetto::base
+// gen_amalgamated begin source: src/base/status.cc
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/base/status.h"
+
+#include <stdarg.h>
+#include <algorithm>
+
+namespace perfetto {
+namespace base {
+
+Status ErrStatus(const char* format, ...) {
+  char buffer[1024];
+  va_list ap;
+  va_start(ap, format);
+  vsnprintf(buffer, sizeof(buffer), format, ap);
+  va_end(ap);
+  Status status(buffer);
+  return status;
+}
+
+std::optional<std::string_view> Status::GetPayload(
+    std::string_view type_url) const {
+  if (ok()) {
+    return std::nullopt;
+  }
+  for (const auto& kv : payloads_) {
+    if (kv.type_url == type_url) {
+      return kv.payload;
+    }
+  }
+  return std::nullopt;
+}
+
+void Status::SetPayload(std::string_view type_url, std::string value) {
+  if (ok()) {
+    return;
+  }
+  for (auto& kv : payloads_) {
+    if (kv.type_url == type_url) {
+      kv.payload = value;
+      return;
+    }
+  }
+  payloads_.push_back(Payload{std::string(type_url), std::move(value)});
+}
+
+bool Status::ErasePayload(std::string_view type_url) {
+  if (ok()) {
+    return false;
+  }
+  auto it = std::remove_if(
+      payloads_.begin(), payloads_.end(),
+      [type_url](const Payload& p) { return p.type_url == type_url; });
+  bool erased = it != payloads_.end();
+  payloads_.erase(it, payloads_.end());
+  return erased;
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/string_splitter.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/string_splitter.h
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_STRING_SPLITTER_H_
+#define INCLUDE_PERFETTO_EXT_BASE_STRING_SPLITTER_H_
+
+#include <string>
+
+namespace perfetto {
+namespace base {
+
+// C++ version of strtok(). Splits a string without making copies or any heap
+// allocations. Destructs the original string passed in input.
+// Supports the special case of using \0 as a delimiter.
+// The token returned in output are valid as long as the input string is valid.
+class StringSplitter {
+ public:
+  // Whether an empty string (two delimiters side-to-side) is a valid token.
+  enum class EmptyTokenMode {
+    DISALLOW_EMPTY_TOKENS,
+    ALLOW_EMPTY_TOKENS,
+
+    DEFAULT = DISALLOW_EMPTY_TOKENS,
+  };
+
+  // Can take ownership of the string if passed via std::move(), e.g.:
+  // StringSplitter(std::move(str), '\n');
+  StringSplitter(std::string,
+                 char delimiter,
+                 EmptyTokenMode empty_token_mode = EmptyTokenMode::DEFAULT);
+
+  // Splits a C-string. The input string will be forcefully null-terminated (so
+  // str[size - 1] should be == '\0' or the last char will be truncated).
+  StringSplitter(char* str,
+                 size_t size,
+                 char delimiter,
+                 EmptyTokenMode empty_token_mode = EmptyTokenMode::DEFAULT);
+
+  // Splits the current token from an outer StringSplitter instance. This is to
+  // chain splitters as follows:
+  // for (base::StringSplitter lines(x, '\n'); ss.Next();)
+  //   for (base::StringSplitter words(&lines, ' '); words.Next();)
+  StringSplitter(StringSplitter*,
+                 char delimiter,
+                 EmptyTokenMode empty_token_mode = EmptyTokenMode::DEFAULT);
+
+  // Returns true if a token is found (in which case it will be stored in
+  // cur_token()), false if no more tokens are found.
+  bool Next();
+
+  // Returns the current token iff last call to Next() returned true. In this
+  // case it guarantees that the returned string is always null terminated.
+  // In all other cases (before the 1st call to Next() and after Next() returns
+  // false) returns nullptr.
+  char* cur_token() { return cur_; }
+
+  // Returns the length of the current token (excluding the null terminator).
+  size_t cur_token_size() const { return cur_size_; }
+
+ private:
+  StringSplitter(const StringSplitter&) = delete;
+  StringSplitter& operator=(const StringSplitter&) = delete;
+  void Initialize(char* str, size_t size);
+
+  std::string str_;
+  char* cur_;
+  size_t cur_size_;
+  char* next_;
+  char* end_;  // STL-style, points one past the last char.
+  const char delimiter_;
+  const EmptyTokenMode empty_token_mode_;
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_STRING_SPLITTER_H_
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_splitter.h"
+
+#include <utility>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+
+namespace perfetto {
+namespace base {
+
+StringSplitter::StringSplitter(std::string str,
+                               char delimiter,
+                               EmptyTokenMode empty_token_mode)
+    : str_(std::move(str)),
+      delimiter_(delimiter),
+      empty_token_mode_(empty_token_mode) {
+  // It's legal to access str[str.size()] in C++11 (it always returns \0),
+  // hence the +1 (which becomes just size() after the -1 in Initialize()).
+  Initialize(&str_[0], str_.size() + 1);
+}
+
+StringSplitter::StringSplitter(char* str,
+                               size_t size,
+                               char delimiter,
+                               EmptyTokenMode empty_token_mode)
+    : delimiter_(delimiter), empty_token_mode_(empty_token_mode) {
+  Initialize(str, size);
+}
+
+StringSplitter::StringSplitter(StringSplitter* outer,
+                               char delimiter,
+                               EmptyTokenMode empty_token_mode)
+    : delimiter_(delimiter), empty_token_mode_(empty_token_mode) {
+  Initialize(outer->cur_token(), outer->cur_token_size() + 1);
+}
+
+void StringSplitter::Initialize(char* str, size_t size) {
+  PERFETTO_DCHECK(!size || str);
+  next_ = str;
+  end_ = str + size;
+  cur_ = nullptr;
+  cur_size_ = 0;
+  if (size)
+    next_[size - 1] = '\0';
+}
+
+bool StringSplitter::Next() {
+  for (; next_ < end_; next_++) {
+    if (*next_ == delimiter_ &&
+        empty_token_mode_ == EmptyTokenMode::DISALLOW_EMPTY_TOKENS) {
+      // If empty tokens are disallowed, find fist non-delimiter character.
+      continue;
+    }
+    cur_ = next_;
+    for (;; next_++) {
+      if (*next_ == delimiter_) {
+        cur_size_ = static_cast<size_t>(next_ - cur_);
+        *(next_++) = '\0';
+        break;
+      }
+      if (*next_ == '\0') {
+        cur_size_ = static_cast<size_t>(next_ - cur_);
+        next_ = end_;
+        break;
+      }
+    }
+    if (*cur_ || empty_token_mode_ == EmptyTokenMode::ALLOW_EMPTY_TOKENS)
+      return true;
+    break;
+  }
+  cur_ = nullptr;
+  cur_size_ = 0;
+  return false;
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/string_utils.cc
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
+
+#include <locale.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include <algorithm>
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+#include <xlocale.h>
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <Windows.h>
+#endif
+
+#include <cinttypes>
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+
+namespace perfetto {
+namespace base {
+
+// Locale-independant as possible version of strtod.
+double StrToD(const char* nptr, char** endptr) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+  static auto c_locale = newlocale(LC_ALL, "C", nullptr);
+  return strtod_l(nptr, endptr, c_locale);
+#else
+  return strtod(nptr, endptr);
+#endif
+}
+
+bool StartsWith(const std::string& str, const std::string& prefix) {
+  return str.compare(0, prefix.length(), prefix) == 0;
+}
+
+bool StartsWithAny(const std::string& str,
+                   const std::vector<std::string>& prefixes) {
+  return std::any_of(
+      prefixes.begin(), prefixes.end(),
+      [&str](const std::string& prefix) { return StartsWith(str, prefix); });
+}
+
+bool EndsWith(const std::string& str, const std::string& suffix) {
+  if (suffix.size() > str.size())
+    return false;
+  return str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
+}
+
+bool Contains(const std::string& haystack, const std::string& needle) {
+  return haystack.find(needle) != std::string::npos;
+}
+
+bool Contains(const std::string& haystack, const char needle) {
+  return haystack.find(needle) != std::string::npos;
+}
+
+size_t Find(const StringView& needle, const StringView& haystack) {
+  if (needle.empty())
+    return 0;
+  if (needle.size() > haystack.size())
+    return std::string::npos;
+  for (size_t i = 0; i < haystack.size() - (needle.size() - 1); ++i) {
+    if (strncmp(haystack.data() + i, needle.data(), needle.size()) == 0)
+      return i;
+  }
+  return std::string::npos;
+}
+
+bool CaseInsensitiveEqual(const std::string& first, const std::string& second) {
+  return first.size() == second.size() &&
+         std::equal(
+             first.begin(), first.end(), second.begin(),
+             [](char a, char b) { return Lowercase(a) == Lowercase(b); });
+}
+
+std::string Join(const std::vector<std::string>& parts,
+                 const std::string& delim) {
+  std::string acc;
+  for (size_t i = 0; i < parts.size(); ++i) {
+    acc += parts[i];
+    if (i + 1 != parts.size()) {
+      acc += delim;
+    }
+  }
+  return acc;
+}
+
+std::vector<std::string> SplitString(const std::string& text,
+                                     const std::string& delimiter) {
+  PERFETTO_CHECK(!delimiter.empty());
+
+  std::vector<std::string> output;
+  size_t start = 0;
+  size_t next;
+  for (;;) {
+    next = std::min(text.find(delimiter, start), text.size());
+    if (next > start)
+      output.emplace_back(&text[start], next - start);
+    start = next + delimiter.size();
+    if (start >= text.size())
+      break;
+  }
+  return output;
+}
+
+std::string TrimWhitespace(const std::string& str) {
+  std::string whitespaces = "\t\n ";
+
+  size_t front_idx = str.find_first_not_of(whitespaces);
+  std::string front_trimmed =
+      front_idx == std::string::npos ? "" : str.substr(front_idx);
+
+  size_t end_idx = front_trimmed.find_last_not_of(whitespaces);
+  return end_idx == std::string::npos ? ""
+                                      : front_trimmed.substr(0, end_idx + 1);
+}
+
+std::string StripPrefix(const std::string& str, const std::string& prefix) {
+  return StartsWith(str, prefix) ? str.substr(prefix.size()) : str;
+}
+
+std::string StripSuffix(const std::string& str, const std::string& suffix) {
+  return EndsWith(str, suffix) ? str.substr(0, str.size() - suffix.size())
+                               : str;
+}
+
+std::string ToUpper(const std::string& str) {
+  // Don't use toupper(), it depends on the locale.
+  std::string res(str);
+  auto end = res.end();
+  for (auto c = res.begin(); c != end; ++c)
+    *c = Uppercase(*c);
+  return res;
+}
+
+std::string ToLower(const std::string& str) {
+  // Don't use tolower(), it depends on the locale.
+  std::string res(str);
+  auto end = res.end();
+  for (auto c = res.begin(); c != end; ++c)
+    *c = Lowercase(*c);
+  return res;
+}
+
+std::string ToHex(const char* data, size_t size) {
+  std::string hex(2 * size + 1, 'x');
+  for (size_t i = 0; i < size; ++i) {
+    // snprintf prints 3 characters, the two hex digits and a null byte. As we
+    // write left to right, we keep overwriting the nullbytes, except for the
+    // last call to snprintf.
+    snprintf(&(hex[2 * i]), 3, "%02hhx", data[i]);
+  }
+  // Remove the trailing nullbyte produced by the last snprintf.
+  hex.resize(2 * size);
+  return hex;
+}
+
+std::string IntToHexString(uint32_t number) {
+  size_t max_size = 11;  // Max uint32 is 0xFFFFFFFF + 1 for null byte.
+  std::string buf;
+  buf.resize(max_size);
+  size_t final_len = SprintfTrunc(&buf[0], max_size, "0x%02x", number);
+  buf.resize(static_cast<size_t>(final_len));  // Cuts off the final null byte.
+  return buf;
+}
+
+std::string Uint64ToHexString(uint64_t number) {
+  return "0x" + Uint64ToHexStringNoPrefix(number);
+}
+
+std::string Uint64ToHexStringNoPrefix(uint64_t number) {
+  size_t max_size = 17;  // Max uint64 is FFFFFFFFFFFFFFFF + 1 for null byte.
+  std::string buf;
+  buf.resize(max_size);
+  size_t final_len = SprintfTrunc(&buf[0], max_size, "%" PRIx64 "", number);
+  buf.resize(static_cast<size_t>(final_len));  // Cuts off the final null byte.
+  return buf;
+}
+
+std::string StripChars(const std::string& str,
+                       const std::string& chars,
+                       char replacement) {
+  std::string res(str);
+  const char* start = res.c_str();
+  const char* remove = chars.c_str();
+  for (const char* c = strpbrk(start, remove); c; c = strpbrk(c + 1, remove))
+    res[static_cast<uintptr_t>(c - start)] = replacement;
+  return res;
+}
+
+std::string ReplaceAll(std::string str,
+                       const std::string& to_replace,
+                       const std::string& replacement) {
+  PERFETTO_CHECK(!to_replace.empty());
+  size_t pos = 0;
+  while ((pos = str.find(to_replace, pos)) != std::string::npos) {
+    str.replace(pos, to_replace.length(), replacement);
+    pos += replacement.length();
+  }
+  return str;
+}
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+bool WideToUTF8(const std::wstring& source, std::string& output) {
+  if (source.empty() ||
+      source.size() > static_cast<size_t>(std::numeric_limits<int>::max())) {
+    return false;
+  }
+  int size = ::WideCharToMultiByte(CP_UTF8, 0, &source[0],
+                                   static_cast<int>(source.size()), nullptr, 0,
+                                   nullptr, nullptr);
+  output.assign(static_cast<size_t>(size), '\0');
+  if (::WideCharToMultiByte(CP_UTF8, 0, &source[0],
+                            static_cast<int>(source.size()), &output[0], size,
+                            nullptr, nullptr) != size) {
+    return false;
+  }
+  return true;
+}
+#endif // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+bool UTF8ToWide(const std::string& source, std::wstring& output) {
+  if (source.empty() ||
+      source.size() > static_cast<size_t>(std::numeric_limits<int>::max())) {
+    return false;
+  }
+  int size = ::MultiByteToWideChar(CP_UTF8, 0, &source[0],
+                                   static_cast<int>(source.size()), nullptr, 0);
+  output.assign(static_cast<size_t>(size), L'\0');
+  if (::MultiByteToWideChar(CP_UTF8, 0, &source[0],
+                            static_cast<int>(source.size()), &output[0],
+                            size) != size) {
+    return false;
+  }
+  return true;
+}
+#endif // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+size_t SprintfTrunc(char* dst, size_t dst_size, const char* fmt, ...) {
+  if (PERFETTO_UNLIKELY(dst_size) == 0)
+    return 0;
+
+  va_list args;
+  va_start(args, fmt);
+  int src_size = vsnprintf(dst, dst_size, fmt, args);
+  va_end(args);
+
+  if (PERFETTO_UNLIKELY(src_size) <= 0) {
+    dst[0] = '\0';
+    return 0;
+  }
+
+  size_t res;
+  if (PERFETTO_LIKELY(src_size < static_cast<int>(dst_size))) {
+    // Most common case.
+    res = static_cast<size_t>(src_size);
+  } else {
+    // Truncation case.
+    res = dst_size - 1;
+  }
+
+  PERFETTO_DCHECK(res < dst_size);
+  PERFETTO_DCHECK(dst[res] == '\0');
+  return res;
+}
+
+std::optional<LineWithOffset> FindLineWithOffset(base::StringView str,
+                                                 uint32_t offset) {
+  static constexpr char kNewLine = '\n';
+  uint32_t line_offset = 0;
+  uint32_t line_count = 1;
+  for (uint32_t i = 0; i < str.size(); ++i) {
+    if (str.at(i) == kNewLine) {
+      line_offset = i + 1;
+      line_count++;
+      continue;
+    }
+    if (i == offset) {
+      size_t end_offset = str.find(kNewLine, i);
+      if (end_offset == std::string::npos) {
+        end_offset = str.size();
+      }
+      base::StringView line = str.substr(line_offset, end_offset - line_offset);
+      return LineWithOffset{line, offset - line_offset, line_count};
+    }
+  }
+  return std::nullopt;
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/string_view.cc
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
+
+namespace perfetto {
+namespace base {
+
+// Without ignoring this warning we get the message:
+//   error: out-of-line definition of constexpr static data member is redundant
+//   in C++17 and is deprecated
+// when using clang-cl in Windows.
+#if defined(__GNUC__)  // GCC & clang
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated"
+#endif  // __GNUC__
+
+// static
+constexpr size_t StringView::npos;
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/temp_file.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/temp_file.h
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_TEMP_FILE_H_
+#define INCLUDE_PERFETTO_EXT_BASE_TEMP_FILE_H_
+
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+
+namespace perfetto {
+namespace base {
+
+std::string GetSysTempDir();
+
+class TempFile {
+ public:
+  static TempFile CreateUnlinked();
+  static TempFile Create();
+
+  TempFile(TempFile&&) noexcept;
+  TempFile& operator=(TempFile&&);
+  ~TempFile();
+
+  const std::string& path() const { return path_; }
+  int fd() const { return *fd_; }
+  int operator*() const { return *fd_; }
+
+  // Unlinks the file from the filesystem but keeps the fd() open.
+  // It is safe to call this multiple times.
+  void Unlink();
+
+  // Releases the underlying file descriptor. Will unlink the file from the
+  // filesystem if it was created via CreateUnlinked().
+  ScopedFile ReleaseFD();
+
+ private:
+  TempFile();
+  TempFile(const TempFile&) = delete;
+  TempFile& operator=(const TempFile&) = delete;
+
+  ScopedFile fd_;
+  std::string path_;
+};
+
+class TempDir {
+ public:
+  static TempDir Create();
+
+  TempDir(TempDir&&) noexcept;
+  TempDir& operator=(TempDir&&);
+  ~TempDir();
+
+  const std::string& path() const { return path_; }
+
+ private:
+  TempDir();
+  TempDir(const TempDir&) = delete;
+  TempDir& operator=(const TempDir&) = delete;
+
+  std::string path_;
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_TEMP_FILE_H_
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/temp_file.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <Windows.h>
+#include <direct.h>
+#include <fileapi.h>
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
+
+namespace perfetto {
+namespace base {
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+namespace {
+std::string GetTempFilePathWin() {
+  std::string tmplt = GetSysTempDir() + "\\perfetto-XXXXXX";
+  StackString<255> name("%s\\perfetto-XXXXXX", GetSysTempDir().c_str());
+  PERFETTO_CHECK(_mktemp_s(name.mutable_data(), name.len() + 1) == 0);
+  return name.ToStdString();
+}
+}  // namespace
+#endif
+
+std::string GetSysTempDir() {
+  const char* tmpdir = nullptr;
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  if ((tmpdir = getenv("TMP")))
+    return tmpdir;
+  if ((tmpdir = getenv("TEMP")))
+    return tmpdir;
+  return "C:\\TEMP";
+#else
+  if ((tmpdir = getenv("TMPDIR")))
+    return base::StripSuffix(tmpdir, "/");
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  return "/data/local/tmp";
+#else
+  return "/tmp";
+#endif  // !OS_ANDROID
+#endif  // !OS_WIN
+}
+
+// static
+TempFile TempFile::Create() {
+  TempFile temp_file;
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  temp_file.path_ = GetTempFilePathWin();
+  // Several tests want to read-back the temp file while still open. On Windows,
+  // that requires FILE_SHARE_READ. FILE_SHARE_READ is NOT settable when using
+  // the POSIX-compat equivalent function _open(). Hence the CreateFileA +
+  // _open_osfhandle dance here.
+  HANDLE h =
+      ::CreateFileA(temp_file.path_.c_str(), GENERIC_READ | GENERIC_WRITE,
+                    FILE_SHARE_DELETE | FILE_SHARE_READ, nullptr, CREATE_ALWAYS,
+                    FILE_ATTRIBUTE_TEMPORARY, nullptr);
+  PERFETTO_CHECK(PlatformHandleChecker::IsValid(h));
+  // According to MSDN, when using _open_osfhandle the caller must not call
+  // CloseHandle(). Ownership is moved to the file descriptor, which then needs
+  // to be closed with just with _close().
+  temp_file.fd_.reset(_open_osfhandle(reinterpret_cast<intptr_t>(h), 0));
+#else
+  temp_file.path_ = GetSysTempDir() + "/perfetto-XXXXXXXX";
+  temp_file.fd_.reset(mkstemp(&temp_file.path_[0]));
+#endif
+  if (PERFETTO_UNLIKELY(!temp_file.fd_)) {
+    PERFETTO_FATAL("Could not create temp file %s", temp_file.path_.c_str());
+  }
+  return temp_file;
+}
+
+// static
+TempFile TempFile::CreateUnlinked() {
+  TempFile temp_file = TempFile::Create();
+  temp_file.Unlink();
+  return temp_file;
+}
+
+TempFile::TempFile() = default;
+
+TempFile::~TempFile() {
+  Unlink();
+}
+
+ScopedFile TempFile::ReleaseFD() {
+  Unlink();
+  return std::move(fd_);
+}
+
+void TempFile::Unlink() {
+  if (path_.empty())
+    return;
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  // If the FD is still open DeleteFile will mark the file as pending deletion
+  // and delete it only when the process exists.
+  PERFETTO_CHECK(DeleteFileA(path_.c_str()));
+#else
+  PERFETTO_CHECK(unlink(path_.c_str()) == 0);
+#endif
+  path_.clear();
+}
+
+TempFile::TempFile(TempFile&&) noexcept = default;
+TempFile& TempFile::operator=(TempFile&&) = default;
+
+// static
+TempDir TempDir::Create() {
+  TempDir temp_dir;
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  temp_dir.path_ = GetTempFilePathWin();
+  PERFETTO_CHECK(_mkdir(temp_dir.path_.c_str()) == 0);
+#else
+  temp_dir.path_ = GetSysTempDir() + "/perfetto-XXXXXXXX";
+  PERFETTO_CHECK(mkdtemp(&temp_dir.path_[0]));
+#endif
+  return temp_dir;
+}
+
+TempDir::TempDir() = default;
+TempDir::TempDir(TempDir&&) noexcept = default;
+TempDir& TempDir::operator=(TempDir&&) = default;
+
+TempDir::~TempDir() {
+  if (path_.empty())
+    return;  // For objects that get std::move()d.
+  PERFETTO_CHECK(Rmdir(path_));
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/thread_checker.cc
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <Windows.h>
+#endif
+
+namespace perfetto {
+namespace base {
+
+namespace {
+constexpr ThreadID kDetached{};
+
+ThreadID CurrentThreadId() {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  return ::GetCurrentThreadId();
+#else
+  return pthread_self();
+#endif
+}
+}  // namespace
+
+ThreadChecker::ThreadChecker() {
+  thread_id_.store(CurrentThreadId());
+}
+
+ThreadChecker::~ThreadChecker() = default;
+
+ThreadChecker::ThreadChecker(const ThreadChecker& other) {
+  thread_id_ = other.thread_id_.load();
+}
+
+ThreadChecker& ThreadChecker::operator=(const ThreadChecker& other) {
+  thread_id_ = other.thread_id_.load();
+  return *this;
+}
+
+bool ThreadChecker::CalledOnValidThread() const {
+  auto self = CurrentThreadId();
+
+  // Will re-attach if previously detached using DetachFromThread().
+  auto prev_value = kDetached;
+  if (thread_id_.compare_exchange_strong(prev_value, self))
+    return true;
+  return prev_value == self;
+}
+
+void ThreadChecker::DetachFromThread() {
+  thread_id_.store(kDetached);
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/thread_utils.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/thread_utils.h
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_UTILS_H_
+#define INCLUDE_PERFETTO_EXT_BASE_THREAD_UTILS_H_
+
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+#include <pthread.h>
+#include <string.h>
+#include <algorithm>
+#endif
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#include <sys/prctl.h>
+#endif
+
+// Internal implementation utils that aren't as widely useful/supported as
+// base/thread_utils.h.
+
+namespace perfetto {
+namespace base {
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+// Sets the "comm" of the calling thread to the first 15 chars of the given
+// string.
+inline bool MaybeSetThreadName(const std::string& name) {
+  char buf[16] = {};
+  StringCopy(buf, name.c_str(), sizeof(buf));
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+  return pthread_setname_np(buf) == 0;
+#else
+  return pthread_setname_np(pthread_self(), buf) == 0;
+#endif
+}
+
+inline bool GetThreadName(std::string& out_result) {
+  char buf[16] = {};
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  if (prctl(PR_GET_NAME, buf) != 0)
+    return false;
+#else
+  if (pthread_getname_np(pthread_self(), buf, sizeof(buf)) != 0)
+    return false;
+#endif
+  out_result = std::string(buf);
+  return true;
+}
+
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+PERFETTO_EXPORT_COMPONENT bool MaybeSetThreadName(const std::string& name);
+PERFETTO_EXPORT_COMPONENT bool GetThreadName(std::string& out_result);
+
+#else
+inline bool MaybeSetThreadName(const std::string&) {
+  return false;
+}
+inline bool GetThreadName(std::string&) {
+  return false;
+}
+#endif
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_THREAD_UTILS_H_
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/base/thread_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_utils.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+#include <zircon/process.h>
+#include <zircon/syscalls.h>
+#include <zircon/types.h>
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <Windows.h>
+#endif
+
+namespace perfetto {
+namespace base {
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+static PlatformThreadId ResolveThreadId() {
+  zx_info_handle_basic_t basic;
+  return (zx_object_get_info(zx_thread_self(), ZX_INFO_HANDLE_BASIC, &basic,
+                             sizeof(basic), nullptr, nullptr) == ZX_OK)
+             ? basic.koid
+             : ZX_KOID_INVALID;
+}
+PlatformThreadId GetThreadId() {
+  thread_local static PlatformThreadId thread_id = ResolveThreadId();
+  return thread_id;
+}
+
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+// The SetThreadDescription API was brought in version 1607 of Windows 10.
+typedef HRESULT(WINAPI* SetThreadDescription)(HANDLE hThread,
+                                              PCWSTR lpThreadDescription);
+
+// The SetThreadDescription API was brought in version 1607 of Windows 10.
+typedef HRESULT(WINAPI* GetThreadDescription)(HANDLE hThread,
+                                              PWSTR* ppszThreadDescription);
+
+bool MaybeSetThreadName(const std::string& name) {
+  // The SetThreadDescription API works even if no debugger is attached.
+  static auto set_thread_description_func =
+      reinterpret_cast<SetThreadDescription>(
+          reinterpret_cast<void*>(::GetProcAddress(
+              ::GetModuleHandleA("Kernel32.dll"), "SetThreadDescription")));
+  if (!set_thread_description_func) {
+    return false;
+  }
+  std::wstring wide_thread_name;
+  if (!UTF8ToWide(name, wide_thread_name)) {
+    return false;
+  }
+  HRESULT result = set_thread_description_func(::GetCurrentThread(),
+                                               wide_thread_name.c_str());
+  return !FAILED(result);
+}
+
+bool GetThreadName(std::string& out_result) {
+  static auto get_thread_description_func =
+      reinterpret_cast<GetThreadDescription>(
+          reinterpret_cast<void*>(::GetProcAddress(
+              ::GetModuleHandleA("Kernel32.dll"), "GetThreadDescription")));
+  if (!get_thread_description_func) {
+    return false;
+  }
+  wchar_t* wide_thread_name;
+  HRESULT result =
+      get_thread_description_func(::GetCurrentThread(), &wide_thread_name);
+  if (SUCCEEDED(result)) {
+    bool success = WideToUTF8(std::wstring(wide_thread_name), out_result);
+    LocalFree(wide_thread_name);
+    return success;
+  }
+  return false;
+}
+
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/time.cc
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <atomic>
+
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <Windows.h>
+#else
+#include <unistd.h>
+#endif
+
+namespace perfetto {
+namespace base {
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#if !PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_ARM64)
+namespace {
+
+// Returns the current value of the performance counter.
+int64_t QPCNowRaw() {
+  LARGE_INTEGER perf_counter_now = {};
+  // According to the MSDN documentation for QueryPerformanceCounter(), this
+  // will never fail on systems that run XP or later.
+  // https://msdn.microsoft.com/library/windows/desktop/ms644904.aspx
+  ::QueryPerformanceCounter(&perf_counter_now);
+  return perf_counter_now.QuadPart;
+}
+
+double TSCTicksPerSecond() {
+  // The value returned by QueryPerformanceFrequency() cannot be used as the TSC
+  // frequency, because there is no guarantee that the TSC frequency is equal to
+  // the performance counter frequency.
+  // The TSC frequency is cached in a static variable because it takes some time
+  // to compute it.
+  static std::atomic<double> tsc_ticks_per_second = 0;
+  double value = tsc_ticks_per_second.load(std::memory_order_relaxed);
+  if (value != 0)
+    return value;
+
+  // Increase the thread priority to reduces the chances of having a context
+  // switch during a reading of the TSC and the performance counter.
+  const int previous_priority = ::GetThreadPriority(::GetCurrentThread());
+  ::SetThreadPriority(::GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
+
+  // The first time that this function is called, make an initial reading of the
+  // TSC and the performance counter. Initialization of static variable is
+  // thread-safe. Threads can race initializing tsc_initial vs
+  // perf_counter_initial, although they should be storing very similar values.
+
+  static const uint64_t tsc_initial = __rdtsc();
+  static const int64_t perf_counter_initial = QPCNowRaw();
+
+  // Make a another reading of the TSC and the performance counter every time
+  // that this function is called.
+  const uint64_t tsc_now = __rdtsc();
+  const int64_t perf_counter_now = QPCNowRaw();
+
+  // Reset the thread priority.
+  ::SetThreadPriority(::GetCurrentThread(), previous_priority);
+
+  // Make sure that at least 50 ms elapsed between the 2 readings. The first
+  // time that this function is called, we don't expect this to be the case.
+  // Note: The longer the elapsed time between the 2 readings is, the more
+  //   accurate the computed TSC frequency will be. The 50 ms value was
+  //   chosen because local benchmarks show that it allows us to get a
+  //   stddev of less than 1 tick/us between multiple runs.
+  // Note: According to the MSDN documentation for QueryPerformanceFrequency(),
+  //   this will never fail on systems that run XP or later.
+  //   https://msdn.microsoft.com/library/windows/desktop/ms644905.aspx
+  LARGE_INTEGER perf_counter_frequency = {};
+  ::QueryPerformanceFrequency(&perf_counter_frequency);
+  PERFETTO_CHECK(perf_counter_now >= perf_counter_initial);
+  const int64_t perf_counter_ticks = perf_counter_now - perf_counter_initial;
+  const double elapsed_time_seconds =
+      static_cast<double>(perf_counter_ticks) /
+      static_cast<double>(perf_counter_frequency.QuadPart);
+
+  constexpr double kMinimumEvaluationPeriodSeconds = 0.05;
+  if (elapsed_time_seconds < kMinimumEvaluationPeriodSeconds)
+    return 0;
+
+  // Compute the frequency of the TSC.
+  PERFETTO_CHECK(tsc_now >= tsc_initial);
+  const uint64_t tsc_ticks = tsc_now - tsc_initial;
+  // Racing with another thread to write |tsc_ticks_per_second| is benign
+  // because both threads will write a valid result.
+  tsc_ticks_per_second.store(
+      static_cast<double>(tsc_ticks) / elapsed_time_seconds,
+      std::memory_order_relaxed);
+
+  return tsc_ticks_per_second.load(std::memory_order_relaxed);
+}
+
+}  // namespace
+#endif  // !PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_ARM64)
+
+TimeNanos GetWallTimeNs() {
+  LARGE_INTEGER freq;
+  ::QueryPerformanceFrequency(&freq);
+  LARGE_INTEGER counter;
+  ::QueryPerformanceCounter(&counter);
+  double elapsed_nanoseconds = (1e9 * static_cast<double>(counter.QuadPart)) /
+                               static_cast<double>(freq.QuadPart);
+  return TimeNanos(static_cast<uint64_t>(elapsed_nanoseconds));
+}
+
+TimeNanos GetThreadCPUTimeNs() {
+#if PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_ARM64)
+  // QueryThreadCycleTime versus TSCTicksPerSecond doesn't have much relation to
+  // actual elapsed time on Windows on Arm, because QueryThreadCycleTime is
+  // backed by the actual number of CPU cycles executed, rather than a
+  // constant-rate timer like Intel. To work around this, use GetThreadTimes
+  // (which isn't as accurate but is meaningful as a measure of elapsed
+  // per-thread time).
+  FILETIME dummy, kernel_ftime, user_ftime;
+  ::GetThreadTimes(GetCurrentThread(), &dummy, &dummy, &kernel_ftime,
+                   &user_ftime);
+  uint64_t kernel_time =
+      kernel_ftime.dwHighDateTime * 0x100000000 + kernel_ftime.dwLowDateTime;
+  uint64_t user_time =
+      user_ftime.dwHighDateTime * 0x100000000 + user_ftime.dwLowDateTime;
+
+  return TimeNanos((kernel_time + user_time) * 100);
+#else   // !PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_ARM64)
+  // Get the number of TSC ticks used by the current thread.
+  ULONG64 thread_cycle_time = 0;
+  ::QueryThreadCycleTime(GetCurrentThread(), &thread_cycle_time);
+
+  // Get the frequency of the TSC.
+  const double tsc_ticks_per_second = TSCTicksPerSecond();
+  if (tsc_ticks_per_second == 0)
+    return TimeNanos();
+
+  // Return the CPU time of the current thread.
+  const double thread_time_seconds =
+      static_cast<double>(thread_cycle_time) / tsc_ticks_per_second;
+  constexpr int64_t kNanosecondsPerSecond = 1000 * 1000 * 1000;
+  return TimeNanos(
+      static_cast<int64_t>(thread_time_seconds * kNanosecondsPerSecond));
+#endif  // !PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_ARM64)
+}
+
+void SleepMicroseconds(unsigned interval_us) {
+  // The Windows Sleep function takes a millisecond count. Round up so that
+  // short sleeps don't turn into a busy wait. Note that the sleep granularity
+  // on Windows can dynamically vary from 1 ms to ~16 ms, so don't count on this
+  // being a short sleep.
+  ::Sleep(static_cast<DWORD>((interval_us + 999) / 1000));
+}
+
+void InitializeTime() {
+#if !PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_ARM64)
+  // Make an early first call to TSCTicksPerSecond() to start 50 ms elapsed time
+  // (see comment in TSCTicksPerSecond()).
+  TSCTicksPerSecond();
+#endif  // !PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_ARM64)
+}
+
+#else  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+void SleepMicroseconds(unsigned interval_us) {
+  ::usleep(static_cast<useconds_t>(interval_us));
+}
+
+void InitializeTime() {}
+
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+std::string GetTimeFmt(const std::string& fmt) {
+  time_t raw_time;
+  time(&raw_time);
+  struct tm* local_tm;
+  local_tm = localtime(&raw_time);
+  char buf[128];
+  PERFETTO_CHECK(strftime(buf, 80, fmt.c_str(), local_tm) > 0);
+  return buf;
+}
+
+std::optional<int32_t> GetTimezoneOffsetMins() {
+  std::string tz = GetTimeFmt("%z");
+  if (tz.size() != 5 || (tz[0] != '+' && tz[0] != '-'))
+    return std::nullopt;
+  char sign = '\0';
+  int32_t hh = 0;
+  int32_t mm = 0;
+  if (sscanf(tz.c_str(), "%c%2d%2d", &sign, &hh, &mm) != 3)
+    return std::nullopt;
+  return (hh * 60 + mm) * (sign == '-' ? -1 : 1);
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/utils.cc
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+#include <limits.h>
+#include <stdlib.h>  // For _exit()
+#include <unistd.h>  // For getpagesize() and geteuid() & fork()
+#endif
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+#include <mach-o/dyld.h>
+#include <mach/vm_page_size.h>
+#endif
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <Windows.h>
+#include <io.h>
+#include <malloc.h>  // For _aligned_malloc().
+#endif
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#include <dlfcn.h>
+#include <malloc.h>
+
+#ifdef M_PURGE
+#define PERFETTO_M_PURGE M_PURGE
+#else
+// Only available in in-tree builds and on newer SDKs.
+#define PERFETTO_M_PURGE -101
+#endif  // M_PURGE
+
+#ifdef M_PURGE_ALL
+#define PERFETTO_M_PURGE_ALL M_PURGE_ALL
+#else
+// Only available in in-tree builds and on newer SDKs.
+#define PERFETTO_M_PURGE_ALL -104
+#endif  // M_PURGE
+
+namespace {
+extern "C" {
+using MalloptType = int (*)(int, int);
+}
+}  // namespace
+#endif  // OS_ANDROID
+
+namespace {
+
+#if PERFETTO_BUILDFLAG(PERFETTO_X64_CPU_OPT)
+
+// Preserve the %rbx register via %rdi to work around a clang bug
+// https://bugs.llvm.org/show_bug.cgi?id=17907 (%rbx in an output constraint
+// is not considered a clobbered register).
+#define PERFETTO_GETCPUID(a, b, c, d, a_inp, c_inp) \
+  asm("mov %%rbx, %%rdi\n"                          \
+      "cpuid\n"                                     \
+      "xchg %%rdi, %%rbx\n"                         \
+      : "=a"(a), "=D"(b), "=c"(c), "=d"(d)          \
+      : "a"(a_inp), "2"(c_inp))
+
+uint32_t GetXCR0EAX() {
+  uint32_t eax = 0, edx = 0;
+  asm("xgetbv" : "=a"(eax), "=d"(edx) : "c"(0));
+  return eax;
+}
+
+// If we are building with -msse4 check that the CPU actually supports it.
+// This file must be kept in sync with gn/standalone/BUILD.gn.
+void PERFETTO_EXPORT_COMPONENT __attribute__((constructor))
+CheckCpuOptimizations() {
+  uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
+  PERFETTO_GETCPUID(eax, ebx, ecx, edx, 1, 0);
+
+  static constexpr uint64_t xcr0_xmm_mask = 0x2;
+  static constexpr uint64_t xcr0_ymm_mask = 0x4;
+  static constexpr uint64_t xcr0_avx_mask = xcr0_xmm_mask | xcr0_ymm_mask;
+
+  const bool have_popcnt = ecx & (1u << 23);
+  const bool have_sse4_2 = ecx & (1u << 20);
+  const bool have_avx =
+      // Does the OS save/restore XMM and YMM state?
+      (ecx & (1u << 27)) &&  // OS support XGETBV.
+      (ecx & (1u << 28)) &&  // AVX supported in hardware
+      ((GetXCR0EAX() & xcr0_avx_mask) == xcr0_avx_mask);
+
+  // Get level 7 features (eax = 7 and ecx= 0), to check for AVX2 support.
+  // (See Intel 64 and IA-32 Architectures Software Developer's Manual
+  //  Volume 2A: Instruction Set Reference, A-M CPUID).
+  PERFETTO_GETCPUID(eax, ebx, ecx, edx, 7, 0);
+  const bool have_avx2 = have_avx && ((ebx >> 5) & 0x1);
+  const bool have_bmi = (ebx >> 3) & 0x1;
+  const bool have_bmi2 = (ebx >> 8) & 0x1;
+
+  if (!have_sse4_2 || !have_popcnt || !have_avx2 || !have_bmi || !have_bmi2) {
+    fprintf(
+        stderr,
+        "This executable requires a x86_64 cpu that supports SSE4.2, BMI2 and "
+        "AVX2.\n"
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+        "On MacOS, this might be caused by running x86_64 binaries on arm64.\n"
+        "See https://github.com/google/perfetto/issues/294 for more.\n"
+#endif
+        "Rebuild with enable_perfetto_x64_cpu_opt=false.\n");
+    _exit(126);
+  }
+}
+#endif
+
+}  // namespace
+
+namespace perfetto {
+namespace base {
+
+namespace internal {
+
+std::atomic<uint32_t> g_cached_page_size{0};
+
+uint32_t GetSysPageSizeSlowpath() {
+  uint32_t page_size = 0;
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  const int page_size_int = getpagesize();
+  // If sysconf() fails for obscure reasons (e.g. SELinux denial) assume the
+  // page size is 4KB. This is to avoid regressing subtle SDK usages, as old
+  // versions of this code had a static constant baked in.
+  page_size = static_cast<uint32_t>(page_size_int > 0 ? page_size_int : 4096);
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+  page_size = static_cast<uint32_t>(vm_page_size);
+#else
+  page_size = 4096;
+#endif
+
+  PERFETTO_CHECK(page_size > 0 && page_size % 4096 == 0);
+
+  // Races here are fine because any thread will write the same value.
+  g_cached_page_size.store(page_size, std::memory_order_relaxed);
+  return page_size;
+}
+
+}  // namespace internal
+
+void MaybeReleaseAllocatorMemToOS() {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  // mallopt() on Android requires SDK level 26. Many targets and embedders
+  // still depend on a lower SDK level. Given mallopt() is a quite simple API,
+  // use reflection to do this rather than bumping the SDK level for all
+  // embedders. This keeps the behavior of standalone builds aligned with
+  // in-tree builds.
+  static MalloptType mallopt_fn =
+      reinterpret_cast<MalloptType>(dlsym(RTLD_DEFAULT, "mallopt"));
+  if (!mallopt_fn)
+    return;
+  if (mallopt_fn(PERFETTO_M_PURGE_ALL, 0) == 0) {
+    mallopt_fn(PERFETTO_M_PURGE, 0);
+  }
+#endif
+}
+
+uid_t GetCurrentUserId() {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+  return geteuid();
+#else
+  // TODO(primiano): On Windows we could hash the current user SID and derive a
+  // numeric user id [1]. It is not clear whether we need that. Right now that
+  // would not bring any benefit. Returning 0 unil we can prove we need it.
+  // [1]:https://android-review.googlesource.com/c/platform/external/perfetto/+/1513879/25/src/base/utils.cc
+  return 0;
+#endif
+}
+
+void SetEnv(const std::string& key, const std::string& value) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  PERFETTO_CHECK(::_putenv_s(key.c_str(), value.c_str()) == 0);
+#else
+  PERFETTO_CHECK(::setenv(key.c_str(), value.c_str(), /*overwrite=*/true) == 0);
+#endif
+}
+
+void UnsetEnv(const std::string& key) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  PERFETTO_CHECK(::_putenv_s(key.c_str(), "") == 0);
+#else
+  PERFETTO_CHECK(::unsetenv(key.c_str()) == 0);
+#endif
+}
+
+void Daemonize(std::function<int()> parent_cb) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+  Pipe pipe = Pipe::Create(Pipe::kBothBlock);
+  pid_t pid;
+  switch (pid = fork()) {
+    case -1:
+      PERFETTO_FATAL("fork");
+    case 0: {
+      PERFETTO_CHECK(setsid() != -1);
+      base::ignore_result(chdir("/"));
+      base::ScopedFile null = base::OpenFile("/dev/null", O_RDONLY);
+      PERFETTO_CHECK(null);
+      PERFETTO_CHECK(dup2(*null, STDIN_FILENO) != -1);
+      PERFETTO_CHECK(dup2(*null, STDOUT_FILENO) != -1);
+      PERFETTO_CHECK(dup2(*null, STDERR_FILENO) != -1);
+      // Do not accidentally close stdin/stdout/stderr.
+      if (*null <= 2)
+        null.release();
+      WriteAll(*pipe.wr, "1", 1);
+      break;
+    }
+    default: {
+      // Wait for the child process to have reached the setsid() call. This is
+      // to avoid that 'adb shell perfetto -D' destroys the terminal (hence
+      // sending a SIGHUP to the child) before the child has detached from the
+      // terminal (see b/238644870).
+
+      // This is to unblock the read() below (with EOF, which will fail the
+      // CHECK) in the unlikely case of the child crashing before WriteAll("1").
+      pipe.wr.reset();
+      char one = '\0';
+      PERFETTO_CHECK(Read(*pipe.rd, &one, sizeof(one)) == 1 && one == '1');
+      printf("%d\n", pid);
+      int err = parent_cb();
+      exit(err);
+    }
+  }
+#else
+  // Avoid -Wunreachable warnings.
+  if (reinterpret_cast<intptr_t>(&Daemonize) != 16)
+    PERFETTO_FATAL("--background is only supported on Linux/Android/Mac");
+  ignore_result(parent_cb);
+#endif  // OS_WIN
+}
+
+std::string GetCurExecutablePath() {
+  std::string self_path;
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+  char buf[PATH_MAX];
+  ssize_t size = readlink("/proc/self/exe", buf, sizeof(buf));
+  PERFETTO_CHECK(size != -1);
+  // readlink does not null terminate.
+  self_path = std::string(buf, static_cast<size_t>(size));
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+  uint32_t size = 0;
+  PERFETTO_CHECK(_NSGetExecutablePath(nullptr, &size));
+  self_path.resize(size);
+  PERFETTO_CHECK(_NSGetExecutablePath(&self_path[0], &size) == 0);
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  char buf[MAX_PATH];
+  auto len = ::GetModuleFileNameA(nullptr /*current*/, buf, sizeof(buf));
+  self_path = std::string(buf, len);
+#else
+  PERFETTO_FATAL(
+      "GetCurExecutableDir() not implemented on the current platform");
+#endif
+  return self_path;
+}
+
+std::string GetCurExecutableDir() {
+  auto path = GetCurExecutablePath();
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  // Paths in Windows can have both kinds of slashes (mingw vs msvc).
+  path = path.substr(0, path.find_last_of('\\'));
+#endif
+  path = path.substr(0, path.find_last_of('/'));
+  return path;
+}
+
+void* AlignedAlloc(size_t alignment, size_t size) {
+  void* res = nullptr;
+  alignment = AlignUp<sizeof(void*)>(alignment);  // At least pointer size.
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  // Window's _aligned_malloc() has a nearly identically signature to Unix's
+  // aligned_alloc() but its arguments are obviously swapped.
+  res = _aligned_malloc(size, alignment);
+#else
+  // aligned_alloc() has been introduced in Android only in API 28.
+  // Also NaCl and Fuchsia seems to have only posix_memalign().
+  ignore_result(posix_memalign(&res, alignment, size));
+#endif
+  PERFETTO_CHECK(res);
+  return res;
+}
+
+void AlignedFree(void* ptr) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  _aligned_free(ptr);  // MSDN says it is fine to pass nullptr.
+#else
+  free(ptr);
+#endif
+}
+
+std::string HexDump(const void* data_void, size_t len, size_t bytes_per_line) {
+  const char* data = reinterpret_cast<const char*>(data_void);
+  std::string res;
+  static const size_t kPadding = bytes_per_line * 3 + 12;
+  std::unique_ptr<char[]> line(new char[bytes_per_line * 4 + 128]);
+  for (size_t i = 0; i < len; i += bytes_per_line) {
+    char* wptr = line.get();
+    wptr += base::SprintfTrunc(wptr, 19, "%08zX: ", i);
+    for (size_t j = i; j < i + bytes_per_line && j < len; j++) {
+      wptr += base::SprintfTrunc(wptr, 4, "%02X ",
+                                 static_cast<unsigned>(data[j]) & 0xFF);
+    }
+    for (size_t j = static_cast<size_t>(wptr - line.get()); j < kPadding; ++j)
+      *(wptr++) = ' ';
+    for (size_t j = i; j < i + bytes_per_line && j < len; j++) {
+      char c = data[j];
+      *(wptr++) = (c >= 32 && c < 127) ? c : '.';
+    }
+    *(wptr++) = '\n';
+    *(wptr++) = '\0';
+    res.append(line.get());
+  }
+  return res;
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/uuid.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/uuid.h
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_UUID_H_
+#define INCLUDE_PERFETTO_EXT_BASE_UUID_H_
+
+#include <string.h>
+#include <array>
+#include <cstdint>
+#include <optional>
+#include <string>
+
+namespace perfetto {
+namespace base {
+
+class Uuid {
+ public:
+  explicit Uuid(const std::string& s);
+  explicit Uuid(int64_t lsb, int64_t msb);
+  Uuid();
+
+  std::array<uint8_t, 16>* data() { return &data_; }
+  const std::array<uint8_t, 16>* data() const { return &data_; }
+
+  bool operator==(const Uuid& other) const { return data_ == other.data_; }
+
+  bool operator!=(const Uuid& other) const { return !(*this == other); }
+
+  explicit operator bool() const { return *this != Uuid(); }
+
+  int64_t msb() const {
+    int64_t result;
+    memcpy(&result, data_.data() + 8, 8);
+    return result;
+  }
+
+  int64_t lsb() const {
+    int64_t result;
+    memcpy(&result, data_.data(), 8);
+    return result;
+  }
+
+  void set_lsb_msb(int64_t lsb, int64_t msb) {
+    set_lsb(lsb);
+    set_msb(msb);
+  }
+  void set_msb(int64_t msb) { memcpy(data_.data() + 8, &msb, 8); }
+  void set_lsb(int64_t lsb) { memcpy(data_.data(), &lsb, 8); }
+
+  std::string ToString() const;
+  std::string ToPrettyString() const;
+
+ private:
+  std::array<uint8_t, 16> data_{};
+};
+
+Uuid Uuidv4();
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_UUID_H_
+// gen_amalgamated begin header: include/perfetto/ext/base/no_destructor.h
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_NO_DESTRUCTOR_H_
+#define INCLUDE_PERFETTO_EXT_BASE_NO_DESTRUCTOR_H_
+
+#include <new>
+#include <utility>
+
+namespace perfetto {
+namespace base {
+
+// Wrapper that can hold an object of type T, without invoking the contained
+// object's destructor when being destroyed. Useful for creating statics while
+// avoiding static destructors.
+//
+// Stores the object inline, and therefore doesn't incur memory allocation and
+// pointer indirection overheads.
+//
+// Example of use:
+//
+//   const std::string& GetStr() {
+//     static base::NoDestructor<std::string> s("hello");
+//     return s.ref();
+//   }
+//
+template <typename T>
+class NoDestructor {
+ public:
+  // Forward arguments to T's constructor. Note that this doesn't cover
+  // construction from initializer lists.
+  template <typename... Args>
+  explicit NoDestructor(Args&&... args) {
+    new (storage_) T(std::forward<Args>(args)...);
+  }
+
+  NoDestructor(const NoDestructor&) = delete;
+  NoDestructor& operator=(const NoDestructor&) = delete;
+  NoDestructor(NoDestructor&&) = delete;
+  NoDestructor& operator=(NoDestructor&&) = delete;
+
+  ~NoDestructor() = default;
+
+  /* To avoid type-punned pointer strict aliasing warnings on GCC6 and below
+   * these need to be split over two lines. If they are collapsed onto one line.
+   *   return reinterpret_cast<const T*>(storage_);
+   * The error fires.
+   */
+  const T& ref() const {
+    auto* const cast = reinterpret_cast<const T*>(storage_);
+    return *cast;
+  }
+  T& ref() {
+    auto* const cast = reinterpret_cast<T*>(storage_);
+    return *cast;
+  }
+
+ private:
+  alignas(T) char storage_[sizeof(T)];
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_NO_DESTRUCTOR_H_
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/uuid.h"
+
+#include <mutex>
+#include <random>
+
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/no_destructor.h"
+
+namespace perfetto {
+namespace base {
+namespace {
+
+constexpr char kHexmap[] = {'0', '1', '2', '3', '4', '5', '6', '7',
+                            '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+}  // namespace
+
+// A globally unique 128-bit number.
+// In the early days of perfetto we were (sorta) respecting rfc4122. Later we
+// started replacing the LSB of the UUID with the statsd subscription ID in
+// other parts of the codebase (see perfetto_cmd.cc) for the convenience of
+// trace lookups, so rfc4122 made no sense as it just reduced entropy.
+Uuid Uuidv4() {
+  // Mix different sources of entropy to reduce the chances of collisions.
+  // Only using boot time is not enough. Under the assumption that most traces
+  // are started around the same time at boot, within a 1s window, the birthday
+  // paradox gives a chance of 90% collisions with 70k traces over a 1e9 space
+  // (Number of ns in a 1s window).
+  // &kHexmap >> 14 is used to feed use indirectly ASLR as a source of entropy.
+  // We deliberately don't use /dev/urandom as that might block for
+  // unpredictable time if the system is idle.
+  // The UUID does NOT need to be cryptographically secure, but random enough
+  // to avoid collisions across a large number of devices.
+  static std::minstd_rand rng(
+      static_cast<uint32_t>(static_cast<uint64_t>(GetBootTimeNs().count()) ^
+                            static_cast<uint64_t>(GetWallTimeNs().count()) ^
+                            (reinterpret_cast<uintptr_t>(&kHexmap) >> 14)));
+  Uuid uuid;
+  auto& data = *uuid.data();
+
+  // std::random is not thread safe and users of this class might mistakenly
+  // assume Uuidv4() is thread_safe because from the outside looks like a
+  // local object.
+  static base::NoDestructor<std::mutex> rand_mutex;
+  std::unique_lock<std::mutex> rand_lock(rand_mutex.ref());
+
+  for (size_t i = 0; i < sizeof(data);) {
+    // Note: the 32-th bit of rng() is always 0 as minstd_rand operates modulo
+    // 2**31. Fill in blocks of 16b rather than 32b to not lose 1b of entropy.
+    const auto rnd_data = static_cast<uint16_t>(rng());
+    memcpy(&data[i], &rnd_data, sizeof(rnd_data));
+    i += sizeof(rnd_data);
+  }
+
+  return uuid;
+}
+
+Uuid::Uuid() {}
+
+Uuid::Uuid(const std::string& s) {
+  PERFETTO_CHECK(s.size() == data_.size());
+  memcpy(data_.data(), s.data(), s.size());
+}
+
+Uuid::Uuid(int64_t lsb, int64_t msb) {
+  set_lsb_msb(lsb, msb);
+}
+
+std::string Uuid::ToString() const {
+  return std::string(reinterpret_cast<const char*>(data_.data()), data_.size());
+}
+
+std::string Uuid::ToPrettyString() const {
+  std::string s(data_.size() * 2 + 4, '-');
+  // Format is 123e4567-e89b-12d3-a456-426655443322.
+  size_t j = 0;
+  for (size_t i = 0; i < data_.size(); ++i) {
+    if (i == 4 || i == 6 || i == 8 || i == 10)
+      j++;
+    s[2 * i + j] = kHexmap[(data_[data_.size() - i - 1] & 0xf0) >> 4];
+    s[2 * i + 1 + j] = kHexmap[(data_[data_.size() - i - 1] & 0x0f)];
+  }
+  return s;
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/virtual_destructors.cc
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+
+// This translation unit contains the definitions for the destructor of pure
+// virtual interfaces for the current build target. The alternative would be
+// introducing a one-liner .cc file for each pure virtual interface, which is
+// overkill. This is for compliance with -Wweak-vtables.
+
+namespace perfetto {
+namespace base {
+
+TaskRunner::~TaskRunner() = default;
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/waitable_event.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/waitable_event.h
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_WAITABLE_EVENT_H_
+#define INCLUDE_PERFETTO_EXT_BASE_WAITABLE_EVENT_H_
+
+#include <condition_variable>
+#include <mutex>
+
+namespace perfetto {
+namespace base {
+
+// A waitable event for cross-thread synchronization.
+// All methods on this class can be called from any thread.
+class WaitableEvent {
+ public:
+  WaitableEvent();
+  ~WaitableEvent();
+  WaitableEvent(const WaitableEvent&) = delete;
+  WaitableEvent operator=(const WaitableEvent&) = delete;
+
+  // Synchronously block until the event is notified `notification` times.
+  void Wait(uint64_t notifications = 1);
+
+  // Signal the event, waking up blocked waiters.
+  void Notify();
+
+ private:
+  std::mutex mutex_;
+  std::condition_variable event_;
+  uint64_t notifications_ = 0;
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_WAITABLE_EVENT_H_
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/waitable_event.h"
+
+namespace perfetto {
+namespace base {
+
+WaitableEvent::WaitableEvent() = default;
+WaitableEvent::~WaitableEvent() = default;
+
+void WaitableEvent::Wait(uint64_t notifications) {
+  std::unique_lock<std::mutex> lock(mutex_);
+  return event_.wait(lock, [&] { return notifications_ >= notifications; });
+}
+
+void WaitableEvent::Notify() {
+  std::unique_lock<std::mutex> lock(mutex_);
+  notifications_++;
+  event_.notify_all();
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/watchdog_posix.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/watchdog.h
+// gen_amalgamated begin header: include/perfetto/ext/base/watchdog_noop.h
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_NOOP_H_
+#define INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_NOOP_H_
+
+#include <stdint.h>
+
+namespace perfetto {
+namespace base {
+
+enum class WatchdogCrashReason;  // Defined in watchdog.h.
+
+class Watchdog {
+ public:
+  class Timer {
+   public:
+    // Define an empty dtor to avoid "unused variable" errors on the call site.
+    Timer() {}
+    Timer(const Timer&) {}
+    ~Timer() {}
+  };
+  static Watchdog* GetInstance() {
+    static Watchdog* watchdog = new Watchdog();
+    return watchdog;
+  }
+  Timer CreateFatalTimer(uint32_t /*ms*/, WatchdogCrashReason) {
+    return Timer();
+  }
+  void Start() {}
+  void SetMemoryLimit(uint64_t /*bytes*/, uint32_t /*window_ms*/) {}
+  void SetCpuLimit(uint32_t /*percentage*/, uint32_t /*window_ms*/) {}
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_NOOP_H_
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_H_
+#define INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_H_
+
+#include <functional>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+// The POSIX watchdog is only supported on Linux and Android in non-embedder
+// builds.
+#if PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
+// gen_amalgamated expanded: #include "perfetto/ext/base/watchdog_posix.h"
+#else
+// gen_amalgamated expanded: #include "perfetto/ext/base/watchdog_noop.h"
+#endif
+
+namespace perfetto {
+namespace base {
+
+// Used only to add more details to crash reporting.
+enum class WatchdogCrashReason {
+  kUnspecified = 0,
+  kCpuGuardrail = 1,
+  kMemGuardrail = 2,
+  kTaskRunnerHung = 3,
+  kTraceDidntStop = 4,
+};
+
+// Make the limits more relaxed on desktop, where multi-GB traces are likely.
+// Multi-GB traces can take bursts of cpu time to write into disk at the end of
+// the trace.
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+constexpr uint32_t kWatchdogDefaultCpuLimit = 75;
+constexpr uint32_t kWatchdogDefaultCpuWindow = 5 * 60 * 1000;  // 5 minutes.
+#else
+constexpr uint32_t kWatchdogDefaultCpuLimit = 90;
+constexpr uint32_t kWatchdogDefaultCpuWindow = 10 * 60 * 1000;  // 10 minutes.
+#endif
+
+// The default memory margin we give to our processes. This is used as as a
+// constant to put on top of the trace buffers.
+constexpr uint64_t kWatchdogDefaultMemorySlack = 32 * 1024 * 1024;  // 32 MiB.
+constexpr uint32_t kWatchdogDefaultMemoryWindow = 30 * 1000;  // 30 seconds.
+
+inline void RunTaskWithWatchdogGuard(const std::function<void()>& task) {
+  // Maximum time a single task can take in a TaskRunner before the
+  // program suicides.
+  constexpr int64_t kWatchdogMillis = 30000;  // 30s
+
+  Watchdog::Timer handle = base::Watchdog::GetInstance()->CreateFatalTimer(
+      kWatchdogMillis, WatchdogCrashReason::kTaskRunnerHung);
+  task();
+
+  // Suppress unused variable warnings in the client library amalgamated build.
+  (void)kWatchdogDefaultCpuLimit;
+  (void)kWatchdogDefaultCpuWindow;
+  (void)kWatchdogDefaultMemorySlack;
+  (void)kWatchdogDefaultMemoryWindow;
+}
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_H_
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/platform.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/watchdog.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
+
+#include <fcntl.h>
+#include <poll.h>
+#include <signal.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <sys/syscall.h>
+#include <sys/timerfd.h>
+#include <unistd.h>
+
+#include <algorithm>
+#include <cinttypes>
+#include <fstream>
+#include <thread>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/thread_utils.h"
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/crash_keys.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+
+namespace perfetto {
+namespace base {
+
+namespace {
+
+constexpr uint32_t kDefaultPollingInterval = 30 * 1000;
+
+base::CrashKey g_crash_key_reason("wdog_reason");
+
+bool IsMultipleOf(uint32_t number, uint32_t divisor) {
+  return number >= divisor && number % divisor == 0;
+}
+
+double MeanForArray(const uint64_t array[], size_t size) {
+  uint64_t total = 0;
+  for (size_t i = 0; i < size; i++) {
+    total += array[i];
+  }
+  return static_cast<double>(total / size);
+}
+
+}  //  namespace
+
+bool ReadProcStat(int fd, ProcStat* out) {
+  char c[512];
+  size_t c_pos = 0;
+  while (c_pos < sizeof(c) - 1) {
+    ssize_t rd = PERFETTO_EINTR(read(fd, c + c_pos, sizeof(c) - c_pos));
+    if (rd < 0) {
+      PERFETTO_ELOG("Failed to read stat file to enforce resource limits.");
+      return false;
+    }
+    if (rd == 0)
+      break;
+    c_pos += static_cast<size_t>(rd);
+  }
+  PERFETTO_CHECK(c_pos < sizeof(c));
+  c[c_pos] = '\0';
+
+  if (sscanf(c,
+             "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %lu "
+             "%lu %*d %*d %*d %*d %*d %*d %*u %*u %ld",
+             &out->utime, &out->stime, &out->rss_pages) != 3) {
+    PERFETTO_ELOG("Invalid stat format: %s", c);
+    return false;
+  }
+  return true;
+}
+
+Watchdog::Watchdog(uint32_t polling_interval_ms)
+    : polling_interval_ms_(polling_interval_ms) {}
+
+Watchdog::~Watchdog() {
+  if (!thread_.joinable()) {
+    PERFETTO_DCHECK(!enabled_);
+    return;
+  }
+  PERFETTO_DCHECK(enabled_);
+  enabled_ = false;
+
+  // Rearm the timer to 1ns from now. This will cause the watchdog thread to
+  // wakeup from the poll() and see |enabled_| == false.
+  // This code path is used only in tests. In production code the watchdog is
+  // a singleton and is never destroyed.
+  struct itimerspec ts {};
+  ts.it_value.tv_sec = 0;
+  ts.it_value.tv_nsec = 1;
+  timerfd_settime(*timer_fd_, /*flags=*/0, &ts, nullptr);
+
+  thread_.join();
+}
+
+Watchdog* Watchdog::GetInstance() {
+  static Watchdog* watchdog = new Watchdog(kDefaultPollingInterval);
+  return watchdog;
+}
+
+// Can be called from any thread.
+Watchdog::Timer Watchdog::CreateFatalTimer(uint32_t ms,
+                                           WatchdogCrashReason crash_reason) {
+  if (!enabled_.load(std::memory_order_relaxed))
+    return Watchdog::Timer(this, 0, crash_reason);
+
+  return Watchdog::Timer(this, ms, crash_reason);
+}
+
+// Can be called from any thread.
+void Watchdog::AddFatalTimer(TimerData timer) {
+  std::lock_guard<std::mutex> guard(mutex_);
+  timers_.emplace_back(std::move(timer));
+  RearmTimerFd_Locked();
+}
+
+// Can be called from any thread.
+void Watchdog::RemoveFatalTimer(TimerData timer) {
+  std::lock_guard<std::mutex> guard(mutex_);
+  for (auto it = timers_.begin(); it != timers_.end(); it++) {
+    if (*it == timer) {
+      timers_.erase(it);
+      break;  // Remove only one. Doesn't matter which one.
+    }
+  }
+  RearmTimerFd_Locked();
+}
+
+void Watchdog::RearmTimerFd_Locked() {
+  if (!enabled_)
+    return;
+  auto it = std::min_element(timers_.begin(), timers_.end());
+
+  // We use one timerfd to handle all the oustanding |timers_|. Keep it armed
+  // to the task expiring soonest.
+  struct itimerspec ts {};
+  if (it != timers_.end()) {
+    ts.it_value = ToPosixTimespec(it->deadline);
+  }
+  // If |timers_| is empty (it == end()) |ts.it_value| will remain
+  // zero-initialized and that will disarm the timer in the call below.
+  int res = timerfd_settime(*timer_fd_, TFD_TIMER_ABSTIME, &ts, nullptr);
+  PERFETTO_DCHECK(res == 0);
+}
+
+void Watchdog::Start() {
+  std::lock_guard<std::mutex> guard(mutex_);
+  if (thread_.joinable()) {
+    PERFETTO_DCHECK(enabled_);
+  } else {
+    PERFETTO_DCHECK(!enabled_);
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+    // Kick the thread to start running but only on Android or Linux.
+    timer_fd_.reset(
+        timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK));
+    if (!timer_fd_) {
+      PERFETTO_PLOG(
+          "timerfd_create failed, the Perfetto watchdog is not available");
+      return;
+    }
+    enabled_ = true;
+    RearmTimerFd_Locked();  // Deal with timers created before Start().
+    thread_ = std::thread(&Watchdog::ThreadMain, this);
+#endif
+  }
+}
+
+void Watchdog::SetMemoryLimit(uint64_t bytes, uint32_t window_ms) {
+  // Update the fields under the lock.
+  std::lock_guard<std::mutex> guard(mutex_);
+
+  PERFETTO_CHECK(IsMultipleOf(window_ms, polling_interval_ms_) || bytes == 0);
+
+  size_t size = bytes == 0 ? 0 : window_ms / polling_interval_ms_ + 1;
+  memory_window_bytes_.Reset(size);
+  memory_limit_bytes_ = bytes;
+}
+
+void Watchdog::SetCpuLimit(uint32_t percentage, uint32_t window_ms) {
+  std::lock_guard<std::mutex> guard(mutex_);
+
+  PERFETTO_CHECK(percentage <= 100);
+  PERFETTO_CHECK(IsMultipleOf(window_ms, polling_interval_ms_) ||
+                 percentage == 0);
+
+  size_t size = percentage == 0 ? 0 : window_ms / polling_interval_ms_ + 1;
+  cpu_window_time_ticks_.Reset(size);
+  cpu_limit_percentage_ = percentage;
+}
+
+void Watchdog::ThreadMain() {
+  // Register crash keys explicitly to avoid running out of slots at crash time.
+  g_crash_key_reason.Register();
+
+  base::ScopedFile stat_fd(base::OpenFile("/proc/self/stat", O_RDONLY));
+  if (!stat_fd) {
+    PERFETTO_ELOG("Failed to open stat file to enforce resource limits.");
+    return;
+  }
+
+  PERFETTO_DCHECK(timer_fd_);
+
+  constexpr uint8_t kFdCount = 1;
+  struct pollfd fds[kFdCount]{};
+  fds[0].fd = *timer_fd_;
+  fds[0].events = POLLIN;
+
+  for (;;) {
+    // We use the poll() timeout to drive the periodic ticks for the cpu/memory
+    // checks. The only other case when the poll() unblocks is when we crash
+    // (or have to quit via enabled_ == false, but that happens only in tests).
+    platform::BeforeMaybeBlockingSyscall();
+    auto ret = poll(fds, kFdCount, static_cast<int>(polling_interval_ms_));
+    platform::AfterMaybeBlockingSyscall();
+    if (!enabled_)
+      return;
+    if (ret < 0) {
+      if (errno == ENOMEM || errno == EINTR) {
+        // Should happen extremely rarely.
+        std::this_thread::sleep_for(std::chrono::milliseconds(100));
+        continue;
+      }
+      PERFETTO_FATAL("watchdog poll() failed");
+    }
+
+    // If we get here either:
+    // 1. poll() timed out, in which case we should process cpu/mem guardrails.
+    // 2. A timer expired, in which case we shall crash.
+
+    uint64_t expired = 0;  // Must be exactly 8 bytes.
+    auto res = PERFETTO_EINTR(read(*timer_fd_, &expired, sizeof(expired)));
+    PERFETTO_DCHECK((res < 0 && (errno == EAGAIN)) ||
+                    (res == sizeof(expired) && expired > 0));
+    const auto now = GetWallTimeMs();
+
+    // Check if any of the timers expired.
+    int tid_to_kill = 0;
+    WatchdogCrashReason crash_reason{};
+    std::unique_lock<std::mutex> guard(mutex_);
+    for (const auto& timer : timers_) {
+      if (now >= timer.deadline) {
+        tid_to_kill = timer.thread_id;
+        crash_reason = timer.crash_reason;
+        break;
+      }
+    }
+    guard.unlock();
+
+    if (tid_to_kill)
+      SerializeLogsAndKillThread(tid_to_kill, crash_reason);
+
+    // Check CPU and memory guardrails (if enabled).
+    lseek(stat_fd.get(), 0, SEEK_SET);
+    ProcStat stat;
+    if (!ReadProcStat(stat_fd.get(), &stat))
+      continue;
+    uint64_t cpu_time = stat.utime + stat.stime;
+    uint64_t rss_bytes =
+        static_cast<uint64_t>(stat.rss_pages) * base::GetSysPageSize();
+
+    bool threshold_exceeded = false;
+    guard.lock();
+    if (CheckMemory_Locked(rss_bytes)) {
+      threshold_exceeded = true;
+      crash_reason = WatchdogCrashReason::kMemGuardrail;
+    } else if (CheckCpu_Locked(cpu_time)) {
+      threshold_exceeded = true;
+      crash_reason = WatchdogCrashReason::kCpuGuardrail;
+    }
+    guard.unlock();
+
+    if (threshold_exceeded)
+      SerializeLogsAndKillThread(getpid(), crash_reason);
+  }
+}
+
+void Watchdog::SerializeLogsAndKillThread(int tid,
+                                          WatchdogCrashReason crash_reason) {
+  g_crash_key_reason.Set(static_cast<int>(crash_reason));
+
+  // We are about to die. Serialize the logs into the crash buffer so the
+  // debuggerd crash handler picks them up and attaches to the bugreport.
+  // In the case of a PERFETTO_CHECK/PERFETTO_FATAL this is done in logging.h.
+  // But in the watchdog case, we don't hit that codepath and must do ourselves.
+  MaybeSerializeLastLogsForCrashReporting();
+
+  // Send a SIGABRT to the thread that armed the timer. This is to see the
+  // callstack of the thread that is stuck in a long task rather than the
+  // watchdog thread.
+  if (syscall(__NR_tgkill, getpid(), tid, SIGABRT) < 0) {
+    // At this point the process must die. If for any reason the tgkill doesn't
+    // work (e.g. the thread has disappeared), force a crash from here.
+    abort();
+  }
+
+  if (disable_kill_failsafe_for_testing_)
+    return;
+
+  // The tgkill() above will take some milliseconds to cause a crash, as it
+  // involves the kernel to queue the SIGABRT on the target thread (often the
+  // main thread, which is != watchdog thread) and do a scheduling round.
+  // If something goes wrong though (the target thread has signals masked or
+  // is stuck in an uninterruptible+wakekill syscall) force quit from this
+  // thread.
+  std::this_thread::sleep_for(std::chrono::seconds(10));
+  abort();
+}
+
+bool Watchdog::CheckMemory_Locked(uint64_t rss_bytes) {
+  if (memory_limit_bytes_ == 0)
+    return false;
+
+  // Add the current stat value to the ring buffer and check that the mean
+  // remains under our threshold.
+  if (memory_window_bytes_.Push(rss_bytes)) {
+    if (memory_window_bytes_.Mean() >
+        static_cast<double>(memory_limit_bytes_)) {
+      PERFETTO_ELOG(
+          "Memory watchdog trigger. Memory window of %f bytes is above the "
+          "%" PRIu64 " bytes limit.",
+          memory_window_bytes_.Mean(), memory_limit_bytes_);
+      return true;
+    }
+  }
+  return false;
+}
+
+bool Watchdog::CheckCpu_Locked(uint64_t cpu_time) {
+  if (cpu_limit_percentage_ == 0)
+    return false;
+
+  // Add the cpu time to the ring buffer.
+  if (cpu_window_time_ticks_.Push(cpu_time)) {
+    // Compute the percentage over the whole window and check that it remains
+    // under the threshold.
+    uint64_t difference_ticks = cpu_window_time_ticks_.NewestWhenFull() -
+                                cpu_window_time_ticks_.OldestWhenFull();
+    double window_interval_ticks =
+        (static_cast<double>(WindowTimeForRingBuffer(cpu_window_time_ticks_)) /
+         1000.0) *
+        static_cast<double>(sysconf(_SC_CLK_TCK));
+    double percentage = static_cast<double>(difference_ticks) /
+                        static_cast<double>(window_interval_ticks) * 100;
+    if (percentage > cpu_limit_percentage_) {
+      PERFETTO_ELOG("CPU watchdog trigger. %f%% CPU use is above the %" PRIu32
+                    "%% CPU limit.",
+                    percentage, cpu_limit_percentage_);
+      return true;
+    }
+  }
+  return false;
+}
+
+uint32_t Watchdog::WindowTimeForRingBuffer(const WindowedInterval& window) {
+  return static_cast<uint32_t>(window.size() - 1) * polling_interval_ms_;
+}
+
+bool Watchdog::WindowedInterval::Push(uint64_t sample) {
+  // Add the sample to the current position in the ring buffer.
+  buffer_[position_] = sample;
+
+  // Update the position with next one circularily.
+  position_ = (position_ + 1) % size_;
+
+  // Set the filled flag the first time we wrap.
+  filled_ = filled_ || position_ == 0;
+  return filled_;
+}
+
+double Watchdog::WindowedInterval::Mean() const {
+  return MeanForArray(buffer_.get(), size_);
+}
+
+void Watchdog::WindowedInterval::Clear() {
+  position_ = 0;
+  buffer_.reset(new uint64_t[size_]());
+}
+
+void Watchdog::WindowedInterval::Reset(size_t new_size) {
+  position_ = 0;
+  size_ = new_size;
+  buffer_.reset(new_size == 0 ? nullptr : new uint64_t[new_size]());
+}
+
+Watchdog::Timer::Timer(Watchdog* watchdog,
+                       uint32_t ms,
+                       WatchdogCrashReason crash_reason)
+    : watchdog_(watchdog) {
+  if (!ms)
+    return;  // No-op timer created when the watchdog is disabled.
+  timer_data_.deadline = GetWallTimeMs() + std::chrono::milliseconds(ms);
+  timer_data_.thread_id = GetThreadId();
+  timer_data_.crash_reason = crash_reason;
+  PERFETTO_DCHECK(watchdog_);
+  watchdog_->AddFatalTimer(timer_data_);
+}
+
+Watchdog::Timer::~Timer() {
+  if (timer_data_.deadline.count())
+    watchdog_->RemoveFatalTimer(timer_data_);
+}
+
+Watchdog::Timer::Timer(Timer&& other) noexcept {
+  watchdog_ = std::move(other.watchdog_);
+  other.watchdog_ = nullptr;
+  timer_data_ = std::move(other.timer_data_);
+  other.timer_data_ = TimerData();
+}
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
+// gen_amalgamated begin source: src/base/thread_task_runner.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/thread_task_runner.h
+// gen_amalgamated begin header: include/perfetto/ext/base/unix_task_runner.h
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_UNIX_TASK_RUNNER_H_
+#define INCLUDE_PERFETTO_EXT_BASE_UNIX_TASK_RUNNER_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/base/thread_utils.h"
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/event_fd.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
+
+#include <chrono>
+#include <deque>
+#include <map>
+#include <mutex>
+#include <vector>
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <poll.h>
+#endif
+
+namespace perfetto {
+namespace base {
+
+// Runs a task runner on the current thread.
+//
+// Implementation note: we currently assume (and enforce in debug builds) that
+// Run() is called from the thread that constructed the UnixTaskRunner. This is
+// not strictly necessary, and we could instead track the thread that invokes
+// Run(). However, a related property that *might* be important to enforce is
+// that the destructor runs on the task-running thread. Otherwise, if there are
+// still-pending tasks at the time of destruction, we would destroy those
+// outside of the task thread (which might be unexpected to the caller). On the
+// other hand, the std::function task interface discourages use of any
+// resource-owning tasks (as the callable needs to be copyable), so this might
+// not be important in practice.
+//
+// TODO(rsavitski): consider adding a thread-check in the destructor, after
+// auditing existing usages.
+// TODO(primiano): rename this to TaskRunnerImpl. The "Unix" part is misleading
+// now as it supports also Windows.
+class UnixTaskRunner : public TaskRunner {
+ public:
+  UnixTaskRunner();
+  ~UnixTaskRunner() override;
+
+  // Start executing tasks. Doesn't return until Quit() is called. Run() may be
+  // called multiple times on the same task runner.
+  void Run();
+  void Quit();
+
+  // Checks whether there are any pending immediate tasks to run. Note that
+  // delayed tasks don't count even if they are due to run.
+  bool IsIdleForTesting();
+
+  // TaskRunner implementation:
+  void PostTask(std::function<void()>) override;
+  void PostDelayedTask(std::function<void()>, uint32_t delay_ms) override;
+  void AddFileDescriptorWatch(PlatformHandle, std::function<void()>) override;
+  void RemoveFileDescriptorWatch(PlatformHandle) override;
+  bool RunsTasksOnCurrentThread() const override;
+
+  // Returns true if the task runner is quitting, or has quit and hasn't been
+  // restarted since. Exposed primarily for ThreadTaskRunner, not necessary for
+  // normal use of this class.
+  bool QuitCalled();
+
+ private:
+  void WakeUp();
+  void UpdateWatchTasksLocked();
+  int GetDelayMsToNextTaskLocked() const;
+  void RunImmediateAndDelayedTask();
+  void PostFileDescriptorWatches(uint64_t windows_wait_result);
+  void RunFileDescriptorWatch(PlatformHandle);
+
+  ThreadChecker thread_checker_;
+  PlatformThreadId created_thread_id_ = GetThreadId();
+
+  EventFd event_;
+
+// The array of fds/handles passed to poll(2) / WaitForMultipleObjects().
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  std::vector<PlatformHandle> poll_fds_;
+#else
+  std::vector<struct pollfd> poll_fds_;
+#endif
+
+  // --- Begin lock-protected members ---
+
+  std::mutex lock_;
+
+  std::deque<std::function<void()>> immediate_tasks_;
+  std::multimap<TimeMillis, std::function<void()>> delayed_tasks_;
+  bool quit_ = false;
+
+  struct WatchTask {
+    std::function<void()> callback;
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    // On UNIX systems we make the FD number negative in |poll_fds_| to avoid
+    // polling it again until the queued task runs. On Windows we can't do that.
+    // Instead we keep track of its state here.
+    bool pending = false;
+#else
+    size_t poll_fd_index;  // Index into |poll_fds_|.
+#endif
+  };
+
+  std::map<PlatformHandle, WatchTask> watch_tasks_;
+  bool watch_tasks_changed_ = false;
+
+  // --- End lock-protected members ---
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_UNIX_TASK_RUNNER_H_
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_TASK_RUNNER_H_
+#define INCLUDE_PERFETTO_EXT_BASE_THREAD_TASK_RUNNER_H_
+
+#include <functional>
+#include <thread>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/unix_task_runner.h"
+
+namespace perfetto {
+namespace base {
+
+// A UnixTaskRunner backed by a dedicated task thread. Shuts down the runner and
+// joins the thread upon destruction. Can be moved to transfer ownership.
+//
+// Guarantees that:
+// * the UnixTaskRunner will be constructed and destructed on the task thread.
+// * the task thread will live for the lifetime of the UnixTaskRunner.
+//
+class PERFETTO_EXPORT_COMPONENT ThreadTaskRunner : public TaskRunner {
+ public:
+  static ThreadTaskRunner CreateAndStart(const std::string& name = "") {
+    return ThreadTaskRunner(name);
+  }
+
+  ThreadTaskRunner(const ThreadTaskRunner&) = delete;
+  ThreadTaskRunner& operator=(const ThreadTaskRunner&) = delete;
+
+  ThreadTaskRunner(ThreadTaskRunner&&) noexcept;
+  ThreadTaskRunner& operator=(ThreadTaskRunner&&);
+  ~ThreadTaskRunner() override;
+
+  // Executes the given function on the task runner thread and blocks the caller
+  // thread until the function has run.
+  void PostTaskAndWaitForTesting(std::function<void()>);
+
+  // Can be called from another thread to get the CPU time of the thread the
+  // task-runner is executing on.
+  uint64_t GetThreadCPUTimeNsForTesting();
+
+  // Returns a pointer to the UnixTaskRunner, which is valid for the lifetime of
+  // this ThreadTaskRunner object (unless this object is moved-from, in which
+  // case the pointer remains valid for the lifetime of the new owning
+  // ThreadTaskRunner).
+  //
+  // Warning: do not call Quit() on the returned runner pointer, the termination
+  // should be handled exclusively by this class' destructor.
+  UnixTaskRunner* get() const { return task_runner_; }
+
+  // TaskRunner implementation.
+  // These methods just proxy to the underlying task_runner_.
+  void PostTask(std::function<void()>) override;
+  void PostDelayedTask(std::function<void()>, uint32_t delay_ms) override;
+  void AddFileDescriptorWatch(PlatformHandle, std::function<void()>) override;
+  void RemoveFileDescriptorWatch(PlatformHandle) override;
+  bool RunsTasksOnCurrentThread() const override;
+
+ private:
+  explicit ThreadTaskRunner(const std::string& name);
+  void RunTaskThread(std::function<void(UnixTaskRunner*)> initializer);
+
+  std::thread thread_;
+  std::string name_;
+  UnixTaskRunner* task_runner_ = nullptr;
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_THREAD_TASK_RUNNER_H_
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_task_runner.h"
+
+#include <condition_variable>
+#include <functional>
+#include <mutex>
+#include <thread>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/unix_task_runner.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#include <sys/prctl.h>
+#endif
+
+namespace perfetto {
+namespace base {
+
+ThreadTaskRunner::ThreadTaskRunner(ThreadTaskRunner&& other) noexcept
+    : thread_(std::move(other.thread_)), task_runner_(other.task_runner_) {
+  other.task_runner_ = nullptr;
+}
+
+ThreadTaskRunner& ThreadTaskRunner::operator=(ThreadTaskRunner&& other) {
+  this->~ThreadTaskRunner();
+  new (this) ThreadTaskRunner(std::move(other));
+  return *this;
+}
+
+ThreadTaskRunner::~ThreadTaskRunner() {
+  if (task_runner_) {
+    PERFETTO_CHECK(!task_runner_->QuitCalled());
+    task_runner_->Quit();
+
+    PERFETTO_DCHECK(thread_.joinable());
+  }
+  if (thread_.joinable())
+    thread_.join();
+}
+
+ThreadTaskRunner::ThreadTaskRunner(const std::string& name) : name_(name) {
+  std::mutex init_lock;
+  std::condition_variable init_cv;
+
+  std::function<void(UnixTaskRunner*)> initializer =
+      [this, &init_lock, &init_cv](UnixTaskRunner* task_runner) {
+        std::lock_guard<std::mutex> lock(init_lock);
+        task_runner_ = task_runner;
+        // Notify while still holding the lock, as init_cv ceases to exist as
+        // soon as the main thread observes a non-null task_runner_, and it can
+        // wake up spuriously (i.e. before the notify if we had unlocked before
+        // notifying).
+        init_cv.notify_one();
+      };
+
+  thread_ = std::thread(&ThreadTaskRunner::RunTaskThread, this,
+                        std::move(initializer));
+
+  std::unique_lock<std::mutex> lock(init_lock);
+  init_cv.wait(lock, [this] { return !!task_runner_; });
+}
+
+void ThreadTaskRunner::RunTaskThread(
+    std::function<void(UnixTaskRunner*)> initializer) {
+  if (!name_.empty()) {
+    base::MaybeSetThreadName(name_);
+  }
+
+  UnixTaskRunner task_runner;
+  task_runner.PostTask(std::bind(std::move(initializer), &task_runner));
+  task_runner.Run();
+}
+
+void ThreadTaskRunner::PostTaskAndWaitForTesting(std::function<void()> fn) {
+  std::mutex mutex;
+  std::condition_variable cv;
+
+  std::unique_lock<std::mutex> lock(mutex);
+  bool done = false;
+  task_runner_->PostTask([&mutex, &cv, &done, &fn] {
+    fn();
+
+    std::lock_guard<std::mutex> inner_lock(mutex);
+    done = true;
+    cv.notify_one();
+  });
+  cv.wait(lock, [&done] { return done; });
+}
+
+uint64_t ThreadTaskRunner::GetThreadCPUTimeNsForTesting() {
+  uint64_t thread_time_ns = 0;
+  PostTaskAndWaitForTesting([&thread_time_ns] {
+    thread_time_ns = static_cast<uint64_t>(base::GetThreadCPUTimeNs().count());
+  });
+  return thread_time_ns;
+}
+
+void ThreadTaskRunner::PostTask(std::function<void()> task) {
+  task_runner_->PostTask(std::move(task));
+}
+
+void ThreadTaskRunner::PostDelayedTask(std::function<void()> task,
+                                       uint32_t delay_ms) {
+  task_runner_->PostDelayedTask(std::move(task), delay_ms);
+}
+
+void ThreadTaskRunner::AddFileDescriptorWatch(
+    PlatformHandle handle,
+    std::function<void()> watch_task) {
+  task_runner_->AddFileDescriptorWatch(handle, std::move(watch_task));
+}
+
+void ThreadTaskRunner::RemoveFileDescriptorWatch(PlatformHandle handle) {
+  task_runner_->RemoveFileDescriptorWatch(handle);
+}
+
+bool ThreadTaskRunner::RunsTasksOnCurrentThread() const {
+  return task_runner_->RunsTasksOnCurrentThread();
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/unix_task_runner.cc
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/platform.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/unix_task_runner.h"
+
+#include <errno.h>
+#include <stdlib.h>
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <Windows.h>
+#include <synchapi.h>
+#else
+#include <unistd.h>
+#endif
+
+#include <algorithm>
+#include <limits>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/watchdog.h"
+
+namespace perfetto {
+namespace base {
+
+UnixTaskRunner::UnixTaskRunner() {
+  AddFileDescriptorWatch(event_.fd(), [] {
+    // Not reached -- see PostFileDescriptorWatches().
+    PERFETTO_DFATAL("Should be unreachable.");
+  });
+}
+
+UnixTaskRunner::~UnixTaskRunner() = default;
+
+void UnixTaskRunner::WakeUp() {
+  event_.Notify();
+}
+
+void UnixTaskRunner::Run() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  created_thread_id_ = GetThreadId();
+  quit_ = false;
+  for (;;) {
+    int poll_timeout_ms;
+    {
+      std::lock_guard<std::mutex> lock(lock_);
+      if (quit_)
+        return;
+      poll_timeout_ms = GetDelayMsToNextTaskLocked();
+      UpdateWatchTasksLocked();
+    }
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    DWORD timeout =
+        poll_timeout_ms >= 0 ? static_cast<DWORD>(poll_timeout_ms) : INFINITE;
+    DWORD ret =
+        WaitForMultipleObjects(static_cast<DWORD>(poll_fds_.size()),
+                               &poll_fds_[0], /*bWaitAll=*/false, timeout);
+    // Unlike poll(2), WaitForMultipleObjects() returns only *one* handle in the
+    // set, even when >1 is signalled. In order to avoid starvation,
+    // PostFileDescriptorWatches() will WaitForSingleObject() each other handle
+    // to ensure fairness. |ret| here is passed just to avoid an extra
+    // WaitForSingleObject() for the one handle that WaitForMultipleObject()
+    // returned.
+    PostFileDescriptorWatches(ret);
+#else
+    platform::BeforeMaybeBlockingSyscall();
+    int ret = PERFETTO_EINTR(poll(
+        &poll_fds_[0], static_cast<nfds_t>(poll_fds_.size()), poll_timeout_ms));
+    platform::AfterMaybeBlockingSyscall();
+    PERFETTO_CHECK(ret >= 0);
+    PostFileDescriptorWatches(0 /*ignored*/);
+#endif
+
+    // To avoid starvation we always interleave all types of tasks -- immediate,
+    // delayed and file descriptor watches.
+    RunImmediateAndDelayedTask();
+  }
+}
+
+void UnixTaskRunner::Quit() {
+  std::lock_guard<std::mutex> lock(lock_);
+  quit_ = true;
+  WakeUp();
+}
+
+bool UnixTaskRunner::QuitCalled() {
+  std::lock_guard<std::mutex> lock(lock_);
+  return quit_;
+}
+
+bool UnixTaskRunner::IsIdleForTesting() {
+  std::lock_guard<std::mutex> lock(lock_);
+  return immediate_tasks_.empty();
+}
+
+void UnixTaskRunner::UpdateWatchTasksLocked() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  if (!watch_tasks_changed_)
+    return;
+  watch_tasks_changed_ = false;
+#endif
+  poll_fds_.clear();
+  for (auto& it : watch_tasks_) {
+    PlatformHandle handle = it.first;
+    WatchTask& watch_task = it.second;
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    if (!watch_task.pending)
+      poll_fds_.push_back(handle);
+#else
+    watch_task.poll_fd_index = poll_fds_.size();
+    poll_fds_.push_back({handle, POLLIN | POLLHUP, 0});
+#endif
+  }
+}
+
+void UnixTaskRunner::RunImmediateAndDelayedTask() {
+  // If locking overhead becomes an issue, add a separate work queue.
+  std::function<void()> immediate_task;
+  std::function<void()> delayed_task;
+  TimeMillis now = GetWallTimeMs();
+  {
+    std::lock_guard<std::mutex> lock(lock_);
+    if (!immediate_tasks_.empty()) {
+      immediate_task = std::move(immediate_tasks_.front());
+      immediate_tasks_.pop_front();
+    }
+    if (!delayed_tasks_.empty()) {
+      auto it = delayed_tasks_.begin();
+      if (now >= it->first) {
+        delayed_task = std::move(it->second);
+        delayed_tasks_.erase(it);
+      }
+    }
+  }
+
+  errno = 0;
+  if (immediate_task)
+    RunTaskWithWatchdogGuard(immediate_task);
+  errno = 0;
+  if (delayed_task)
+    RunTaskWithWatchdogGuard(delayed_task);
+}
+
+void UnixTaskRunner::PostFileDescriptorWatches(uint64_t windows_wait_result) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  for (size_t i = 0; i < poll_fds_.size(); i++) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    const PlatformHandle handle = poll_fds_[i];
+    // |windows_wait_result| is the result of WaitForMultipleObjects() call. If
+    // one of the objects was signalled, it will have a value between
+    // [0, poll_fds_.size()].
+    if (i != windows_wait_result &&
+        WaitForSingleObject(handle, 0) != WAIT_OBJECT_0) {
+      continue;
+    }
+#else
+    base::ignore_result(windows_wait_result);
+    const PlatformHandle handle = poll_fds_[i].fd;
+    if (!(poll_fds_[i].revents & (POLLIN | POLLHUP)))
+      continue;
+    poll_fds_[i].revents = 0;
+#endif
+
+    // The wake-up event is handled inline to avoid an infinite recursion of
+    // posted tasks.
+    if (handle == event_.fd()) {
+      event_.Clear();
+      continue;
+    }
+
+    // Binding to |this| is safe since we are the only object executing the
+    // task.
+    PostTask(std::bind(&UnixTaskRunner::RunFileDescriptorWatch, this, handle));
+
+    // Flag the task as pending.
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    // On Windows this is done by marking the WatchTask entry as pending. This
+    // is more expensive than Linux as requires rebuilding the |poll_fds_|
+    // vector on each call. There doesn't seem to be a good alternative though.
+    auto it = watch_tasks_.find(handle);
+    PERFETTO_CHECK(it != watch_tasks_.end());
+    PERFETTO_DCHECK(!it->second.pending);
+    it->second.pending = true;
+#else
+    // On UNIX systems instead, we just make the fd negative while its task is
+    // pending. This makes poll(2) ignore the fd.
+    PERFETTO_DCHECK(poll_fds_[i].fd >= 0);
+    poll_fds_[i].fd = -poll_fds_[i].fd;
+#endif
+  }
+}
+
+void UnixTaskRunner::RunFileDescriptorWatch(PlatformHandle fd) {
+  std::function<void()> task;
+  {
+    std::lock_guard<std::mutex> lock(lock_);
+    auto it = watch_tasks_.find(fd);
+    if (it == watch_tasks_.end())
+      return;
+    WatchTask& watch_task = it->second;
+
+    // Make poll(2) pay attention to the fd again. Since another thread may have
+    // updated this watch we need to refresh the set first.
+    UpdateWatchTasksLocked();
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    // On Windows we manually track the presence of outstanding tasks for the
+    // watch. The UpdateWatchTasksLocked() in the Run() loop will re-add the
+    // task to the |poll_fds_| vector.
+    PERFETTO_DCHECK(watch_task.pending);
+    watch_task.pending = false;
+#else
+    size_t fd_index = watch_task.poll_fd_index;
+    PERFETTO_DCHECK(fd_index < poll_fds_.size());
+    PERFETTO_DCHECK(::abs(poll_fds_[fd_index].fd) == fd);
+    poll_fds_[fd_index].fd = fd;
+#endif
+    task = watch_task.callback;
+  }
+  errno = 0;
+  RunTaskWithWatchdogGuard(task);
+}
+
+int UnixTaskRunner::GetDelayMsToNextTaskLocked() const {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!immediate_tasks_.empty())
+    return 0;
+  if (!delayed_tasks_.empty()) {
+    TimeMillis diff = delayed_tasks_.begin()->first - GetWallTimeMs();
+    return std::max(0, static_cast<int>(diff.count()));
+  }
+  return -1;
+}
+
+void UnixTaskRunner::PostTask(std::function<void()> task) {
+  bool was_empty;
+  {
+    std::lock_guard<std::mutex> lock(lock_);
+    was_empty = immediate_tasks_.empty();
+    immediate_tasks_.push_back(std::move(task));
+  }
+  if (was_empty)
+    WakeUp();
+}
+
+void UnixTaskRunner::PostDelayedTask(std::function<void()> task,
+                                     uint32_t delay_ms) {
+  TimeMillis runtime = GetWallTimeMs() + TimeMillis(delay_ms);
+  {
+    std::lock_guard<std::mutex> lock(lock_);
+    delayed_tasks_.insert(std::make_pair(runtime, std::move(task)));
+  }
+  WakeUp();
+}
+
+void UnixTaskRunner::AddFileDescriptorWatch(PlatformHandle fd,
+                                            std::function<void()> task) {
+  PERFETTO_DCHECK(PlatformHandleChecker::IsValid(fd));
+  {
+    std::lock_guard<std::mutex> lock(lock_);
+    PERFETTO_DCHECK(!watch_tasks_.count(fd));
+    WatchTask& watch_task = watch_tasks_[fd];
+    watch_task.callback = std::move(task);
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    watch_task.pending = false;
+#else
+    watch_task.poll_fd_index = SIZE_MAX;
+#endif
+    watch_tasks_changed_ = true;
+  }
+  WakeUp();
+}
+
+void UnixTaskRunner::RemoveFileDescriptorWatch(PlatformHandle fd) {
+  PERFETTO_DCHECK(PlatformHandleChecker::IsValid(fd));
+  {
+    std::lock_guard<std::mutex> lock(lock_);
+    PERFETTO_DCHECK(watch_tasks_.count(fd));
+    watch_tasks_.erase(fd);
+    watch_tasks_changed_ = true;
+  }
+  // No need to schedule a wake-up for this.
+}
+
+bool UnixTaskRunner::RunsTasksOnCurrentThread() const {
+  return GetThreadId() == created_thread_id_;
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/subprocess.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/subprocess.h
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_SUBPROCESS_H_
+#define INCLUDE_PERFETTO_EXT_BASE_SUBPROCESS_H_
+
+#include <condition_variable>
+#include <functional>
+#include <initializer_list>
+#include <mutex>
+#include <optional>
+#include <string>
+#include <thread>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
+// gen_amalgamated expanded: #include "perfetto/base/proc_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/event_fd.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+
+namespace perfetto {
+namespace base {
+
+// Handles creation and lifecycle management of subprocesses, taking care of
+// all subtleties involved in handling processes on UNIX.
+// This class allows to deal with macro two use-cases:
+// 1) fork() + exec() equivalent: for spawning a brand new process image.
+//    This happens when |args.exec_cmd| is not empty.
+//    This is safe to use even in a multi-threaded environment.
+// 2) fork(): for spawning a process and running a function.
+//    This happens when |args.posix_entrypoint_for_testing| is not empty.
+//    This is intended only for tests as it is extremely subtle.
+//    This mode must be used with extreme care. Before the entrypoint is
+//    invoked all file descriptors other than stdin/out/err and the ones
+//    specified in |args.preserve_fds| will be closed, to avoid each process
+//    retaining a dupe of other subprocesses pipes. This however means that
+//    any non trivial calls (including logging) must be avoided as they might
+//    refer to FDs that are now closed. The entrypoint should really be used
+//    just to signal a pipe or similar for synchronizing sequencing in tests.
+
+//
+// This class allows to control stdin/out/err pipe redirection and takes care
+// of keeping all the pipes pumped (stdin) / drained (stdout/err), in a similar
+// fashion of python's subprocess.Communicate()
+// stdin: is always piped and closed once the |args.input| buffer is written.
+// stdout/err can be either:
+//   - dup()ed onto the parent process stdout/err.
+//   - redirected onto /dev/null.
+//   - piped onto a buffer (see output() method). There is only one output
+//     buffer in total. If both stdout and stderr are set to kBuffer mode, they
+//     will be merged onto the same. There doesn't seem any use case where they
+//     are needed distinctly.
+//
+// Some caveats worth mentioning:
+// - It always waitpid()s, to avoid leaving zombies around. If the process is
+//   not terminated by the time the destructor is reached, the dtor will
+//   send a SIGKILL and wait for the termination.
+// - After fork()-ing it will close all file descriptors, preserving only
+//   stdin/out/err and the fds listed in |args.preserve_fds|.
+// - On Linux/Android, the child process will be SIGKILL-ed if the calling
+//   thread exists, even if the Subprocess is std::move()-d onto another thread.
+//   This happens by virtue PR_SET_PDEATHSIG, which is used to avoid that
+//   child processes are leaked in the case of a crash of the parent (frequent
+//   in tests). However, the child process might still be leaked if execing
+//   a setuid/setgid binary (see man 2 prctl).
+//
+// Usage:
+// base::Subprocess p({"/bin/cat", "-"});
+// (or equivalently:
+//     base::Subprocess p;
+//     p.args.exec_cmd.push_back("/bin/cat");
+//     p.args.exec_cmd.push_back("-");
+//  )
+// p.args.stdout_mode = base::Subprocess::kBuffer;
+// p.args.stderr_mode = base::Subprocess::kInherit;
+// p.args.input = "stdin contents";
+// p.Call();
+// (or equivalently:
+//     p.Start();
+//     p.Wait();
+// )
+// EXPECT_EQ(p.status(), base::Subprocess::kTerminated);
+// EXPECT_EQ(p.returncode(), 0);
+class Subprocess {
+ public:
+  enum Status {
+    kNotStarted = 0,  // Before calling Start() or Call().
+    kRunning,         // After calling Start(), before Wait().
+    kTerminated,      // The subprocess terminated, either successfully or not.
+                      // This includes crashes or other signals on UNIX.
+  };
+
+  enum class OutputMode {
+    kInherit = 0,  // Inherit's the caller process stdout/stderr.
+    kDevNull,      // dup() onto /dev/null.
+    kBuffer,       // dup() onto a pipe and move it into the output() buffer.
+    kFd,           // dup() onto the passed args.fd.
+  };
+
+  enum class InputMode {
+    kBuffer = 0,  // dup() onto a pipe and write args.input on it.
+    kDevNull,     // dup() onto /dev/null.
+  };
+
+  // Input arguments for configuring the subprocess behavior.
+  struct Args {
+    Args(std::initializer_list<std::string> _cmd = {}) : exec_cmd(_cmd) {}
+    Args(Args&&) noexcept;
+    Args& operator=(Args&&);
+    // If non-empty this will cause an exec() when Start()/Call() are called.
+    std::vector<std::string> exec_cmd;
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    // If non-empty, it changes the argv[0] argument passed to exec. If
+    // unset, argv[0] == exec_cmd[0]. This is to handle cases like:
+    // exec_cmd = {"/proc/self/exec"}, argv0: "my_custom_test_override".
+    std::string posix_argv0_override_for_testing;
+
+    // If non-empty this will be invoked on the fork()-ed child process, after
+    // stdin/out/err has been redirected and all other file descriptor are
+    // closed. It is valid to specify both |exec_cmd| AND
+    // |posix_entrypoint_for_testing|. In this case the latter will be invoked
+    // just before the exec() call, but after having closed all fds % stdin/o/e.
+    // This is for synchronization barriers in tests.
+    std::function<void()> posix_entrypoint_for_testing;
+
+    // When set, will will move the process to the given process group. If set
+    // and zero, it will create a new process group. Effectively this calls
+    // setpgid(0 /*self_pid*/, posix_proc_group_id).
+    // This can be used to avoid that subprocesses receive CTRL-C from the
+    // terminal, while still living in the same session.
+    std::optional<pid_t> posix_proc_group_id{};
+#endif
+
+    // If non-empty, replaces the environment passed to exec().
+    std::vector<std::string> env;
+
+    // The file descriptors in this list will not be closed.
+    std::vector<int> preserve_fds;
+
+    // The data to push in the child process stdin, if input_mode ==
+    // InputMode::kBuffer.
+    std::string input;
+
+    InputMode stdin_mode = InputMode::kBuffer;
+    OutputMode stdout_mode = OutputMode::kInherit;
+    OutputMode stderr_mode = OutputMode::kInherit;
+
+    base::ScopedPlatformHandle out_fd;
+
+    // Returns " ".join(exec_cmd), quoting arguments.
+    std::string GetCmdString() const;
+  };
+
+  struct ResourceUsage {
+    uint32_t cpu_utime_ms = 0;
+    uint32_t cpu_stime_ms = 0;
+    uint32_t max_rss_kb = 0;
+    uint32_t min_page_faults = 0;
+    uint32_t maj_page_faults = 0;
+    uint32_t vol_ctx_switch = 0;
+    uint32_t invol_ctx_switch = 0;
+
+    uint32_t cpu_time_ms() const { return cpu_utime_ms + cpu_stime_ms; }
+  };
+
+  explicit Subprocess(std::initializer_list<std::string> exec_cmd = {});
+  Subprocess(Subprocess&&) noexcept;
+  Subprocess& operator=(Subprocess&&);
+  ~Subprocess();  // It will KillAndWaitForTermination() if still alive.
+
+  // Starts the subprocess but doesn't wait for its termination. The caller
+  // is expected to either call Wait() or Poll() after this call.
+  void Start();
+
+  // Wait for process termination. Can be called more than once.
+  // Args:
+  //   |timeout_ms| = 0: wait indefinitely.
+  //   |timeout_ms| > 0: wait for at most |timeout_ms|.
+  // Returns:
+  //  True: The process terminated. See status() and returncode().
+  //  False: Timeout reached, the process is still running. In this case the
+  //         process will be left in the kRunning state.
+  bool Wait(int timeout_ms = 0);
+
+  // Equivalent of Start() + Wait();
+  // Returns true if the process exited cleanly with return code 0. False in
+  // any othe case.
+  bool Call(int timeout_ms = 0);
+
+  Status Poll();
+
+  // Sends a signal (SIGKILL if not specified) and wait for process termination.
+  void KillAndWaitForTermination(int sig_num = 0);
+
+  PlatformProcessId pid() const { return s_->pid; }
+
+  // The accessors below are updated only after a call to Poll(), Wait() or
+  // KillAndWaitForTermination().
+  // In most cases you want to call Poll() rather than these accessors.
+
+  Status status() const { return s_->status; }
+  int returncode() const { return s_->returncode; }
+  bool timed_out() const { return s_->timed_out; }
+
+  // This contains both stdout and stderr (if the corresponding _mode ==
+  // OutputMode::kBuffer). It's non-const so the caller can std::move() it.
+  std::string& output() { return s_->output; }
+  const std::string& output() const { return s_->output; }
+
+  const ResourceUsage& posix_rusage() const { return *s_->rusage; }
+
+  Args args;
+
+ private:
+  // The signal/exit code used when killing the process in case of a timeout.
+  static const int kTimeoutSignal;
+
+  Subprocess(const Subprocess&) = delete;
+  Subprocess& operator=(const Subprocess&) = delete;
+
+  // This is to deal robustly with the move operators, without having to
+  // manually maintain member-wise move instructions.
+  struct MovableState {
+    base::Pipe stdin_pipe;
+    base::Pipe stdouterr_pipe;
+    PlatformProcessId pid;
+    Status status = kNotStarted;
+    int returncode = -1;
+    std::string output;  // Stdin+stderr. Only when OutputMode::kBuffer.
+    std::unique_ptr<ResourceUsage> rusage{new ResourceUsage()};
+    bool timed_out = false;
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    std::thread stdouterr_thread;
+    std::thread stdin_thread;
+    ScopedPlatformHandle win_proc_handle;
+    ScopedPlatformHandle win_thread_handle;
+
+    base::EventFd stdouterr_done_event;
+    std::mutex mutex;  // Protects locked_outerr_buf and the two pipes.
+    std::string locked_outerr_buf;
+#else
+    base::Pipe exit_status_pipe;
+    size_t input_written = 0;
+    std::thread waitpid_thread;
+#endif
+  };
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  static void StdinThread(MovableState*, std::string input);
+  static void StdoutErrThread(MovableState*);
+#else
+  void TryPushStdin();
+  void TryReadStdoutAndErr();
+  void TryReadExitStatus();
+  bool PollInternal(int poll_timeout_ms);
+#endif
+
+  std::unique_ptr<MovableState> s_;
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_SUBPROCESS_H_
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/subprocess.h"
+
+#include <tuple>
+
+// This file contains only the common bits (ctors / dtors / move operators).
+// The rest lives in subprocess_posix.cc and subprocess_windows.cc.
+
+namespace perfetto {
+namespace base {
+
+Subprocess::Args::Args(Args&&) noexcept = default;
+Subprocess::Args& Subprocess::Args::operator=(Args&&) = default;
+
+Subprocess::Subprocess(std::initializer_list<std::string> a)
+    : args(a), s_(new MovableState()) {}
+
+Subprocess::Subprocess(Subprocess&& other) noexcept {
+  static_assert(sizeof(Subprocess) ==
+                    sizeof(std::tuple<std::unique_ptr<MovableState>, Args>),
+                "base::Subprocess' move ctor needs updating");
+  s_ = std::move(other.s_);
+  args = std::move(other.args);
+
+  // Reset the state of the moved-from object.
+  other.s_.reset(new MovableState());
+  other.~Subprocess();
+  new (&other) Subprocess();
+}
+
+Subprocess& Subprocess::operator=(Subprocess&& other) {
+  this->~Subprocess();
+  new (this) Subprocess(std::move(other));
+  return *this;
+}
+
+Subprocess::~Subprocess() {
+  if (s_->status == kRunning)
+    KillAndWaitForTermination();
+}
+
+bool Subprocess::Call(int timeout_ms) {
+  PERFETTO_CHECK(s_->status == kNotStarted);
+  Start();
+
+  if (!Wait(timeout_ms)) {
+    s_->timed_out = true;
+    KillAndWaitForTermination(kTimeoutSignal);
+  }
+  PERFETTO_DCHECK(s_->status != kRunning);
+  return s_->status == kTerminated && s_->returncode == 0;
+}
+
+std::string Subprocess::Args::GetCmdString() const {
+  std::string str;
+  for (size_t i = 0; i < exec_cmd.size(); i++) {
+    str += i > 0 ? " \"" : "";
+    str += exec_cmd[i];
+    str += i > 0 ? "\"" : "";
+  }
+  return str;
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/subprocess_posix.cc
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/subprocess.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+
+#include <fcntl.h>
+#include <poll.h>
+#include <signal.h>
+#include <stdio.h>
+#include <sys/resource.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <algorithm>
+#include <thread>
+#include <tuple>
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#include <sys/prctl.h>
+#endif
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+
+// In MacOS this is not defined in any header.
+extern "C" char** environ;
+
+namespace perfetto {
+namespace base {
+
+namespace {
+
+struct ChildProcessArgs {
+  Subprocess::Args* create_args;
+  const char* exec_cmd = nullptr;
+  std::vector<char*> argv;
+  std::vector<char*> env;
+  int stdin_pipe_rd = -1;
+  int stdouterr_pipe_wr = -1;
+};
+
+// Don't add any dynamic allocation in this function. This will be invoked
+// under a fork(), potentially in a state where the allocator lock is held.
+void __attribute__((noreturn)) ChildProcess(ChildProcessArgs* args) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  // In no case we want a child process to outlive its parent process. This is
+  // relevant for tests, so that a test failure/crash doesn't leave child
+  // processes around that get reparented to init.
+  prctl(PR_SET_PDEATHSIG, SIGKILL);
+#endif
+
+  auto die = [args](const char* err) __attribute__((noreturn)) {
+    base::ignore_result(write(args->stdouterr_pipe_wr, err, strlen(err)));
+    base::ignore_result(write(args->stdouterr_pipe_wr, "\n", 1));
+    // From https://www.gnu.org/software/libc/manual/html_node/Exit-Status.html
+    // "In particular, the value 128 is used to indicate failure to execute
+    // another program in a subprocess. This convention is not universally
+    // obeyed, but it is a good idea to follow it in your programs."
+    _exit(128);
+  };
+
+  if (args->create_args->posix_proc_group_id.has_value()) {
+    if (setpgid(0 /*self*/, args->create_args->posix_proc_group_id.value())) {
+      die("setpgid() failed");
+    }
+  }
+
+  auto set_fd_close_on_exec = [&die](int fd, bool close_on_exec) {
+    int flags = fcntl(fd, F_GETFD, 0);
+    if (flags < 0)
+      die("fcntl(F_GETFD) failed");
+    flags = close_on_exec ? (flags | FD_CLOEXEC) : (flags & ~FD_CLOEXEC);
+    if (fcntl(fd, F_SETFD, flags) < 0)
+      die("fcntl(F_SETFD) failed");
+  };
+
+  if (getppid() == 1)
+    die("terminating because parent process died");
+
+  switch (args->create_args->stdin_mode) {
+    case Subprocess::InputMode::kBuffer:
+      if (dup2(args->stdin_pipe_rd, STDIN_FILENO) == -1)
+        die("Failed to dup2(STDIN)");
+      close(args->stdin_pipe_rd);
+      break;
+    case Subprocess::InputMode::kDevNull:
+      if (dup2(open("/dev/null", O_RDONLY), STDIN_FILENO) == -1)
+        die("Failed to dup2(STDOUT)");
+      break;
+  }
+
+  switch (args->create_args->stdout_mode) {
+    case Subprocess::OutputMode::kInherit:
+      break;
+    case Subprocess::OutputMode::kDevNull: {
+      if (dup2(open("/dev/null", O_RDWR), STDOUT_FILENO) == -1)
+        die("Failed to dup2(STDOUT)");
+      break;
+    }
+    case Subprocess::OutputMode::kBuffer:
+      if (dup2(args->stdouterr_pipe_wr, STDOUT_FILENO) == -1)
+        die("Failed to dup2(STDOUT)");
+      break;
+    case Subprocess::OutputMode::kFd:
+      if (dup2(*args->create_args->out_fd, STDOUT_FILENO) == -1)
+        die("Failed to dup2(STDOUT)");
+      break;
+  }
+
+  switch (args->create_args->stderr_mode) {
+    case Subprocess::OutputMode::kInherit:
+      break;
+    case Subprocess::OutputMode::kDevNull: {
+      if (dup2(open("/dev/null", O_RDWR), STDERR_FILENO) == -1)
+        die("Failed to dup2(STDERR)");
+      break;
+    }
+    case Subprocess::OutputMode::kBuffer:
+      if (dup2(args->stdouterr_pipe_wr, STDERR_FILENO) == -1)
+        die("Failed to dup2(STDERR)");
+      break;
+    case Subprocess::OutputMode::kFd:
+      if (dup2(*args->create_args->out_fd, STDERR_FILENO) == -1)
+        die("Failed to dup2(STDERR)");
+      break;
+  }
+
+  // Close all FDs % stdin/out/err and the ones that the client explicitly
+  // asked to retain. The reason for this is twofold:
+  // 1. For exec-only (i.e. entrypoint == empty) cases: it avoids leaking FDs
+  //    that didn't get marked as O_CLOEXEC by accident.
+  // 2. In fork() mode (entrypoint not empty) avoids retaining a dup of eventfds
+  //    that would prevent the parent process to receive EOFs (tests usually use
+  //    pipes as a synchronization mechanism between subprocesses).
+  const auto& preserve_fds = args->create_args->preserve_fds;
+  for (int i = 0; i < 512; i++) {
+    if (i != STDIN_FILENO && i != STDERR_FILENO && i != STDOUT_FILENO &&
+        i != args->stdouterr_pipe_wr &&
+        !std::count(preserve_fds.begin(), preserve_fds.end(), i)) {
+      close(i);
+    }
+  }
+
+  // Clears O_CLOEXEC from stdin/out/err and the |preserve_fds| list. These are
+  // the only FDs that we want to be preserved after the exec().
+  set_fd_close_on_exec(STDIN_FILENO, false);
+  set_fd_close_on_exec(STDOUT_FILENO, false);
+  set_fd_close_on_exec(STDERR_FILENO, false);
+
+  for (auto fd : preserve_fds)
+    set_fd_close_on_exec(fd, false);
+
+  // If the caller specified a std::function entrypoint, run that first.
+  if (args->create_args->posix_entrypoint_for_testing)
+    args->create_args->posix_entrypoint_for_testing();
+
+  // If the caller specified only an entrypoint, without any args, exit now.
+  // Otherwise proceed with the exec() below.
+  if (!args->exec_cmd)
+    _exit(0);
+
+  // If |args[0]| is a path use execv() (which takes a path), othewise use
+  // exevp(), which uses the shell and follows PATH.
+  if (strchr(args->exec_cmd, '/')) {
+    char** env = args->env.empty() ? environ : args->env.data();
+    execve(args->exec_cmd, args->argv.data(), env);
+  } else {
+    // There is no execvpe() on Mac.
+    if (!args->env.empty())
+      die("A full path is required for |exec_cmd| when setting |env|");
+    execvp(args->exec_cmd, args->argv.data());
+  }
+
+  // Reached only if execv fails.
+  die("execve() failed");
+}
+
+}  // namespace
+
+// static
+const int Subprocess::kTimeoutSignal = SIGKILL;
+
+void Subprocess::Start() {
+  ChildProcessArgs proc_args;
+  proc_args.create_args = &args;
+
+  // Setup argv.
+  if (!args.exec_cmd.empty()) {
+    proc_args.exec_cmd = args.exec_cmd[0].c_str();
+    for (const std::string& arg : args.exec_cmd)
+      proc_args.argv.push_back(const_cast<char*>(arg.c_str()));
+    proc_args.argv.push_back(nullptr);
+
+    if (!args.posix_argv0_override_for_testing.empty()) {
+      proc_args.argv[0] =
+          const_cast<char*>(args.posix_argv0_override_for_testing.c_str());
+    }
+  }
+
+  // Setup env.
+  if (!args.env.empty()) {
+    for (const std::string& str : args.env)
+      proc_args.env.push_back(const_cast<char*>(str.c_str()));
+    proc_args.env.push_back(nullptr);
+  }
+
+  // Setup the pipes for stdin/err redirection.
+  if (args.stdin_mode == InputMode::kBuffer) {
+    s_->stdin_pipe = base::Pipe::Create(base::Pipe::kWrNonBlock);
+    proc_args.stdin_pipe_rd = *s_->stdin_pipe.rd;
+  }
+  s_->stdouterr_pipe = base::Pipe::Create(base::Pipe::kRdNonBlock);
+  proc_args.stdouterr_pipe_wr = *s_->stdouterr_pipe.wr;
+
+  // Spawn the child process that will exec().
+  s_->pid = fork();
+  PERFETTO_CHECK(s_->pid >= 0);
+  if (s_->pid == 0) {
+    // Close the parent-ends of the pipes.
+    s_->stdin_pipe.wr.reset();
+    s_->stdouterr_pipe.rd.reset();
+    ChildProcess(&proc_args);
+    // ChildProcess() doesn't return, not even in case of failures.
+    PERFETTO_FATAL("not reached");
+  }
+
+  s_->status = kRunning;
+
+  // Close the child-end of the pipes.
+  // Deliberately NOT closing the s_->stdin_pipe.rd. This is to avoid crashing
+  // with a SIGPIPE if the process exits without consuming its stdin, while
+  // the parent tries to write() on the other end of the stdin pipe.
+  s_->stdouterr_pipe.wr.reset();
+  proc_args.create_args->out_fd.reset();
+
+  // Spawn a thread that is blocked on waitpid() and writes the termination
+  // status onto a pipe. The problem here is that waipid() doesn't have a
+  // timeout option and can't be passed to poll(). The alternative would be
+  // using a SIGCHLD handler, but anecdotally signal handlers introduce more
+  // problems than what they solve.
+  s_->exit_status_pipe = base::Pipe::Create(base::Pipe::kRdNonBlock);
+
+  // Both ends of the pipe are closed after the thread.join().
+  int pid = s_->pid;
+  int exit_status_pipe_wr = s_->exit_status_pipe.wr.release();
+  auto* rusage = s_->rusage.get();
+  s_->waitpid_thread = std::thread([pid, exit_status_pipe_wr, rusage] {
+    int pid_stat = -1;
+    struct rusage usg {};
+    int wait_res = PERFETTO_EINTR(wait4(pid, &pid_stat, 0, &usg));
+    PERFETTO_CHECK(wait_res == pid);
+
+    auto tv_to_ms = [](const struct timeval& tv) {
+      return static_cast<uint32_t>(tv.tv_sec * 1000 + tv.tv_usec / 1000);
+    };
+    rusage->cpu_utime_ms = tv_to_ms(usg.ru_utime);
+    rusage->cpu_stime_ms = tv_to_ms(usg.ru_stime);
+    rusage->max_rss_kb = static_cast<uint32_t>(usg.ru_maxrss) / 1000;
+    rusage->min_page_faults = static_cast<uint32_t>(usg.ru_minflt);
+    rusage->maj_page_faults = static_cast<uint32_t>(usg.ru_majflt);
+    rusage->vol_ctx_switch = static_cast<uint32_t>(usg.ru_nvcsw);
+    rusage->invol_ctx_switch = static_cast<uint32_t>(usg.ru_nivcsw);
+
+    base::ignore_result(PERFETTO_EINTR(
+        write(exit_status_pipe_wr, &pid_stat, sizeof(pid_stat))));
+    PERFETTO_CHECK(close(exit_status_pipe_wr) == 0 || errno == EINTR);
+  });
+}
+
+Subprocess::Status Subprocess::Poll() {
+  if (s_->status != kRunning)
+    return s_->status;  // Nothing to poll.
+  while (PollInternal(0 /* don't block*/)) {
+  }
+  return s_->status;
+}
+
+// |timeout_ms| semantic:
+//   -1: Block indefinitely.
+//    0: Don't block, return immediately.
+//   >0: Block for at most X ms.
+// Returns:
+//  True: Read at least one fd (so there might be more queued).
+//  False: if all fds reached quiescent (no data to read/write).
+bool Subprocess::PollInternal(int poll_timeout_ms) {
+  struct pollfd fds[3]{};
+  size_t num_fds = 0;
+  if (s_->exit_status_pipe.rd) {
+    fds[num_fds].fd = *s_->exit_status_pipe.rd;
+    fds[num_fds].events = POLLIN;
+    num_fds++;
+  }
+  if (s_->stdouterr_pipe.rd) {
+    fds[num_fds].fd = *s_->stdouterr_pipe.rd;
+    fds[num_fds].events = POLLIN;
+    num_fds++;
+  }
+  if (s_->stdin_pipe.wr) {
+    fds[num_fds].fd = *s_->stdin_pipe.wr;
+    fds[num_fds].events = POLLOUT;
+    num_fds++;
+  }
+
+  if (num_fds == 0)
+    return false;
+
+  auto nfds = static_cast<nfds_t>(num_fds);
+  int poll_res = PERFETTO_EINTR(poll(fds, nfds, poll_timeout_ms));
+  PERFETTO_CHECK(poll_res >= 0);
+
+  TryReadStdoutAndErr();
+  TryPushStdin();
+  TryReadExitStatus();
+
+  return poll_res > 0;
+}
+
+bool Subprocess::Wait(int timeout_ms) {
+  PERFETTO_CHECK(s_->status != kNotStarted);
+
+  // Break out of the loop only after both conditions are satisfied:
+  // - All stdout/stderr data has been read (if kBuffer).
+  // - The process exited.
+  // Note that the two events can happen arbitrary order. After the process
+  // exits, there might be still data in the pipe buffer, which we want to
+  // read fully.
+  //
+  // Instead, don't wait on the stdin to be fully written. The child process
+  // might exit prematurely (or crash). If that happens, we can end up in a
+  // state where the write(stdin_pipe_.wr) will never unblock.
+
+  const int64_t t_start = base::GetWallTimeMs().count();
+  while (s_->exit_status_pipe.rd || s_->stdouterr_pipe.rd) {
+    int poll_timeout_ms = -1;  // Block until a FD is ready.
+    if (timeout_ms > 0) {
+      const int64_t now = GetWallTimeMs().count();
+      poll_timeout_ms = timeout_ms - static_cast<int>(now - t_start);
+      if (poll_timeout_ms <= 0)
+        return false;
+    }
+    PollInternal(poll_timeout_ms);
+  }  // while(...)
+  return true;
+}
+
+void Subprocess::TryReadExitStatus() {
+  if (!s_->exit_status_pipe.rd)
+    return;
+
+  int pid_stat = -1;
+  int64_t rsize = PERFETTO_EINTR(
+      read(*s_->exit_status_pipe.rd, &pid_stat, sizeof(pid_stat)));
+  if (rsize < 0 && errno == EAGAIN)
+    return;
+
+  if (rsize > 0) {
+    PERFETTO_CHECK(rsize == sizeof(pid_stat));
+  } else if (rsize < 0) {
+    PERFETTO_PLOG("Subprocess read(s_->exit_status_pipe) failed");
+  }
+  s_->waitpid_thread.join();
+  s_->exit_status_pipe.rd.reset();
+
+  s_->status = kTerminated;
+  if (WIFEXITED(pid_stat)) {
+    s_->returncode = WEXITSTATUS(pid_stat);
+  } else if (WIFSIGNALED(pid_stat)) {
+    s_->returncode = 128 + WTERMSIG(pid_stat);  // Follow bash convention.
+  } else {
+    PERFETTO_FATAL("waitpid() returned an unexpected value (0x%x)", pid_stat);
+  }
+}
+
+// If the stidn pipe is still open, push input data and close it at the end.
+void Subprocess::TryPushStdin() {
+  if (!s_->stdin_pipe.wr)
+    return;
+
+  PERFETTO_DCHECK(args.input.empty() || s_->input_written < args.input.size());
+  if (!args.input.empty()) {
+    int64_t wsize =
+        PERFETTO_EINTR(write(*s_->stdin_pipe.wr, &args.input[s_->input_written],
+                             args.input.size() - s_->input_written));
+    if (wsize < 0 && errno == EAGAIN)
+      return;
+
+    if (wsize >= 0) {
+      // Whether write() can return 0 is one of the greatest mysteries of UNIX.
+      // Just ignore it.
+      s_->input_written += static_cast<size_t>(wsize);
+    } else {
+      PERFETTO_PLOG("Subprocess write(stdin) failed");
+      s_->stdin_pipe.wr.reset();
+    }
+  }
+  PERFETTO_DCHECK(s_->input_written <= args.input.size());
+  if (s_->input_written == args.input.size())
+    s_->stdin_pipe.wr.reset();  // Close stdin.
+}
+
+void Subprocess::TryReadStdoutAndErr() {
+  if (!s_->stdouterr_pipe.rd)
+    return;
+  char buf[4096];
+  int64_t rsize =
+      PERFETTO_EINTR(read(*s_->stdouterr_pipe.rd, buf, sizeof(buf)));
+  if (rsize < 0 && errno == EAGAIN)
+    return;
+
+  if (rsize > 0) {
+    s_->output.append(buf, static_cast<size_t>(rsize));
+  } else if (rsize == 0 /* EOF */) {
+    s_->stdouterr_pipe.rd.reset();
+  } else {
+    PERFETTO_PLOG("Subprocess read(stdout/err) failed");
+    s_->stdouterr_pipe.rd.reset();
+  }
+}
+
+void Subprocess::KillAndWaitForTermination(int sig_num) {
+  kill(s_->pid, sig_num ? sig_num : SIGKILL);
+  Wait();
+  // TryReadExitStatus must have joined the thread.
+  PERFETTO_DCHECK(!s_->waitpid_thread.joinable());
+}
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // PERFETTO_OS_LINUX || PERFETTO_OS_ANDROID || PERFETTO_OS_APPLE
+// gen_amalgamated begin source: src/base/subprocess_windows.cc
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/subprocess.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+#include <stdio.h>
+
+#include <algorithm>
+#include <mutex>
+#include <tuple>
+
+#include <Windows.h>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+
+namespace perfetto {
+namespace base {
+
+// static
+const int Subprocess::kTimeoutSignal = static_cast<int>(STATUS_TIMEOUT);
+
+void Subprocess::Start() {
+  if (args.exec_cmd.empty()) {
+    PERFETTO_ELOG("Subprocess.exec_cmd cannot be empty on Windows");
+    return;
+  }
+
+  // Quote arguments but only when ambiguous. When quoting, CreateProcess()
+  // assumes that the command is an absolute path and does not search in the
+  // %PATH%. If non quoted, instead, CreateProcess() tries both. This is to
+  // allow Subprocess("cmd.exe", "/c", "shell command").
+  std::string cmd;
+  for (const auto& part : args.exec_cmd) {
+    if (part.find(" ") != std::string::npos) {
+      cmd += "\"" + part + "\" ";
+    } else {
+      cmd += part + " ";
+    }
+  }
+  // Remove trailing space.
+  if (!cmd.empty())
+    cmd.resize(cmd.size() - 1);
+
+  if (args.stdin_mode == InputMode::kBuffer) {
+    s_->stdin_pipe = Pipe::Create();
+    // Allow the child process to inherit the other end of the pipe.
+    PERFETTO_CHECK(
+        ::SetHandleInformation(*s_->stdin_pipe.rd, HANDLE_FLAG_INHERIT, 1));
+  }
+
+  if (args.stderr_mode == OutputMode::kBuffer ||
+      args.stdout_mode == OutputMode::kBuffer) {
+    s_->stdouterr_pipe = Pipe::Create();
+    PERFETTO_CHECK(
+        ::SetHandleInformation(*s_->stdouterr_pipe.wr, HANDLE_FLAG_INHERIT, 1));
+  }
+
+  ScopedPlatformHandle nul_handle;
+  if (args.stderr_mode == OutputMode::kDevNull ||
+      args.stdout_mode == OutputMode::kDevNull) {
+    nul_handle.reset(::CreateFileA(
+        "NUL", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
+        nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr));
+    PERFETTO_CHECK(::SetHandleInformation(*nul_handle, HANDLE_FLAG_INHERIT, 1));
+  }
+
+  PROCESS_INFORMATION proc_info{};
+  STARTUPINFOA start_info{};
+  start_info.cb = sizeof(STARTUPINFOA);
+
+  if (args.stderr_mode == OutputMode::kInherit) {
+    start_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE);
+  } else if (args.stderr_mode == OutputMode::kBuffer) {
+    start_info.hStdError = *s_->stdouterr_pipe.wr;
+  } else if (args.stderr_mode == OutputMode::kDevNull) {
+    start_info.hStdError = *nul_handle;
+  } else if (args.stderr_mode == OutputMode::kFd) {
+    PERFETTO_CHECK(
+        ::SetHandleInformation(*args.out_fd, HANDLE_FLAG_INHERIT, 1));
+    start_info.hStdError = *args.out_fd;
+  } else {
+    PERFETTO_CHECK(false);
+  }
+
+  if (args.stdout_mode == OutputMode::kInherit) {
+    start_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE);
+  } else if (args.stdout_mode == OutputMode::kBuffer) {
+    start_info.hStdOutput = *s_->stdouterr_pipe.wr;
+  } else if (args.stdout_mode == OutputMode::kDevNull) {
+    start_info.hStdOutput = *nul_handle;
+  } else if (args.stdout_mode == OutputMode::kFd) {
+    PERFETTO_CHECK(
+        ::SetHandleInformation(*args.out_fd, HANDLE_FLAG_INHERIT, 1));
+    start_info.hStdOutput = *args.out_fd;
+  } else {
+    PERFETTO_CHECK(false);
+  }
+
+  if (args.stdin_mode == InputMode::kBuffer) {
+    start_info.hStdInput = *s_->stdin_pipe.rd;
+  } else if (args.stdin_mode == InputMode::kDevNull) {
+    start_info.hStdInput = *nul_handle;
+  }
+
+  start_info.dwFlags |= STARTF_USESTDHANDLES;
+
+  // Create the child process.
+  bool success =
+      ::CreateProcessA(nullptr,      // App name. Needs to be null to use PATH.
+                       &cmd[0],      // Command line.
+                       nullptr,      // Process security attributes.
+                       nullptr,      // Primary thread security attributes.
+                       true,         // Handles are inherited.
+                       0,            // Flags.
+                       nullptr,      // Use parent's environment.
+                       nullptr,      // Use parent's current directory.
+                       &start_info,  // STARTUPINFO pointer.
+                       &proc_info);  // Receives PROCESS_INFORMATION.
+
+  // Close on our side the pipe ends that we passed to the child process.
+  s_->stdin_pipe.rd.reset();
+  s_->stdouterr_pipe.wr.reset();
+  args.out_fd.reset();
+
+  if (!success) {
+    s_->returncode = ERROR_FILE_NOT_FOUND;
+    s_->status = kTerminated;
+    s_->stdin_pipe.wr.reset();
+    s_->stdouterr_pipe.rd.reset();
+    PERFETTO_ELOG("CreateProcess failed: %lx, cmd: %s", GetLastError(),
+                  &cmd[0]);
+    return;
+  }
+
+  s_->pid = proc_info.dwProcessId;
+  s_->win_proc_handle = ScopedPlatformHandle(proc_info.hProcess);
+  s_->win_thread_handle = ScopedPlatformHandle(proc_info.hThread);
+  s_->status = kRunning;
+
+  MovableState* s = s_.get();
+  if (args.stdin_mode == InputMode::kBuffer) {
+    s_->stdin_thread = std::thread(&Subprocess::StdinThread, s, args.input);
+  }
+
+  if (args.stderr_mode == OutputMode::kBuffer ||
+      args.stdout_mode == OutputMode::kBuffer) {
+    PERFETTO_DCHECK(s_->stdouterr_pipe.rd);
+    s_->stdouterr_thread = std::thread(&Subprocess::StdoutErrThread, s);
+  }
+}
+
+// static
+void Subprocess::StdinThread(MovableState* s, std::string input) {
+  size_t input_written = 0;
+  while (input_written < input.size()) {
+    DWORD wsize = 0;
+    if (::WriteFile(*s->stdin_pipe.wr, input.data() + input_written,
+                    static_cast<DWORD>(input.size() - input_written), &wsize,
+                    nullptr)) {
+      input_written += wsize;
+    } else {
+      // ERROR_BROKEN_PIPE is WAI when the child just closes stdin and stops
+      // accepting input.
+      auto err = ::GetLastError();
+      if (err != ERROR_BROKEN_PIPE)
+        PERFETTO_PLOG("Subprocess WriteFile(stdin) failed %lx", err);
+      break;
+    }
+  }  // while(...)
+  std::unique_lock<std::mutex> lock(s->mutex);
+  s->stdin_pipe.wr.reset();
+}
+
+// static
+void Subprocess::StdoutErrThread(MovableState* s) {
+  char buf[4096];
+  for (;;) {
+    DWORD rsize = 0;
+    bool res =
+        ::ReadFile(*s->stdouterr_pipe.rd, buf, sizeof(buf), &rsize, nullptr);
+    if (!res) {
+      auto err = GetLastError();
+      if (err != ERROR_BROKEN_PIPE)
+        PERFETTO_PLOG("Subprocess ReadFile(stdouterr) failed %ld", err);
+    }
+
+    if (rsize > 0) {
+      std::unique_lock<std::mutex> lock(s->mutex);
+      s->locked_outerr_buf.append(buf, static_cast<size_t>(rsize));
+    } else {  // EOF or some error.
+      break;
+    }
+  }  // For(..)
+
+  // Close the stdouterr_pipe. The main loop looks at the pipe closure to
+  // determine whether the stdout/err thread has completed.
+  {
+    std::unique_lock<std::mutex> lock(s->mutex);
+    s->stdouterr_pipe.rd.reset();
+  }
+  s->stdouterr_done_event.Notify();
+}
+
+Subprocess::Status Subprocess::Poll() {
+  if (s_->status != kRunning)
+    return s_->status;  // Nothing to poll.
+  Wait(1 /*ms*/);
+  return s_->status;
+}
+
+bool Subprocess::Wait(int timeout_ms) {
+  PERFETTO_CHECK(s_->status != kNotStarted);
+  const bool wait_forever = timeout_ms == 0;
+  const int64_t wait_start_ms = base::GetWallTimeMs().count();
+
+  // Break out of the loop only after both conditions are satisfied:
+  // - All stdout/stderr data has been read (if OutputMode::kBuffer).
+  // - The process exited.
+  // Note that the two events can happen arbitrary order. After the process
+  // exits, there might be still data in the pipe buffer, which we want to
+  // read fully.
+  // Note also that stdout/err might be "complete" before starting, if neither
+  // is operating in OutputMode::kBuffer mode. In that case we just want to wait
+  // for the process termination.
+  //
+  // Instead, don't wait on the stdin to be fully written. The child process
+  // might exit prematurely (or crash). If that happens, we can end up in a
+  // state where the write(stdin_pipe_.wr) will never unblock.
+  bool stdouterr_complete = false;
+  for (;;) {
+    HANDLE wait_handles[2]{};
+    DWORD num_handles = 0;
+
+    // Check if the process exited.
+    bool process_exited = !s_->win_proc_handle;
+    if (!process_exited) {
+      DWORD exit_code = STILL_ACTIVE;
+      PERFETTO_CHECK(::GetExitCodeProcess(*s_->win_proc_handle, &exit_code));
+      if (exit_code != STILL_ACTIVE) {
+        s_->returncode = static_cast<int>(exit_code);
+        s_->status = kTerminated;
+        s_->win_proc_handle.reset();
+        s_->win_thread_handle.reset();
+        process_exited = true;
+      }
+    } else {
+      PERFETTO_DCHECK(s_->status != kRunning);
+    }
+    if (!process_exited) {
+      wait_handles[num_handles++] = *s_->win_proc_handle;
+    }
+
+    // Check if there is more output and if the stdout/err pipe has been closed.
+    {
+      std::unique_lock<std::mutex> lock(s_->mutex);
+      // Move the output from the internal buffer shared with the
+      // stdouterr_thread to the final buffer exposed to the client.
+      if (!s_->locked_outerr_buf.empty()) {
+        s_->output.append(std::move(s_->locked_outerr_buf));
+        s_->locked_outerr_buf.clear();
+      }
+      stdouterr_complete = !s_->stdouterr_pipe.rd;
+      if (!stdouterr_complete) {
+        wait_handles[num_handles++] = s_->stdouterr_done_event.fd();
+      }
+    }  // lock(s_->mutex)
+
+    if (num_handles == 0) {
+      PERFETTO_DCHECK(process_exited && stdouterr_complete);
+      break;
+    }
+
+    DWORD wait_ms;  // Note: DWORD is unsigned.
+    if (wait_forever) {
+      wait_ms = INFINITE;
+    } else {
+      const int64_t now = GetWallTimeMs().count();
+      const int64_t wait_left_ms = timeout_ms - (now - wait_start_ms);
+      if (wait_left_ms <= 0)
+        return false;  // Timed out
+      wait_ms = static_cast<DWORD>(wait_left_ms);
+    }
+
+    auto wait_res =
+        ::WaitForMultipleObjects(num_handles, wait_handles, false, wait_ms);
+    PERFETTO_CHECK(wait_res != WAIT_FAILED);
+  }
+
+  PERFETTO_DCHECK(!s_->win_proc_handle);
+  PERFETTO_DCHECK(!s_->win_thread_handle);
+
+  if (s_->stdin_thread.joinable())  // Might not exist if CreateProcess failed.
+    s_->stdin_thread.join();
+  if (s_->stdouterr_thread.joinable())
+    s_->stdouterr_thread.join();
+
+  // The stdin pipe is closed by the dedicated stdin thread. However if that is
+  // not started (e.g. because of no redirection) force close it now. Needs to
+  // happen after the join() to be thread safe.
+  s_->stdin_pipe.wr.reset();
+  s_->stdouterr_pipe.rd.reset();
+
+  return true;
+}
+
+void Subprocess::KillAndWaitForTermination(int exit_code) {
+  auto code = exit_code ? static_cast<DWORD>(exit_code) : STATUS_CONTROL_C_EXIT;
+  ::TerminateProcess(*s_->win_proc_handle, code);
+  Wait();
+  // TryReadExitStatus must have joined the threads.
+  PERFETTO_DCHECK(!s_->stdin_thread.joinable());
+  PERFETTO_DCHECK(!s_->stdouterr_thread.joinable());
+}
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // PERFETTO_OS_WIN
+// gen_amalgamated begin source: src/protozero/field.cc
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+
+#if !PERFETTO_IS_LITTLE_ENDIAN()
+// The memcpy() for fixed32/64 below needs to be adjusted if we want to
+// support big endian CPUs. There doesn't seem to be a compelling need today.
+#error Unimplemented for big endian archs.
+#endif
+
+namespace protozero {
+
+template <typename Container>
+void Field::SerializeAndAppendToInternal(Container* dst) const {
+  namespace pu = proto_utils;
+  size_t initial_size = dst->size();
+  dst->resize(initial_size + pu::kMaxSimpleFieldEncodedSize + size_);
+  uint8_t* start = reinterpret_cast<uint8_t*>(&(*dst)[initial_size]);
+  uint8_t* wptr = start;
+  switch (type_) {
+    case static_cast<int>(pu::ProtoWireType::kVarInt): {
+      wptr = pu::WriteVarInt(pu::MakeTagVarInt(id_), wptr);
+      wptr = pu::WriteVarInt(int_value_, wptr);
+      break;
+    }
+    case static_cast<int>(pu::ProtoWireType::kFixed32): {
+      wptr = pu::WriteVarInt(pu::MakeTagFixed<uint32_t>(id_), wptr);
+      uint32_t value32 = static_cast<uint32_t>(int_value_);
+      memcpy(wptr, &value32, sizeof(value32));
+      wptr += sizeof(uint32_t);
+      break;
+    }
+    case static_cast<int>(pu::ProtoWireType::kFixed64): {
+      wptr = pu::WriteVarInt(pu::MakeTagFixed<uint64_t>(id_), wptr);
+      memcpy(wptr, &int_value_, sizeof(int_value_));
+      wptr += sizeof(uint64_t);
+      break;
+    }
+    case static_cast<int>(pu::ProtoWireType::kLengthDelimited): {
+      ConstBytes payload = as_bytes();
+      wptr = pu::WriteVarInt(pu::MakeTagLengthDelimited(id_), wptr);
+      wptr = pu::WriteVarInt(payload.size, wptr);
+      memcpy(wptr, payload.data, payload.size);
+      wptr += payload.size;
+      break;
+    }
+    default:
+      PERFETTO_FATAL("Unknown field type %u", type_);
+  }
+  size_t written_size = static_cast<size_t>(wptr - start);
+  PERFETTO_DCHECK(written_size > 0 && written_size < pu::kMaxMessageLength);
+  PERFETTO_DCHECK(initial_size + written_size <= dst->size());
+  dst->resize(initial_size + written_size);
+}
+
+void Field::SerializeAndAppendTo(std::string* dst) const {
+  SerializeAndAppendToInternal(dst);
+}
+
+void Field::SerializeAndAppendTo(std::vector<uint8_t>* dst) const {
+  SerializeAndAppendToInternal(dst);
+}
+
+}  // namespace protozero
+// gen_amalgamated begin source: src/protozero/gen_field_helpers.cc
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+
+namespace protozero {
+namespace internal {
+namespace gen_helpers {
+
+void DeserializeString(const protozero::Field& field, std::string* dst) {
+  field.get(dst);
+}
+
+template bool DeserializePackedRepeated<proto_utils::ProtoWireType::kVarInt,
+                                        uint64_t>(const protozero::Field& field,
+                                                  std::vector<uint64_t>* dst);
+
+template bool DeserializePackedRepeated<proto_utils::ProtoWireType::kVarInt,
+                                        int64_t>(const protozero::Field& field,
+                                                 std::vector<int64_t>* dst);
+
+template bool DeserializePackedRepeated<proto_utils::ProtoWireType::kVarInt,
+                                        uint32_t>(const protozero::Field& field,
+                                                  std::vector<uint32_t>* dst);
+
+template bool DeserializePackedRepeated<proto_utils::ProtoWireType::kVarInt,
+                                        int32_t>(const protozero::Field& field,
+                                                 std::vector<int32_t>* dst);
+
+void SerializeTinyVarInt(uint32_t field_id, bool value, Message* msg) {
+  msg->AppendTinyVarInt(field_id, value);
+}
+
+template void SerializeExtendedVarInt<uint64_t>(uint32_t field_id,
+                                                uint64_t value,
+                                                Message* msg);
+
+template void SerializeExtendedVarInt<uint32_t>(uint32_t field_id,
+                                                uint32_t value,
+                                                Message* msg);
+
+template void SerializeFixed<double>(uint32_t field_id,
+                                     double value,
+                                     Message* msg);
+
+template void SerializeFixed<float>(uint32_t field_id,
+                                    float value,
+                                    Message* msg);
+
+template void SerializeFixed<uint64_t>(uint32_t field_id,
+                                       uint64_t value,
+                                       Message* msg);
+
+template void SerializeFixed<int64_t>(uint32_t field_id,
+                                      int64_t value,
+                                      Message* msg);
+
+template void SerializeFixed<uint32_t>(uint32_t field_id,
+                                       uint32_t value,
+                                       Message* msg);
+
+template void SerializeFixed<int32_t>(uint32_t field_id,
+                                      int32_t value,
+                                      Message* msg);
+
+void SerializeString(uint32_t field_id,
+                     const std::string& value,
+                     Message* msg) {
+  msg->AppendString(field_id, value);
+}
+
+void SerializeUnknownFields(const std::string& unknown_fields, Message* msg) {
+  msg->AppendRawProtoBytes(unknown_fields.data(), unknown_fields.size());
+}
+
+MessageSerializer::MessageSerializer() = default;
+
+MessageSerializer::~MessageSerializer() = default;
+
+std::vector<uint8_t> MessageSerializer::SerializeAsArray() {
+  return msg_.SerializeAsArray();
+}
+
+std::string MessageSerializer::SerializeAsString() {
+  return msg_.SerializeAsString();
+}
+
+template bool EqualsField<std::string>(const std::string&, const std::string&);
+
+}  // namespace gen_helpers
+}  // namespace internal
+}  // namespace protozero
+// gen_amalgamated begin source: src/protozero/message.cc
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+
+#include <atomic>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message_arena.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
+
+#if !PERFETTO_IS_LITTLE_ENDIAN()
+// The memcpy() for float and double below needs to be adjusted if we want to
+// support big endian CPUs. There doesn't seem to be a compelling need today.
+#error Unimplemented for big endian archs.
+#endif
+
+namespace protozero {
+
+namespace {
+
+constexpr int kBytesToCompact = proto_utils::kMessageLengthFieldSize - 1u;
+
+#if PERFETTO_DCHECK_IS_ON()
+std::atomic<uint32_t> g_generation;
+#endif
+
+}  // namespace
+
+// Do NOT put any code in the constructor or use default initialization.
+// Use the Reset() method below instead.
+
+// This method is called to initialize both root and nested messages.
+void Message::Reset(ScatteredStreamWriter* stream_writer, MessageArena* arena) {
+// Older versions of libstdcxx don't have is_trivially_constructible.
+#if !defined(__GLIBCXX__) || __GLIBCXX__ >= 20170516
+  static_assert(std::is_trivially_constructible<Message>::value,
+                "Message must be trivially constructible");
+#endif
+
+  static_assert(std::is_trivially_destructible<Message>::value,
+                "Message must be trivially destructible");
+  stream_writer_ = stream_writer;
+  arena_ = arena;
+  size_ = 0;
+  size_field_ = nullptr;
+  nested_message_ = nullptr;
+  message_state_ = MessageState::kNotFinalized;
+#if PERFETTO_DCHECK_IS_ON()
+  handle_ = nullptr;
+  generation_ = g_generation.fetch_add(1, std::memory_order_relaxed);
+#endif
+}
+
+void Message::AppendString(uint32_t field_id, const char* str) {
+  AppendBytes(field_id, str, strlen(str));
+}
+
+void Message::AppendBytes(uint32_t field_id, const void* src, size_t size) {
+  PERFETTO_DCHECK(field_id);
+  if (nested_message_)
+    EndNestedMessage();
+
+  PERFETTO_DCHECK(size < proto_utils::kMaxMessageLength);
+  // Write the proto preamble (field id, type and length of the field).
+  uint8_t buffer[proto_utils::kMaxSimpleFieldEncodedSize];
+  uint8_t* pos = buffer;
+  pos = proto_utils::WriteVarInt(proto_utils::MakeTagLengthDelimited(field_id),
+                                 pos);
+  pos = proto_utils::WriteVarInt(static_cast<uint32_t>(size), pos);
+  WriteToStream(buffer, pos);
+
+  const uint8_t* src_u8 = reinterpret_cast<const uint8_t*>(src);
+  WriteToStream(src_u8, src_u8 + size);
+}
+
+size_t Message::AppendScatteredBytes(uint32_t field_id,
+                                     ContiguousMemoryRange* ranges,
+                                     size_t num_ranges) {
+  PERFETTO_DCHECK(field_id);
+  if (nested_message_)
+    EndNestedMessage();
+
+  size_t size = 0;
+  for (size_t i = 0; i < num_ranges; ++i) {
+    size += ranges[i].size();
+  }
+
+  PERFETTO_DCHECK(size < proto_utils::kMaxMessageLength);
+
+  uint8_t buffer[proto_utils::kMaxSimpleFieldEncodedSize];
+  uint8_t* pos = buffer;
+  pos = proto_utils::WriteVarInt(proto_utils::MakeTagLengthDelimited(field_id),
+                                 pos);
+  pos = proto_utils::WriteVarInt(static_cast<uint32_t>(size), pos);
+  WriteToStream(buffer, pos);
+
+  for (size_t i = 0; i < num_ranges; ++i) {
+    auto& range = ranges[i];
+    WriteToStream(range.begin, range.end);
+  }
+
+  return size;
+}
+
+uint32_t Message::Finalize() {
+  if (is_finalized())
+    return size_;
+
+  if (nested_message_)
+    EndNestedMessage();
+
+  // Write the length of the nested message a posteriori, using a leading-zero
+  // redundant varint encoding. This can be nullptr for the root message, among
+  // many reasons, because the TraceWriterImpl delegate is keeping track of the
+  // root fragment size independently.
+  if (size_field_) {
+    PERFETTO_DCHECK(!is_finalized());
+    PERFETTO_DCHECK(size_ < proto_utils::kMaxMessageLength);
+    //
+    // Normally the size of a protozero message is written with 4 bytes just
+    // before the contents of the message itself:
+    //
+    //    size          message data
+    //   [aa bb cc dd] [01 23 45 67 ...]
+    //
+    // We always reserve 4 bytes for the size, because the real size of the
+    // message isn't known until the call to Finalize(). This is possible
+    // because we can use leading zero redundant varint coding to expand any
+    // size smaller than 256 MiB to 4 bytes.
+    //
+    // However this is wasteful for short, frequently written messages, so the
+    // code below uses a 1 byte size field when possible. This is done by
+    // shifting the already-written data (which should still be in the cache)
+    // back by 3 bytes, resulting in this layout:
+    //
+    //   size  message data
+    //   [aa] [01 23 45 67 ...]
+    //
+    // We can only do this optimization if the message is contained in a single
+    // chunk (since we can't modify previously committed chunks). We can check
+    // this by verifying that the size field is immediately before the message
+    // in memory and is fully contained by the current chunk.
+    //
+    if (PERFETTO_LIKELY(size_ <= proto_utils::kMaxOneByteMessageLength &&
+                        size_field_ ==
+                            stream_writer_->write_ptr() - size_ -
+                                proto_utils::kMessageLengthFieldSize &&
+                        size_field_ >= stream_writer_->cur_range().begin)) {
+      stream_writer_->Rewind(size_, kBytesToCompact);
+      PERFETTO_DCHECK(size_field_ == stream_writer_->write_ptr() - size_ - 1u);
+      *size_field_ = static_cast<uint8_t>(size_);
+      message_state_ = MessageState::kFinalizedWithCompaction;
+    } else {
+      proto_utils::WriteRedundantVarInt(size_, size_field_);
+      message_state_ = MessageState::kFinalized;
+    }
+    size_field_ = nullptr;
+  } else {
+    message_state_ = MessageState::kFinalized;
+  }
+
+#if PERFETTO_DCHECK_IS_ON()
+  if (handle_)
+    handle_->reset_message();
+#endif
+
+  return size_;
+}
+
+Message* Message::BeginNestedMessageInternal(uint32_t field_id) {
+  PERFETTO_DCHECK(field_id);
+  if (nested_message_)
+    EndNestedMessage();
+
+  // Write the proto preamble for the nested message.
+  uint8_t data[proto_utils::kMaxTagEncodedSize];
+  uint8_t* data_end = proto_utils::WriteVarInt(
+      proto_utils::MakeTagLengthDelimited(field_id), data);
+  WriteToStream(data, data_end);
+
+  Message* message = arena_->NewMessage();
+  message->Reset(stream_writer_, arena_);
+
+  // The length of the nested message cannot be known upfront. So right now
+  // just reserve the bytes to encode the size after the nested message is done.
+  message->set_size_field(
+      stream_writer_->ReserveBytes(proto_utils::kMessageLengthFieldSize));
+  size_ += proto_utils::kMessageLengthFieldSize;
+
+  nested_message_ = message;
+  return message;
+}
+
+void Message::EndNestedMessage() {
+  size_ += nested_message_->Finalize();
+  if (nested_message_->message_state_ ==
+      MessageState::kFinalizedWithCompaction) {
+    size_ -= kBytesToCompact;
+  }
+  arena_->DeleteLastMessage(nested_message_);
+  nested_message_ = nullptr;
+}
+
+}  // namespace protozero
+// gen_amalgamated begin source: src/protozero/message_arena.cc
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/protozero/message_arena.h"
+
+#include <atomic>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
+
+namespace protozero {
+
+MessageArena::MessageArena() {
+  // The code below assumes that there is always at least one block.
+  blocks_.emplace_front();
+  static_assert(
+      std::alignment_of<decltype(blocks_.front().storage[0])>::value >=
+          alignof(Message),
+      "MessageArea's storage is not properly aligned");
+}
+
+MessageArena::~MessageArena() = default;
+
+Message* MessageArena::NewMessage() {
+  PERFETTO_DCHECK(!blocks_.empty());  // Should never become empty.
+
+  Block* block = &blocks_.front();
+  if (PERFETTO_UNLIKELY(block->entries >= Block::kCapacity)) {
+    blocks_.emplace_front();
+    block = &blocks_.front();
+  }
+  const auto idx = block->entries++;
+  void* storage = &block->storage[idx];
+  PERFETTO_ASAN_UNPOISON(storage, sizeof(Message));
+  return new (storage) Message();
+}
+
+void MessageArena::DeleteLastMessageInternal() {
+  PERFETTO_DCHECK(!blocks_.empty());  // Should never be empty, see below.
+  Block* block = &blocks_.front();
+  PERFETTO_DCHECK(block->entries > 0);
+
+  // This is the reason why there is no ~Message() call here.
+  // MessageArea::Reset() (see header) also relies on dtor being trivial.
+  static_assert(std::is_trivially_destructible<Message>::value,
+                "Message must be trivially destructible");
+
+  --block->entries;
+  PERFETTO_ASAN_POISON(&block->storage[block->entries], sizeof(Message));
+
+  // Don't remove the first block to avoid malloc/free calls when the root
+  // message is reset. Hitting the allocator all the times is a waste of time.
+  if (block->entries == 0 && std::next(blocks_.cbegin()) != blocks_.cend()) {
+    blocks_.pop_front();
+  }
+}
+
+}  // namespace protozero
+// gen_amalgamated begin source: src/protozero/packed_repeated_fields.cc
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+
+namespace protozero {
+
+void PackedBufferBase::GrowSlowpath() {
+  size_t write_off = static_cast<size_t>(write_ptr_ - storage_begin_);
+  size_t old_size = static_cast<size_t>(storage_end_ - storage_begin_);
+  size_t new_size = old_size < 65536 ? (old_size * 2) : (old_size * 3 / 2);
+  new_size = perfetto::base::AlignUp<4096>(new_size);
+  std::unique_ptr<uint8_t[]> new_buf(new uint8_t[new_size]);
+  memcpy(new_buf.get(), storage_begin_, old_size);
+  heap_buf_ = std::move(new_buf);
+  storage_begin_ = heap_buf_.get();
+  storage_end_ = storage_begin_ + new_size;
+  write_ptr_ = storage_begin_ + write_off;
+}
+
+void PackedBufferBase::Reset() {
+  heap_buf_.reset();
+  storage_begin_ = reinterpret_cast<uint8_t*>(&stack_buf_[0]);
+  storage_end_ = reinterpret_cast<uint8_t*>(&stack_buf_[kOnStackStorageSize]);
+  write_ptr_ = storage_begin_;
+}
+
+}  // namespace protozero
+// gen_amalgamated begin source: src/protozero/proto_decoder.cc
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+
+#include <string.h>
+
+#include <cinttypes>
+#include <limits>
+#include <memory>
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace protozero {
+
+using namespace proto_utils;
+
+#if !PERFETTO_IS_LITTLE_ENDIAN()
+#error Unimplemented for big endian archs.
+#endif
+
+namespace {
+
+struct ParseFieldResult {
+  enum ParseResult { kAbort, kSkip, kOk };
+  ParseResult parse_res;
+  const uint8_t* next;
+  Field field;
+};
+
+// Parses one field and returns the field itself and a pointer to the next
+// field to parse. If parsing fails, the returned |next| == |buffer|.
+ParseFieldResult ParseOneField(const uint8_t* const buffer,
+                               const uint8_t* const end) {
+  ParseFieldResult res{ParseFieldResult::kAbort, buffer, Field{}};
+
+  // The first byte of a proto field is structured as follows:
+  // The least 3 significant bits determine the field type.
+  // The most 5 significant bits determine the field id. If MSB == 1, the
+  // field id continues on the next bytes following the VarInt encoding.
+  const uint8_t kFieldTypeNumBits = 3;
+  const uint64_t kFieldTypeMask = (1 << kFieldTypeNumBits) - 1;  // 0000 0111;
+  const uint8_t* pos = buffer;
+
+  // If we've already hit the end, just return an invalid field.
+  if (PERFETTO_UNLIKELY(pos >= end))
+    return res;
+
+  uint64_t preamble = 0;
+  if (PERFETTO_LIKELY(*pos < 0x80)) {  // Fastpath for fields with ID < 16.
+    preamble = *(pos++);
+  } else {
+    const uint8_t* next = ParseVarInt(pos, end, &preamble);
+    if (PERFETTO_UNLIKELY(pos == next))
+      return res;
+    pos = next;
+  }
+
+  uint32_t field_id = static_cast<uint32_t>(preamble >> kFieldTypeNumBits);
+  if (field_id == 0 || pos >= end)
+    return res;
+
+  auto field_type = static_cast<uint8_t>(preamble & kFieldTypeMask);
+  const uint8_t* new_pos = pos;
+  uint64_t int_value = 0;
+  uint64_t size = 0;
+
+  switch (field_type) {
+    case static_cast<uint8_t>(ProtoWireType::kVarInt): {
+      new_pos = ParseVarInt(pos, end, &int_value);
+
+      // new_pos not being greater than pos means ParseVarInt could not fully
+      // parse the number. This is because we are out of space in the buffer.
+      // Set the id to zero and return but don't update the offset so a future
+      // read can read this field.
+      if (PERFETTO_UNLIKELY(new_pos == pos))
+        return res;
+
+      break;
+    }
+
+    case static_cast<uint8_t>(ProtoWireType::kLengthDelimited): {
+      uint64_t payload_length;
+      new_pos = ParseVarInt(pos, end, &payload_length);
+      if (PERFETTO_UNLIKELY(new_pos == pos))
+        return res;
+
+      // ParseVarInt guarantees that |new_pos| <= |end| when it succeeds;
+      if (payload_length > static_cast<uint64_t>(end - new_pos))
+        return res;
+
+      const uintptr_t payload_start = reinterpret_cast<uintptr_t>(new_pos);
+      int_value = payload_start;
+      size = payload_length;
+      new_pos += payload_length;
+      break;
+    }
+
+    case static_cast<uint8_t>(ProtoWireType::kFixed64): {
+      new_pos = pos + sizeof(uint64_t);
+      if (PERFETTO_UNLIKELY(new_pos > end))
+        return res;
+      memcpy(&int_value, pos, sizeof(uint64_t));
+      break;
+    }
+
+    case static_cast<uint8_t>(ProtoWireType::kFixed32): {
+      new_pos = pos + sizeof(uint32_t);
+      if (PERFETTO_UNLIKELY(new_pos > end))
+        return res;
+      memcpy(&int_value, pos, sizeof(uint32_t));
+      break;
+    }
+
+    default:
+      PERFETTO_DLOG("Invalid proto field type: %u", field_type);
+      return res;
+  }
+
+  res.next = new_pos;
+
+  if (PERFETTO_UNLIKELY(field_id > Field::kMaxId)) {
+    PERFETTO_DLOG("Skipping field %" PRIu32 " because its id > %" PRIu32,
+                  field_id, Field::kMaxId);
+    res.parse_res = ParseFieldResult::kSkip;
+    return res;
+  }
+
+  if (PERFETTO_UNLIKELY(size > proto_utils::kMaxMessageLength)) {
+    PERFETTO_DLOG("Skipping field %" PRIu32 " because it's too big (%" PRIu64
+                  " KB)",
+                  field_id, size / 1024);
+    res.parse_res = ParseFieldResult::kSkip;
+    return res;
+  }
+
+  res.parse_res = ParseFieldResult::kOk;
+  res.field.initialize(field_id, field_type, int_value,
+                       static_cast<uint32_t>(size));
+  return res;
+}
+
+}  // namespace
+
+Field ProtoDecoder::FindField(uint32_t field_id) {
+  Field res{};
+  auto old_position = read_ptr_;
+  read_ptr_ = begin_;
+  for (auto f = ReadField(); f.valid(); f = ReadField()) {
+    if (f.id() == field_id) {
+      res = f;
+      break;
+    }
+  }
+  read_ptr_ = old_position;
+  return res;
+}
+
+Field ProtoDecoder::ReadField() {
+  ParseFieldResult res;
+  do {
+    res = ParseOneField(read_ptr_, end_);
+    read_ptr_ = res.next;
+  } while (PERFETTO_UNLIKELY(res.parse_res == ParseFieldResult::kSkip));
+  return res.field;
+}
+
+void TypedProtoDecoderBase::ParseAllFields() {
+  const uint8_t* cur = begin_;
+  ParseFieldResult res;
+  for (;;) {
+    res = ParseOneField(cur, end_);
+    PERFETTO_DCHECK(res.parse_res != ParseFieldResult::kOk || res.next != cur);
+    cur = res.next;
+    if (PERFETTO_UNLIKELY(res.parse_res == ParseFieldResult::kSkip))
+      continue;
+    if (PERFETTO_UNLIKELY(res.parse_res == ParseFieldResult::kAbort))
+      break;
+
+    PERFETTO_DCHECK(res.parse_res == ParseFieldResult::kOk);
+    PERFETTO_DCHECK(res.field.valid());
+    auto field_id = res.field.id();
+    if (PERFETTO_UNLIKELY(field_id >= num_fields_))
+      continue;
+
+    // There are two reasons why we might want to expand the heap capacity:
+    // 1. We are writing a non-repeated field, which has an id >
+    //    INITIAL_STACK_CAPACITY. In this case ExpandHeapStorage() ensures to
+    //    allocate at least (num_fields_ + 1) slots.
+    // 2. We are writing a repeated field but ran out of capacity.
+    if (PERFETTO_UNLIKELY(field_id >= size_ || size_ >= capacity_))
+      ExpandHeapStorage();
+
+    PERFETTO_DCHECK(field_id < size_);
+    Field* fld = &fields_[field_id];
+    if (PERFETTO_LIKELY(!fld->valid())) {
+      // This is the first time we see this field.
+      *fld = std::move(res.field);
+    } else {
+      // Repeated field case.
+      // In this case we need to:
+      // 1. Append the last value of the field to end of the repeated field
+      //    storage.
+      // 2. Replace the default instance at offset |field_id| with the current
+      //    value. This is because in case of repeated field a call to Get(X) is
+      //    supposed to return the last value of X, not the first one.
+      // This is so that the RepeatedFieldIterator will iterate in the right
+      // order, see comments on RepeatedFieldIterator.
+      if (num_fields_ > size_) {
+        ExpandHeapStorage();
+        fld = &fields_[field_id];
+      }
+
+      PERFETTO_DCHECK(size_ < capacity_);
+      fields_[size_++] = *fld;
+      *fld = std::move(res.field);
+    }
+  }
+  read_ptr_ = res.next;
+}
+
+void TypedProtoDecoderBase::ExpandHeapStorage() {
+  // When we expand the heap we must ensure that we have at very last capacity
+  // to deal with all known fields plus at least one repeated field. We go +2048
+  // here based on observations on a large 4GB android trace. This is to avoid
+  // trivial re-allocations when dealing with repeated fields of a message that
+  // has > INITIAL_STACK_CAPACITY fields.
+  const uint32_t min_capacity = num_fields_ + 2048;  // Any num >= +1 will do.
+  const uint32_t new_capacity = std::max(capacity_ * 2, min_capacity);
+  PERFETTO_CHECK(new_capacity > size_ && new_capacity > num_fields_);
+  std::unique_ptr<Field[]> new_storage(new Field[new_capacity]);
+
+  static_assert(std::is_trivially_constructible<Field>::value,
+                "Field must be trivially constructible");
+  static_assert(std::is_trivially_copyable<Field>::value,
+                "Field must be trivially copyable");
+
+  // Zero-initialize the slots for known field IDs slots, as they can be
+  // randomly accessed. Instead, there is no need to initialize the repeated
+  // slots, because they are written linearly with no gaps and are always
+  // initialized before incrementing |size_|.
+  const uint32_t new_size = std::max(size_, num_fields_);
+  memset(&new_storage[size_], 0, sizeof(Field) * (new_size - size_));
+
+  memcpy(&new_storage[0], fields_, sizeof(Field) * size_);
+
+  heap_storage_ = std::move(new_storage);
+  fields_ = &heap_storage_[0];
+  capacity_ = new_capacity;
+  size_ = new_size;
+}
+
+}  // namespace protozero
+// gen_amalgamated begin source: src/protozero/scattered_heap_buffer.cc
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+
+#include <algorithm>
+
+namespace protozero {
+
+ScatteredHeapBuffer::Slice::Slice()
+    : buffer_(nullptr), size_(0u), unused_bytes_(0u) {}
+
+ScatteredHeapBuffer::Slice::Slice(size_t size)
+    : buffer_(std::unique_ptr<uint8_t[]>(new uint8_t[size])),
+      size_(size),
+      unused_bytes_(size) {
+  PERFETTO_DCHECK(size);
+  Clear();
+}
+
+ScatteredHeapBuffer::Slice::Slice(Slice&& slice) noexcept = default;
+
+ScatteredHeapBuffer::Slice::~Slice() = default;
+
+ScatteredHeapBuffer::Slice& ScatteredHeapBuffer::Slice::operator=(Slice&&) =
+    default;
+
+void ScatteredHeapBuffer::Slice::Clear() {
+  unused_bytes_ = size_;
+#if PERFETTO_DCHECK_IS_ON()
+  memset(start(), 0xff, size_);
+#endif  // PERFETTO_DCHECK_IS_ON()
+}
+
+ScatteredHeapBuffer::ScatteredHeapBuffer(size_t initial_slice_size_bytes,
+                                         size_t maximum_slice_size_bytes)
+    : next_slice_size_(initial_slice_size_bytes),
+      maximum_slice_size_(maximum_slice_size_bytes) {
+  PERFETTO_DCHECK(next_slice_size_ && maximum_slice_size_);
+  PERFETTO_DCHECK(maximum_slice_size_ >= initial_slice_size_bytes);
+}
+
+ScatteredHeapBuffer::~ScatteredHeapBuffer() = default;
+
+protozero::ContiguousMemoryRange ScatteredHeapBuffer::GetNewBuffer() {
+  PERFETTO_CHECK(writer_);
+  AdjustUsedSizeOfCurrentSlice();
+
+  if (cached_slice_.start()) {
+    slices_.push_back(std::move(cached_slice_));
+    PERFETTO_DCHECK(!cached_slice_.start());
+  } else {
+    slices_.emplace_back(next_slice_size_);
+  }
+  next_slice_size_ = std::min(maximum_slice_size_, next_slice_size_ * 2);
+  return slices_.back().GetTotalRange();
+}
+
+const std::vector<ScatteredHeapBuffer::Slice>&
+ScatteredHeapBuffer::GetSlices() {
+  AdjustUsedSizeOfCurrentSlice();
+  return slices_;
+}
+
+std::vector<uint8_t> ScatteredHeapBuffer::StitchSlices() {
+  size_t stitched_size = 0u;
+  const auto& slices = GetSlices();
+  for (const auto& slice : slices)
+    stitched_size += slice.size() - slice.unused_bytes();
+
+  std::vector<uint8_t> buffer;
+  buffer.reserve(stitched_size);
+  for (const auto& slice : slices) {
+    auto used_range = slice.GetUsedRange();
+    buffer.insert(buffer.end(), used_range.begin, used_range.end);
+  }
+  return buffer;
+}
+
+std::vector<protozero::ContiguousMemoryRange> ScatteredHeapBuffer::GetRanges() {
+  std::vector<protozero::ContiguousMemoryRange> ranges;
+  for (const auto& slice : GetSlices())
+    ranges.push_back(slice.GetUsedRange());
+  return ranges;
+}
+
+void ScatteredHeapBuffer::AdjustUsedSizeOfCurrentSlice() {
+  if (!slices_.empty())
+    slices_.back().set_unused_bytes(writer_->bytes_available());
+}
+
+size_t ScatteredHeapBuffer::GetTotalSize() {
+  size_t total_size = 0;
+  for (auto& slice : slices_) {
+    total_size += slice.size();
+  }
+  return total_size;
+}
+
+void ScatteredHeapBuffer::Reset() {
+  if (slices_.empty())
+    return;
+  cached_slice_ = std::move(slices_.front());
+  cached_slice_.Clear();
+  slices_.clear();
+}
+
+}  // namespace protozero
+// gen_amalgamated begin source: src/protozero/scattered_stream_null_delegate.cc
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_null_delegate.h"
+
+namespace protozero {
+
+// An implementation of ScatteredStreamWriter::Delegate which always returns
+// the same piece of memory.
+// This is used when we need to no-op the writers (e.g. during teardown or in
+// case of resource exhaustion), avoiding that the clients have to deal with
+// nullptr checks.
+ScatteredStreamWriterNullDelegate::ScatteredStreamWriterNullDelegate(
+    size_t chunk_size)
+    : chunk_size_(chunk_size),
+      chunk_(std::unique_ptr<uint8_t[]>(new uint8_t[chunk_size_])) {}
+
+ScatteredStreamWriterNullDelegate::~ScatteredStreamWriterNullDelegate() {}
+
+ContiguousMemoryRange ScatteredStreamWriterNullDelegate::GetNewBuffer() {
+  return {chunk_.get(), chunk_.get() + chunk_size_};
+}
+
+}  // namespace protozero
+// gen_amalgamated begin source: src/protozero/scattered_stream_writer.cc
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
+
+#include <algorithm>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+
+namespace protozero {
+
+ScatteredStreamWriter::Delegate::~Delegate() {}
+
+uint8_t* ScatteredStreamWriter::Delegate::AnnotatePatch(uint8_t* patch_addr) {
+  // In most cases, a patch is transparent. The caller can write directly into
+  // `to_patch`, because its memory is not going away. TraceWriterImpl, however,
+  // requires a more complicated logic, because the chunks might be copied
+  // earlier.
+  return patch_addr;
+}
+
+ScatteredStreamWriter::ScatteredStreamWriter(Delegate* delegate)
+    : delegate_(delegate),
+      cur_range_({nullptr, nullptr}),
+      write_ptr_(nullptr) {}
+
+ScatteredStreamWriter::~ScatteredStreamWriter() {}
+
+void ScatteredStreamWriter::Reset(ContiguousMemoryRange range) {
+  written_previously_ += static_cast<uint64_t>(write_ptr_ - cur_range_.begin);
+  cur_range_ = range;
+  write_ptr_ = range.begin;
+  PERFETTO_DCHECK(!write_ptr_ || write_ptr_ < cur_range_.end);
+}
+
+void ScatteredStreamWriter::Extend() {
+  Reset(delegate_->GetNewBuffer());
+}
+
+void ScatteredStreamWriter::WriteBytesSlowPath(const uint8_t* src,
+                                               size_t size) {
+  size_t bytes_left = size;
+  while (bytes_left > 0) {
+    if (write_ptr_ >= cur_range_.end)
+      Extend();
+    const size_t burst_size = std::min(bytes_available(), bytes_left);
+    WriteBytesUnsafe(src, burst_size);
+    bytes_left -= burst_size;
+    src += burst_size;
+  }
+}
+
+// TODO(primiano): perf optimization: I suspect that at the end this will always
+// be called with |size| == 4, in which case we might just hardcode it.
+uint8_t* ScatteredStreamWriter::ReserveBytes(size_t size) {
+  if (write_ptr_ + size > cur_range_.end) {
+    // Assume the reservations are always < Delegate::GetNewBuffer().size(),
+    // so that one single call to Extend() will definitely give enough headroom.
+    Extend();
+    PERFETTO_DCHECK(write_ptr_ + size <= cur_range_.end);
+  }
+  uint8_t* begin = write_ptr_;
+  write_ptr_ += size;
+#if PERFETTO_DCHECK_IS_ON()
+  // In the past, the service had a matching DCHECK in
+  // TraceBuffer::TryPatchChunkContents, which was assuming that service and all
+  // producers are built with matching DCHECK levels. This turned out to be a
+  // source of problems and was removed in b/197340286. This memset is useless
+  // these days and is here only to maintain ABI compatibility between producers
+  // that use a v20+ SDK and older versions of the service that were built in
+  // debug mode. At some point around 2023 it should be safe to remove it.
+  // (running a debug version of traced in production seems a bad idea
+  // regardless).
+  memset(begin, 0, size);
+#endif
+  return begin;
+}
+
+}  // namespace protozero
+// gen_amalgamated begin source: src/protozero/static_buffer.cc
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/protozero/static_buffer.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+
+namespace protozero {
+
+StaticBufferDelegate::~StaticBufferDelegate() = default;
+
+ContiguousMemoryRange StaticBufferDelegate::GetNewBuffer() {
+  if (get_new_buffer_called_once_) {
+    // This is the 2nd time GetNewBuffer is called. The estimate is wrong. We
+    // shouldn't try to grow the buffer after the initial call.
+    PERFETTO_FATAL("Static buffer too small");
+  }
+  get_new_buffer_called_once_ = true;
+  return range_;
+}
+
+}  // namespace protozero
+// gen_amalgamated begin source: src/protozero/virtual_destructors.cc
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
+
+namespace protozero {
+
+CppMessageObj::~CppMessageObj() = default;
+MessageFinalizationListener::~MessageFinalizationListener() = default;
+
+}  // namespace protozero
+// gen_amalgamated begin source: gen/protos/perfetto/common/android_energy_consumer_descriptor.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/common/android_energy_consumer_descriptor.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+AndroidEnergyConsumerDescriptor::AndroidEnergyConsumerDescriptor() = default;
+AndroidEnergyConsumerDescriptor::~AndroidEnergyConsumerDescriptor() = default;
+AndroidEnergyConsumerDescriptor::AndroidEnergyConsumerDescriptor(const AndroidEnergyConsumerDescriptor&) = default;
+AndroidEnergyConsumerDescriptor& AndroidEnergyConsumerDescriptor::operator=(const AndroidEnergyConsumerDescriptor&) = default;
+AndroidEnergyConsumerDescriptor::AndroidEnergyConsumerDescriptor(AndroidEnergyConsumerDescriptor&&) noexcept = default;
+AndroidEnergyConsumerDescriptor& AndroidEnergyConsumerDescriptor::operator=(AndroidEnergyConsumerDescriptor&&) = default;
+
+bool AndroidEnergyConsumerDescriptor::operator==(const AndroidEnergyConsumerDescriptor& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(energy_consumers_, other.energy_consumers_);
+}
+
+int AndroidEnergyConsumerDescriptor::energy_consumers_size() const { return static_cast<int>(energy_consumers_.size()); }
+void AndroidEnergyConsumerDescriptor::clear_energy_consumers() { energy_consumers_.clear(); }
+AndroidEnergyConsumer* AndroidEnergyConsumerDescriptor::add_energy_consumers() { energy_consumers_.emplace_back(); return &energy_consumers_.back(); }
+bool AndroidEnergyConsumerDescriptor::ParseFromArray(const void* raw, size_t size) {
+  energy_consumers_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* energy_consumers */:
+        energy_consumers_.emplace_back();
+        energy_consumers_.back().ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string AndroidEnergyConsumerDescriptor::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> AndroidEnergyConsumerDescriptor::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void AndroidEnergyConsumerDescriptor::Serialize(::protozero::Message* msg) const {
+  // Field 1: energy_consumers
+  for (auto& it : energy_consumers_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+AndroidEnergyConsumer::AndroidEnergyConsumer() = default;
+AndroidEnergyConsumer::~AndroidEnergyConsumer() = default;
+AndroidEnergyConsumer::AndroidEnergyConsumer(const AndroidEnergyConsumer&) = default;
+AndroidEnergyConsumer& AndroidEnergyConsumer::operator=(const AndroidEnergyConsumer&) = default;
+AndroidEnergyConsumer::AndroidEnergyConsumer(AndroidEnergyConsumer&&) noexcept = default;
+AndroidEnergyConsumer& AndroidEnergyConsumer::operator=(AndroidEnergyConsumer&&) = default;
+
+bool AndroidEnergyConsumer::operator==(const AndroidEnergyConsumer& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(energy_consumer_id_, other.energy_consumer_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(ordinal_, other.ordinal_)
+   && ::protozero::internal::gen_helpers::EqualsField(type_, other.type_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_);
+}
+
+bool AndroidEnergyConsumer::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* energy_consumer_id */:
+        field.get(&energy_consumer_id_);
+        break;
+      case 2 /* ordinal */:
+        field.get(&ordinal_);
+        break;
+      case 3 /* type */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &type_);
+        break;
+      case 4 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string AndroidEnergyConsumer::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> AndroidEnergyConsumer::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void AndroidEnergyConsumer::Serialize(::protozero::Message* msg) const {
+  // Field 1: energy_consumer_id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, energy_consumer_id_, msg);
+  }
+
+  // Field 2: ordinal
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, ordinal_, msg);
+  }
+
+  // Field 3: type
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeString(3, type_, msg);
+  }
+
+  // Field 4: name
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeString(4, name_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/common/android_log_constants.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/common/builtin_clock.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/common/commit_data_request.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/common/commit_data_request.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+CommitDataRequest::CommitDataRequest() = default;
+CommitDataRequest::~CommitDataRequest() = default;
+CommitDataRequest::CommitDataRequest(const CommitDataRequest&) = default;
+CommitDataRequest& CommitDataRequest::operator=(const CommitDataRequest&) = default;
+CommitDataRequest::CommitDataRequest(CommitDataRequest&&) noexcept = default;
+CommitDataRequest& CommitDataRequest::operator=(CommitDataRequest&&) = default;
+
+bool CommitDataRequest::operator==(const CommitDataRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(chunks_to_move_, other.chunks_to_move_)
+   && ::protozero::internal::gen_helpers::EqualsField(chunks_to_patch_, other.chunks_to_patch_)
+   && ::protozero::internal::gen_helpers::EqualsField(flush_request_id_, other.flush_request_id_);
+}
+
+int CommitDataRequest::chunks_to_move_size() const { return static_cast<int>(chunks_to_move_.size()); }
+void CommitDataRequest::clear_chunks_to_move() { chunks_to_move_.clear(); }
+CommitDataRequest_ChunksToMove* CommitDataRequest::add_chunks_to_move() { chunks_to_move_.emplace_back(); return &chunks_to_move_.back(); }
+int CommitDataRequest::chunks_to_patch_size() const { return static_cast<int>(chunks_to_patch_.size()); }
+void CommitDataRequest::clear_chunks_to_patch() { chunks_to_patch_.clear(); }
+CommitDataRequest_ChunkToPatch* CommitDataRequest::add_chunks_to_patch() { chunks_to_patch_.emplace_back(); return &chunks_to_patch_.back(); }
+bool CommitDataRequest::ParseFromArray(const void* raw, size_t size) {
+  chunks_to_move_.clear();
+  chunks_to_patch_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* chunks_to_move */:
+        chunks_to_move_.emplace_back();
+        chunks_to_move_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 2 /* chunks_to_patch */:
+        chunks_to_patch_.emplace_back();
+        chunks_to_patch_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 3 /* flush_request_id */:
+        field.get(&flush_request_id_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string CommitDataRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> CommitDataRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void CommitDataRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: chunks_to_move
+  for (auto& it : chunks_to_move_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  // Field 2: chunks_to_patch
+  for (auto& it : chunks_to_patch_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  // Field 3: flush_request_id
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, flush_request_id_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+CommitDataRequest_ChunkToPatch::CommitDataRequest_ChunkToPatch() = default;
+CommitDataRequest_ChunkToPatch::~CommitDataRequest_ChunkToPatch() = default;
+CommitDataRequest_ChunkToPatch::CommitDataRequest_ChunkToPatch(const CommitDataRequest_ChunkToPatch&) = default;
+CommitDataRequest_ChunkToPatch& CommitDataRequest_ChunkToPatch::operator=(const CommitDataRequest_ChunkToPatch&) = default;
+CommitDataRequest_ChunkToPatch::CommitDataRequest_ChunkToPatch(CommitDataRequest_ChunkToPatch&&) noexcept = default;
+CommitDataRequest_ChunkToPatch& CommitDataRequest_ChunkToPatch::operator=(CommitDataRequest_ChunkToPatch&&) = default;
+
+bool CommitDataRequest_ChunkToPatch::operator==(const CommitDataRequest_ChunkToPatch& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(target_buffer_, other.target_buffer_)
+   && ::protozero::internal::gen_helpers::EqualsField(writer_id_, other.writer_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(chunk_id_, other.chunk_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(patches_, other.patches_)
+   && ::protozero::internal::gen_helpers::EqualsField(has_more_patches_, other.has_more_patches_);
+}
+
+int CommitDataRequest_ChunkToPatch::patches_size() const { return static_cast<int>(patches_.size()); }
+void CommitDataRequest_ChunkToPatch::clear_patches() { patches_.clear(); }
+CommitDataRequest_ChunkToPatch_Patch* CommitDataRequest_ChunkToPatch::add_patches() { patches_.emplace_back(); return &patches_.back(); }
+bool CommitDataRequest_ChunkToPatch::ParseFromArray(const void* raw, size_t size) {
+  patches_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* target_buffer */:
+        field.get(&target_buffer_);
+        break;
+      case 2 /* writer_id */:
+        field.get(&writer_id_);
+        break;
+      case 3 /* chunk_id */:
+        field.get(&chunk_id_);
+        break;
+      case 4 /* patches */:
+        patches_.emplace_back();
+        patches_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 5 /* has_more_patches */:
+        field.get(&has_more_patches_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string CommitDataRequest_ChunkToPatch::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> CommitDataRequest_ChunkToPatch::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void CommitDataRequest_ChunkToPatch::Serialize(::protozero::Message* msg) const {
+  // Field 1: target_buffer
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, target_buffer_, msg);
+  }
+
+  // Field 2: writer_id
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, writer_id_, msg);
+  }
+
+  // Field 3: chunk_id
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, chunk_id_, msg);
+  }
+
+  // Field 4: patches
+  for (auto& it : patches_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
+  }
+
+  // Field 5: has_more_patches
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, has_more_patches_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+CommitDataRequest_ChunkToPatch_Patch::CommitDataRequest_ChunkToPatch_Patch() = default;
+CommitDataRequest_ChunkToPatch_Patch::~CommitDataRequest_ChunkToPatch_Patch() = default;
+CommitDataRequest_ChunkToPatch_Patch::CommitDataRequest_ChunkToPatch_Patch(const CommitDataRequest_ChunkToPatch_Patch&) = default;
+CommitDataRequest_ChunkToPatch_Patch& CommitDataRequest_ChunkToPatch_Patch::operator=(const CommitDataRequest_ChunkToPatch_Patch&) = default;
+CommitDataRequest_ChunkToPatch_Patch::CommitDataRequest_ChunkToPatch_Patch(CommitDataRequest_ChunkToPatch_Patch&&) noexcept = default;
+CommitDataRequest_ChunkToPatch_Patch& CommitDataRequest_ChunkToPatch_Patch::operator=(CommitDataRequest_ChunkToPatch_Patch&&) = default;
+
+bool CommitDataRequest_ChunkToPatch_Patch::operator==(const CommitDataRequest_ChunkToPatch_Patch& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(offset_, other.offset_)
+   && ::protozero::internal::gen_helpers::EqualsField(data_, other.data_);
+}
+
+bool CommitDataRequest_ChunkToPatch_Patch::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* offset */:
+        field.get(&offset_);
+        break;
+      case 2 /* data */:
+        field.get(&data_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string CommitDataRequest_ChunkToPatch_Patch::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> CommitDataRequest_ChunkToPatch_Patch::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void CommitDataRequest_ChunkToPatch_Patch::Serialize(::protozero::Message* msg) const {
+  // Field 1: offset
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, offset_, msg);
+  }
+
+  // Field 2: data
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, data_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+CommitDataRequest_ChunksToMove::CommitDataRequest_ChunksToMove() = default;
+CommitDataRequest_ChunksToMove::~CommitDataRequest_ChunksToMove() = default;
+CommitDataRequest_ChunksToMove::CommitDataRequest_ChunksToMove(const CommitDataRequest_ChunksToMove&) = default;
+CommitDataRequest_ChunksToMove& CommitDataRequest_ChunksToMove::operator=(const CommitDataRequest_ChunksToMove&) = default;
+CommitDataRequest_ChunksToMove::CommitDataRequest_ChunksToMove(CommitDataRequest_ChunksToMove&&) noexcept = default;
+CommitDataRequest_ChunksToMove& CommitDataRequest_ChunksToMove::operator=(CommitDataRequest_ChunksToMove&&) = default;
+
+bool CommitDataRequest_ChunksToMove::operator==(const CommitDataRequest_ChunksToMove& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(page_, other.page_)
+   && ::protozero::internal::gen_helpers::EqualsField(chunk_, other.chunk_)
+   && ::protozero::internal::gen_helpers::EqualsField(target_buffer_, other.target_buffer_)
+   && ::protozero::internal::gen_helpers::EqualsField(data_, other.data_);
+}
+
+bool CommitDataRequest_ChunksToMove::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* page */:
+        field.get(&page_);
+        break;
+      case 2 /* chunk */:
+        field.get(&chunk_);
+        break;
+      case 3 /* target_buffer */:
+        field.get(&target_buffer_);
+        break;
+      case 4 /* data */:
+        field.get(&data_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string CommitDataRequest_ChunksToMove::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> CommitDataRequest_ChunksToMove::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void CommitDataRequest_ChunksToMove::Serialize(::protozero::Message* msg) const {
+  // Field 1: page
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, page_, msg);
+  }
+
+  // Field 2: chunk
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, chunk_, msg);
+  }
+
+  // Field 3: target_buffer
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, target_buffer_, msg);
+  }
+
+  // Field 4: data
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeString(4, data_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/common/data_source_descriptor.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+DataSourceDescriptor::DataSourceDescriptor() = default;
+DataSourceDescriptor::~DataSourceDescriptor() = default;
+DataSourceDescriptor::DataSourceDescriptor(const DataSourceDescriptor&) = default;
+DataSourceDescriptor& DataSourceDescriptor::operator=(const DataSourceDescriptor&) = default;
+DataSourceDescriptor::DataSourceDescriptor(DataSourceDescriptor&&) noexcept = default;
+DataSourceDescriptor& DataSourceDescriptor::operator=(DataSourceDescriptor&&) = default;
+
+bool DataSourceDescriptor::operator==(const DataSourceDescriptor& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(id_, other.id_)
+   && ::protozero::internal::gen_helpers::EqualsField(will_notify_on_stop_, other.will_notify_on_stop_)
+   && ::protozero::internal::gen_helpers::EqualsField(will_notify_on_start_, other.will_notify_on_start_)
+   && ::protozero::internal::gen_helpers::EqualsField(handles_incremental_state_clear_, other.handles_incremental_state_clear_)
+   && ::protozero::internal::gen_helpers::EqualsField(no_flush_, other.no_flush_)
+   && ::protozero::internal::gen_helpers::EqualsField(gpu_counter_descriptor_, other.gpu_counter_descriptor_)
+   && ::protozero::internal::gen_helpers::EqualsField(track_event_descriptor_, other.track_event_descriptor_)
+   && ::protozero::internal::gen_helpers::EqualsField(ftrace_descriptor_, other.ftrace_descriptor_);
+}
+
+bool DataSourceDescriptor::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 7 /* id */:
+        field.get(&id_);
+        break;
+      case 2 /* will_notify_on_stop */:
+        field.get(&will_notify_on_stop_);
+        break;
+      case 3 /* will_notify_on_start */:
+        field.get(&will_notify_on_start_);
+        break;
+      case 4 /* handles_incremental_state_clear */:
+        field.get(&handles_incremental_state_clear_);
+        break;
+      case 9 /* no_flush */:
+        field.get(&no_flush_);
+        break;
+      case 5 /* gpu_counter_descriptor */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &gpu_counter_descriptor_);
+        break;
+      case 6 /* track_event_descriptor */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &track_event_descriptor_);
+        break;
+      case 8 /* ftrace_descriptor */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &ftrace_descriptor_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string DataSourceDescriptor::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> DataSourceDescriptor::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void DataSourceDescriptor::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
+  }
+
+  // Field 7: id
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(7, id_, msg);
+  }
+
+  // Field 2: will_notify_on_stop
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, will_notify_on_stop_, msg);
+  }
+
+  // Field 3: will_notify_on_start
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, will_notify_on_start_, msg);
+  }
+
+  // Field 4: handles_incremental_state_clear
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, handles_incremental_state_clear_, msg);
+  }
+
+  // Field 9: no_flush
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(9, no_flush_, msg);
+  }
+
+  // Field 5: gpu_counter_descriptor
+  if (_has_field_[5]) {
+    msg->AppendString(5, gpu_counter_descriptor_);
+  }
+
+  // Field 6: track_event_descriptor
+  if (_has_field_[6]) {
+    msg->AppendString(6, track_event_descriptor_);
+  }
+
+  // Field 8: ftrace_descriptor
+  if (_has_field_[8]) {
+    msg->AppendString(8, ftrace_descriptor_);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/common/descriptor.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/common/descriptor.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+OneofOptions::OneofOptions() = default;
+OneofOptions::~OneofOptions() = default;
+OneofOptions::OneofOptions(const OneofOptions&) = default;
+OneofOptions& OneofOptions::operator=(const OneofOptions&) = default;
+OneofOptions::OneofOptions(OneofOptions&&) noexcept = default;
+OneofOptions& OneofOptions::operator=(OneofOptions&&) = default;
+
+bool OneofOptions::operator==(const OneofOptions& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool OneofOptions::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string OneofOptions::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> OneofOptions::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void OneofOptions::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+EnumValueDescriptorProto::EnumValueDescriptorProto() = default;
+EnumValueDescriptorProto::~EnumValueDescriptorProto() = default;
+EnumValueDescriptorProto::EnumValueDescriptorProto(const EnumValueDescriptorProto&) = default;
+EnumValueDescriptorProto& EnumValueDescriptorProto::operator=(const EnumValueDescriptorProto&) = default;
+EnumValueDescriptorProto::EnumValueDescriptorProto(EnumValueDescriptorProto&&) noexcept = default;
+EnumValueDescriptorProto& EnumValueDescriptorProto::operator=(EnumValueDescriptorProto&&) = default;
+
+bool EnumValueDescriptorProto::operator==(const EnumValueDescriptorProto& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(number_, other.number_);
+}
+
+bool EnumValueDescriptorProto::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 2 /* number */:
+        field.get(&number_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string EnumValueDescriptorProto::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> EnumValueDescriptorProto::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void EnumValueDescriptorProto::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
+  }
+
+  // Field 2: number
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, number_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+EnumDescriptorProto::EnumDescriptorProto() = default;
+EnumDescriptorProto::~EnumDescriptorProto() = default;
+EnumDescriptorProto::EnumDescriptorProto(const EnumDescriptorProto&) = default;
+EnumDescriptorProto& EnumDescriptorProto::operator=(const EnumDescriptorProto&) = default;
+EnumDescriptorProto::EnumDescriptorProto(EnumDescriptorProto&&) noexcept = default;
+EnumDescriptorProto& EnumDescriptorProto::operator=(EnumDescriptorProto&&) = default;
+
+bool EnumDescriptorProto::operator==(const EnumDescriptorProto& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(value_, other.value_)
+   && ::protozero::internal::gen_helpers::EqualsField(reserved_name_, other.reserved_name_);
+}
+
+int EnumDescriptorProto::value_size() const { return static_cast<int>(value_.size()); }
+void EnumDescriptorProto::clear_value() { value_.clear(); }
+EnumValueDescriptorProto* EnumDescriptorProto::add_value() { value_.emplace_back(); return &value_.back(); }
+bool EnumDescriptorProto::ParseFromArray(const void* raw, size_t size) {
+  value_.clear();
+  reserved_name_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 2 /* value */:
+        value_.emplace_back();
+        value_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 5 /* reserved_name */:
+        reserved_name_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &reserved_name_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string EnumDescriptorProto::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> EnumDescriptorProto::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void EnumDescriptorProto::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
+  }
+
+  // Field 2: value
+  for (auto& it : value_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  // Field 5: reserved_name
+  for (auto& it : reserved_name_) {
+    ::protozero::internal::gen_helpers::SerializeString(5, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+OneofDescriptorProto::OneofDescriptorProto() = default;
+OneofDescriptorProto::~OneofDescriptorProto() = default;
+OneofDescriptorProto::OneofDescriptorProto(const OneofDescriptorProto&) = default;
+OneofDescriptorProto& OneofDescriptorProto::operator=(const OneofDescriptorProto&) = default;
+OneofDescriptorProto::OneofDescriptorProto(OneofDescriptorProto&&) noexcept = default;
+OneofDescriptorProto& OneofDescriptorProto::operator=(OneofDescriptorProto&&) = default;
+
+bool OneofDescriptorProto::operator==(const OneofDescriptorProto& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(options_, other.options_);
+}
+
+bool OneofDescriptorProto::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 2 /* options */:
+        (*options_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string OneofDescriptorProto::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> OneofDescriptorProto::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void OneofDescriptorProto::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
+  }
+
+  // Field 2: options
+  if (_has_field_[2]) {
+    (*options_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+FieldDescriptorProto::FieldDescriptorProto() = default;
+FieldDescriptorProto::~FieldDescriptorProto() = default;
+FieldDescriptorProto::FieldDescriptorProto(const FieldDescriptorProto&) = default;
+FieldDescriptorProto& FieldDescriptorProto::operator=(const FieldDescriptorProto&) = default;
+FieldDescriptorProto::FieldDescriptorProto(FieldDescriptorProto&&) noexcept = default;
+FieldDescriptorProto& FieldDescriptorProto::operator=(FieldDescriptorProto&&) = default;
+
+bool FieldDescriptorProto::operator==(const FieldDescriptorProto& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(number_, other.number_)
+   && ::protozero::internal::gen_helpers::EqualsField(label_, other.label_)
+   && ::protozero::internal::gen_helpers::EqualsField(type_, other.type_)
+   && ::protozero::internal::gen_helpers::EqualsField(type_name_, other.type_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(extendee_, other.extendee_)
+   && ::protozero::internal::gen_helpers::EqualsField(default_value_, other.default_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(options_, other.options_)
+   && ::protozero::internal::gen_helpers::EqualsField(oneof_index_, other.oneof_index_);
+}
+
+bool FieldDescriptorProto::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 3 /* number */:
+        field.get(&number_);
+        break;
+      case 4 /* label */:
+        field.get(&label_);
+        break;
+      case 5 /* type */:
+        field.get(&type_);
+        break;
+      case 6 /* type_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &type_name_);
+        break;
+      case 2 /* extendee */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &extendee_);
+        break;
+      case 7 /* default_value */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &default_value_);
+        break;
+      case 8 /* options */:
+        (*options_).ParseFromArray(field.data(), field.size());
+        break;
+      case 9 /* oneof_index */:
+        field.get(&oneof_index_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string FieldDescriptorProto::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FieldDescriptorProto::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FieldDescriptorProto::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
+  }
+
+  // Field 3: number
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, number_, msg);
+  }
+
+  // Field 4: label
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, label_, msg);
+  }
+
+  // Field 5: type
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, type_, msg);
+  }
+
+  // Field 6: type_name
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeString(6, type_name_, msg);
+  }
+
+  // Field 2: extendee
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, extendee_, msg);
+  }
+
+  // Field 7: default_value
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeString(7, default_value_, msg);
+  }
+
+  // Field 8: options
+  if (_has_field_[8]) {
+    (*options_).Serialize(msg->BeginNestedMessage<::protozero::Message>(8));
+  }
+
+  // Field 9: oneof_index
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(9, oneof_index_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+FieldOptions::FieldOptions() = default;
+FieldOptions::~FieldOptions() = default;
+FieldOptions::FieldOptions(const FieldOptions&) = default;
+FieldOptions& FieldOptions::operator=(const FieldOptions&) = default;
+FieldOptions::FieldOptions(FieldOptions&&) noexcept = default;
+FieldOptions& FieldOptions::operator=(FieldOptions&&) = default;
+
+bool FieldOptions::operator==(const FieldOptions& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(packed_, other.packed_)
+   && ::protozero::internal::gen_helpers::EqualsField(uninterpreted_option_, other.uninterpreted_option_);
+}
+
+int FieldOptions::uninterpreted_option_size() const { return static_cast<int>(uninterpreted_option_.size()); }
+void FieldOptions::clear_uninterpreted_option() { uninterpreted_option_.clear(); }
+UninterpretedOption* FieldOptions::add_uninterpreted_option() { uninterpreted_option_.emplace_back(); return &uninterpreted_option_.back(); }
+bool FieldOptions::ParseFromArray(const void* raw, size_t size) {
+  uninterpreted_option_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 2 /* packed */:
+        field.get(&packed_);
+        break;
+      case 999 /* uninterpreted_option */:
+        uninterpreted_option_.emplace_back();
+        uninterpreted_option_.back().ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string FieldOptions::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FieldOptions::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FieldOptions::Serialize(::protozero::Message* msg) const {
+  // Field 2: packed
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, packed_, msg);
+  }
+
+  // Field 999: uninterpreted_option
+  for (auto& it : uninterpreted_option_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(999));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+UninterpretedOption::UninterpretedOption() = default;
+UninterpretedOption::~UninterpretedOption() = default;
+UninterpretedOption::UninterpretedOption(const UninterpretedOption&) = default;
+UninterpretedOption& UninterpretedOption::operator=(const UninterpretedOption&) = default;
+UninterpretedOption::UninterpretedOption(UninterpretedOption&&) noexcept = default;
+UninterpretedOption& UninterpretedOption::operator=(UninterpretedOption&&) = default;
+
+bool UninterpretedOption::operator==(const UninterpretedOption& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(identifier_value_, other.identifier_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(positive_int_value_, other.positive_int_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(negative_int_value_, other.negative_int_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(double_value_, other.double_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(string_value_, other.string_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(aggregate_value_, other.aggregate_value_);
+}
+
+int UninterpretedOption::name_size() const { return static_cast<int>(name_.size()); }
+void UninterpretedOption::clear_name() { name_.clear(); }
+UninterpretedOption_NamePart* UninterpretedOption::add_name() { name_.emplace_back(); return &name_.back(); }
+bool UninterpretedOption::ParseFromArray(const void* raw, size_t size) {
+  name_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 2 /* name */:
+        name_.emplace_back();
+        name_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 3 /* identifier_value */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &identifier_value_);
+        break;
+      case 4 /* positive_int_value */:
+        field.get(&positive_int_value_);
+        break;
+      case 5 /* negative_int_value */:
+        field.get(&negative_int_value_);
+        break;
+      case 6 /* double_value */:
+        field.get(&double_value_);
+        break;
+      case 7 /* string_value */:
+        field.get(&string_value_);
+        break;
+      case 8 /* aggregate_value */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &aggregate_value_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string UninterpretedOption::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> UninterpretedOption::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void UninterpretedOption::Serialize(::protozero::Message* msg) const {
+  // Field 2: name
+  for (auto& it : name_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  // Field 3: identifier_value
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeString(3, identifier_value_, msg);
+  }
+
+  // Field 4: positive_int_value
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, positive_int_value_, msg);
+  }
+
+  // Field 5: negative_int_value
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, negative_int_value_, msg);
+  }
+
+  // Field 6: double_value
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeFixed(6, double_value_, msg);
+  }
+
+  // Field 7: string_value
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeString(7, string_value_, msg);
+  }
+
+  // Field 8: aggregate_value
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeString(8, aggregate_value_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+UninterpretedOption_NamePart::UninterpretedOption_NamePart() = default;
+UninterpretedOption_NamePart::~UninterpretedOption_NamePart() = default;
+UninterpretedOption_NamePart::UninterpretedOption_NamePart(const UninterpretedOption_NamePart&) = default;
+UninterpretedOption_NamePart& UninterpretedOption_NamePart::operator=(const UninterpretedOption_NamePart&) = default;
+UninterpretedOption_NamePart::UninterpretedOption_NamePart(UninterpretedOption_NamePart&&) noexcept = default;
+UninterpretedOption_NamePart& UninterpretedOption_NamePart::operator=(UninterpretedOption_NamePart&&) = default;
+
+bool UninterpretedOption_NamePart::operator==(const UninterpretedOption_NamePart& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_part_, other.name_part_)
+   && ::protozero::internal::gen_helpers::EqualsField(is_extension_, other.is_extension_);
+}
+
+bool UninterpretedOption_NamePart::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name_part */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_part_);
+        break;
+      case 2 /* is_extension */:
+        field.get(&is_extension_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string UninterpretedOption_NamePart::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> UninterpretedOption_NamePart::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void UninterpretedOption_NamePart::Serialize(::protozero::Message* msg) const {
+  // Field 1: name_part
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, name_part_, msg);
+  }
+
+  // Field 2: is_extension
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, is_extension_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+DescriptorProto::DescriptorProto() = default;
+DescriptorProto::~DescriptorProto() = default;
+DescriptorProto::DescriptorProto(const DescriptorProto&) = default;
+DescriptorProto& DescriptorProto::operator=(const DescriptorProto&) = default;
+DescriptorProto::DescriptorProto(DescriptorProto&&) noexcept = default;
+DescriptorProto& DescriptorProto::operator=(DescriptorProto&&) = default;
+
+bool DescriptorProto::operator==(const DescriptorProto& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(field_, other.field_)
+   && ::protozero::internal::gen_helpers::EqualsField(extension_, other.extension_)
+   && ::protozero::internal::gen_helpers::EqualsField(nested_type_, other.nested_type_)
+   && ::protozero::internal::gen_helpers::EqualsField(enum_type_, other.enum_type_)
+   && ::protozero::internal::gen_helpers::EqualsField(oneof_decl_, other.oneof_decl_)
+   && ::protozero::internal::gen_helpers::EqualsField(reserved_range_, other.reserved_range_)
+   && ::protozero::internal::gen_helpers::EqualsField(reserved_name_, other.reserved_name_);
+}
+
+int DescriptorProto::field_size() const { return static_cast<int>(field_.size()); }
+void DescriptorProto::clear_field() { field_.clear(); }
+FieldDescriptorProto* DescriptorProto::add_field() { field_.emplace_back(); return &field_.back(); }
+int DescriptorProto::extension_size() const { return static_cast<int>(extension_.size()); }
+void DescriptorProto::clear_extension() { extension_.clear(); }
+FieldDescriptorProto* DescriptorProto::add_extension() { extension_.emplace_back(); return &extension_.back(); }
+int DescriptorProto::nested_type_size() const { return static_cast<int>(nested_type_.size()); }
+void DescriptorProto::clear_nested_type() { nested_type_.clear(); }
+DescriptorProto* DescriptorProto::add_nested_type() { nested_type_.emplace_back(); return &nested_type_.back(); }
+int DescriptorProto::enum_type_size() const { return static_cast<int>(enum_type_.size()); }
+void DescriptorProto::clear_enum_type() { enum_type_.clear(); }
+EnumDescriptorProto* DescriptorProto::add_enum_type() { enum_type_.emplace_back(); return &enum_type_.back(); }
+int DescriptorProto::oneof_decl_size() const { return static_cast<int>(oneof_decl_.size()); }
+void DescriptorProto::clear_oneof_decl() { oneof_decl_.clear(); }
+OneofDescriptorProto* DescriptorProto::add_oneof_decl() { oneof_decl_.emplace_back(); return &oneof_decl_.back(); }
+int DescriptorProto::reserved_range_size() const { return static_cast<int>(reserved_range_.size()); }
+void DescriptorProto::clear_reserved_range() { reserved_range_.clear(); }
+DescriptorProto_ReservedRange* DescriptorProto::add_reserved_range() { reserved_range_.emplace_back(); return &reserved_range_.back(); }
+bool DescriptorProto::ParseFromArray(const void* raw, size_t size) {
+  field_.clear();
+  extension_.clear();
+  nested_type_.clear();
+  enum_type_.clear();
+  oneof_decl_.clear();
+  reserved_range_.clear();
+  reserved_name_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 2 /* field */:
+        field_.emplace_back();
+        field_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 6 /* extension */:
+        extension_.emplace_back();
+        extension_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 3 /* nested_type */:
+        nested_type_.emplace_back();
+        nested_type_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 4 /* enum_type */:
+        enum_type_.emplace_back();
+        enum_type_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 8 /* oneof_decl */:
+        oneof_decl_.emplace_back();
+        oneof_decl_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 9 /* reserved_range */:
+        reserved_range_.emplace_back();
+        reserved_range_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 10 /* reserved_name */:
+        reserved_name_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &reserved_name_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string DescriptorProto::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> DescriptorProto::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void DescriptorProto::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
+  }
+
+  // Field 2: field
+  for (auto& it : field_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  // Field 6: extension
+  for (auto& it : extension_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
+  }
+
+  // Field 3: nested_type
+  for (auto& it : nested_type_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
+  }
+
+  // Field 4: enum_type
+  for (auto& it : enum_type_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
+  }
+
+  // Field 8: oneof_decl
+  for (auto& it : oneof_decl_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(8));
+  }
+
+  // Field 9: reserved_range
+  for (auto& it : reserved_range_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(9));
+  }
+
+  // Field 10: reserved_name
+  for (auto& it : reserved_name_) {
+    ::protozero::internal::gen_helpers::SerializeString(10, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+DescriptorProto_ReservedRange::DescriptorProto_ReservedRange() = default;
+DescriptorProto_ReservedRange::~DescriptorProto_ReservedRange() = default;
+DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(const DescriptorProto_ReservedRange&) = default;
+DescriptorProto_ReservedRange& DescriptorProto_ReservedRange::operator=(const DescriptorProto_ReservedRange&) = default;
+DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(DescriptorProto_ReservedRange&&) noexcept = default;
+DescriptorProto_ReservedRange& DescriptorProto_ReservedRange::operator=(DescriptorProto_ReservedRange&&) = default;
+
+bool DescriptorProto_ReservedRange::operator==(const DescriptorProto_ReservedRange& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(start_, other.start_)
+   && ::protozero::internal::gen_helpers::EqualsField(end_, other.end_);
+}
+
+bool DescriptorProto_ReservedRange::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* start */:
+        field.get(&start_);
+        break;
+      case 2 /* end */:
+        field.get(&end_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string DescriptorProto_ReservedRange::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> DescriptorProto_ReservedRange::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void DescriptorProto_ReservedRange::Serialize(::protozero::Message* msg) const {
+  // Field 1: start
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, start_, msg);
+  }
+
+  // Field 2: end
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, end_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+FileDescriptorProto::FileDescriptorProto() = default;
+FileDescriptorProto::~FileDescriptorProto() = default;
+FileDescriptorProto::FileDescriptorProto(const FileDescriptorProto&) = default;
+FileDescriptorProto& FileDescriptorProto::operator=(const FileDescriptorProto&) = default;
+FileDescriptorProto::FileDescriptorProto(FileDescriptorProto&&) noexcept = default;
+FileDescriptorProto& FileDescriptorProto::operator=(FileDescriptorProto&&) = default;
+
+bool FileDescriptorProto::operator==(const FileDescriptorProto& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(package_, other.package_)
+   && ::protozero::internal::gen_helpers::EqualsField(dependency_, other.dependency_)
+   && ::protozero::internal::gen_helpers::EqualsField(public_dependency_, other.public_dependency_)
+   && ::protozero::internal::gen_helpers::EqualsField(weak_dependency_, other.weak_dependency_)
+   && ::protozero::internal::gen_helpers::EqualsField(message_type_, other.message_type_)
+   && ::protozero::internal::gen_helpers::EqualsField(enum_type_, other.enum_type_)
+   && ::protozero::internal::gen_helpers::EqualsField(extension_, other.extension_);
+}
+
+int FileDescriptorProto::message_type_size() const { return static_cast<int>(message_type_.size()); }
+void FileDescriptorProto::clear_message_type() { message_type_.clear(); }
+DescriptorProto* FileDescriptorProto::add_message_type() { message_type_.emplace_back(); return &message_type_.back(); }
+int FileDescriptorProto::enum_type_size() const { return static_cast<int>(enum_type_.size()); }
+void FileDescriptorProto::clear_enum_type() { enum_type_.clear(); }
+EnumDescriptorProto* FileDescriptorProto::add_enum_type() { enum_type_.emplace_back(); return &enum_type_.back(); }
+int FileDescriptorProto::extension_size() const { return static_cast<int>(extension_.size()); }
+void FileDescriptorProto::clear_extension() { extension_.clear(); }
+FieldDescriptorProto* FileDescriptorProto::add_extension() { extension_.emplace_back(); return &extension_.back(); }
+bool FileDescriptorProto::ParseFromArray(const void* raw, size_t size) {
+  dependency_.clear();
+  public_dependency_.clear();
+  weak_dependency_.clear();
+  message_type_.clear();
+  enum_type_.clear();
+  extension_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 2 /* package */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &package_);
+        break;
+      case 3 /* dependency */:
+        dependency_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &dependency_.back());
+        break;
+      case 10 /* public_dependency */:
+        public_dependency_.emplace_back();
+        field.get(&public_dependency_.back());
+        break;
+      case 11 /* weak_dependency */:
+        weak_dependency_.emplace_back();
+        field.get(&weak_dependency_.back());
+        break;
+      case 4 /* message_type */:
+        message_type_.emplace_back();
+        message_type_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 5 /* enum_type */:
+        enum_type_.emplace_back();
+        enum_type_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 7 /* extension */:
+        extension_.emplace_back();
+        extension_.back().ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string FileDescriptorProto::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FileDescriptorProto::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FileDescriptorProto::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
+  }
+
+  // Field 2: package
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, package_, msg);
+  }
+
+  // Field 3: dependency
+  for (auto& it : dependency_) {
+    ::protozero::internal::gen_helpers::SerializeString(3, it, msg);
+  }
+
+  // Field 10: public_dependency
+  for (auto& it : public_dependency_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(10, it, msg);
+  }
+
+  // Field 11: weak_dependency
+  for (auto& it : weak_dependency_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(11, it, msg);
+  }
+
+  // Field 4: message_type
+  for (auto& it : message_type_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
+  }
+
+  // Field 5: enum_type
+  for (auto& it : enum_type_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
+  }
+
+  // Field 7: extension
+  for (auto& it : extension_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(7));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+FileDescriptorSet::FileDescriptorSet() = default;
+FileDescriptorSet::~FileDescriptorSet() = default;
+FileDescriptorSet::FileDescriptorSet(const FileDescriptorSet&) = default;
+FileDescriptorSet& FileDescriptorSet::operator=(const FileDescriptorSet&) = default;
+FileDescriptorSet::FileDescriptorSet(FileDescriptorSet&&) noexcept = default;
+FileDescriptorSet& FileDescriptorSet::operator=(FileDescriptorSet&&) = default;
+
+bool FileDescriptorSet::operator==(const FileDescriptorSet& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(file_, other.file_);
+}
+
+int FileDescriptorSet::file_size() const { return static_cast<int>(file_.size()); }
+void FileDescriptorSet::clear_file() { file_.clear(); }
+FileDescriptorProto* FileDescriptorSet::add_file() { file_.emplace_back(); return &file_.back(); }
+bool FileDescriptorSet::ParseFromArray(const void* raw, size_t size) {
+  file_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* file */:
+        file_.emplace_back();
+        file_.back().ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string FileDescriptorSet::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FileDescriptorSet::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FileDescriptorSet::Serialize(::protozero::Message* msg) const {
+  // Field 1: file
+  for (auto& it : file_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/common/ftrace_descriptor.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/common/ftrace_descriptor.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+FtraceDescriptor::FtraceDescriptor() = default;
+FtraceDescriptor::~FtraceDescriptor() = default;
+FtraceDescriptor::FtraceDescriptor(const FtraceDescriptor&) = default;
+FtraceDescriptor& FtraceDescriptor::operator=(const FtraceDescriptor&) = default;
+FtraceDescriptor::FtraceDescriptor(FtraceDescriptor&&) noexcept = default;
+FtraceDescriptor& FtraceDescriptor::operator=(FtraceDescriptor&&) = default;
+
+bool FtraceDescriptor::operator==(const FtraceDescriptor& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(atrace_categories_, other.atrace_categories_);
+}
+
+int FtraceDescriptor::atrace_categories_size() const { return static_cast<int>(atrace_categories_.size()); }
+void FtraceDescriptor::clear_atrace_categories() { atrace_categories_.clear(); }
+FtraceDescriptor_AtraceCategory* FtraceDescriptor::add_atrace_categories() { atrace_categories_.emplace_back(); return &atrace_categories_.back(); }
+bool FtraceDescriptor::ParseFromArray(const void* raw, size_t size) {
+  atrace_categories_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* atrace_categories */:
+        atrace_categories_.emplace_back();
+        atrace_categories_.back().ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string FtraceDescriptor::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FtraceDescriptor::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FtraceDescriptor::Serialize(::protozero::Message* msg) const {
+  // Field 1: atrace_categories
+  for (auto& it : atrace_categories_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+FtraceDescriptor_AtraceCategory::FtraceDescriptor_AtraceCategory() = default;
+FtraceDescriptor_AtraceCategory::~FtraceDescriptor_AtraceCategory() = default;
+FtraceDescriptor_AtraceCategory::FtraceDescriptor_AtraceCategory(const FtraceDescriptor_AtraceCategory&) = default;
+FtraceDescriptor_AtraceCategory& FtraceDescriptor_AtraceCategory::operator=(const FtraceDescriptor_AtraceCategory&) = default;
+FtraceDescriptor_AtraceCategory::FtraceDescriptor_AtraceCategory(FtraceDescriptor_AtraceCategory&&) noexcept = default;
+FtraceDescriptor_AtraceCategory& FtraceDescriptor_AtraceCategory::operator=(FtraceDescriptor_AtraceCategory&&) = default;
+
+bool FtraceDescriptor_AtraceCategory::operator==(const FtraceDescriptor_AtraceCategory& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(description_, other.description_);
+}
+
+bool FtraceDescriptor_AtraceCategory::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 2 /* description */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &description_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string FtraceDescriptor_AtraceCategory::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FtraceDescriptor_AtraceCategory::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FtraceDescriptor_AtraceCategory::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
+  }
+
+  // Field 2: description
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, description_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/common/gpu_counter_descriptor.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/common/gpu_counter_descriptor.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+GpuCounterDescriptor::GpuCounterDescriptor() = default;
+GpuCounterDescriptor::~GpuCounterDescriptor() = default;
+GpuCounterDescriptor::GpuCounterDescriptor(const GpuCounterDescriptor&) = default;
+GpuCounterDescriptor& GpuCounterDescriptor::operator=(const GpuCounterDescriptor&) = default;
+GpuCounterDescriptor::GpuCounterDescriptor(GpuCounterDescriptor&&) noexcept = default;
+GpuCounterDescriptor& GpuCounterDescriptor::operator=(GpuCounterDescriptor&&) = default;
+
+bool GpuCounterDescriptor::operator==(const GpuCounterDescriptor& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(specs_, other.specs_)
+   && ::protozero::internal::gen_helpers::EqualsField(blocks_, other.blocks_)
+   && ::protozero::internal::gen_helpers::EqualsField(min_sampling_period_ns_, other.min_sampling_period_ns_)
+   && ::protozero::internal::gen_helpers::EqualsField(max_sampling_period_ns_, other.max_sampling_period_ns_)
+   && ::protozero::internal::gen_helpers::EqualsField(supports_instrumented_sampling_, other.supports_instrumented_sampling_);
+}
+
+int GpuCounterDescriptor::specs_size() const { return static_cast<int>(specs_.size()); }
+void GpuCounterDescriptor::clear_specs() { specs_.clear(); }
+GpuCounterDescriptor_GpuCounterSpec* GpuCounterDescriptor::add_specs() { specs_.emplace_back(); return &specs_.back(); }
+int GpuCounterDescriptor::blocks_size() const { return static_cast<int>(blocks_.size()); }
+void GpuCounterDescriptor::clear_blocks() { blocks_.clear(); }
+GpuCounterDescriptor_GpuCounterBlock* GpuCounterDescriptor::add_blocks() { blocks_.emplace_back(); return &blocks_.back(); }
+bool GpuCounterDescriptor::ParseFromArray(const void* raw, size_t size) {
+  specs_.clear();
+  blocks_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* specs */:
+        specs_.emplace_back();
+        specs_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 2 /* blocks */:
+        blocks_.emplace_back();
+        blocks_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 3 /* min_sampling_period_ns */:
+        field.get(&min_sampling_period_ns_);
+        break;
+      case 4 /* max_sampling_period_ns */:
+        field.get(&max_sampling_period_ns_);
+        break;
+      case 5 /* supports_instrumented_sampling */:
+        field.get(&supports_instrumented_sampling_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string GpuCounterDescriptor::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GpuCounterDescriptor::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void GpuCounterDescriptor::Serialize(::protozero::Message* msg) const {
+  // Field 1: specs
+  for (auto& it : specs_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  // Field 2: blocks
+  for (auto& it : blocks_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  // Field 3: min_sampling_period_ns
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, min_sampling_period_ns_, msg);
+  }
+
+  // Field 4: max_sampling_period_ns
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, max_sampling_period_ns_, msg);
+  }
+
+  // Field 5: supports_instrumented_sampling
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, supports_instrumented_sampling_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+GpuCounterDescriptor_GpuCounterBlock::GpuCounterDescriptor_GpuCounterBlock() = default;
+GpuCounterDescriptor_GpuCounterBlock::~GpuCounterDescriptor_GpuCounterBlock() = default;
+GpuCounterDescriptor_GpuCounterBlock::GpuCounterDescriptor_GpuCounterBlock(const GpuCounterDescriptor_GpuCounterBlock&) = default;
+GpuCounterDescriptor_GpuCounterBlock& GpuCounterDescriptor_GpuCounterBlock::operator=(const GpuCounterDescriptor_GpuCounterBlock&) = default;
+GpuCounterDescriptor_GpuCounterBlock::GpuCounterDescriptor_GpuCounterBlock(GpuCounterDescriptor_GpuCounterBlock&&) noexcept = default;
+GpuCounterDescriptor_GpuCounterBlock& GpuCounterDescriptor_GpuCounterBlock::operator=(GpuCounterDescriptor_GpuCounterBlock&&) = default;
+
+bool GpuCounterDescriptor_GpuCounterBlock::operator==(const GpuCounterDescriptor_GpuCounterBlock& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(block_id_, other.block_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(block_capacity_, other.block_capacity_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(description_, other.description_)
+   && ::protozero::internal::gen_helpers::EqualsField(counter_ids_, other.counter_ids_);
+}
+
+bool GpuCounterDescriptor_GpuCounterBlock::ParseFromArray(const void* raw, size_t size) {
+  counter_ids_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* block_id */:
+        field.get(&block_id_);
+        break;
+      case 2 /* block_capacity */:
+        field.get(&block_capacity_);
+        break;
+      case 3 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 4 /* description */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &description_);
+        break;
+      case 5 /* counter_ids */:
+        counter_ids_.emplace_back();
+        field.get(&counter_ids_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string GpuCounterDescriptor_GpuCounterBlock::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GpuCounterDescriptor_GpuCounterBlock::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void GpuCounterDescriptor_GpuCounterBlock::Serialize(::protozero::Message* msg) const {
+  // Field 1: block_id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, block_id_, msg);
+  }
+
+  // Field 2: block_capacity
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, block_capacity_, msg);
+  }
+
+  // Field 3: name
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeString(3, name_, msg);
+  }
+
+  // Field 4: description
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeString(4, description_, msg);
+  }
+
+  // Field 5: counter_ids
+  for (auto& it : counter_ids_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+GpuCounterDescriptor_GpuCounterSpec::GpuCounterDescriptor_GpuCounterSpec() = default;
+GpuCounterDescriptor_GpuCounterSpec::~GpuCounterDescriptor_GpuCounterSpec() = default;
+GpuCounterDescriptor_GpuCounterSpec::GpuCounterDescriptor_GpuCounterSpec(const GpuCounterDescriptor_GpuCounterSpec&) = default;
+GpuCounterDescriptor_GpuCounterSpec& GpuCounterDescriptor_GpuCounterSpec::operator=(const GpuCounterDescriptor_GpuCounterSpec&) = default;
+GpuCounterDescriptor_GpuCounterSpec::GpuCounterDescriptor_GpuCounterSpec(GpuCounterDescriptor_GpuCounterSpec&&) noexcept = default;
+GpuCounterDescriptor_GpuCounterSpec& GpuCounterDescriptor_GpuCounterSpec::operator=(GpuCounterDescriptor_GpuCounterSpec&&) = default;
+
+bool GpuCounterDescriptor_GpuCounterSpec::operator==(const GpuCounterDescriptor_GpuCounterSpec& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(counter_id_, other.counter_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(description_, other.description_)
+   && ::protozero::internal::gen_helpers::EqualsField(int_peak_value_, other.int_peak_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(double_peak_value_, other.double_peak_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(numerator_units_, other.numerator_units_)
+   && ::protozero::internal::gen_helpers::EqualsField(denominator_units_, other.denominator_units_)
+   && ::protozero::internal::gen_helpers::EqualsField(select_by_default_, other.select_by_default_)
+   && ::protozero::internal::gen_helpers::EqualsField(groups_, other.groups_);
+}
+
+bool GpuCounterDescriptor_GpuCounterSpec::ParseFromArray(const void* raw, size_t size) {
+  numerator_units_.clear();
+  denominator_units_.clear();
+  groups_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* counter_id */:
+        field.get(&counter_id_);
+        break;
+      case 2 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 3 /* description */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &description_);
+        break;
+      case 5 /* int_peak_value */:
+        field.get(&int_peak_value_);
+        break;
+      case 6 /* double_peak_value */:
+        field.get(&double_peak_value_);
+        break;
+      case 7 /* numerator_units */:
+        numerator_units_.emplace_back();
+        field.get(&numerator_units_.back());
+        break;
+      case 8 /* denominator_units */:
+        denominator_units_.emplace_back();
+        field.get(&denominator_units_.back());
+        break;
+      case 9 /* select_by_default */:
+        field.get(&select_by_default_);
+        break;
+      case 10 /* groups */:
+        groups_.emplace_back();
+        field.get(&groups_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string GpuCounterDescriptor_GpuCounterSpec::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GpuCounterDescriptor_GpuCounterSpec::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void GpuCounterDescriptor_GpuCounterSpec::Serialize(::protozero::Message* msg) const {
+  // Field 1: counter_id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, counter_id_, msg);
+  }
+
+  // Field 2: name
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, name_, msg);
+  }
+
+  // Field 3: description
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeString(3, description_, msg);
+  }
+
+  // Field 5: int_peak_value
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, int_peak_value_, msg);
+  }
+
+  // Field 6: double_peak_value
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeFixed(6, double_peak_value_, msg);
+  }
+
+  // Field 7: numerator_units
+  for (auto& it : numerator_units_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(7, it, msg);
+  }
+
+  // Field 8: denominator_units
+  for (auto& it : denominator_units_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(8, it, msg);
+  }
+
+  // Field 9: select_by_default
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(9, select_by_default_, msg);
+  }
+
+  // Field 10: groups
+  for (auto& it : groups_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(10, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/common/interceptor_descriptor.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/common/interceptor_descriptor.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+InterceptorDescriptor::InterceptorDescriptor() = default;
+InterceptorDescriptor::~InterceptorDescriptor() = default;
+InterceptorDescriptor::InterceptorDescriptor(const InterceptorDescriptor&) = default;
+InterceptorDescriptor& InterceptorDescriptor::operator=(const InterceptorDescriptor&) = default;
+InterceptorDescriptor::InterceptorDescriptor(InterceptorDescriptor&&) noexcept = default;
+InterceptorDescriptor& InterceptorDescriptor::operator=(InterceptorDescriptor&&) = default;
+
+bool InterceptorDescriptor::operator==(const InterceptorDescriptor& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_);
+}
+
+bool InterceptorDescriptor::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string InterceptorDescriptor::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> InterceptorDescriptor::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void InterceptorDescriptor::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/common/observable_events.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/common/observable_events.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ObservableEvents::ObservableEvents() = default;
+ObservableEvents::~ObservableEvents() = default;
+ObservableEvents::ObservableEvents(const ObservableEvents&) = default;
+ObservableEvents& ObservableEvents::operator=(const ObservableEvents&) = default;
+ObservableEvents::ObservableEvents(ObservableEvents&&) noexcept = default;
+ObservableEvents& ObservableEvents::operator=(ObservableEvents&&) = default;
+
+bool ObservableEvents::operator==(const ObservableEvents& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(instance_state_changes_, other.instance_state_changes_)
+   && ::protozero::internal::gen_helpers::EqualsField(all_data_sources_started_, other.all_data_sources_started_)
+   && ::protozero::internal::gen_helpers::EqualsField(clone_trigger_hit_, other.clone_trigger_hit_);
+}
+
+int ObservableEvents::instance_state_changes_size() const { return static_cast<int>(instance_state_changes_.size()); }
+void ObservableEvents::clear_instance_state_changes() { instance_state_changes_.clear(); }
+ObservableEvents_DataSourceInstanceStateChange* ObservableEvents::add_instance_state_changes() { instance_state_changes_.emplace_back(); return &instance_state_changes_.back(); }
+bool ObservableEvents::ParseFromArray(const void* raw, size_t size) {
+  instance_state_changes_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* instance_state_changes */:
+        instance_state_changes_.emplace_back();
+        instance_state_changes_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 2 /* all_data_sources_started */:
+        field.get(&all_data_sources_started_);
+        break;
+      case 3 /* clone_trigger_hit */:
+        (*clone_trigger_hit_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ObservableEvents::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ObservableEvents::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ObservableEvents::Serialize(::protozero::Message* msg) const {
+  // Field 1: instance_state_changes
+  for (auto& it : instance_state_changes_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  // Field 2: all_data_sources_started
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, all_data_sources_started_, msg);
+  }
+
+  // Field 3: clone_trigger_hit
+  if (_has_field_[3]) {
+    (*clone_trigger_hit_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+ObservableEvents_CloneTriggerHit::ObservableEvents_CloneTriggerHit() = default;
+ObservableEvents_CloneTriggerHit::~ObservableEvents_CloneTriggerHit() = default;
+ObservableEvents_CloneTriggerHit::ObservableEvents_CloneTriggerHit(const ObservableEvents_CloneTriggerHit&) = default;
+ObservableEvents_CloneTriggerHit& ObservableEvents_CloneTriggerHit::operator=(const ObservableEvents_CloneTriggerHit&) = default;
+ObservableEvents_CloneTriggerHit::ObservableEvents_CloneTriggerHit(ObservableEvents_CloneTriggerHit&&) noexcept = default;
+ObservableEvents_CloneTriggerHit& ObservableEvents_CloneTriggerHit::operator=(ObservableEvents_CloneTriggerHit&&) = default;
+
+bool ObservableEvents_CloneTriggerHit::operator==(const ObservableEvents_CloneTriggerHit& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(tracing_session_id_, other.tracing_session_id_);
+}
+
+bool ObservableEvents_CloneTriggerHit::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* tracing_session_id */:
+        field.get(&tracing_session_id_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ObservableEvents_CloneTriggerHit::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ObservableEvents_CloneTriggerHit::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ObservableEvents_CloneTriggerHit::Serialize(::protozero::Message* msg) const {
+  // Field 1: tracing_session_id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, tracing_session_id_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+ObservableEvents_DataSourceInstanceStateChange::ObservableEvents_DataSourceInstanceStateChange() = default;
+ObservableEvents_DataSourceInstanceStateChange::~ObservableEvents_DataSourceInstanceStateChange() = default;
+ObservableEvents_DataSourceInstanceStateChange::ObservableEvents_DataSourceInstanceStateChange(const ObservableEvents_DataSourceInstanceStateChange&) = default;
+ObservableEvents_DataSourceInstanceStateChange& ObservableEvents_DataSourceInstanceStateChange::operator=(const ObservableEvents_DataSourceInstanceStateChange&) = default;
+ObservableEvents_DataSourceInstanceStateChange::ObservableEvents_DataSourceInstanceStateChange(ObservableEvents_DataSourceInstanceStateChange&&) noexcept = default;
+ObservableEvents_DataSourceInstanceStateChange& ObservableEvents_DataSourceInstanceStateChange::operator=(ObservableEvents_DataSourceInstanceStateChange&&) = default;
+
+bool ObservableEvents_DataSourceInstanceStateChange::operator==(const ObservableEvents_DataSourceInstanceStateChange& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(producer_name_, other.producer_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(data_source_name_, other.data_source_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(state_, other.state_);
+}
+
+bool ObservableEvents_DataSourceInstanceStateChange::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* producer_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &producer_name_);
+        break;
+      case 2 /* data_source_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &data_source_name_);
+        break;
+      case 3 /* state */:
+        field.get(&state_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ObservableEvents_DataSourceInstanceStateChange::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ObservableEvents_DataSourceInstanceStateChange::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ObservableEvents_DataSourceInstanceStateChange::Serialize(::protozero::Message* msg) const {
+  // Field 1: producer_name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, producer_name_, msg);
+  }
+
+  // Field 2: data_source_name
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, data_source_name_, msg);
+  }
+
+  // Field 3: state
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, state_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/common/perf_events.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/common/perf_events.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+PerfEvents::PerfEvents() = default;
+PerfEvents::~PerfEvents() = default;
+PerfEvents::PerfEvents(const PerfEvents&) = default;
+PerfEvents& PerfEvents::operator=(const PerfEvents&) = default;
+PerfEvents::PerfEvents(PerfEvents&&) noexcept = default;
+PerfEvents& PerfEvents::operator=(PerfEvents&&) = default;
+
+bool PerfEvents::operator==(const PerfEvents& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool PerfEvents::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string PerfEvents::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> PerfEvents::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void PerfEvents::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+PerfEvents_RawEvent::PerfEvents_RawEvent() = default;
+PerfEvents_RawEvent::~PerfEvents_RawEvent() = default;
+PerfEvents_RawEvent::PerfEvents_RawEvent(const PerfEvents_RawEvent&) = default;
+PerfEvents_RawEvent& PerfEvents_RawEvent::operator=(const PerfEvents_RawEvent&) = default;
+PerfEvents_RawEvent::PerfEvents_RawEvent(PerfEvents_RawEvent&&) noexcept = default;
+PerfEvents_RawEvent& PerfEvents_RawEvent::operator=(PerfEvents_RawEvent&&) = default;
+
+bool PerfEvents_RawEvent::operator==(const PerfEvents_RawEvent& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(type_, other.type_)
+   && ::protozero::internal::gen_helpers::EqualsField(config_, other.config_)
+   && ::protozero::internal::gen_helpers::EqualsField(config1_, other.config1_)
+   && ::protozero::internal::gen_helpers::EqualsField(config2_, other.config2_);
+}
+
+bool PerfEvents_RawEvent::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* type */:
+        field.get(&type_);
+        break;
+      case 2 /* config */:
+        field.get(&config_);
+        break;
+      case 3 /* config1 */:
+        field.get(&config1_);
+        break;
+      case 4 /* config2 */:
+        field.get(&config2_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string PerfEvents_RawEvent::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> PerfEvents_RawEvent::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void PerfEvents_RawEvent::Serialize(::protozero::Message* msg) const {
+  // Field 1: type
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, type_, msg);
+  }
+
+  // Field 2: config
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, config_, msg);
+  }
+
+  // Field 3: config1
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, config1_, msg);
+  }
+
+  // Field 4: config2
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, config2_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+PerfEvents_Tracepoint::PerfEvents_Tracepoint() = default;
+PerfEvents_Tracepoint::~PerfEvents_Tracepoint() = default;
+PerfEvents_Tracepoint::PerfEvents_Tracepoint(const PerfEvents_Tracepoint&) = default;
+PerfEvents_Tracepoint& PerfEvents_Tracepoint::operator=(const PerfEvents_Tracepoint&) = default;
+PerfEvents_Tracepoint::PerfEvents_Tracepoint(PerfEvents_Tracepoint&&) noexcept = default;
+PerfEvents_Tracepoint& PerfEvents_Tracepoint::operator=(PerfEvents_Tracepoint&&) = default;
+
+bool PerfEvents_Tracepoint::operator==(const PerfEvents_Tracepoint& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(filter_, other.filter_);
+}
+
+bool PerfEvents_Tracepoint::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 2 /* filter */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &filter_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string PerfEvents_Tracepoint::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> PerfEvents_Tracepoint::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void PerfEvents_Tracepoint::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
+  }
+
+  // Field 2: filter
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, filter_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+PerfEvents_Timebase::PerfEvents_Timebase() = default;
+PerfEvents_Timebase::~PerfEvents_Timebase() = default;
+PerfEvents_Timebase::PerfEvents_Timebase(const PerfEvents_Timebase&) = default;
+PerfEvents_Timebase& PerfEvents_Timebase::operator=(const PerfEvents_Timebase&) = default;
+PerfEvents_Timebase::PerfEvents_Timebase(PerfEvents_Timebase&&) noexcept = default;
+PerfEvents_Timebase& PerfEvents_Timebase::operator=(PerfEvents_Timebase&&) = default;
+
+bool PerfEvents_Timebase::operator==(const PerfEvents_Timebase& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(frequency_, other.frequency_)
+   && ::protozero::internal::gen_helpers::EqualsField(period_, other.period_)
+   && ::protozero::internal::gen_helpers::EqualsField(counter_, other.counter_)
+   && ::protozero::internal::gen_helpers::EqualsField(tracepoint_, other.tracepoint_)
+   && ::protozero::internal::gen_helpers::EqualsField(raw_event_, other.raw_event_)
+   && ::protozero::internal::gen_helpers::EqualsField(timestamp_clock_, other.timestamp_clock_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_);
+}
+
+bool PerfEvents_Timebase::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 2 /* frequency */:
+        field.get(&frequency_);
+        break;
+      case 1 /* period */:
+        field.get(&period_);
+        break;
+      case 4 /* counter */:
+        field.get(&counter_);
+        break;
+      case 3 /* tracepoint */:
+        (*tracepoint_).ParseFromArray(field.data(), field.size());
+        break;
+      case 5 /* raw_event */:
+        (*raw_event_).ParseFromArray(field.data(), field.size());
+        break;
+      case 11 /* timestamp_clock */:
+        field.get(&timestamp_clock_);
+        break;
+      case 10 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string PerfEvents_Timebase::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> PerfEvents_Timebase::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void PerfEvents_Timebase::Serialize(::protozero::Message* msg) const {
+  // Field 2: frequency
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, frequency_, msg);
+  }
+
+  // Field 1: period
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, period_, msg);
+  }
+
+  // Field 4: counter
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, counter_, msg);
+  }
+
+  // Field 3: tracepoint
+  if (_has_field_[3]) {
+    (*tracepoint_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
+  }
+
+  // Field 5: raw_event
+  if (_has_field_[5]) {
+    (*raw_event_).Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
+  }
+
+  // Field 11: timestamp_clock
+  if (_has_field_[11]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(11, timestamp_clock_, msg);
+  }
+
+  // Field 10: name
+  if (_has_field_[10]) {
+    ::protozero::internal::gen_helpers::SerializeString(10, name_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/common/protolog_common.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/common/protolog_common.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/common/sys_stats_counters.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/common/trace_stats.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/common/trace_stats.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+TraceStats::TraceStats() = default;
+TraceStats::~TraceStats() = default;
+TraceStats::TraceStats(const TraceStats&) = default;
+TraceStats& TraceStats::operator=(const TraceStats&) = default;
+TraceStats::TraceStats(TraceStats&&) noexcept = default;
+TraceStats& TraceStats::operator=(TraceStats&&) = default;
+
+bool TraceStats::operator==(const TraceStats& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(buffer_stats_, other.buffer_stats_)
+   && ::protozero::internal::gen_helpers::EqualsField(chunk_payload_histogram_def_, other.chunk_payload_histogram_def_)
+   && ::protozero::internal::gen_helpers::EqualsField(writer_stats_, other.writer_stats_)
+   && ::protozero::internal::gen_helpers::EqualsField(producers_connected_, other.producers_connected_)
+   && ::protozero::internal::gen_helpers::EqualsField(producers_seen_, other.producers_seen_)
+   && ::protozero::internal::gen_helpers::EqualsField(data_sources_registered_, other.data_sources_registered_)
+   && ::protozero::internal::gen_helpers::EqualsField(data_sources_seen_, other.data_sources_seen_)
+   && ::protozero::internal::gen_helpers::EqualsField(tracing_sessions_, other.tracing_sessions_)
+   && ::protozero::internal::gen_helpers::EqualsField(total_buffers_, other.total_buffers_)
+   && ::protozero::internal::gen_helpers::EqualsField(chunks_discarded_, other.chunks_discarded_)
+   && ::protozero::internal::gen_helpers::EqualsField(patches_discarded_, other.patches_discarded_)
+   && ::protozero::internal::gen_helpers::EqualsField(invalid_packets_, other.invalid_packets_)
+   && ::protozero::internal::gen_helpers::EqualsField(filter_stats_, other.filter_stats_)
+   && ::protozero::internal::gen_helpers::EqualsField(flushes_requested_, other.flushes_requested_)
+   && ::protozero::internal::gen_helpers::EqualsField(flushes_succeeded_, other.flushes_succeeded_)
+   && ::protozero::internal::gen_helpers::EqualsField(flushes_failed_, other.flushes_failed_)
+   && ::protozero::internal::gen_helpers::EqualsField(final_flush_outcome_, other.final_flush_outcome_);
+}
+
+int TraceStats::buffer_stats_size() const { return static_cast<int>(buffer_stats_.size()); }
+void TraceStats::clear_buffer_stats() { buffer_stats_.clear(); }
+TraceStats_BufferStats* TraceStats::add_buffer_stats() { buffer_stats_.emplace_back(); return &buffer_stats_.back(); }
+int TraceStats::writer_stats_size() const { return static_cast<int>(writer_stats_.size()); }
+void TraceStats::clear_writer_stats() { writer_stats_.clear(); }
+TraceStats_WriterStats* TraceStats::add_writer_stats() { writer_stats_.emplace_back(); return &writer_stats_.back(); }
+bool TraceStats::ParseFromArray(const void* raw, size_t size) {
+  buffer_stats_.clear();
+  chunk_payload_histogram_def_.clear();
+  writer_stats_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* buffer_stats */:
+        buffer_stats_.emplace_back();
+        buffer_stats_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 17 /* chunk_payload_histogram_def */:
+        chunk_payload_histogram_def_.emplace_back();
+        field.get(&chunk_payload_histogram_def_.back());
+        break;
+      case 18 /* writer_stats */:
+        writer_stats_.emplace_back();
+        writer_stats_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 2 /* producers_connected */:
+        field.get(&producers_connected_);
+        break;
+      case 3 /* producers_seen */:
+        field.get(&producers_seen_);
+        break;
+      case 4 /* data_sources_registered */:
+        field.get(&data_sources_registered_);
+        break;
+      case 5 /* data_sources_seen */:
+        field.get(&data_sources_seen_);
+        break;
+      case 6 /* tracing_sessions */:
+        field.get(&tracing_sessions_);
+        break;
+      case 7 /* total_buffers */:
+        field.get(&total_buffers_);
+        break;
+      case 8 /* chunks_discarded */:
+        field.get(&chunks_discarded_);
+        break;
+      case 9 /* patches_discarded */:
+        field.get(&patches_discarded_);
+        break;
+      case 10 /* invalid_packets */:
+        field.get(&invalid_packets_);
+        break;
+      case 11 /* filter_stats */:
+        (*filter_stats_).ParseFromArray(field.data(), field.size());
+        break;
+      case 12 /* flushes_requested */:
+        field.get(&flushes_requested_);
+        break;
+      case 13 /* flushes_succeeded */:
+        field.get(&flushes_succeeded_);
+        break;
+      case 14 /* flushes_failed */:
+        field.get(&flushes_failed_);
+        break;
+      case 15 /* final_flush_outcome */:
+        field.get(&final_flush_outcome_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceStats::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceStats::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceStats::Serialize(::protozero::Message* msg) const {
+  // Field 1: buffer_stats
+  for (auto& it : buffer_stats_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  // Field 17: chunk_payload_histogram_def
+  for (auto& it : chunk_payload_histogram_def_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(17, it, msg);
+  }
+
+  // Field 18: writer_stats
+  for (auto& it : writer_stats_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(18));
+  }
+
+  // Field 2: producers_connected
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, producers_connected_, msg);
+  }
+
+  // Field 3: producers_seen
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, producers_seen_, msg);
+  }
+
+  // Field 4: data_sources_registered
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, data_sources_registered_, msg);
+  }
+
+  // Field 5: data_sources_seen
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, data_sources_seen_, msg);
+  }
+
+  // Field 6: tracing_sessions
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, tracing_sessions_, msg);
+  }
+
+  // Field 7: total_buffers
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(7, total_buffers_, msg);
+  }
+
+  // Field 8: chunks_discarded
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(8, chunks_discarded_, msg);
+  }
+
+  // Field 9: patches_discarded
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(9, patches_discarded_, msg);
+  }
+
+  // Field 10: invalid_packets
+  if (_has_field_[10]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(10, invalid_packets_, msg);
+  }
+
+  // Field 11: filter_stats
+  if (_has_field_[11]) {
+    (*filter_stats_).Serialize(msg->BeginNestedMessage<::protozero::Message>(11));
+  }
+
+  // Field 12: flushes_requested
+  if (_has_field_[12]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(12, flushes_requested_, msg);
+  }
+
+  // Field 13: flushes_succeeded
+  if (_has_field_[13]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(13, flushes_succeeded_, msg);
+  }
+
+  // Field 14: flushes_failed
+  if (_has_field_[14]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(14, flushes_failed_, msg);
+  }
+
+  // Field 15: final_flush_outcome
+  if (_has_field_[15]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(15, final_flush_outcome_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TraceStats_FilterStats::TraceStats_FilterStats() = default;
+TraceStats_FilterStats::~TraceStats_FilterStats() = default;
+TraceStats_FilterStats::TraceStats_FilterStats(const TraceStats_FilterStats&) = default;
+TraceStats_FilterStats& TraceStats_FilterStats::operator=(const TraceStats_FilterStats&) = default;
+TraceStats_FilterStats::TraceStats_FilterStats(TraceStats_FilterStats&&) noexcept = default;
+TraceStats_FilterStats& TraceStats_FilterStats::operator=(TraceStats_FilterStats&&) = default;
+
+bool TraceStats_FilterStats::operator==(const TraceStats_FilterStats& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(input_packets_, other.input_packets_)
+   && ::protozero::internal::gen_helpers::EqualsField(input_bytes_, other.input_bytes_)
+   && ::protozero::internal::gen_helpers::EqualsField(output_bytes_, other.output_bytes_)
+   && ::protozero::internal::gen_helpers::EqualsField(errors_, other.errors_)
+   && ::protozero::internal::gen_helpers::EqualsField(time_taken_ns_, other.time_taken_ns_)
+   && ::protozero::internal::gen_helpers::EqualsField(bytes_discarded_per_buffer_, other.bytes_discarded_per_buffer_);
+}
+
+bool TraceStats_FilterStats::ParseFromArray(const void* raw, size_t size) {
+  bytes_discarded_per_buffer_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* input_packets */:
+        field.get(&input_packets_);
+        break;
+      case 2 /* input_bytes */:
+        field.get(&input_bytes_);
+        break;
+      case 3 /* output_bytes */:
+        field.get(&output_bytes_);
+        break;
+      case 4 /* errors */:
+        field.get(&errors_);
+        break;
+      case 5 /* time_taken_ns */:
+        field.get(&time_taken_ns_);
+        break;
+      case 20 /* bytes_discarded_per_buffer */:
+        bytes_discarded_per_buffer_.emplace_back();
+        field.get(&bytes_discarded_per_buffer_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceStats_FilterStats::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceStats_FilterStats::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceStats_FilterStats::Serialize(::protozero::Message* msg) const {
+  // Field 1: input_packets
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, input_packets_, msg);
+  }
+
+  // Field 2: input_bytes
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, input_bytes_, msg);
+  }
+
+  // Field 3: output_bytes
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, output_bytes_, msg);
+  }
+
+  // Field 4: errors
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, errors_, msg);
+  }
+
+  // Field 5: time_taken_ns
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, time_taken_ns_, msg);
+  }
+
+  // Field 20: bytes_discarded_per_buffer
+  for (auto& it : bytes_discarded_per_buffer_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(20, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TraceStats_WriterStats::TraceStats_WriterStats() = default;
+TraceStats_WriterStats::~TraceStats_WriterStats() = default;
+TraceStats_WriterStats::TraceStats_WriterStats(const TraceStats_WriterStats&) = default;
+TraceStats_WriterStats& TraceStats_WriterStats::operator=(const TraceStats_WriterStats&) = default;
+TraceStats_WriterStats::TraceStats_WriterStats(TraceStats_WriterStats&&) noexcept = default;
+TraceStats_WriterStats& TraceStats_WriterStats::operator=(TraceStats_WriterStats&&) = default;
+
+bool TraceStats_WriterStats::operator==(const TraceStats_WriterStats& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(sequence_id_, other.sequence_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(buffer_, other.buffer_)
+   && ::protozero::internal::gen_helpers::EqualsField(chunk_payload_histogram_counts_, other.chunk_payload_histogram_counts_)
+   && ::protozero::internal::gen_helpers::EqualsField(chunk_payload_histogram_sum_, other.chunk_payload_histogram_sum_);
+}
+
+bool TraceStats_WriterStats::ParseFromArray(const void* raw, size_t size) {
+  chunk_payload_histogram_counts_.clear();
+  chunk_payload_histogram_sum_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* sequence_id */:
+        field.get(&sequence_id_);
+        break;
+      case 4 /* buffer */:
+        field.get(&buffer_);
+        break;
+      case 2 /* chunk_payload_histogram_counts */:
+        if (!::protozero::internal::gen_helpers::DeserializePackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, uint64_t>(field, &chunk_payload_histogram_counts_)) {
+          packed_error = true;}
+        break;
+      case 3 /* chunk_payload_histogram_sum */:
+        if (!::protozero::internal::gen_helpers::DeserializePackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, int64_t>(field, &chunk_payload_histogram_sum_)) {
+          packed_error = true;}
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceStats_WriterStats::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceStats_WriterStats::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceStats_WriterStats::Serialize(::protozero::Message* msg) const {
+  // Field 1: sequence_id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, sequence_id_, msg);
+  }
+
+  // Field 4: buffer
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, buffer_, msg);
+  }
+
+  // Field 2: chunk_payload_histogram_counts
+  {
+    ::protozero::PackedVarInt pack;
+    for (auto& it : chunk_payload_histogram_counts_)
+      pack.Append(it);
+    msg->AppendBytes(2, pack.data(), pack.size());
+  }
+
+  // Field 3: chunk_payload_histogram_sum
+  {
+    ::protozero::PackedVarInt pack;
+    for (auto& it : chunk_payload_histogram_sum_)
+      pack.Append(it);
+    msg->AppendBytes(3, pack.data(), pack.size());
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TraceStats_BufferStats::TraceStats_BufferStats() = default;
+TraceStats_BufferStats::~TraceStats_BufferStats() = default;
+TraceStats_BufferStats::TraceStats_BufferStats(const TraceStats_BufferStats&) = default;
+TraceStats_BufferStats& TraceStats_BufferStats::operator=(const TraceStats_BufferStats&) = default;
+TraceStats_BufferStats::TraceStats_BufferStats(TraceStats_BufferStats&&) noexcept = default;
+TraceStats_BufferStats& TraceStats_BufferStats::operator=(TraceStats_BufferStats&&) = default;
+
+bool TraceStats_BufferStats::operator==(const TraceStats_BufferStats& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(buffer_size_, other.buffer_size_)
+   && ::protozero::internal::gen_helpers::EqualsField(bytes_written_, other.bytes_written_)
+   && ::protozero::internal::gen_helpers::EqualsField(bytes_overwritten_, other.bytes_overwritten_)
+   && ::protozero::internal::gen_helpers::EqualsField(bytes_read_, other.bytes_read_)
+   && ::protozero::internal::gen_helpers::EqualsField(padding_bytes_written_, other.padding_bytes_written_)
+   && ::protozero::internal::gen_helpers::EqualsField(padding_bytes_cleared_, other.padding_bytes_cleared_)
+   && ::protozero::internal::gen_helpers::EqualsField(chunks_written_, other.chunks_written_)
+   && ::protozero::internal::gen_helpers::EqualsField(chunks_rewritten_, other.chunks_rewritten_)
+   && ::protozero::internal::gen_helpers::EqualsField(chunks_overwritten_, other.chunks_overwritten_)
+   && ::protozero::internal::gen_helpers::EqualsField(chunks_discarded_, other.chunks_discarded_)
+   && ::protozero::internal::gen_helpers::EqualsField(chunks_read_, other.chunks_read_)
+   && ::protozero::internal::gen_helpers::EqualsField(chunks_committed_out_of_order_, other.chunks_committed_out_of_order_)
+   && ::protozero::internal::gen_helpers::EqualsField(write_wrap_count_, other.write_wrap_count_)
+   && ::protozero::internal::gen_helpers::EqualsField(patches_succeeded_, other.patches_succeeded_)
+   && ::protozero::internal::gen_helpers::EqualsField(patches_failed_, other.patches_failed_)
+   && ::protozero::internal::gen_helpers::EqualsField(readaheads_succeeded_, other.readaheads_succeeded_)
+   && ::protozero::internal::gen_helpers::EqualsField(readaheads_failed_, other.readaheads_failed_)
+   && ::protozero::internal::gen_helpers::EqualsField(abi_violations_, other.abi_violations_)
+   && ::protozero::internal::gen_helpers::EqualsField(trace_writer_packet_loss_, other.trace_writer_packet_loss_);
+}
+
+bool TraceStats_BufferStats::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 12 /* buffer_size */:
+        field.get(&buffer_size_);
+        break;
+      case 1 /* bytes_written */:
+        field.get(&bytes_written_);
+        break;
+      case 13 /* bytes_overwritten */:
+        field.get(&bytes_overwritten_);
+        break;
+      case 14 /* bytes_read */:
+        field.get(&bytes_read_);
+        break;
+      case 15 /* padding_bytes_written */:
+        field.get(&padding_bytes_written_);
+        break;
+      case 16 /* padding_bytes_cleared */:
+        field.get(&padding_bytes_cleared_);
+        break;
+      case 2 /* chunks_written */:
+        field.get(&chunks_written_);
+        break;
+      case 10 /* chunks_rewritten */:
+        field.get(&chunks_rewritten_);
+        break;
+      case 3 /* chunks_overwritten */:
+        field.get(&chunks_overwritten_);
+        break;
+      case 18 /* chunks_discarded */:
+        field.get(&chunks_discarded_);
+        break;
+      case 17 /* chunks_read */:
+        field.get(&chunks_read_);
+        break;
+      case 11 /* chunks_committed_out_of_order */:
+        field.get(&chunks_committed_out_of_order_);
+        break;
+      case 4 /* write_wrap_count */:
+        field.get(&write_wrap_count_);
+        break;
+      case 5 /* patches_succeeded */:
+        field.get(&patches_succeeded_);
+        break;
+      case 6 /* patches_failed */:
+        field.get(&patches_failed_);
+        break;
+      case 7 /* readaheads_succeeded */:
+        field.get(&readaheads_succeeded_);
+        break;
+      case 8 /* readaheads_failed */:
+        field.get(&readaheads_failed_);
+        break;
+      case 9 /* abi_violations */:
+        field.get(&abi_violations_);
+        break;
+      case 19 /* trace_writer_packet_loss */:
+        field.get(&trace_writer_packet_loss_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceStats_BufferStats::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceStats_BufferStats::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceStats_BufferStats::Serialize(::protozero::Message* msg) const {
+  // Field 12: buffer_size
+  if (_has_field_[12]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(12, buffer_size_, msg);
+  }
+
+  // Field 1: bytes_written
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, bytes_written_, msg);
+  }
+
+  // Field 13: bytes_overwritten
+  if (_has_field_[13]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(13, bytes_overwritten_, msg);
+  }
+
+  // Field 14: bytes_read
+  if (_has_field_[14]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(14, bytes_read_, msg);
+  }
+
+  // Field 15: padding_bytes_written
+  if (_has_field_[15]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(15, padding_bytes_written_, msg);
+  }
+
+  // Field 16: padding_bytes_cleared
+  if (_has_field_[16]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(16, padding_bytes_cleared_, msg);
+  }
+
+  // Field 2: chunks_written
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, chunks_written_, msg);
+  }
+
+  // Field 10: chunks_rewritten
+  if (_has_field_[10]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(10, chunks_rewritten_, msg);
+  }
+
+  // Field 3: chunks_overwritten
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, chunks_overwritten_, msg);
+  }
+
+  // Field 18: chunks_discarded
+  if (_has_field_[18]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(18, chunks_discarded_, msg);
+  }
+
+  // Field 17: chunks_read
+  if (_has_field_[17]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(17, chunks_read_, msg);
+  }
+
+  // Field 11: chunks_committed_out_of_order
+  if (_has_field_[11]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(11, chunks_committed_out_of_order_, msg);
+  }
+
+  // Field 4: write_wrap_count
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, write_wrap_count_, msg);
+  }
+
+  // Field 5: patches_succeeded
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, patches_succeeded_, msg);
+  }
+
+  // Field 6: patches_failed
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, patches_failed_, msg);
+  }
+
+  // Field 7: readaheads_succeeded
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(7, readaheads_succeeded_, msg);
+  }
+
+  // Field 8: readaheads_failed
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(8, readaheads_failed_, msg);
+  }
+
+  // Field 9: abi_violations
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(9, abi_violations_, msg);
+  }
+
+  // Field 19: trace_writer_packet_loss
+  if (_has_field_[19]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(19, trace_writer_packet_loss_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/common/tracing_service_capabilities.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_capabilities.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/observable_events.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+TracingServiceCapabilities::TracingServiceCapabilities() = default;
+TracingServiceCapabilities::~TracingServiceCapabilities() = default;
+TracingServiceCapabilities::TracingServiceCapabilities(const TracingServiceCapabilities&) = default;
+TracingServiceCapabilities& TracingServiceCapabilities::operator=(const TracingServiceCapabilities&) = default;
+TracingServiceCapabilities::TracingServiceCapabilities(TracingServiceCapabilities&&) noexcept = default;
+TracingServiceCapabilities& TracingServiceCapabilities::operator=(TracingServiceCapabilities&&) = default;
+
+bool TracingServiceCapabilities::operator==(const TracingServiceCapabilities& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(has_query_capabilities_, other.has_query_capabilities_)
+   && ::protozero::internal::gen_helpers::EqualsField(observable_events_, other.observable_events_)
+   && ::protozero::internal::gen_helpers::EqualsField(has_trace_config_output_path_, other.has_trace_config_output_path_)
+   && ::protozero::internal::gen_helpers::EqualsField(has_clone_session_, other.has_clone_session_);
+}
+
+bool TracingServiceCapabilities::ParseFromArray(const void* raw, size_t size) {
+  observable_events_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* has_query_capabilities */:
+        field.get(&has_query_capabilities_);
+        break;
+      case 2 /* observable_events */:
+        observable_events_.emplace_back();
+        field.get(&observable_events_.back());
+        break;
+      case 3 /* has_trace_config_output_path */:
+        field.get(&has_trace_config_output_path_);
+        break;
+      case 4 /* has_clone_session */:
+        field.get(&has_clone_session_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TracingServiceCapabilities::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TracingServiceCapabilities::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TracingServiceCapabilities::Serialize(::protozero::Message* msg) const {
+  // Field 1: has_query_capabilities
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, has_query_capabilities_, msg);
+  }
+
+  // Field 2: observable_events
+  for (auto& it : observable_events_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, it, msg);
+  }
+
+  // Field 3: has_trace_config_output_path
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, has_trace_config_output_path_, msg);
+  }
+
+  // Field 4: has_clone_session
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, has_clone_session_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/common/tracing_service_state.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_state.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/track_event_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/gpu_counter_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/ftrace_descriptor.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+TracingServiceState::TracingServiceState() = default;
+TracingServiceState::~TracingServiceState() = default;
+TracingServiceState::TracingServiceState(const TracingServiceState&) = default;
+TracingServiceState& TracingServiceState::operator=(const TracingServiceState&) = default;
+TracingServiceState::TracingServiceState(TracingServiceState&&) noexcept = default;
+TracingServiceState& TracingServiceState::operator=(TracingServiceState&&) = default;
+
+bool TracingServiceState::operator==(const TracingServiceState& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(producers_, other.producers_)
+   && ::protozero::internal::gen_helpers::EqualsField(data_sources_, other.data_sources_)
+   && ::protozero::internal::gen_helpers::EqualsField(tracing_sessions_, other.tracing_sessions_)
+   && ::protozero::internal::gen_helpers::EqualsField(supports_tracing_sessions_, other.supports_tracing_sessions_)
+   && ::protozero::internal::gen_helpers::EqualsField(num_sessions_, other.num_sessions_)
+   && ::protozero::internal::gen_helpers::EqualsField(num_sessions_started_, other.num_sessions_started_)
+   && ::protozero::internal::gen_helpers::EqualsField(tracing_service_version_, other.tracing_service_version_);
+}
+
+int TracingServiceState::producers_size() const { return static_cast<int>(producers_.size()); }
+void TracingServiceState::clear_producers() { producers_.clear(); }
+TracingServiceState_Producer* TracingServiceState::add_producers() { producers_.emplace_back(); return &producers_.back(); }
+int TracingServiceState::data_sources_size() const { return static_cast<int>(data_sources_.size()); }
+void TracingServiceState::clear_data_sources() { data_sources_.clear(); }
+TracingServiceState_DataSource* TracingServiceState::add_data_sources() { data_sources_.emplace_back(); return &data_sources_.back(); }
+int TracingServiceState::tracing_sessions_size() const { return static_cast<int>(tracing_sessions_.size()); }
+void TracingServiceState::clear_tracing_sessions() { tracing_sessions_.clear(); }
+TracingServiceState_TracingSession* TracingServiceState::add_tracing_sessions() { tracing_sessions_.emplace_back(); return &tracing_sessions_.back(); }
+bool TracingServiceState::ParseFromArray(const void* raw, size_t size) {
+  producers_.clear();
+  data_sources_.clear();
+  tracing_sessions_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* producers */:
+        producers_.emplace_back();
+        producers_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 2 /* data_sources */:
+        data_sources_.emplace_back();
+        data_sources_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 6 /* tracing_sessions */:
+        tracing_sessions_.emplace_back();
+        tracing_sessions_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 7 /* supports_tracing_sessions */:
+        field.get(&supports_tracing_sessions_);
+        break;
+      case 3 /* num_sessions */:
+        field.get(&num_sessions_);
+        break;
+      case 4 /* num_sessions_started */:
+        field.get(&num_sessions_started_);
+        break;
+      case 5 /* tracing_service_version */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &tracing_service_version_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TracingServiceState::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TracingServiceState::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TracingServiceState::Serialize(::protozero::Message* msg) const {
+  // Field 1: producers
+  for (auto& it : producers_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  // Field 2: data_sources
+  for (auto& it : data_sources_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  // Field 6: tracing_sessions
+  for (auto& it : tracing_sessions_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
+  }
+
+  // Field 7: supports_tracing_sessions
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(7, supports_tracing_sessions_, msg);
+  }
+
+  // Field 3: num_sessions
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, num_sessions_, msg);
+  }
+
+  // Field 4: num_sessions_started
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, num_sessions_started_, msg);
+  }
+
+  // Field 5: tracing_service_version
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeString(5, tracing_service_version_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TracingServiceState_TracingSession::TracingServiceState_TracingSession() = default;
+TracingServiceState_TracingSession::~TracingServiceState_TracingSession() = default;
+TracingServiceState_TracingSession::TracingServiceState_TracingSession(const TracingServiceState_TracingSession&) = default;
+TracingServiceState_TracingSession& TracingServiceState_TracingSession::operator=(const TracingServiceState_TracingSession&) = default;
+TracingServiceState_TracingSession::TracingServiceState_TracingSession(TracingServiceState_TracingSession&&) noexcept = default;
+TracingServiceState_TracingSession& TracingServiceState_TracingSession::operator=(TracingServiceState_TracingSession&&) = default;
+
+bool TracingServiceState_TracingSession::operator==(const TracingServiceState_TracingSession& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(id_, other.id_)
+   && ::protozero::internal::gen_helpers::EqualsField(consumer_uid_, other.consumer_uid_)
+   && ::protozero::internal::gen_helpers::EqualsField(state_, other.state_)
+   && ::protozero::internal::gen_helpers::EqualsField(unique_session_name_, other.unique_session_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(buffer_size_kb_, other.buffer_size_kb_)
+   && ::protozero::internal::gen_helpers::EqualsField(duration_ms_, other.duration_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(num_data_sources_, other.num_data_sources_)
+   && ::protozero::internal::gen_helpers::EqualsField(start_realtime_ns_, other.start_realtime_ns_)
+   && ::protozero::internal::gen_helpers::EqualsField(bugreport_score_, other.bugreport_score_)
+   && ::protozero::internal::gen_helpers::EqualsField(bugreport_filename_, other.bugreport_filename_)
+   && ::protozero::internal::gen_helpers::EqualsField(is_started_, other.is_started_);
+}
+
+bool TracingServiceState_TracingSession::ParseFromArray(const void* raw, size_t size) {
+  buffer_size_kb_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* id */:
+        field.get(&id_);
+        break;
+      case 2 /* consumer_uid */:
+        field.get(&consumer_uid_);
+        break;
+      case 3 /* state */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &state_);
+        break;
+      case 4 /* unique_session_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &unique_session_name_);
+        break;
+      case 5 /* buffer_size_kb */:
+        buffer_size_kb_.emplace_back();
+        field.get(&buffer_size_kb_.back());
+        break;
+      case 6 /* duration_ms */:
+        field.get(&duration_ms_);
+        break;
+      case 7 /* num_data_sources */:
+        field.get(&num_data_sources_);
+        break;
+      case 8 /* start_realtime_ns */:
+        field.get(&start_realtime_ns_);
+        break;
+      case 9 /* bugreport_score */:
+        field.get(&bugreport_score_);
+        break;
+      case 10 /* bugreport_filename */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &bugreport_filename_);
+        break;
+      case 11 /* is_started */:
+        field.get(&is_started_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TracingServiceState_TracingSession::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TracingServiceState_TracingSession::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TracingServiceState_TracingSession::Serialize(::protozero::Message* msg) const {
+  // Field 1: id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, id_, msg);
+  }
+
+  // Field 2: consumer_uid
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, consumer_uid_, msg);
+  }
+
+  // Field 3: state
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeString(3, state_, msg);
+  }
+
+  // Field 4: unique_session_name
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeString(4, unique_session_name_, msg);
+  }
+
+  // Field 5: buffer_size_kb
+  for (auto& it : buffer_size_kb_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, it, msg);
+  }
+
+  // Field 6: duration_ms
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, duration_ms_, msg);
+  }
+
+  // Field 7: num_data_sources
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(7, num_data_sources_, msg);
+  }
+
+  // Field 8: start_realtime_ns
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(8, start_realtime_ns_, msg);
+  }
+
+  // Field 9: bugreport_score
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(9, bugreport_score_, msg);
+  }
+
+  // Field 10: bugreport_filename
+  if (_has_field_[10]) {
+    ::protozero::internal::gen_helpers::SerializeString(10, bugreport_filename_, msg);
+  }
+
+  // Field 11: is_started
+  if (_has_field_[11]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(11, is_started_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TracingServiceState_DataSource::TracingServiceState_DataSource() = default;
+TracingServiceState_DataSource::~TracingServiceState_DataSource() = default;
+TracingServiceState_DataSource::TracingServiceState_DataSource(const TracingServiceState_DataSource&) = default;
+TracingServiceState_DataSource& TracingServiceState_DataSource::operator=(const TracingServiceState_DataSource&) = default;
+TracingServiceState_DataSource::TracingServiceState_DataSource(TracingServiceState_DataSource&&) noexcept = default;
+TracingServiceState_DataSource& TracingServiceState_DataSource::operator=(TracingServiceState_DataSource&&) = default;
+
+bool TracingServiceState_DataSource::operator==(const TracingServiceState_DataSource& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(ds_descriptor_, other.ds_descriptor_)
+   && ::protozero::internal::gen_helpers::EqualsField(producer_id_, other.producer_id_);
+}
+
+bool TracingServiceState_DataSource::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* ds_descriptor */:
+        (*ds_descriptor_).ParseFromArray(field.data(), field.size());
+        break;
+      case 2 /* producer_id */:
+        field.get(&producer_id_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TracingServiceState_DataSource::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TracingServiceState_DataSource::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TracingServiceState_DataSource::Serialize(::protozero::Message* msg) const {
+  // Field 1: ds_descriptor
+  if (_has_field_[1]) {
+    (*ds_descriptor_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  // Field 2: producer_id
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, producer_id_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TracingServiceState_Producer::TracingServiceState_Producer() = default;
+TracingServiceState_Producer::~TracingServiceState_Producer() = default;
+TracingServiceState_Producer::TracingServiceState_Producer(const TracingServiceState_Producer&) = default;
+TracingServiceState_Producer& TracingServiceState_Producer::operator=(const TracingServiceState_Producer&) = default;
+TracingServiceState_Producer::TracingServiceState_Producer(TracingServiceState_Producer&&) noexcept = default;
+TracingServiceState_Producer& TracingServiceState_Producer::operator=(TracingServiceState_Producer&&) = default;
+
+bool TracingServiceState_Producer::operator==(const TracingServiceState_Producer& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(id_, other.id_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(pid_, other.pid_)
+   && ::protozero::internal::gen_helpers::EqualsField(uid_, other.uid_)
+   && ::protozero::internal::gen_helpers::EqualsField(sdk_version_, other.sdk_version_);
+}
+
+bool TracingServiceState_Producer::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* id */:
+        field.get(&id_);
+        break;
+      case 2 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 5 /* pid */:
+        field.get(&pid_);
+        break;
+      case 3 /* uid */:
+        field.get(&uid_);
+        break;
+      case 4 /* sdk_version */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &sdk_version_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TracingServiceState_Producer::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TracingServiceState_Producer::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TracingServiceState_Producer::Serialize(::protozero::Message* msg) const {
+  // Field 1: id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, id_, msg);
+  }
+
+  // Field 2: name
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, name_, msg);
+  }
+
+  // Field 5: pid
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, pid_, msg);
+  }
+
+  // Field 3: uid
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, uid_, msg);
+  }
+
+  // Field 4: sdk_version
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeString(4, sdk_version_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/common/track_event_descriptor.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/common/track_event_descriptor.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+TrackEventDescriptor::TrackEventDescriptor() = default;
+TrackEventDescriptor::~TrackEventDescriptor() = default;
+TrackEventDescriptor::TrackEventDescriptor(const TrackEventDescriptor&) = default;
+TrackEventDescriptor& TrackEventDescriptor::operator=(const TrackEventDescriptor&) = default;
+TrackEventDescriptor::TrackEventDescriptor(TrackEventDescriptor&&) noexcept = default;
+TrackEventDescriptor& TrackEventDescriptor::operator=(TrackEventDescriptor&&) = default;
+
+bool TrackEventDescriptor::operator==(const TrackEventDescriptor& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(available_categories_, other.available_categories_);
+}
+
+int TrackEventDescriptor::available_categories_size() const { return static_cast<int>(available_categories_.size()); }
+void TrackEventDescriptor::clear_available_categories() { available_categories_.clear(); }
+TrackEventCategory* TrackEventDescriptor::add_available_categories() { available_categories_.emplace_back(); return &available_categories_.back(); }
+bool TrackEventDescriptor::ParseFromArray(const void* raw, size_t size) {
+  available_categories_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* available_categories */:
+        available_categories_.emplace_back();
+        available_categories_.back().ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TrackEventDescriptor::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TrackEventDescriptor::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TrackEventDescriptor::Serialize(::protozero::Message* msg) const {
+  // Field 1: available_categories
+  for (auto& it : available_categories_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TrackEventCategory::TrackEventCategory() = default;
+TrackEventCategory::~TrackEventCategory() = default;
+TrackEventCategory::TrackEventCategory(const TrackEventCategory&) = default;
+TrackEventCategory& TrackEventCategory::operator=(const TrackEventCategory&) = default;
+TrackEventCategory::TrackEventCategory(TrackEventCategory&&) noexcept = default;
+TrackEventCategory& TrackEventCategory::operator=(TrackEventCategory&&) = default;
+
+bool TrackEventCategory::operator==(const TrackEventCategory& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(description_, other.description_)
+   && ::protozero::internal::gen_helpers::EqualsField(tags_, other.tags_);
+}
+
+bool TrackEventCategory::ParseFromArray(const void* raw, size_t size) {
+  tags_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 2 /* description */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &description_);
+        break;
+      case 3 /* tags */:
+        tags_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &tags_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TrackEventCategory::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TrackEventCategory::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TrackEventCategory::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
+  }
+
+  // Field 2: description
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, description_, msg);
+  }
+
+  // Field 3: tags
+  for (auto& it : tags_) {
+    ::protozero::internal::gen_helpers::SerializeString(3, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/android_game_intervention_list_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_game_intervention_list_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+AndroidGameInterventionListConfig::AndroidGameInterventionListConfig() = default;
+AndroidGameInterventionListConfig::~AndroidGameInterventionListConfig() = default;
+AndroidGameInterventionListConfig::AndroidGameInterventionListConfig(const AndroidGameInterventionListConfig&) = default;
+AndroidGameInterventionListConfig& AndroidGameInterventionListConfig::operator=(const AndroidGameInterventionListConfig&) = default;
+AndroidGameInterventionListConfig::AndroidGameInterventionListConfig(AndroidGameInterventionListConfig&&) noexcept = default;
+AndroidGameInterventionListConfig& AndroidGameInterventionListConfig::operator=(AndroidGameInterventionListConfig&&) = default;
+
+bool AndroidGameInterventionListConfig::operator==(const AndroidGameInterventionListConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(package_name_filter_, other.package_name_filter_);
+}
+
+bool AndroidGameInterventionListConfig::ParseFromArray(const void* raw, size_t size) {
+  package_name_filter_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* package_name_filter */:
+        package_name_filter_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &package_name_filter_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string AndroidGameInterventionListConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> AndroidGameInterventionListConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void AndroidGameInterventionListConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: package_name_filter
+  for (auto& it : package_name_filter_) {
+    ::protozero::internal::gen_helpers::SerializeString(1, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/android_input_event_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_input_event_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+AndroidInputEventConfig::AndroidInputEventConfig() = default;
+AndroidInputEventConfig::~AndroidInputEventConfig() = default;
+AndroidInputEventConfig::AndroidInputEventConfig(const AndroidInputEventConfig&) = default;
+AndroidInputEventConfig& AndroidInputEventConfig::operator=(const AndroidInputEventConfig&) = default;
+AndroidInputEventConfig::AndroidInputEventConfig(AndroidInputEventConfig&&) noexcept = default;
+AndroidInputEventConfig& AndroidInputEventConfig::operator=(AndroidInputEventConfig&&) = default;
+
+bool AndroidInputEventConfig::operator==(const AndroidInputEventConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(mode_, other.mode_)
+   && ::protozero::internal::gen_helpers::EqualsField(rules_, other.rules_)
+   && ::protozero::internal::gen_helpers::EqualsField(trace_dispatcher_input_events_, other.trace_dispatcher_input_events_)
+   && ::protozero::internal::gen_helpers::EqualsField(trace_dispatcher_window_dispatch_, other.trace_dispatcher_window_dispatch_);
+}
+
+int AndroidInputEventConfig::rules_size() const { return static_cast<int>(rules_.size()); }
+void AndroidInputEventConfig::clear_rules() { rules_.clear(); }
+AndroidInputEventConfig_TraceRule* AndroidInputEventConfig::add_rules() { rules_.emplace_back(); return &rules_.back(); }
+bool AndroidInputEventConfig::ParseFromArray(const void* raw, size_t size) {
+  rules_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* mode */:
+        field.get(&mode_);
+        break;
+      case 2 /* rules */:
+        rules_.emplace_back();
+        rules_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 3 /* trace_dispatcher_input_events */:
+        field.get(&trace_dispatcher_input_events_);
+        break;
+      case 4 /* trace_dispatcher_window_dispatch */:
+        field.get(&trace_dispatcher_window_dispatch_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string AndroidInputEventConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> AndroidInputEventConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void AndroidInputEventConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: mode
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, mode_, msg);
+  }
+
+  // Field 2: rules
+  for (auto& it : rules_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  // Field 3: trace_dispatcher_input_events
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, trace_dispatcher_input_events_, msg);
+  }
+
+  // Field 4: trace_dispatcher_window_dispatch
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, trace_dispatcher_window_dispatch_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+AndroidInputEventConfig_TraceRule::AndroidInputEventConfig_TraceRule() = default;
+AndroidInputEventConfig_TraceRule::~AndroidInputEventConfig_TraceRule() = default;
+AndroidInputEventConfig_TraceRule::AndroidInputEventConfig_TraceRule(const AndroidInputEventConfig_TraceRule&) = default;
+AndroidInputEventConfig_TraceRule& AndroidInputEventConfig_TraceRule::operator=(const AndroidInputEventConfig_TraceRule&) = default;
+AndroidInputEventConfig_TraceRule::AndroidInputEventConfig_TraceRule(AndroidInputEventConfig_TraceRule&&) noexcept = default;
+AndroidInputEventConfig_TraceRule& AndroidInputEventConfig_TraceRule::operator=(AndroidInputEventConfig_TraceRule&&) = default;
+
+bool AndroidInputEventConfig_TraceRule::operator==(const AndroidInputEventConfig_TraceRule& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(trace_level_, other.trace_level_)
+   && ::protozero::internal::gen_helpers::EqualsField(match_all_packages_, other.match_all_packages_)
+   && ::protozero::internal::gen_helpers::EqualsField(match_any_packages_, other.match_any_packages_)
+   && ::protozero::internal::gen_helpers::EqualsField(match_secure_, other.match_secure_)
+   && ::protozero::internal::gen_helpers::EqualsField(match_ime_connection_active_, other.match_ime_connection_active_);
+}
+
+bool AndroidInputEventConfig_TraceRule::ParseFromArray(const void* raw, size_t size) {
+  match_all_packages_.clear();
+  match_any_packages_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* trace_level */:
+        field.get(&trace_level_);
+        break;
+      case 2 /* match_all_packages */:
+        match_all_packages_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &match_all_packages_.back());
+        break;
+      case 3 /* match_any_packages */:
+        match_any_packages_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &match_any_packages_.back());
+        break;
+      case 4 /* match_secure */:
+        field.get(&match_secure_);
+        break;
+      case 5 /* match_ime_connection_active */:
+        field.get(&match_ime_connection_active_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string AndroidInputEventConfig_TraceRule::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> AndroidInputEventConfig_TraceRule::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void AndroidInputEventConfig_TraceRule::Serialize(::protozero::Message* msg) const {
+  // Field 1: trace_level
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, trace_level_, msg);
+  }
+
+  // Field 2: match_all_packages
+  for (auto& it : match_all_packages_) {
+    ::protozero::internal::gen_helpers::SerializeString(2, it, msg);
+  }
+
+  // Field 3: match_any_packages
+  for (auto& it : match_any_packages_) {
+    ::protozero::internal::gen_helpers::SerializeString(3, it, msg);
+  }
+
+  // Field 4: match_secure
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, match_secure_, msg);
+  }
+
+  // Field 5: match_ime_connection_active
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, match_ime_connection_active_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/android_log_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_log_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+AndroidLogConfig::AndroidLogConfig() = default;
+AndroidLogConfig::~AndroidLogConfig() = default;
+AndroidLogConfig::AndroidLogConfig(const AndroidLogConfig&) = default;
+AndroidLogConfig& AndroidLogConfig::operator=(const AndroidLogConfig&) = default;
+AndroidLogConfig::AndroidLogConfig(AndroidLogConfig&&) noexcept = default;
+AndroidLogConfig& AndroidLogConfig::operator=(AndroidLogConfig&&) = default;
+
+bool AndroidLogConfig::operator==(const AndroidLogConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(log_ids_, other.log_ids_)
+   && ::protozero::internal::gen_helpers::EqualsField(min_prio_, other.min_prio_)
+   && ::protozero::internal::gen_helpers::EqualsField(filter_tags_, other.filter_tags_);
+}
+
+bool AndroidLogConfig::ParseFromArray(const void* raw, size_t size) {
+  log_ids_.clear();
+  filter_tags_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* log_ids */:
+        log_ids_.emplace_back();
+        field.get(&log_ids_.back());
+        break;
+      case 3 /* min_prio */:
+        field.get(&min_prio_);
+        break;
+      case 4 /* filter_tags */:
+        filter_tags_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &filter_tags_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string AndroidLogConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> AndroidLogConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void AndroidLogConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: log_ids
+  for (auto& it : log_ids_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, it, msg);
+  }
+
+  // Field 3: min_prio
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, min_prio_, msg);
+  }
+
+  // Field 4: filter_tags
+  for (auto& it : filter_tags_) {
+    ::protozero::internal::gen_helpers::SerializeString(4, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/android_polled_state_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_polled_state_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+AndroidPolledStateConfig::AndroidPolledStateConfig() = default;
+AndroidPolledStateConfig::~AndroidPolledStateConfig() = default;
+AndroidPolledStateConfig::AndroidPolledStateConfig(const AndroidPolledStateConfig&) = default;
+AndroidPolledStateConfig& AndroidPolledStateConfig::operator=(const AndroidPolledStateConfig&) = default;
+AndroidPolledStateConfig::AndroidPolledStateConfig(AndroidPolledStateConfig&&) noexcept = default;
+AndroidPolledStateConfig& AndroidPolledStateConfig::operator=(AndroidPolledStateConfig&&) = default;
+
+bool AndroidPolledStateConfig::operator==(const AndroidPolledStateConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(poll_ms_, other.poll_ms_);
+}
+
+bool AndroidPolledStateConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* poll_ms */:
+        field.get(&poll_ms_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string AndroidPolledStateConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> AndroidPolledStateConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void AndroidPolledStateConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: poll_ms
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, poll_ms_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/android_sdk_sysprop_guard_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_sdk_sysprop_guard_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+AndroidSdkSyspropGuardConfig::AndroidSdkSyspropGuardConfig() = default;
+AndroidSdkSyspropGuardConfig::~AndroidSdkSyspropGuardConfig() = default;
+AndroidSdkSyspropGuardConfig::AndroidSdkSyspropGuardConfig(const AndroidSdkSyspropGuardConfig&) = default;
+AndroidSdkSyspropGuardConfig& AndroidSdkSyspropGuardConfig::operator=(const AndroidSdkSyspropGuardConfig&) = default;
+AndroidSdkSyspropGuardConfig::AndroidSdkSyspropGuardConfig(AndroidSdkSyspropGuardConfig&&) noexcept = default;
+AndroidSdkSyspropGuardConfig& AndroidSdkSyspropGuardConfig::operator=(AndroidSdkSyspropGuardConfig&&) = default;
+
+bool AndroidSdkSyspropGuardConfig::operator==(const AndroidSdkSyspropGuardConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(surfaceflinger_skia_track_events_, other.surfaceflinger_skia_track_events_)
+   && ::protozero::internal::gen_helpers::EqualsField(hwui_skia_track_events_, other.hwui_skia_track_events_)
+   && ::protozero::internal::gen_helpers::EqualsField(hwui_package_name_filter_, other.hwui_package_name_filter_);
+}
+
+bool AndroidSdkSyspropGuardConfig::ParseFromArray(const void* raw, size_t size) {
+  hwui_package_name_filter_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* surfaceflinger_skia_track_events */:
+        field.get(&surfaceflinger_skia_track_events_);
+        break;
+      case 2 /* hwui_skia_track_events */:
+        field.get(&hwui_skia_track_events_);
+        break;
+      case 3 /* hwui_package_name_filter */:
+        hwui_package_name_filter_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &hwui_package_name_filter_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string AndroidSdkSyspropGuardConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> AndroidSdkSyspropGuardConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void AndroidSdkSyspropGuardConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: surfaceflinger_skia_track_events
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, surfaceflinger_skia_track_events_, msg);
+  }
+
+  // Field 2: hwui_skia_track_events
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, hwui_skia_track_events_, msg);
+  }
+
+  // Field 3: hwui_package_name_filter
+  for (auto& it : hwui_package_name_filter_) {
+    ::protozero::internal::gen_helpers::SerializeString(3, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/android_system_property_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_system_property_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+AndroidSystemPropertyConfig::AndroidSystemPropertyConfig() = default;
+AndroidSystemPropertyConfig::~AndroidSystemPropertyConfig() = default;
+AndroidSystemPropertyConfig::AndroidSystemPropertyConfig(const AndroidSystemPropertyConfig&) = default;
+AndroidSystemPropertyConfig& AndroidSystemPropertyConfig::operator=(const AndroidSystemPropertyConfig&) = default;
+AndroidSystemPropertyConfig::AndroidSystemPropertyConfig(AndroidSystemPropertyConfig&&) noexcept = default;
+AndroidSystemPropertyConfig& AndroidSystemPropertyConfig::operator=(AndroidSystemPropertyConfig&&) = default;
+
+bool AndroidSystemPropertyConfig::operator==(const AndroidSystemPropertyConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(poll_ms_, other.poll_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(property_name_, other.property_name_);
+}
+
+bool AndroidSystemPropertyConfig::ParseFromArray(const void* raw, size_t size) {
+  property_name_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* poll_ms */:
+        field.get(&poll_ms_);
+        break;
+      case 2 /* property_name */:
+        property_name_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &property_name_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string AndroidSystemPropertyConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> AndroidSystemPropertyConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void AndroidSystemPropertyConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: poll_ms
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, poll_ms_, msg);
+  }
+
+  // Field 2: property_name
+  for (auto& it : property_name_) {
+    ::protozero::internal::gen_helpers::SerializeString(2, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/network_trace_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/network_trace_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+NetworkPacketTraceConfig::NetworkPacketTraceConfig() = default;
+NetworkPacketTraceConfig::~NetworkPacketTraceConfig() = default;
+NetworkPacketTraceConfig::NetworkPacketTraceConfig(const NetworkPacketTraceConfig&) = default;
+NetworkPacketTraceConfig& NetworkPacketTraceConfig::operator=(const NetworkPacketTraceConfig&) = default;
+NetworkPacketTraceConfig::NetworkPacketTraceConfig(NetworkPacketTraceConfig&&) noexcept = default;
+NetworkPacketTraceConfig& NetworkPacketTraceConfig::operator=(NetworkPacketTraceConfig&&) = default;
+
+bool NetworkPacketTraceConfig::operator==(const NetworkPacketTraceConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(poll_ms_, other.poll_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(aggregation_threshold_, other.aggregation_threshold_)
+   && ::protozero::internal::gen_helpers::EqualsField(intern_limit_, other.intern_limit_)
+   && ::protozero::internal::gen_helpers::EqualsField(drop_local_port_, other.drop_local_port_)
+   && ::protozero::internal::gen_helpers::EqualsField(drop_remote_port_, other.drop_remote_port_)
+   && ::protozero::internal::gen_helpers::EqualsField(drop_tcp_flags_, other.drop_tcp_flags_);
+}
+
+bool NetworkPacketTraceConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* poll_ms */:
+        field.get(&poll_ms_);
+        break;
+      case 2 /* aggregation_threshold */:
+        field.get(&aggregation_threshold_);
+        break;
+      case 3 /* intern_limit */:
+        field.get(&intern_limit_);
+        break;
+      case 4 /* drop_local_port */:
+        field.get(&drop_local_port_);
+        break;
+      case 5 /* drop_remote_port */:
+        field.get(&drop_remote_port_);
+        break;
+      case 6 /* drop_tcp_flags */:
+        field.get(&drop_tcp_flags_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string NetworkPacketTraceConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> NetworkPacketTraceConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void NetworkPacketTraceConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: poll_ms
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, poll_ms_, msg);
+  }
+
+  // Field 2: aggregation_threshold
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, aggregation_threshold_, msg);
+  }
+
+  // Field 3: intern_limit
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, intern_limit_, msg);
+  }
+
+  // Field 4: drop_local_port
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, drop_local_port_, msg);
+  }
+
+  // Field 5: drop_remote_port
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, drop_remote_port_, msg);
+  }
+
+  // Field 6: drop_tcp_flags
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(6, drop_tcp_flags_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/packages_list_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/packages_list_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+PackagesListConfig::PackagesListConfig() = default;
+PackagesListConfig::~PackagesListConfig() = default;
+PackagesListConfig::PackagesListConfig(const PackagesListConfig&) = default;
+PackagesListConfig& PackagesListConfig::operator=(const PackagesListConfig&) = default;
+PackagesListConfig::PackagesListConfig(PackagesListConfig&&) noexcept = default;
+PackagesListConfig& PackagesListConfig::operator=(PackagesListConfig&&) = default;
+
+bool PackagesListConfig::operator==(const PackagesListConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(package_name_filter_, other.package_name_filter_);
+}
+
+bool PackagesListConfig::ParseFromArray(const void* raw, size_t size) {
+  package_name_filter_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* package_name_filter */:
+        package_name_filter_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &package_name_filter_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string PackagesListConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> PackagesListConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void PackagesListConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: package_name_filter
+  for (auto& it : package_name_filter_) {
+    ::protozero::internal::gen_helpers::SerializeString(1, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/pixel_modem_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/pixel_modem_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+PixelModemConfig::PixelModemConfig() = default;
+PixelModemConfig::~PixelModemConfig() = default;
+PixelModemConfig::PixelModemConfig(const PixelModemConfig&) = default;
+PixelModemConfig& PixelModemConfig::operator=(const PixelModemConfig&) = default;
+PixelModemConfig::PixelModemConfig(PixelModemConfig&&) noexcept = default;
+PixelModemConfig& PixelModemConfig::operator=(PixelModemConfig&&) = default;
+
+bool PixelModemConfig::operator==(const PixelModemConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(event_group_, other.event_group_)
+   && ::protozero::internal::gen_helpers::EqualsField(pigweed_hash_allow_list_, other.pigweed_hash_allow_list_)
+   && ::protozero::internal::gen_helpers::EqualsField(pigweed_hash_deny_list_, other.pigweed_hash_deny_list_);
+}
+
+bool PixelModemConfig::ParseFromArray(const void* raw, size_t size) {
+  pigweed_hash_allow_list_.clear();
+  pigweed_hash_deny_list_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* event_group */:
+        field.get(&event_group_);
+        break;
+      case 2 /* pigweed_hash_allow_list */:
+        pigweed_hash_allow_list_.emplace_back();
+        field.get(&pigweed_hash_allow_list_.back());
+        break;
+      case 3 /* pigweed_hash_deny_list */:
+        pigweed_hash_deny_list_.emplace_back();
+        field.get(&pigweed_hash_deny_list_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string PixelModemConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> PixelModemConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void PixelModemConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: event_group
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, event_group_, msg);
+  }
+
+  // Field 2: pigweed_hash_allow_list
+  for (auto& it : pigweed_hash_allow_list_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, it, msg);
+  }
+
+  // Field 3: pigweed_hash_deny_list
+  for (auto& it : pigweed_hash_deny_list_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/protolog_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/protolog_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/protolog_common.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ProtoLogGroup::ProtoLogGroup() = default;
+ProtoLogGroup::~ProtoLogGroup() = default;
+ProtoLogGroup::ProtoLogGroup(const ProtoLogGroup&) = default;
+ProtoLogGroup& ProtoLogGroup::operator=(const ProtoLogGroup&) = default;
+ProtoLogGroup::ProtoLogGroup(ProtoLogGroup&&) noexcept = default;
+ProtoLogGroup& ProtoLogGroup::operator=(ProtoLogGroup&&) = default;
+
+bool ProtoLogGroup::operator==(const ProtoLogGroup& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(group_name_, other.group_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(log_from_, other.log_from_)
+   && ::protozero::internal::gen_helpers::EqualsField(collect_stacktrace_, other.collect_stacktrace_);
+}
+
+bool ProtoLogGroup::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* group_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &group_name_);
+        break;
+      case 2 /* log_from */:
+        field.get(&log_from_);
+        break;
+      case 3 /* collect_stacktrace */:
+        field.get(&collect_stacktrace_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ProtoLogGroup::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ProtoLogGroup::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ProtoLogGroup::Serialize(::protozero::Message* msg) const {
+  // Field 1: group_name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, group_name_, msg);
+  }
+
+  // Field 2: log_from
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, log_from_, msg);
+  }
+
+  // Field 3: collect_stacktrace
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, collect_stacktrace_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+ProtoLogConfig::ProtoLogConfig() = default;
+ProtoLogConfig::~ProtoLogConfig() = default;
+ProtoLogConfig::ProtoLogConfig(const ProtoLogConfig&) = default;
+ProtoLogConfig& ProtoLogConfig::operator=(const ProtoLogConfig&) = default;
+ProtoLogConfig::ProtoLogConfig(ProtoLogConfig&&) noexcept = default;
+ProtoLogConfig& ProtoLogConfig::operator=(ProtoLogConfig&&) = default;
+
+bool ProtoLogConfig::operator==(const ProtoLogConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(group_overrides_, other.group_overrides_)
+   && ::protozero::internal::gen_helpers::EqualsField(tracing_mode_, other.tracing_mode_);
+}
+
+int ProtoLogConfig::group_overrides_size() const { return static_cast<int>(group_overrides_.size()); }
+void ProtoLogConfig::clear_group_overrides() { group_overrides_.clear(); }
+ProtoLogGroup* ProtoLogConfig::add_group_overrides() { group_overrides_.emplace_back(); return &group_overrides_.back(); }
+bool ProtoLogConfig::ParseFromArray(const void* raw, size_t size) {
+  group_overrides_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* group_overrides */:
+        group_overrides_.emplace_back();
+        group_overrides_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 2 /* tracing_mode */:
+        field.get(&tracing_mode_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ProtoLogConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ProtoLogConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ProtoLogConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: group_overrides
+  for (auto& it : group_overrides_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  // Field 2: tracing_mode
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, tracing_mode_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/surfaceflinger_layers_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_layers_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+SurfaceFlingerLayersConfig::SurfaceFlingerLayersConfig() = default;
+SurfaceFlingerLayersConfig::~SurfaceFlingerLayersConfig() = default;
+SurfaceFlingerLayersConfig::SurfaceFlingerLayersConfig(const SurfaceFlingerLayersConfig&) = default;
+SurfaceFlingerLayersConfig& SurfaceFlingerLayersConfig::operator=(const SurfaceFlingerLayersConfig&) = default;
+SurfaceFlingerLayersConfig::SurfaceFlingerLayersConfig(SurfaceFlingerLayersConfig&&) noexcept = default;
+SurfaceFlingerLayersConfig& SurfaceFlingerLayersConfig::operator=(SurfaceFlingerLayersConfig&&) = default;
+
+bool SurfaceFlingerLayersConfig::operator==(const SurfaceFlingerLayersConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(mode_, other.mode_)
+   && ::protozero::internal::gen_helpers::EqualsField(trace_flags_, other.trace_flags_);
+}
+
+bool SurfaceFlingerLayersConfig::ParseFromArray(const void* raw, size_t size) {
+  trace_flags_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* mode */:
+        field.get(&mode_);
+        break;
+      case 2 /* trace_flags */:
+        trace_flags_.emplace_back();
+        field.get(&trace_flags_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string SurfaceFlingerLayersConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> SurfaceFlingerLayersConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void SurfaceFlingerLayersConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: mode
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, mode_, msg);
+  }
+
+  // Field 2: trace_flags
+  for (auto& it : trace_flags_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/surfaceflinger_transactions_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_transactions_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+SurfaceFlingerTransactionsConfig::SurfaceFlingerTransactionsConfig() = default;
+SurfaceFlingerTransactionsConfig::~SurfaceFlingerTransactionsConfig() = default;
+SurfaceFlingerTransactionsConfig::SurfaceFlingerTransactionsConfig(const SurfaceFlingerTransactionsConfig&) = default;
+SurfaceFlingerTransactionsConfig& SurfaceFlingerTransactionsConfig::operator=(const SurfaceFlingerTransactionsConfig&) = default;
+SurfaceFlingerTransactionsConfig::SurfaceFlingerTransactionsConfig(SurfaceFlingerTransactionsConfig&&) noexcept = default;
+SurfaceFlingerTransactionsConfig& SurfaceFlingerTransactionsConfig::operator=(SurfaceFlingerTransactionsConfig&&) = default;
+
+bool SurfaceFlingerTransactionsConfig::operator==(const SurfaceFlingerTransactionsConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(mode_, other.mode_);
+}
+
+bool SurfaceFlingerTransactionsConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* mode */:
+        field.get(&mode_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string SurfaceFlingerTransactionsConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> SurfaceFlingerTransactionsConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void SurfaceFlingerTransactionsConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: mode
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, mode_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/ftrace/ftrace_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/ftrace/ftrace_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+FtraceConfig::FtraceConfig() = default;
+FtraceConfig::~FtraceConfig() = default;
+FtraceConfig::FtraceConfig(const FtraceConfig&) = default;
+FtraceConfig& FtraceConfig::operator=(const FtraceConfig&) = default;
+FtraceConfig::FtraceConfig(FtraceConfig&&) noexcept = default;
+FtraceConfig& FtraceConfig::operator=(FtraceConfig&&) = default;
+
+bool FtraceConfig::operator==(const FtraceConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(ftrace_events_, other.ftrace_events_)
+   && ::protozero::internal::gen_helpers::EqualsField(atrace_categories_, other.atrace_categories_)
+   && ::protozero::internal::gen_helpers::EqualsField(atrace_apps_, other.atrace_apps_)
+   && ::protozero::internal::gen_helpers::EqualsField(buffer_size_kb_, other.buffer_size_kb_)
+   && ::protozero::internal::gen_helpers::EqualsField(drain_period_ms_, other.drain_period_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(drain_buffer_percent_, other.drain_buffer_percent_)
+   && ::protozero::internal::gen_helpers::EqualsField(compact_sched_, other.compact_sched_)
+   && ::protozero::internal::gen_helpers::EqualsField(print_filter_, other.print_filter_)
+   && ::protozero::internal::gen_helpers::EqualsField(symbolize_ksyms_, other.symbolize_ksyms_)
+   && ::protozero::internal::gen_helpers::EqualsField(ksyms_mem_policy_, other.ksyms_mem_policy_)
+   && ::protozero::internal::gen_helpers::EqualsField(initialize_ksyms_synchronously_for_testing_, other.initialize_ksyms_synchronously_for_testing_)
+   && ::protozero::internal::gen_helpers::EqualsField(throttle_rss_stat_, other.throttle_rss_stat_)
+   && ::protozero::internal::gen_helpers::EqualsField(disable_generic_events_, other.disable_generic_events_)
+   && ::protozero::internal::gen_helpers::EqualsField(syscall_events_, other.syscall_events_)
+   && ::protozero::internal::gen_helpers::EqualsField(enable_function_graph_, other.enable_function_graph_)
+   && ::protozero::internal::gen_helpers::EqualsField(function_filters_, other.function_filters_)
+   && ::protozero::internal::gen_helpers::EqualsField(function_graph_roots_, other.function_graph_roots_)
+   && ::protozero::internal::gen_helpers::EqualsField(preserve_ftrace_buffer_, other.preserve_ftrace_buffer_)
+   && ::protozero::internal::gen_helpers::EqualsField(use_monotonic_raw_clock_, other.use_monotonic_raw_clock_)
+   && ::protozero::internal::gen_helpers::EqualsField(instance_name_, other.instance_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(buffer_size_lower_bound_, other.buffer_size_lower_bound_);
+}
+
+bool FtraceConfig::ParseFromArray(const void* raw, size_t size) {
+  ftrace_events_.clear();
+  atrace_categories_.clear();
+  atrace_apps_.clear();
+  syscall_events_.clear();
+  function_filters_.clear();
+  function_graph_roots_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* ftrace_events */:
+        ftrace_events_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &ftrace_events_.back());
+        break;
+      case 2 /* atrace_categories */:
+        atrace_categories_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &atrace_categories_.back());
+        break;
+      case 3 /* atrace_apps */:
+        atrace_apps_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &atrace_apps_.back());
+        break;
+      case 10 /* buffer_size_kb */:
+        field.get(&buffer_size_kb_);
+        break;
+      case 11 /* drain_period_ms */:
+        field.get(&drain_period_ms_);
+        break;
+      case 26 /* drain_buffer_percent */:
+        field.get(&drain_buffer_percent_);
+        break;
+      case 12 /* compact_sched */:
+        (*compact_sched_).ParseFromArray(field.data(), field.size());
+        break;
+      case 22 /* print_filter */:
+        (*print_filter_).ParseFromArray(field.data(), field.size());
+        break;
+      case 13 /* symbolize_ksyms */:
+        field.get(&symbolize_ksyms_);
+        break;
+      case 17 /* ksyms_mem_policy */:
+        field.get(&ksyms_mem_policy_);
+        break;
+      case 14 /* initialize_ksyms_synchronously_for_testing */:
+        field.get(&initialize_ksyms_synchronously_for_testing_);
+        break;
+      case 15 /* throttle_rss_stat */:
+        field.get(&throttle_rss_stat_);
+        break;
+      case 16 /* disable_generic_events */:
+        field.get(&disable_generic_events_);
+        break;
+      case 18 /* syscall_events */:
+        syscall_events_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &syscall_events_.back());
+        break;
+      case 19 /* enable_function_graph */:
+        field.get(&enable_function_graph_);
+        break;
+      case 20 /* function_filters */:
+        function_filters_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &function_filters_.back());
+        break;
+      case 21 /* function_graph_roots */:
+        function_graph_roots_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &function_graph_roots_.back());
+        break;
+      case 23 /* preserve_ftrace_buffer */:
+        field.get(&preserve_ftrace_buffer_);
+        break;
+      case 24 /* use_monotonic_raw_clock */:
+        field.get(&use_monotonic_raw_clock_);
+        break;
+      case 25 /* instance_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &instance_name_);
+        break;
+      case 27 /* buffer_size_lower_bound */:
+        field.get(&buffer_size_lower_bound_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string FtraceConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FtraceConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FtraceConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: ftrace_events
+  for (auto& it : ftrace_events_) {
+    ::protozero::internal::gen_helpers::SerializeString(1, it, msg);
+  }
+
+  // Field 2: atrace_categories
+  for (auto& it : atrace_categories_) {
+    ::protozero::internal::gen_helpers::SerializeString(2, it, msg);
+  }
+
+  // Field 3: atrace_apps
+  for (auto& it : atrace_apps_) {
+    ::protozero::internal::gen_helpers::SerializeString(3, it, msg);
+  }
+
+  // Field 10: buffer_size_kb
+  if (_has_field_[10]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(10, buffer_size_kb_, msg);
+  }
+
+  // Field 11: drain_period_ms
+  if (_has_field_[11]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(11, drain_period_ms_, msg);
+  }
+
+  // Field 26: drain_buffer_percent
+  if (_has_field_[26]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(26, drain_buffer_percent_, msg);
+  }
+
+  // Field 12: compact_sched
+  if (_has_field_[12]) {
+    (*compact_sched_).Serialize(msg->BeginNestedMessage<::protozero::Message>(12));
+  }
+
+  // Field 22: print_filter
+  if (_has_field_[22]) {
+    (*print_filter_).Serialize(msg->BeginNestedMessage<::protozero::Message>(22));
+  }
+
+  // Field 13: symbolize_ksyms
+  if (_has_field_[13]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(13, symbolize_ksyms_, msg);
+  }
+
+  // Field 17: ksyms_mem_policy
+  if (_has_field_[17]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(17, ksyms_mem_policy_, msg);
+  }
+
+  // Field 14: initialize_ksyms_synchronously_for_testing
+  if (_has_field_[14]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(14, initialize_ksyms_synchronously_for_testing_, msg);
+  }
+
+  // Field 15: throttle_rss_stat
+  if (_has_field_[15]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(15, throttle_rss_stat_, msg);
+  }
+
+  // Field 16: disable_generic_events
+  if (_has_field_[16]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(16, disable_generic_events_, msg);
+  }
+
+  // Field 18: syscall_events
+  for (auto& it : syscall_events_) {
+    ::protozero::internal::gen_helpers::SerializeString(18, it, msg);
+  }
+
+  // Field 19: enable_function_graph
+  if (_has_field_[19]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(19, enable_function_graph_, msg);
+  }
+
+  // Field 20: function_filters
+  for (auto& it : function_filters_) {
+    ::protozero::internal::gen_helpers::SerializeString(20, it, msg);
+  }
+
+  // Field 21: function_graph_roots
+  for (auto& it : function_graph_roots_) {
+    ::protozero::internal::gen_helpers::SerializeString(21, it, msg);
+  }
+
+  // Field 23: preserve_ftrace_buffer
+  if (_has_field_[23]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(23, preserve_ftrace_buffer_, msg);
+  }
+
+  // Field 24: use_monotonic_raw_clock
+  if (_has_field_[24]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(24, use_monotonic_raw_clock_, msg);
+  }
+
+  // Field 25: instance_name
+  if (_has_field_[25]) {
+    ::protozero::internal::gen_helpers::SerializeString(25, instance_name_, msg);
+  }
+
+  // Field 27: buffer_size_lower_bound
+  if (_has_field_[27]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(27, buffer_size_lower_bound_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+FtraceConfig_PrintFilter::FtraceConfig_PrintFilter() = default;
+FtraceConfig_PrintFilter::~FtraceConfig_PrintFilter() = default;
+FtraceConfig_PrintFilter::FtraceConfig_PrintFilter(const FtraceConfig_PrintFilter&) = default;
+FtraceConfig_PrintFilter& FtraceConfig_PrintFilter::operator=(const FtraceConfig_PrintFilter&) = default;
+FtraceConfig_PrintFilter::FtraceConfig_PrintFilter(FtraceConfig_PrintFilter&&) noexcept = default;
+FtraceConfig_PrintFilter& FtraceConfig_PrintFilter::operator=(FtraceConfig_PrintFilter&&) = default;
+
+bool FtraceConfig_PrintFilter::operator==(const FtraceConfig_PrintFilter& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(rules_, other.rules_);
+}
+
+int FtraceConfig_PrintFilter::rules_size() const { return static_cast<int>(rules_.size()); }
+void FtraceConfig_PrintFilter::clear_rules() { rules_.clear(); }
+FtraceConfig_PrintFilter_Rule* FtraceConfig_PrintFilter::add_rules() { rules_.emplace_back(); return &rules_.back(); }
+bool FtraceConfig_PrintFilter::ParseFromArray(const void* raw, size_t size) {
+  rules_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* rules */:
+        rules_.emplace_back();
+        rules_.back().ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string FtraceConfig_PrintFilter::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FtraceConfig_PrintFilter::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FtraceConfig_PrintFilter::Serialize(::protozero::Message* msg) const {
+  // Field 1: rules
+  for (auto& it : rules_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+FtraceConfig_PrintFilter_Rule::FtraceConfig_PrintFilter_Rule() = default;
+FtraceConfig_PrintFilter_Rule::~FtraceConfig_PrintFilter_Rule() = default;
+FtraceConfig_PrintFilter_Rule::FtraceConfig_PrintFilter_Rule(const FtraceConfig_PrintFilter_Rule&) = default;
+FtraceConfig_PrintFilter_Rule& FtraceConfig_PrintFilter_Rule::operator=(const FtraceConfig_PrintFilter_Rule&) = default;
+FtraceConfig_PrintFilter_Rule::FtraceConfig_PrintFilter_Rule(FtraceConfig_PrintFilter_Rule&&) noexcept = default;
+FtraceConfig_PrintFilter_Rule& FtraceConfig_PrintFilter_Rule::operator=(FtraceConfig_PrintFilter_Rule&&) = default;
+
+bool FtraceConfig_PrintFilter_Rule::operator==(const FtraceConfig_PrintFilter_Rule& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(prefix_, other.prefix_)
+   && ::protozero::internal::gen_helpers::EqualsField(atrace_msg_, other.atrace_msg_)
+   && ::protozero::internal::gen_helpers::EqualsField(allow_, other.allow_);
+}
+
+bool FtraceConfig_PrintFilter_Rule::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* prefix */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &prefix_);
+        break;
+      case 3 /* atrace_msg */:
+        (*atrace_msg_).ParseFromArray(field.data(), field.size());
+        break;
+      case 2 /* allow */:
+        field.get(&allow_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string FtraceConfig_PrintFilter_Rule::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FtraceConfig_PrintFilter_Rule::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FtraceConfig_PrintFilter_Rule::Serialize(::protozero::Message* msg) const {
+  // Field 1: prefix
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, prefix_, msg);
+  }
+
+  // Field 3: atrace_msg
+  if (_has_field_[3]) {
+    (*atrace_msg_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
+  }
+
+  // Field 2: allow
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, allow_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+FtraceConfig_PrintFilter_Rule_AtraceMessage::FtraceConfig_PrintFilter_Rule_AtraceMessage() = default;
+FtraceConfig_PrintFilter_Rule_AtraceMessage::~FtraceConfig_PrintFilter_Rule_AtraceMessage() = default;
+FtraceConfig_PrintFilter_Rule_AtraceMessage::FtraceConfig_PrintFilter_Rule_AtraceMessage(const FtraceConfig_PrintFilter_Rule_AtraceMessage&) = default;
+FtraceConfig_PrintFilter_Rule_AtraceMessage& FtraceConfig_PrintFilter_Rule_AtraceMessage::operator=(const FtraceConfig_PrintFilter_Rule_AtraceMessage&) = default;
+FtraceConfig_PrintFilter_Rule_AtraceMessage::FtraceConfig_PrintFilter_Rule_AtraceMessage(FtraceConfig_PrintFilter_Rule_AtraceMessage&&) noexcept = default;
+FtraceConfig_PrintFilter_Rule_AtraceMessage& FtraceConfig_PrintFilter_Rule_AtraceMessage::operator=(FtraceConfig_PrintFilter_Rule_AtraceMessage&&) = default;
+
+bool FtraceConfig_PrintFilter_Rule_AtraceMessage::operator==(const FtraceConfig_PrintFilter_Rule_AtraceMessage& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(type_, other.type_)
+   && ::protozero::internal::gen_helpers::EqualsField(prefix_, other.prefix_);
+}
+
+bool FtraceConfig_PrintFilter_Rule_AtraceMessage::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* type */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &type_);
+        break;
+      case 2 /* prefix */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &prefix_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string FtraceConfig_PrintFilter_Rule_AtraceMessage::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FtraceConfig_PrintFilter_Rule_AtraceMessage::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FtraceConfig_PrintFilter_Rule_AtraceMessage::Serialize(::protozero::Message* msg) const {
+  // Field 1: type
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, type_, msg);
+  }
+
+  // Field 2: prefix
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, prefix_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+FtraceConfig_CompactSchedConfig::FtraceConfig_CompactSchedConfig() = default;
+FtraceConfig_CompactSchedConfig::~FtraceConfig_CompactSchedConfig() = default;
+FtraceConfig_CompactSchedConfig::FtraceConfig_CompactSchedConfig(const FtraceConfig_CompactSchedConfig&) = default;
+FtraceConfig_CompactSchedConfig& FtraceConfig_CompactSchedConfig::operator=(const FtraceConfig_CompactSchedConfig&) = default;
+FtraceConfig_CompactSchedConfig::FtraceConfig_CompactSchedConfig(FtraceConfig_CompactSchedConfig&&) noexcept = default;
+FtraceConfig_CompactSchedConfig& FtraceConfig_CompactSchedConfig::operator=(FtraceConfig_CompactSchedConfig&&) = default;
+
+bool FtraceConfig_CompactSchedConfig::operator==(const FtraceConfig_CompactSchedConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(enabled_, other.enabled_);
+}
+
+bool FtraceConfig_CompactSchedConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* enabled */:
+        field.get(&enabled_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string FtraceConfig_CompactSchedConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FtraceConfig_CompactSchedConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FtraceConfig_CompactSchedConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: enabled
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, enabled_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/gpu/gpu_counter_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/gpu/gpu_counter_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+GpuCounterConfig::GpuCounterConfig() = default;
+GpuCounterConfig::~GpuCounterConfig() = default;
+GpuCounterConfig::GpuCounterConfig(const GpuCounterConfig&) = default;
+GpuCounterConfig& GpuCounterConfig::operator=(const GpuCounterConfig&) = default;
+GpuCounterConfig::GpuCounterConfig(GpuCounterConfig&&) noexcept = default;
+GpuCounterConfig& GpuCounterConfig::operator=(GpuCounterConfig&&) = default;
+
+bool GpuCounterConfig::operator==(const GpuCounterConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(counter_period_ns_, other.counter_period_ns_)
+   && ::protozero::internal::gen_helpers::EqualsField(counter_ids_, other.counter_ids_)
+   && ::protozero::internal::gen_helpers::EqualsField(instrumented_sampling_, other.instrumented_sampling_)
+   && ::protozero::internal::gen_helpers::EqualsField(fix_gpu_clock_, other.fix_gpu_clock_);
+}
+
+bool GpuCounterConfig::ParseFromArray(const void* raw, size_t size) {
+  counter_ids_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* counter_period_ns */:
+        field.get(&counter_period_ns_);
+        break;
+      case 2 /* counter_ids */:
+        counter_ids_.emplace_back();
+        field.get(&counter_ids_.back());
+        break;
+      case 3 /* instrumented_sampling */:
+        field.get(&instrumented_sampling_);
+        break;
+      case 4 /* fix_gpu_clock */:
+        field.get(&fix_gpu_clock_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string GpuCounterConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GpuCounterConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void GpuCounterConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: counter_period_ns
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, counter_period_ns_, msg);
+  }
+
+  // Field 2: counter_ids
+  for (auto& it : counter_ids_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, it, msg);
+  }
+
+  // Field 3: instrumented_sampling
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, instrumented_sampling_, msg);
+  }
+
+  // Field 4: fix_gpu_clock
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, fix_gpu_clock_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/gpu/vulkan_memory_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/gpu/vulkan_memory_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+VulkanMemoryConfig::VulkanMemoryConfig() = default;
+VulkanMemoryConfig::~VulkanMemoryConfig() = default;
+VulkanMemoryConfig::VulkanMemoryConfig(const VulkanMemoryConfig&) = default;
+VulkanMemoryConfig& VulkanMemoryConfig::operator=(const VulkanMemoryConfig&) = default;
+VulkanMemoryConfig::VulkanMemoryConfig(VulkanMemoryConfig&&) noexcept = default;
+VulkanMemoryConfig& VulkanMemoryConfig::operator=(VulkanMemoryConfig&&) = default;
+
+bool VulkanMemoryConfig::operator==(const VulkanMemoryConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(track_driver_memory_usage_, other.track_driver_memory_usage_)
+   && ::protozero::internal::gen_helpers::EqualsField(track_device_memory_usage_, other.track_device_memory_usage_);
+}
+
+bool VulkanMemoryConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* track_driver_memory_usage */:
+        field.get(&track_driver_memory_usage_);
+        break;
+      case 2 /* track_device_memory_usage */:
+        field.get(&track_device_memory_usage_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string VulkanMemoryConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> VulkanMemoryConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void VulkanMemoryConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: track_driver_memory_usage
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, track_driver_memory_usage_, msg);
+  }
+
+  // Field 2: track_device_memory_usage
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, track_device_memory_usage_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/inode_file/inode_file_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/inode_file/inode_file_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+InodeFileConfig::InodeFileConfig() = default;
+InodeFileConfig::~InodeFileConfig() = default;
+InodeFileConfig::InodeFileConfig(const InodeFileConfig&) = default;
+InodeFileConfig& InodeFileConfig::operator=(const InodeFileConfig&) = default;
+InodeFileConfig::InodeFileConfig(InodeFileConfig&&) noexcept = default;
+InodeFileConfig& InodeFileConfig::operator=(InodeFileConfig&&) = default;
+
+bool InodeFileConfig::operator==(const InodeFileConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(scan_interval_ms_, other.scan_interval_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(scan_delay_ms_, other.scan_delay_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(scan_batch_size_, other.scan_batch_size_)
+   && ::protozero::internal::gen_helpers::EqualsField(do_not_scan_, other.do_not_scan_)
+   && ::protozero::internal::gen_helpers::EqualsField(scan_mount_points_, other.scan_mount_points_)
+   && ::protozero::internal::gen_helpers::EqualsField(mount_point_mapping_, other.mount_point_mapping_);
+}
+
+int InodeFileConfig::mount_point_mapping_size() const { return static_cast<int>(mount_point_mapping_.size()); }
+void InodeFileConfig::clear_mount_point_mapping() { mount_point_mapping_.clear(); }
+InodeFileConfig_MountPointMappingEntry* InodeFileConfig::add_mount_point_mapping() { mount_point_mapping_.emplace_back(); return &mount_point_mapping_.back(); }
+bool InodeFileConfig::ParseFromArray(const void* raw, size_t size) {
+  scan_mount_points_.clear();
+  mount_point_mapping_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* scan_interval_ms */:
+        field.get(&scan_interval_ms_);
+        break;
+      case 2 /* scan_delay_ms */:
+        field.get(&scan_delay_ms_);
+        break;
+      case 3 /* scan_batch_size */:
+        field.get(&scan_batch_size_);
+        break;
+      case 4 /* do_not_scan */:
+        field.get(&do_not_scan_);
+        break;
+      case 5 /* scan_mount_points */:
+        scan_mount_points_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &scan_mount_points_.back());
+        break;
+      case 6 /* mount_point_mapping */:
+        mount_point_mapping_.emplace_back();
+        mount_point_mapping_.back().ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string InodeFileConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> InodeFileConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void InodeFileConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: scan_interval_ms
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, scan_interval_ms_, msg);
+  }
+
+  // Field 2: scan_delay_ms
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, scan_delay_ms_, msg);
+  }
+
+  // Field 3: scan_batch_size
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, scan_batch_size_, msg);
+  }
+
+  // Field 4: do_not_scan
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, do_not_scan_, msg);
+  }
+
+  // Field 5: scan_mount_points
+  for (auto& it : scan_mount_points_) {
+    ::protozero::internal::gen_helpers::SerializeString(5, it, msg);
+  }
+
+  // Field 6: mount_point_mapping
+  for (auto& it : mount_point_mapping_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+InodeFileConfig_MountPointMappingEntry::InodeFileConfig_MountPointMappingEntry() = default;
+InodeFileConfig_MountPointMappingEntry::~InodeFileConfig_MountPointMappingEntry() = default;
+InodeFileConfig_MountPointMappingEntry::InodeFileConfig_MountPointMappingEntry(const InodeFileConfig_MountPointMappingEntry&) = default;
+InodeFileConfig_MountPointMappingEntry& InodeFileConfig_MountPointMappingEntry::operator=(const InodeFileConfig_MountPointMappingEntry&) = default;
+InodeFileConfig_MountPointMappingEntry::InodeFileConfig_MountPointMappingEntry(InodeFileConfig_MountPointMappingEntry&&) noexcept = default;
+InodeFileConfig_MountPointMappingEntry& InodeFileConfig_MountPointMappingEntry::operator=(InodeFileConfig_MountPointMappingEntry&&) = default;
+
+bool InodeFileConfig_MountPointMappingEntry::operator==(const InodeFileConfig_MountPointMappingEntry& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(mountpoint_, other.mountpoint_)
+   && ::protozero::internal::gen_helpers::EqualsField(scan_roots_, other.scan_roots_);
+}
+
+bool InodeFileConfig_MountPointMappingEntry::ParseFromArray(const void* raw, size_t size) {
+  scan_roots_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* mountpoint */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &mountpoint_);
+        break;
+      case 2 /* scan_roots */:
+        scan_roots_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &scan_roots_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string InodeFileConfig_MountPointMappingEntry::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> InodeFileConfig_MountPointMappingEntry::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void InodeFileConfig_MountPointMappingEntry::Serialize(::protozero::Message* msg) const {
+  // Field 1: mountpoint
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, mountpoint_, msg);
+  }
+
+  // Field 2: scan_roots
+  for (auto& it : scan_roots_) {
+    ::protozero::internal::gen_helpers::SerializeString(2, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/interceptors/console_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ConsoleConfig::ConsoleConfig() = default;
+ConsoleConfig::~ConsoleConfig() = default;
+ConsoleConfig::ConsoleConfig(const ConsoleConfig&) = default;
+ConsoleConfig& ConsoleConfig::operator=(const ConsoleConfig&) = default;
+ConsoleConfig::ConsoleConfig(ConsoleConfig&&) noexcept = default;
+ConsoleConfig& ConsoleConfig::operator=(ConsoleConfig&&) = default;
+
+bool ConsoleConfig::operator==(const ConsoleConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(output_, other.output_)
+   && ::protozero::internal::gen_helpers::EqualsField(enable_colors_, other.enable_colors_);
+}
+
+bool ConsoleConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* output */:
+        field.get(&output_);
+        break;
+      case 2 /* enable_colors */:
+        field.get(&enable_colors_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ConsoleConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ConsoleConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ConsoleConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: output
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, output_, msg);
+  }
+
+  // Field 2: enable_colors
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, enable_colors_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/power/android_power_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/power/android_power_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+AndroidPowerConfig::AndroidPowerConfig() = default;
+AndroidPowerConfig::~AndroidPowerConfig() = default;
+AndroidPowerConfig::AndroidPowerConfig(const AndroidPowerConfig&) = default;
+AndroidPowerConfig& AndroidPowerConfig::operator=(const AndroidPowerConfig&) = default;
+AndroidPowerConfig::AndroidPowerConfig(AndroidPowerConfig&&) noexcept = default;
+AndroidPowerConfig& AndroidPowerConfig::operator=(AndroidPowerConfig&&) = default;
+
+bool AndroidPowerConfig::operator==(const AndroidPowerConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(battery_poll_ms_, other.battery_poll_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(battery_counters_, other.battery_counters_)
+   && ::protozero::internal::gen_helpers::EqualsField(collect_power_rails_, other.collect_power_rails_)
+   && ::protozero::internal::gen_helpers::EqualsField(collect_energy_estimation_breakdown_, other.collect_energy_estimation_breakdown_)
+   && ::protozero::internal::gen_helpers::EqualsField(collect_entity_state_residency_, other.collect_entity_state_residency_);
+}
+
+bool AndroidPowerConfig::ParseFromArray(const void* raw, size_t size) {
+  battery_counters_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* battery_poll_ms */:
+        field.get(&battery_poll_ms_);
+        break;
+      case 2 /* battery_counters */:
+        battery_counters_.emplace_back();
+        field.get(&battery_counters_.back());
+        break;
+      case 3 /* collect_power_rails */:
+        field.get(&collect_power_rails_);
+        break;
+      case 4 /* collect_energy_estimation_breakdown */:
+        field.get(&collect_energy_estimation_breakdown_);
+        break;
+      case 5 /* collect_entity_state_residency */:
+        field.get(&collect_entity_state_residency_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string AndroidPowerConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> AndroidPowerConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void AndroidPowerConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: battery_poll_ms
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, battery_poll_ms_, msg);
+  }
+
+  // Field 2: battery_counters
+  for (auto& it : battery_counters_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, it, msg);
+  }
+
+  // Field 3: collect_power_rails
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, collect_power_rails_, msg);
+  }
+
+  // Field 4: collect_energy_estimation_breakdown
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, collect_energy_estimation_breakdown_, msg);
+  }
+
+  // Field 5: collect_entity_state_residency
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, collect_entity_state_residency_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/process_stats/process_stats_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/process_stats/process_stats_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ProcessStatsConfig::ProcessStatsConfig() = default;
+ProcessStatsConfig::~ProcessStatsConfig() = default;
+ProcessStatsConfig::ProcessStatsConfig(const ProcessStatsConfig&) = default;
+ProcessStatsConfig& ProcessStatsConfig::operator=(const ProcessStatsConfig&) = default;
+ProcessStatsConfig::ProcessStatsConfig(ProcessStatsConfig&&) noexcept = default;
+ProcessStatsConfig& ProcessStatsConfig::operator=(ProcessStatsConfig&&) = default;
+
+bool ProcessStatsConfig::operator==(const ProcessStatsConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(quirks_, other.quirks_)
+   && ::protozero::internal::gen_helpers::EqualsField(scan_all_processes_on_start_, other.scan_all_processes_on_start_)
+   && ::protozero::internal::gen_helpers::EqualsField(record_thread_names_, other.record_thread_names_)
+   && ::protozero::internal::gen_helpers::EqualsField(proc_stats_poll_ms_, other.proc_stats_poll_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(proc_stats_cache_ttl_ms_, other.proc_stats_cache_ttl_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(resolve_process_fds_, other.resolve_process_fds_)
+   && ::protozero::internal::gen_helpers::EqualsField(scan_smaps_rollup_, other.scan_smaps_rollup_)
+   && ::protozero::internal::gen_helpers::EqualsField(record_process_age_, other.record_process_age_)
+   && ::protozero::internal::gen_helpers::EqualsField(record_process_runtime_, other.record_process_runtime_);
+}
+
+bool ProcessStatsConfig::ParseFromArray(const void* raw, size_t size) {
+  quirks_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* quirks */:
+        quirks_.emplace_back();
+        field.get(&quirks_.back());
+        break;
+      case 2 /* scan_all_processes_on_start */:
+        field.get(&scan_all_processes_on_start_);
+        break;
+      case 3 /* record_thread_names */:
+        field.get(&record_thread_names_);
+        break;
+      case 4 /* proc_stats_poll_ms */:
+        field.get(&proc_stats_poll_ms_);
+        break;
+      case 6 /* proc_stats_cache_ttl_ms */:
+        field.get(&proc_stats_cache_ttl_ms_);
+        break;
+      case 9 /* resolve_process_fds */:
+        field.get(&resolve_process_fds_);
+        break;
+      case 10 /* scan_smaps_rollup */:
+        field.get(&scan_smaps_rollup_);
+        break;
+      case 11 /* record_process_age */:
+        field.get(&record_process_age_);
+        break;
+      case 12 /* record_process_runtime */:
+        field.get(&record_process_runtime_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ProcessStatsConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ProcessStatsConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ProcessStatsConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: quirks
+  for (auto& it : quirks_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, it, msg);
+  }
+
+  // Field 2: scan_all_processes_on_start
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, scan_all_processes_on_start_, msg);
+  }
+
+  // Field 3: record_thread_names
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, record_thread_names_, msg);
+  }
+
+  // Field 4: proc_stats_poll_ms
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, proc_stats_poll_ms_, msg);
+  }
+
+  // Field 6: proc_stats_cache_ttl_ms
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, proc_stats_cache_ttl_ms_, msg);
+  }
+
+  // Field 9: resolve_process_fds
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(9, resolve_process_fds_, msg);
+  }
+
+  // Field 10: scan_smaps_rollup
+  if (_has_field_[10]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(10, scan_smaps_rollup_, msg);
+  }
+
+  // Field 11: record_process_age
+  if (_has_field_[11]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(11, record_process_age_, msg);
+  }
+
+  // Field 12: record_process_runtime
+  if (_has_field_[12]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(12, record_process_runtime_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/profiling/heapprofd_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/heapprofd_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+HeapprofdConfig::HeapprofdConfig() = default;
+HeapprofdConfig::~HeapprofdConfig() = default;
+HeapprofdConfig::HeapprofdConfig(const HeapprofdConfig&) = default;
+HeapprofdConfig& HeapprofdConfig::operator=(const HeapprofdConfig&) = default;
+HeapprofdConfig::HeapprofdConfig(HeapprofdConfig&&) noexcept = default;
+HeapprofdConfig& HeapprofdConfig::operator=(HeapprofdConfig&&) = default;
+
+bool HeapprofdConfig::operator==(const HeapprofdConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(sampling_interval_bytes_, other.sampling_interval_bytes_)
+   && ::protozero::internal::gen_helpers::EqualsField(adaptive_sampling_shmem_threshold_, other.adaptive_sampling_shmem_threshold_)
+   && ::protozero::internal::gen_helpers::EqualsField(adaptive_sampling_max_sampling_interval_bytes_, other.adaptive_sampling_max_sampling_interval_bytes_)
+   && ::protozero::internal::gen_helpers::EqualsField(process_cmdline_, other.process_cmdline_)
+   && ::protozero::internal::gen_helpers::EqualsField(pid_, other.pid_)
+   && ::protozero::internal::gen_helpers::EqualsField(target_installed_by_, other.target_installed_by_)
+   && ::protozero::internal::gen_helpers::EqualsField(heaps_, other.heaps_)
+   && ::protozero::internal::gen_helpers::EqualsField(exclude_heaps_, other.exclude_heaps_)
+   && ::protozero::internal::gen_helpers::EqualsField(stream_allocations_, other.stream_allocations_)
+   && ::protozero::internal::gen_helpers::EqualsField(heap_sampling_intervals_, other.heap_sampling_intervals_)
+   && ::protozero::internal::gen_helpers::EqualsField(all_heaps_, other.all_heaps_)
+   && ::protozero::internal::gen_helpers::EqualsField(all_, other.all_)
+   && ::protozero::internal::gen_helpers::EqualsField(min_anonymous_memory_kb_, other.min_anonymous_memory_kb_)
+   && ::protozero::internal::gen_helpers::EqualsField(max_heapprofd_memory_kb_, other.max_heapprofd_memory_kb_)
+   && ::protozero::internal::gen_helpers::EqualsField(max_heapprofd_cpu_secs_, other.max_heapprofd_cpu_secs_)
+   && ::protozero::internal::gen_helpers::EqualsField(skip_symbol_prefix_, other.skip_symbol_prefix_)
+   && ::protozero::internal::gen_helpers::EqualsField(continuous_dump_config_, other.continuous_dump_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(shmem_size_bytes_, other.shmem_size_bytes_)
+   && ::protozero::internal::gen_helpers::EqualsField(block_client_, other.block_client_)
+   && ::protozero::internal::gen_helpers::EqualsField(block_client_timeout_us_, other.block_client_timeout_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(no_startup_, other.no_startup_)
+   && ::protozero::internal::gen_helpers::EqualsField(no_running_, other.no_running_)
+   && ::protozero::internal::gen_helpers::EqualsField(dump_at_max_, other.dump_at_max_)
+   && ::protozero::internal::gen_helpers::EqualsField(disable_fork_teardown_, other.disable_fork_teardown_)
+   && ::protozero::internal::gen_helpers::EqualsField(disable_vfork_detection_, other.disable_vfork_detection_);
+}
+
+bool HeapprofdConfig::ParseFromArray(const void* raw, size_t size) {
+  process_cmdline_.clear();
+  pid_.clear();
+  target_installed_by_.clear();
+  heaps_.clear();
+  exclude_heaps_.clear();
+  heap_sampling_intervals_.clear();
+  skip_symbol_prefix_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* sampling_interval_bytes */:
+        field.get(&sampling_interval_bytes_);
+        break;
+      case 24 /* adaptive_sampling_shmem_threshold */:
+        field.get(&adaptive_sampling_shmem_threshold_);
+        break;
+      case 25 /* adaptive_sampling_max_sampling_interval_bytes */:
+        field.get(&adaptive_sampling_max_sampling_interval_bytes_);
+        break;
+      case 2 /* process_cmdline */:
+        process_cmdline_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &process_cmdline_.back());
+        break;
+      case 4 /* pid */:
+        pid_.emplace_back();
+        field.get(&pid_.back());
+        break;
+      case 26 /* target_installed_by */:
+        target_installed_by_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &target_installed_by_.back());
+        break;
+      case 20 /* heaps */:
+        heaps_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &heaps_.back());
+        break;
+      case 27 /* exclude_heaps */:
+        exclude_heaps_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &exclude_heaps_.back());
+        break;
+      case 23 /* stream_allocations */:
+        field.get(&stream_allocations_);
+        break;
+      case 22 /* heap_sampling_intervals */:
+        heap_sampling_intervals_.emplace_back();
+        field.get(&heap_sampling_intervals_.back());
+        break;
+      case 21 /* all_heaps */:
+        field.get(&all_heaps_);
+        break;
+      case 5 /* all */:
+        field.get(&all_);
+        break;
+      case 15 /* min_anonymous_memory_kb */:
+        field.get(&min_anonymous_memory_kb_);
+        break;
+      case 16 /* max_heapprofd_memory_kb */:
+        field.get(&max_heapprofd_memory_kb_);
+        break;
+      case 17 /* max_heapprofd_cpu_secs */:
+        field.get(&max_heapprofd_cpu_secs_);
+        break;
+      case 7 /* skip_symbol_prefix */:
+        skip_symbol_prefix_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &skip_symbol_prefix_.back());
+        break;
+      case 6 /* continuous_dump_config */:
+        (*continuous_dump_config_).ParseFromArray(field.data(), field.size());
+        break;
+      case 8 /* shmem_size_bytes */:
+        field.get(&shmem_size_bytes_);
+        break;
+      case 9 /* block_client */:
+        field.get(&block_client_);
+        break;
+      case 14 /* block_client_timeout_us */:
+        field.get(&block_client_timeout_us_);
+        break;
+      case 10 /* no_startup */:
+        field.get(&no_startup_);
+        break;
+      case 11 /* no_running */:
+        field.get(&no_running_);
+        break;
+      case 13 /* dump_at_max */:
+        field.get(&dump_at_max_);
+        break;
+      case 18 /* disable_fork_teardown */:
+        field.get(&disable_fork_teardown_);
+        break;
+      case 19 /* disable_vfork_detection */:
+        field.get(&disable_vfork_detection_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string HeapprofdConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> HeapprofdConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void HeapprofdConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: sampling_interval_bytes
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, sampling_interval_bytes_, msg);
+  }
+
+  // Field 24: adaptive_sampling_shmem_threshold
+  if (_has_field_[24]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(24, adaptive_sampling_shmem_threshold_, msg);
+  }
+
+  // Field 25: adaptive_sampling_max_sampling_interval_bytes
+  if (_has_field_[25]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(25, adaptive_sampling_max_sampling_interval_bytes_, msg);
+  }
+
+  // Field 2: process_cmdline
+  for (auto& it : process_cmdline_) {
+    ::protozero::internal::gen_helpers::SerializeString(2, it, msg);
+  }
+
+  // Field 4: pid
+  for (auto& it : pid_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, it, msg);
+  }
+
+  // Field 26: target_installed_by
+  for (auto& it : target_installed_by_) {
+    ::protozero::internal::gen_helpers::SerializeString(26, it, msg);
+  }
+
+  // Field 20: heaps
+  for (auto& it : heaps_) {
+    ::protozero::internal::gen_helpers::SerializeString(20, it, msg);
+  }
+
+  // Field 27: exclude_heaps
+  for (auto& it : exclude_heaps_) {
+    ::protozero::internal::gen_helpers::SerializeString(27, it, msg);
+  }
+
+  // Field 23: stream_allocations
+  if (_has_field_[23]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(23, stream_allocations_, msg);
+  }
+
+  // Field 22: heap_sampling_intervals
+  for (auto& it : heap_sampling_intervals_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(22, it, msg);
+  }
+
+  // Field 21: all_heaps
+  if (_has_field_[21]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(21, all_heaps_, msg);
+  }
+
+  // Field 5: all
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, all_, msg);
+  }
+
+  // Field 15: min_anonymous_memory_kb
+  if (_has_field_[15]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(15, min_anonymous_memory_kb_, msg);
+  }
+
+  // Field 16: max_heapprofd_memory_kb
+  if (_has_field_[16]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(16, max_heapprofd_memory_kb_, msg);
+  }
+
+  // Field 17: max_heapprofd_cpu_secs
+  if (_has_field_[17]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(17, max_heapprofd_cpu_secs_, msg);
+  }
+
+  // Field 7: skip_symbol_prefix
+  for (auto& it : skip_symbol_prefix_) {
+    ::protozero::internal::gen_helpers::SerializeString(7, it, msg);
+  }
+
+  // Field 6: continuous_dump_config
+  if (_has_field_[6]) {
+    (*continuous_dump_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
+  }
+
+  // Field 8: shmem_size_bytes
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(8, shmem_size_bytes_, msg);
+  }
+
+  // Field 9: block_client
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(9, block_client_, msg);
+  }
+
+  // Field 14: block_client_timeout_us
+  if (_has_field_[14]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(14, block_client_timeout_us_, msg);
+  }
+
+  // Field 10: no_startup
+  if (_has_field_[10]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(10, no_startup_, msg);
+  }
+
+  // Field 11: no_running
+  if (_has_field_[11]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(11, no_running_, msg);
+  }
+
+  // Field 13: dump_at_max
+  if (_has_field_[13]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(13, dump_at_max_, msg);
+  }
+
+  // Field 18: disable_fork_teardown
+  if (_has_field_[18]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(18, disable_fork_teardown_, msg);
+  }
+
+  // Field 19: disable_vfork_detection
+  if (_has_field_[19]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(19, disable_vfork_detection_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+HeapprofdConfig_ContinuousDumpConfig::HeapprofdConfig_ContinuousDumpConfig() = default;
+HeapprofdConfig_ContinuousDumpConfig::~HeapprofdConfig_ContinuousDumpConfig() = default;
+HeapprofdConfig_ContinuousDumpConfig::HeapprofdConfig_ContinuousDumpConfig(const HeapprofdConfig_ContinuousDumpConfig&) = default;
+HeapprofdConfig_ContinuousDumpConfig& HeapprofdConfig_ContinuousDumpConfig::operator=(const HeapprofdConfig_ContinuousDumpConfig&) = default;
+HeapprofdConfig_ContinuousDumpConfig::HeapprofdConfig_ContinuousDumpConfig(HeapprofdConfig_ContinuousDumpConfig&&) noexcept = default;
+HeapprofdConfig_ContinuousDumpConfig& HeapprofdConfig_ContinuousDumpConfig::operator=(HeapprofdConfig_ContinuousDumpConfig&&) = default;
+
+bool HeapprofdConfig_ContinuousDumpConfig::operator==(const HeapprofdConfig_ContinuousDumpConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(dump_phase_ms_, other.dump_phase_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(dump_interval_ms_, other.dump_interval_ms_);
+}
+
+bool HeapprofdConfig_ContinuousDumpConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 5 /* dump_phase_ms */:
+        field.get(&dump_phase_ms_);
+        break;
+      case 6 /* dump_interval_ms */:
+        field.get(&dump_interval_ms_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string HeapprofdConfig_ContinuousDumpConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> HeapprofdConfig_ContinuousDumpConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void HeapprofdConfig_ContinuousDumpConfig::Serialize(::protozero::Message* msg) const {
+  // Field 5: dump_phase_ms
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, dump_phase_ms_, msg);
+  }
+
+  // Field 6: dump_interval_ms
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, dump_interval_ms_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/profiling/java_hprof_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/java_hprof_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+JavaHprofConfig::JavaHprofConfig() = default;
+JavaHprofConfig::~JavaHprofConfig() = default;
+JavaHprofConfig::JavaHprofConfig(const JavaHprofConfig&) = default;
+JavaHprofConfig& JavaHprofConfig::operator=(const JavaHprofConfig&) = default;
+JavaHprofConfig::JavaHprofConfig(JavaHprofConfig&&) noexcept = default;
+JavaHprofConfig& JavaHprofConfig::operator=(JavaHprofConfig&&) = default;
+
+bool JavaHprofConfig::operator==(const JavaHprofConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(process_cmdline_, other.process_cmdline_)
+   && ::protozero::internal::gen_helpers::EqualsField(pid_, other.pid_)
+   && ::protozero::internal::gen_helpers::EqualsField(target_installed_by_, other.target_installed_by_)
+   && ::protozero::internal::gen_helpers::EqualsField(continuous_dump_config_, other.continuous_dump_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(min_anonymous_memory_kb_, other.min_anonymous_memory_kb_)
+   && ::protozero::internal::gen_helpers::EqualsField(dump_smaps_, other.dump_smaps_)
+   && ::protozero::internal::gen_helpers::EqualsField(ignored_types_, other.ignored_types_);
+}
+
+bool JavaHprofConfig::ParseFromArray(const void* raw, size_t size) {
+  process_cmdline_.clear();
+  pid_.clear();
+  target_installed_by_.clear();
+  ignored_types_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* process_cmdline */:
+        process_cmdline_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &process_cmdline_.back());
+        break;
+      case 2 /* pid */:
+        pid_.emplace_back();
+        field.get(&pid_.back());
+        break;
+      case 7 /* target_installed_by */:
+        target_installed_by_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &target_installed_by_.back());
+        break;
+      case 3 /* continuous_dump_config */:
+        (*continuous_dump_config_).ParseFromArray(field.data(), field.size());
+        break;
+      case 4 /* min_anonymous_memory_kb */:
+        field.get(&min_anonymous_memory_kb_);
+        break;
+      case 5 /* dump_smaps */:
+        field.get(&dump_smaps_);
+        break;
+      case 6 /* ignored_types */:
+        ignored_types_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &ignored_types_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string JavaHprofConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> JavaHprofConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void JavaHprofConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: process_cmdline
+  for (auto& it : process_cmdline_) {
+    ::protozero::internal::gen_helpers::SerializeString(1, it, msg);
+  }
+
+  // Field 2: pid
+  for (auto& it : pid_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, it, msg);
+  }
+
+  // Field 7: target_installed_by
+  for (auto& it : target_installed_by_) {
+    ::protozero::internal::gen_helpers::SerializeString(7, it, msg);
+  }
+
+  // Field 3: continuous_dump_config
+  if (_has_field_[3]) {
+    (*continuous_dump_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
+  }
+
+  // Field 4: min_anonymous_memory_kb
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, min_anonymous_memory_kb_, msg);
+  }
+
+  // Field 5: dump_smaps
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, dump_smaps_, msg);
+  }
+
+  // Field 6: ignored_types
+  for (auto& it : ignored_types_) {
+    ::protozero::internal::gen_helpers::SerializeString(6, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+JavaHprofConfig_ContinuousDumpConfig::JavaHprofConfig_ContinuousDumpConfig() = default;
+JavaHprofConfig_ContinuousDumpConfig::~JavaHprofConfig_ContinuousDumpConfig() = default;
+JavaHprofConfig_ContinuousDumpConfig::JavaHprofConfig_ContinuousDumpConfig(const JavaHprofConfig_ContinuousDumpConfig&) = default;
+JavaHprofConfig_ContinuousDumpConfig& JavaHprofConfig_ContinuousDumpConfig::operator=(const JavaHprofConfig_ContinuousDumpConfig&) = default;
+JavaHprofConfig_ContinuousDumpConfig::JavaHprofConfig_ContinuousDumpConfig(JavaHprofConfig_ContinuousDumpConfig&&) noexcept = default;
+JavaHprofConfig_ContinuousDumpConfig& JavaHprofConfig_ContinuousDumpConfig::operator=(JavaHprofConfig_ContinuousDumpConfig&&) = default;
+
+bool JavaHprofConfig_ContinuousDumpConfig::operator==(const JavaHprofConfig_ContinuousDumpConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(dump_phase_ms_, other.dump_phase_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(dump_interval_ms_, other.dump_interval_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(scan_pids_only_on_start_, other.scan_pids_only_on_start_);
+}
+
+bool JavaHprofConfig_ContinuousDumpConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* dump_phase_ms */:
+        field.get(&dump_phase_ms_);
+        break;
+      case 2 /* dump_interval_ms */:
+        field.get(&dump_interval_ms_);
+        break;
+      case 3 /* scan_pids_only_on_start */:
+        field.get(&scan_pids_only_on_start_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string JavaHprofConfig_ContinuousDumpConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> JavaHprofConfig_ContinuousDumpConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void JavaHprofConfig_ContinuousDumpConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: dump_phase_ms
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, dump_phase_ms_, msg);
+  }
+
+  // Field 2: dump_interval_ms
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, dump_interval_ms_, msg);
+  }
+
+  // Field 3: scan_pids_only_on_start
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, scan_pids_only_on_start_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/profiling/perf_event_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/perf_event_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/perf_events.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+PerfEventConfig::PerfEventConfig() = default;
+PerfEventConfig::~PerfEventConfig() = default;
+PerfEventConfig::PerfEventConfig(const PerfEventConfig&) = default;
+PerfEventConfig& PerfEventConfig::operator=(const PerfEventConfig&) = default;
+PerfEventConfig::PerfEventConfig(PerfEventConfig&&) noexcept = default;
+PerfEventConfig& PerfEventConfig::operator=(PerfEventConfig&&) = default;
+
+bool PerfEventConfig::operator==(const PerfEventConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(timebase_, other.timebase_)
+   && ::protozero::internal::gen_helpers::EqualsField(callstack_sampling_, other.callstack_sampling_)
+   && ::protozero::internal::gen_helpers::EqualsField(ring_buffer_read_period_ms_, other.ring_buffer_read_period_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(ring_buffer_pages_, other.ring_buffer_pages_)
+   && ::protozero::internal::gen_helpers::EqualsField(max_enqueued_footprint_kb_, other.max_enqueued_footprint_kb_)
+   && ::protozero::internal::gen_helpers::EqualsField(max_daemon_memory_kb_, other.max_daemon_memory_kb_)
+   && ::protozero::internal::gen_helpers::EqualsField(remote_descriptor_timeout_ms_, other.remote_descriptor_timeout_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(unwind_state_clear_period_ms_, other.unwind_state_clear_period_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(target_installed_by_, other.target_installed_by_)
+   && ::protozero::internal::gen_helpers::EqualsField(all_cpus_, other.all_cpus_)
+   && ::protozero::internal::gen_helpers::EqualsField(sampling_frequency_, other.sampling_frequency_)
+   && ::protozero::internal::gen_helpers::EqualsField(kernel_frames_, other.kernel_frames_)
+   && ::protozero::internal::gen_helpers::EqualsField(target_pid_, other.target_pid_)
+   && ::protozero::internal::gen_helpers::EqualsField(target_cmdline_, other.target_cmdline_)
+   && ::protozero::internal::gen_helpers::EqualsField(exclude_pid_, other.exclude_pid_)
+   && ::protozero::internal::gen_helpers::EqualsField(exclude_cmdline_, other.exclude_cmdline_)
+   && ::protozero::internal::gen_helpers::EqualsField(additional_cmdline_count_, other.additional_cmdline_count_);
+}
+
+bool PerfEventConfig::ParseFromArray(const void* raw, size_t size) {
+  target_installed_by_.clear();
+  target_pid_.clear();
+  target_cmdline_.clear();
+  exclude_pid_.clear();
+  exclude_cmdline_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 15 /* timebase */:
+        (*timebase_).ParseFromArray(field.data(), field.size());
+        break;
+      case 16 /* callstack_sampling */:
+        (*callstack_sampling_).ParseFromArray(field.data(), field.size());
+        break;
+      case 8 /* ring_buffer_read_period_ms */:
+        field.get(&ring_buffer_read_period_ms_);
+        break;
+      case 3 /* ring_buffer_pages */:
+        field.get(&ring_buffer_pages_);
+        break;
+      case 17 /* max_enqueued_footprint_kb */:
+        field.get(&max_enqueued_footprint_kb_);
+        break;
+      case 13 /* max_daemon_memory_kb */:
+        field.get(&max_daemon_memory_kb_);
+        break;
+      case 9 /* remote_descriptor_timeout_ms */:
+        field.get(&remote_descriptor_timeout_ms_);
+        break;
+      case 10 /* unwind_state_clear_period_ms */:
+        field.get(&unwind_state_clear_period_ms_);
+        break;
+      case 18 /* target_installed_by */:
+        target_installed_by_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &target_installed_by_.back());
+        break;
+      case 1 /* all_cpus */:
+        field.get(&all_cpus_);
+        break;
+      case 2 /* sampling_frequency */:
+        field.get(&sampling_frequency_);
+        break;
+      case 12 /* kernel_frames */:
+        field.get(&kernel_frames_);
+        break;
+      case 4 /* target_pid */:
+        target_pid_.emplace_back();
+        field.get(&target_pid_.back());
+        break;
+      case 5 /* target_cmdline */:
+        target_cmdline_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &target_cmdline_.back());
+        break;
+      case 6 /* exclude_pid */:
+        exclude_pid_.emplace_back();
+        field.get(&exclude_pid_.back());
+        break;
+      case 7 /* exclude_cmdline */:
+        exclude_cmdline_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &exclude_cmdline_.back());
+        break;
+      case 11 /* additional_cmdline_count */:
+        field.get(&additional_cmdline_count_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string PerfEventConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> PerfEventConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void PerfEventConfig::Serialize(::protozero::Message* msg) const {
+  // Field 15: timebase
+  if (_has_field_[15]) {
+    (*timebase_).Serialize(msg->BeginNestedMessage<::protozero::Message>(15));
+  }
+
+  // Field 16: callstack_sampling
+  if (_has_field_[16]) {
+    (*callstack_sampling_).Serialize(msg->BeginNestedMessage<::protozero::Message>(16));
+  }
+
+  // Field 8: ring_buffer_read_period_ms
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(8, ring_buffer_read_period_ms_, msg);
+  }
+
+  // Field 3: ring_buffer_pages
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, ring_buffer_pages_, msg);
+  }
+
+  // Field 17: max_enqueued_footprint_kb
+  if (_has_field_[17]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(17, max_enqueued_footprint_kb_, msg);
+  }
+
+  // Field 13: max_daemon_memory_kb
+  if (_has_field_[13]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(13, max_daemon_memory_kb_, msg);
+  }
+
+  // Field 9: remote_descriptor_timeout_ms
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(9, remote_descriptor_timeout_ms_, msg);
+  }
+
+  // Field 10: unwind_state_clear_period_ms
+  if (_has_field_[10]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(10, unwind_state_clear_period_ms_, msg);
+  }
+
+  // Field 18: target_installed_by
+  for (auto& it : target_installed_by_) {
+    ::protozero::internal::gen_helpers::SerializeString(18, it, msg);
+  }
+
+  // Field 1: all_cpus
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, all_cpus_, msg);
+  }
+
+  // Field 2: sampling_frequency
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, sampling_frequency_, msg);
+  }
+
+  // Field 12: kernel_frames
+  if (_has_field_[12]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(12, kernel_frames_, msg);
+  }
+
+  // Field 4: target_pid
+  for (auto& it : target_pid_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, it, msg);
+  }
+
+  // Field 5: target_cmdline
+  for (auto& it : target_cmdline_) {
+    ::protozero::internal::gen_helpers::SerializeString(5, it, msg);
+  }
+
+  // Field 6: exclude_pid
+  for (auto& it : exclude_pid_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, it, msg);
+  }
+
+  // Field 7: exclude_cmdline
+  for (auto& it : exclude_cmdline_) {
+    ::protozero::internal::gen_helpers::SerializeString(7, it, msg);
+  }
+
+  // Field 11: additional_cmdline_count
+  if (_has_field_[11]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(11, additional_cmdline_count_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+PerfEventConfig_CallstackSampling::PerfEventConfig_CallstackSampling() = default;
+PerfEventConfig_CallstackSampling::~PerfEventConfig_CallstackSampling() = default;
+PerfEventConfig_CallstackSampling::PerfEventConfig_CallstackSampling(const PerfEventConfig_CallstackSampling&) = default;
+PerfEventConfig_CallstackSampling& PerfEventConfig_CallstackSampling::operator=(const PerfEventConfig_CallstackSampling&) = default;
+PerfEventConfig_CallstackSampling::PerfEventConfig_CallstackSampling(PerfEventConfig_CallstackSampling&&) noexcept = default;
+PerfEventConfig_CallstackSampling& PerfEventConfig_CallstackSampling::operator=(PerfEventConfig_CallstackSampling&&) = default;
+
+bool PerfEventConfig_CallstackSampling::operator==(const PerfEventConfig_CallstackSampling& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(scope_, other.scope_)
+   && ::protozero::internal::gen_helpers::EqualsField(kernel_frames_, other.kernel_frames_)
+   && ::protozero::internal::gen_helpers::EqualsField(user_frames_, other.user_frames_);
+}
+
+bool PerfEventConfig_CallstackSampling::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* scope */:
+        (*scope_).ParseFromArray(field.data(), field.size());
+        break;
+      case 2 /* kernel_frames */:
+        field.get(&kernel_frames_);
+        break;
+      case 3 /* user_frames */:
+        field.get(&user_frames_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string PerfEventConfig_CallstackSampling::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> PerfEventConfig_CallstackSampling::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void PerfEventConfig_CallstackSampling::Serialize(::protozero::Message* msg) const {
+  // Field 1: scope
+  if (_has_field_[1]) {
+    (*scope_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  // Field 2: kernel_frames
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, kernel_frames_, msg);
+  }
+
+  // Field 3: user_frames
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, user_frames_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+PerfEventConfig_Scope::PerfEventConfig_Scope() = default;
+PerfEventConfig_Scope::~PerfEventConfig_Scope() = default;
+PerfEventConfig_Scope::PerfEventConfig_Scope(const PerfEventConfig_Scope&) = default;
+PerfEventConfig_Scope& PerfEventConfig_Scope::operator=(const PerfEventConfig_Scope&) = default;
+PerfEventConfig_Scope::PerfEventConfig_Scope(PerfEventConfig_Scope&&) noexcept = default;
+PerfEventConfig_Scope& PerfEventConfig_Scope::operator=(PerfEventConfig_Scope&&) = default;
+
+bool PerfEventConfig_Scope::operator==(const PerfEventConfig_Scope& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(target_pid_, other.target_pid_)
+   && ::protozero::internal::gen_helpers::EqualsField(target_cmdline_, other.target_cmdline_)
+   && ::protozero::internal::gen_helpers::EqualsField(exclude_pid_, other.exclude_pid_)
+   && ::protozero::internal::gen_helpers::EqualsField(exclude_cmdline_, other.exclude_cmdline_)
+   && ::protozero::internal::gen_helpers::EqualsField(additional_cmdline_count_, other.additional_cmdline_count_)
+   && ::protozero::internal::gen_helpers::EqualsField(process_shard_count_, other.process_shard_count_);
+}
+
+bool PerfEventConfig_Scope::ParseFromArray(const void* raw, size_t size) {
+  target_pid_.clear();
+  target_cmdline_.clear();
+  exclude_pid_.clear();
+  exclude_cmdline_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* target_pid */:
+        target_pid_.emplace_back();
+        field.get(&target_pid_.back());
+        break;
+      case 2 /* target_cmdline */:
+        target_cmdline_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &target_cmdline_.back());
+        break;
+      case 3 /* exclude_pid */:
+        exclude_pid_.emplace_back();
+        field.get(&exclude_pid_.back());
+        break;
+      case 4 /* exclude_cmdline */:
+        exclude_cmdline_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &exclude_cmdline_.back());
+        break;
+      case 5 /* additional_cmdline_count */:
+        field.get(&additional_cmdline_count_);
+        break;
+      case 6 /* process_shard_count */:
+        field.get(&process_shard_count_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string PerfEventConfig_Scope::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> PerfEventConfig_Scope::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void PerfEventConfig_Scope::Serialize(::protozero::Message* msg) const {
+  // Field 1: target_pid
+  for (auto& it : target_pid_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, it, msg);
+  }
+
+  // Field 2: target_cmdline
+  for (auto& it : target_cmdline_) {
+    ::protozero::internal::gen_helpers::SerializeString(2, it, msg);
+  }
+
+  // Field 3: exclude_pid
+  for (auto& it : exclude_pid_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, it, msg);
+  }
+
+  // Field 4: exclude_cmdline
+  for (auto& it : exclude_cmdline_) {
+    ::protozero::internal::gen_helpers::SerializeString(4, it, msg);
+  }
+
+  // Field 5: additional_cmdline_count
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, additional_cmdline_count_, msg);
+  }
+
+  // Field 6: process_shard_count
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, process_shard_count_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/statsd/atom_ids.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/atom_ids.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/statsd/statsd_tracing_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/statsd_tracing_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/atom_ids.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+StatsdPullAtomConfig::StatsdPullAtomConfig() = default;
+StatsdPullAtomConfig::~StatsdPullAtomConfig() = default;
+StatsdPullAtomConfig::StatsdPullAtomConfig(const StatsdPullAtomConfig&) = default;
+StatsdPullAtomConfig& StatsdPullAtomConfig::operator=(const StatsdPullAtomConfig&) = default;
+StatsdPullAtomConfig::StatsdPullAtomConfig(StatsdPullAtomConfig&&) noexcept = default;
+StatsdPullAtomConfig& StatsdPullAtomConfig::operator=(StatsdPullAtomConfig&&) = default;
+
+bool StatsdPullAtomConfig::operator==(const StatsdPullAtomConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(pull_atom_id_, other.pull_atom_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(raw_pull_atom_id_, other.raw_pull_atom_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(pull_frequency_ms_, other.pull_frequency_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(packages_, other.packages_);
+}
+
+bool StatsdPullAtomConfig::ParseFromArray(const void* raw, size_t size) {
+  pull_atom_id_.clear();
+  raw_pull_atom_id_.clear();
+  packages_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* pull_atom_id */:
+        pull_atom_id_.emplace_back();
+        field.get(&pull_atom_id_.back());
+        break;
+      case 2 /* raw_pull_atom_id */:
+        raw_pull_atom_id_.emplace_back();
+        field.get(&raw_pull_atom_id_.back());
+        break;
+      case 3 /* pull_frequency_ms */:
+        field.get(&pull_frequency_ms_);
+        break;
+      case 4 /* packages */:
+        packages_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &packages_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string StatsdPullAtomConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> StatsdPullAtomConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void StatsdPullAtomConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: pull_atom_id
+  for (auto& it : pull_atom_id_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, it, msg);
+  }
+
+  // Field 2: raw_pull_atom_id
+  for (auto& it : raw_pull_atom_id_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, it, msg);
+  }
+
+  // Field 3: pull_frequency_ms
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, pull_frequency_ms_, msg);
+  }
+
+  // Field 4: packages
+  for (auto& it : packages_) {
+    ::protozero::internal::gen_helpers::SerializeString(4, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+StatsdTracingConfig::StatsdTracingConfig() = default;
+StatsdTracingConfig::~StatsdTracingConfig() = default;
+StatsdTracingConfig::StatsdTracingConfig(const StatsdTracingConfig&) = default;
+StatsdTracingConfig& StatsdTracingConfig::operator=(const StatsdTracingConfig&) = default;
+StatsdTracingConfig::StatsdTracingConfig(StatsdTracingConfig&&) noexcept = default;
+StatsdTracingConfig& StatsdTracingConfig::operator=(StatsdTracingConfig&&) = default;
+
+bool StatsdTracingConfig::operator==(const StatsdTracingConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(push_atom_id_, other.push_atom_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(raw_push_atom_id_, other.raw_push_atom_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(pull_config_, other.pull_config_);
+}
+
+int StatsdTracingConfig::pull_config_size() const { return static_cast<int>(pull_config_.size()); }
+void StatsdTracingConfig::clear_pull_config() { pull_config_.clear(); }
+StatsdPullAtomConfig* StatsdTracingConfig::add_pull_config() { pull_config_.emplace_back(); return &pull_config_.back(); }
+bool StatsdTracingConfig::ParseFromArray(const void* raw, size_t size) {
+  push_atom_id_.clear();
+  raw_push_atom_id_.clear();
+  pull_config_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* push_atom_id */:
+        push_atom_id_.emplace_back();
+        field.get(&push_atom_id_.back());
+        break;
+      case 2 /* raw_push_atom_id */:
+        raw_push_atom_id_.emplace_back();
+        field.get(&raw_push_atom_id_.back());
+        break;
+      case 3 /* pull_config */:
+        pull_config_.emplace_back();
+        pull_config_.back().ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string StatsdTracingConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> StatsdTracingConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void StatsdTracingConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: push_atom_id
+  for (auto& it : push_atom_id_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, it, msg);
+  }
+
+  // Field 2: raw_push_atom_id
+  for (auto& it : raw_push_atom_id_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, it, msg);
+  }
+
+  // Field 3: pull_config
+  for (auto& it : pull_config_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/sys_stats/sys_stats_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/sys_stats/sys_stats_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+SysStatsConfig::SysStatsConfig() = default;
+SysStatsConfig::~SysStatsConfig() = default;
+SysStatsConfig::SysStatsConfig(const SysStatsConfig&) = default;
+SysStatsConfig& SysStatsConfig::operator=(const SysStatsConfig&) = default;
+SysStatsConfig::SysStatsConfig(SysStatsConfig&&) noexcept = default;
+SysStatsConfig& SysStatsConfig::operator=(SysStatsConfig&&) = default;
+
+bool SysStatsConfig::operator==(const SysStatsConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(meminfo_period_ms_, other.meminfo_period_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(meminfo_counters_, other.meminfo_counters_)
+   && ::protozero::internal::gen_helpers::EqualsField(vmstat_period_ms_, other.vmstat_period_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(vmstat_counters_, other.vmstat_counters_)
+   && ::protozero::internal::gen_helpers::EqualsField(stat_period_ms_, other.stat_period_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(stat_counters_, other.stat_counters_)
+   && ::protozero::internal::gen_helpers::EqualsField(devfreq_period_ms_, other.devfreq_period_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(cpufreq_period_ms_, other.cpufreq_period_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(buddyinfo_period_ms_, other.buddyinfo_period_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(diskstat_period_ms_, other.diskstat_period_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(psi_period_ms_, other.psi_period_ms_);
+}
+
+bool SysStatsConfig::ParseFromArray(const void* raw, size_t size) {
+  meminfo_counters_.clear();
+  vmstat_counters_.clear();
+  stat_counters_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* meminfo_period_ms */:
+        field.get(&meminfo_period_ms_);
+        break;
+      case 2 /* meminfo_counters */:
+        meminfo_counters_.emplace_back();
+        field.get(&meminfo_counters_.back());
+        break;
+      case 3 /* vmstat_period_ms */:
+        field.get(&vmstat_period_ms_);
+        break;
+      case 4 /* vmstat_counters */:
+        vmstat_counters_.emplace_back();
+        field.get(&vmstat_counters_.back());
+        break;
+      case 5 /* stat_period_ms */:
+        field.get(&stat_period_ms_);
+        break;
+      case 6 /* stat_counters */:
+        stat_counters_.emplace_back();
+        field.get(&stat_counters_.back());
+        break;
+      case 7 /* devfreq_period_ms */:
+        field.get(&devfreq_period_ms_);
+        break;
+      case 8 /* cpufreq_period_ms */:
+        field.get(&cpufreq_period_ms_);
+        break;
+      case 9 /* buddyinfo_period_ms */:
+        field.get(&buddyinfo_period_ms_);
+        break;
+      case 10 /* diskstat_period_ms */:
+        field.get(&diskstat_period_ms_);
+        break;
+      case 11 /* psi_period_ms */:
+        field.get(&psi_period_ms_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string SysStatsConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> SysStatsConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void SysStatsConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: meminfo_period_ms
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, meminfo_period_ms_, msg);
+  }
+
+  // Field 2: meminfo_counters
+  for (auto& it : meminfo_counters_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, it, msg);
+  }
+
+  // Field 3: vmstat_period_ms
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, vmstat_period_ms_, msg);
+  }
+
+  // Field 4: vmstat_counters
+  for (auto& it : vmstat_counters_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, it, msg);
+  }
+
+  // Field 5: stat_period_ms
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, stat_period_ms_, msg);
+  }
+
+  // Field 6: stat_counters
+  for (auto& it : stat_counters_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, it, msg);
+  }
+
+  // Field 7: devfreq_period_ms
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(7, devfreq_period_ms_, msg);
+  }
+
+  // Field 8: cpufreq_period_ms
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(8, cpufreq_period_ms_, msg);
+  }
+
+  // Field 9: buddyinfo_period_ms
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(9, buddyinfo_period_ms_, msg);
+  }
+
+  // Field 10: diskstat_period_ms
+  if (_has_field_[10]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(10, diskstat_period_ms_, msg);
+  }
+
+  // Field 11: psi_period_ms
+  if (_has_field_[11]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(11, psi_period_ms_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/system_info/system_info.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/system_info/system_info.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+SystemInfoConfig::SystemInfoConfig() = default;
+SystemInfoConfig::~SystemInfoConfig() = default;
+SystemInfoConfig::SystemInfoConfig(const SystemInfoConfig&) = default;
+SystemInfoConfig& SystemInfoConfig::operator=(const SystemInfoConfig&) = default;
+SystemInfoConfig::SystemInfoConfig(SystemInfoConfig&&) noexcept = default;
+SystemInfoConfig& SystemInfoConfig::operator=(SystemInfoConfig&&) = default;
+
+bool SystemInfoConfig::operator==(const SystemInfoConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool SystemInfoConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string SystemInfoConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> SystemInfoConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void SystemInfoConfig::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/track_event/track_event_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/track_event/track_event_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+TrackEventConfig::TrackEventConfig() = default;
+TrackEventConfig::~TrackEventConfig() = default;
+TrackEventConfig::TrackEventConfig(const TrackEventConfig&) = default;
+TrackEventConfig& TrackEventConfig::operator=(const TrackEventConfig&) = default;
+TrackEventConfig::TrackEventConfig(TrackEventConfig&&) noexcept = default;
+TrackEventConfig& TrackEventConfig::operator=(TrackEventConfig&&) = default;
+
+bool TrackEventConfig::operator==(const TrackEventConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(disabled_categories_, other.disabled_categories_)
+   && ::protozero::internal::gen_helpers::EqualsField(enabled_categories_, other.enabled_categories_)
+   && ::protozero::internal::gen_helpers::EqualsField(disabled_tags_, other.disabled_tags_)
+   && ::protozero::internal::gen_helpers::EqualsField(enabled_tags_, other.enabled_tags_)
+   && ::protozero::internal::gen_helpers::EqualsField(disable_incremental_timestamps_, other.disable_incremental_timestamps_)
+   && ::protozero::internal::gen_helpers::EqualsField(timestamp_unit_multiplier_, other.timestamp_unit_multiplier_)
+   && ::protozero::internal::gen_helpers::EqualsField(filter_debug_annotations_, other.filter_debug_annotations_)
+   && ::protozero::internal::gen_helpers::EqualsField(enable_thread_time_sampling_, other.enable_thread_time_sampling_)
+   && ::protozero::internal::gen_helpers::EqualsField(filter_dynamic_event_names_, other.filter_dynamic_event_names_);
+}
+
+bool TrackEventConfig::ParseFromArray(const void* raw, size_t size) {
+  disabled_categories_.clear();
+  enabled_categories_.clear();
+  disabled_tags_.clear();
+  enabled_tags_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* disabled_categories */:
+        disabled_categories_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &disabled_categories_.back());
+        break;
+      case 2 /* enabled_categories */:
+        enabled_categories_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &enabled_categories_.back());
+        break;
+      case 3 /* disabled_tags */:
+        disabled_tags_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &disabled_tags_.back());
+        break;
+      case 4 /* enabled_tags */:
+        enabled_tags_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &enabled_tags_.back());
+        break;
+      case 5 /* disable_incremental_timestamps */:
+        field.get(&disable_incremental_timestamps_);
+        break;
+      case 6 /* timestamp_unit_multiplier */:
+        field.get(&timestamp_unit_multiplier_);
+        break;
+      case 7 /* filter_debug_annotations */:
+        field.get(&filter_debug_annotations_);
+        break;
+      case 8 /* enable_thread_time_sampling */:
+        field.get(&enable_thread_time_sampling_);
+        break;
+      case 9 /* filter_dynamic_event_names */:
+        field.get(&filter_dynamic_event_names_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TrackEventConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TrackEventConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TrackEventConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: disabled_categories
+  for (auto& it : disabled_categories_) {
+    ::protozero::internal::gen_helpers::SerializeString(1, it, msg);
+  }
+
+  // Field 2: enabled_categories
+  for (auto& it : enabled_categories_) {
+    ::protozero::internal::gen_helpers::SerializeString(2, it, msg);
+  }
+
+  // Field 3: disabled_tags
+  for (auto& it : disabled_tags_) {
+    ::protozero::internal::gen_helpers::SerializeString(3, it, msg);
+  }
+
+  // Field 4: enabled_tags
+  for (auto& it : enabled_tags_) {
+    ::protozero::internal::gen_helpers::SerializeString(4, it, msg);
+  }
+
+  // Field 5: disable_incremental_timestamps
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, disable_incremental_timestamps_, msg);
+  }
+
+  // Field 6: timestamp_unit_multiplier
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, timestamp_unit_multiplier_, msg);
+  }
+
+  // Field 7: filter_debug_annotations
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(7, filter_debug_annotations_, msg);
+  }
+
+  // Field 8: enable_thread_time_sampling
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(8, enable_thread_time_sampling_, msg);
+  }
+
+  // Field 9: filter_dynamic_event_names
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(9, filter_dynamic_event_names_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/chrome/chrome_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ChromeConfig::ChromeConfig() = default;
+ChromeConfig::~ChromeConfig() = default;
+ChromeConfig::ChromeConfig(const ChromeConfig&) = default;
+ChromeConfig& ChromeConfig::operator=(const ChromeConfig&) = default;
+ChromeConfig::ChromeConfig(ChromeConfig&&) noexcept = default;
+ChromeConfig& ChromeConfig::operator=(ChromeConfig&&) = default;
+
+bool ChromeConfig::operator==(const ChromeConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(trace_config_, other.trace_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(privacy_filtering_enabled_, other.privacy_filtering_enabled_)
+   && ::protozero::internal::gen_helpers::EqualsField(convert_to_legacy_json_, other.convert_to_legacy_json_)
+   && ::protozero::internal::gen_helpers::EqualsField(client_priority_, other.client_priority_)
+   && ::protozero::internal::gen_helpers::EqualsField(json_agent_label_filter_, other.json_agent_label_filter_);
+}
+
+bool ChromeConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* trace_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &trace_config_);
+        break;
+      case 2 /* privacy_filtering_enabled */:
+        field.get(&privacy_filtering_enabled_);
+        break;
+      case 3 /* convert_to_legacy_json */:
+        field.get(&convert_to_legacy_json_);
+        break;
+      case 4 /* client_priority */:
+        field.get(&client_priority_);
+        break;
+      case 5 /* json_agent_label_filter */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &json_agent_label_filter_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: trace_config
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, trace_config_, msg);
+  }
+
+  // Field 2: privacy_filtering_enabled
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, privacy_filtering_enabled_, msg);
+  }
+
+  // Field 3: convert_to_legacy_json
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, convert_to_legacy_json_, msg);
+  }
+
+  // Field 4: client_priority
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, client_priority_, msg);
+  }
+
+  // Field 5: json_agent_label_filter
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeString(5, json_agent_label_filter_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/chrome/scenario_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/chrome/scenario_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/trace_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/system_info/system_info.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/track_event/track_event_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/sys_stats/sys_stats_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/perf_event_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/perf_events.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/java_hprof_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/heapprofd_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/process_stats/process_stats_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/statsd_tracing_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/atom_ids.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/power/android_power_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/inode_file/inode_file_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/gpu/vulkan_memory_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/gpu/gpu_counter_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/ftrace/ftrace_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/etw/etw_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/chrome/v8_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_transactions_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_layers_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/protolog_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/protolog_common.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/pixel_modem_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/packages_list_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/network_trace_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_sdk_sysprop_guard_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_system_property_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_polled_state_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_log_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_input_event_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_game_intervention_list_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+TracingTriggerRulesConfig::TracingTriggerRulesConfig() = default;
+TracingTriggerRulesConfig::~TracingTriggerRulesConfig() = default;
+TracingTriggerRulesConfig::TracingTriggerRulesConfig(const TracingTriggerRulesConfig&) = default;
+TracingTriggerRulesConfig& TracingTriggerRulesConfig::operator=(const TracingTriggerRulesConfig&) = default;
+TracingTriggerRulesConfig::TracingTriggerRulesConfig(TracingTriggerRulesConfig&&) noexcept = default;
+TracingTriggerRulesConfig& TracingTriggerRulesConfig::operator=(TracingTriggerRulesConfig&&) = default;
+
+bool TracingTriggerRulesConfig::operator==(const TracingTriggerRulesConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(rules_, other.rules_);
+}
+
+int TracingTriggerRulesConfig::rules_size() const { return static_cast<int>(rules_.size()); }
+void TracingTriggerRulesConfig::clear_rules() { rules_.clear(); }
+TriggerRule* TracingTriggerRulesConfig::add_rules() { rules_.emplace_back(); return &rules_.back(); }
+bool TracingTriggerRulesConfig::ParseFromArray(const void* raw, size_t size) {
+  rules_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* rules */:
+        rules_.emplace_back();
+        rules_.back().ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TracingTriggerRulesConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TracingTriggerRulesConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TracingTriggerRulesConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: rules
+  for (auto& it : rules_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TriggerRule::TriggerRule() = default;
+TriggerRule::~TriggerRule() = default;
+TriggerRule::TriggerRule(const TriggerRule&) = default;
+TriggerRule& TriggerRule::operator=(const TriggerRule&) = default;
+TriggerRule::TriggerRule(TriggerRule&&) noexcept = default;
+TriggerRule& TriggerRule::operator=(TriggerRule&&) = default;
+
+bool TriggerRule::operator==(const TriggerRule& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(trigger_chance_, other.trigger_chance_)
+   && ::protozero::internal::gen_helpers::EqualsField(delay_ms_, other.delay_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(activation_delay_ms_, other.activation_delay_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(manual_trigger_name_, other.manual_trigger_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(histogram_, other.histogram_)
+   && ::protozero::internal::gen_helpers::EqualsField(repeating_interval_, other.repeating_interval_);
+}
+
+bool TriggerRule::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 2 /* trigger_chance */:
+        field.get(&trigger_chance_);
+        break;
+      case 3 /* delay_ms */:
+        field.get(&delay_ms_);
+        break;
+      case 8 /* activation_delay_ms */:
+        field.get(&activation_delay_ms_);
+        break;
+      case 4 /* manual_trigger_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &manual_trigger_name_);
+        break;
+      case 5 /* histogram */:
+        (*histogram_).ParseFromArray(field.data(), field.size());
+        break;
+      case 6 /* repeating_interval */:
+        (*repeating_interval_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TriggerRule::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TriggerRule::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TriggerRule::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
+  }
+
+  // Field 2: trigger_chance
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeFixed(2, trigger_chance_, msg);
+  }
+
+  // Field 3: delay_ms
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, delay_ms_, msg);
+  }
+
+  // Field 8: activation_delay_ms
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(8, activation_delay_ms_, msg);
+  }
+
+  // Field 4: manual_trigger_name
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeString(4, manual_trigger_name_, msg);
+  }
+
+  // Field 5: histogram
+  if (_has_field_[5]) {
+    (*histogram_).Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
+  }
+
+  // Field 6: repeating_interval
+  if (_has_field_[6]) {
+    (*repeating_interval_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TriggerRule_RepeatingInterval::TriggerRule_RepeatingInterval() = default;
+TriggerRule_RepeatingInterval::~TriggerRule_RepeatingInterval() = default;
+TriggerRule_RepeatingInterval::TriggerRule_RepeatingInterval(const TriggerRule_RepeatingInterval&) = default;
+TriggerRule_RepeatingInterval& TriggerRule_RepeatingInterval::operator=(const TriggerRule_RepeatingInterval&) = default;
+TriggerRule_RepeatingInterval::TriggerRule_RepeatingInterval(TriggerRule_RepeatingInterval&&) noexcept = default;
+TriggerRule_RepeatingInterval& TriggerRule_RepeatingInterval::operator=(TriggerRule_RepeatingInterval&&) = default;
+
+bool TriggerRule_RepeatingInterval::operator==(const TriggerRule_RepeatingInterval& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(period_ms_, other.period_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(randomized_, other.randomized_);
+}
+
+bool TriggerRule_RepeatingInterval::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* period_ms */:
+        field.get(&period_ms_);
+        break;
+      case 2 /* randomized */:
+        field.get(&randomized_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TriggerRule_RepeatingInterval::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TriggerRule_RepeatingInterval::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TriggerRule_RepeatingInterval::Serialize(::protozero::Message* msg) const {
+  // Field 1: period_ms
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, period_ms_, msg);
+  }
+
+  // Field 2: randomized
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, randomized_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TriggerRule_HistogramTrigger::TriggerRule_HistogramTrigger() = default;
+TriggerRule_HistogramTrigger::~TriggerRule_HistogramTrigger() = default;
+TriggerRule_HistogramTrigger::TriggerRule_HistogramTrigger(const TriggerRule_HistogramTrigger&) = default;
+TriggerRule_HistogramTrigger& TriggerRule_HistogramTrigger::operator=(const TriggerRule_HistogramTrigger&) = default;
+TriggerRule_HistogramTrigger::TriggerRule_HistogramTrigger(TriggerRule_HistogramTrigger&&) noexcept = default;
+TriggerRule_HistogramTrigger& TriggerRule_HistogramTrigger::operator=(TriggerRule_HistogramTrigger&&) = default;
+
+bool TriggerRule_HistogramTrigger::operator==(const TriggerRule_HistogramTrigger& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(histogram_name_, other.histogram_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(min_value_, other.min_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(max_value_, other.max_value_);
+}
+
+bool TriggerRule_HistogramTrigger::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* histogram_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &histogram_name_);
+        break;
+      case 2 /* min_value */:
+        field.get(&min_value_);
+        break;
+      case 3 /* max_value */:
+        field.get(&max_value_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TriggerRule_HistogramTrigger::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TriggerRule_HistogramTrigger::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TriggerRule_HistogramTrigger::Serialize(::protozero::Message* msg) const {
+  // Field 1: histogram_name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, histogram_name_, msg);
+  }
+
+  // Field 2: min_value
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, min_value_, msg);
+  }
+
+  // Field 3: max_value
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, max_value_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+ChromeFieldTracingConfig::ChromeFieldTracingConfig() = default;
+ChromeFieldTracingConfig::~ChromeFieldTracingConfig() = default;
+ChromeFieldTracingConfig::ChromeFieldTracingConfig(const ChromeFieldTracingConfig&) = default;
+ChromeFieldTracingConfig& ChromeFieldTracingConfig::operator=(const ChromeFieldTracingConfig&) = default;
+ChromeFieldTracingConfig::ChromeFieldTracingConfig(ChromeFieldTracingConfig&&) noexcept = default;
+ChromeFieldTracingConfig& ChromeFieldTracingConfig::operator=(ChromeFieldTracingConfig&&) = default;
+
+bool ChromeFieldTracingConfig::operator==(const ChromeFieldTracingConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(scenarios_, other.scenarios_);
+}
+
+int ChromeFieldTracingConfig::scenarios_size() const { return static_cast<int>(scenarios_.size()); }
+void ChromeFieldTracingConfig::clear_scenarios() { scenarios_.clear(); }
+ScenarioConfig* ChromeFieldTracingConfig::add_scenarios() { scenarios_.emplace_back(); return &scenarios_.back(); }
+bool ChromeFieldTracingConfig::ParseFromArray(const void* raw, size_t size) {
+  scenarios_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* scenarios */:
+        scenarios_.emplace_back();
+        scenarios_.back().ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeFieldTracingConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeFieldTracingConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeFieldTracingConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: scenarios
+  for (auto& it : scenarios_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+ScenarioConfig::ScenarioConfig() = default;
+ScenarioConfig::~ScenarioConfig() = default;
+ScenarioConfig::ScenarioConfig(const ScenarioConfig&) = default;
+ScenarioConfig& ScenarioConfig::operator=(const ScenarioConfig&) = default;
+ScenarioConfig::ScenarioConfig(ScenarioConfig&&) noexcept = default;
+ScenarioConfig& ScenarioConfig::operator=(ScenarioConfig&&) = default;
+
+bool ScenarioConfig::operator==(const ScenarioConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(scenario_name_, other.scenario_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(start_rules_, other.start_rules_)
+   && ::protozero::internal::gen_helpers::EqualsField(stop_rules_, other.stop_rules_)
+   && ::protozero::internal::gen_helpers::EqualsField(upload_rules_, other.upload_rules_)
+   && ::protozero::internal::gen_helpers::EqualsField(setup_rules_, other.setup_rules_)
+   && ::protozero::internal::gen_helpers::EqualsField(trace_config_, other.trace_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(nested_scenarios_, other.nested_scenarios_);
+}
+
+int ScenarioConfig::start_rules_size() const { return static_cast<int>(start_rules_.size()); }
+void ScenarioConfig::clear_start_rules() { start_rules_.clear(); }
+TriggerRule* ScenarioConfig::add_start_rules() { start_rules_.emplace_back(); return &start_rules_.back(); }
+int ScenarioConfig::stop_rules_size() const { return static_cast<int>(stop_rules_.size()); }
+void ScenarioConfig::clear_stop_rules() { stop_rules_.clear(); }
+TriggerRule* ScenarioConfig::add_stop_rules() { stop_rules_.emplace_back(); return &stop_rules_.back(); }
+int ScenarioConfig::upload_rules_size() const { return static_cast<int>(upload_rules_.size()); }
+void ScenarioConfig::clear_upload_rules() { upload_rules_.clear(); }
+TriggerRule* ScenarioConfig::add_upload_rules() { upload_rules_.emplace_back(); return &upload_rules_.back(); }
+int ScenarioConfig::setup_rules_size() const { return static_cast<int>(setup_rules_.size()); }
+void ScenarioConfig::clear_setup_rules() { setup_rules_.clear(); }
+TriggerRule* ScenarioConfig::add_setup_rules() { setup_rules_.emplace_back(); return &setup_rules_.back(); }
+int ScenarioConfig::nested_scenarios_size() const { return static_cast<int>(nested_scenarios_.size()); }
+void ScenarioConfig::clear_nested_scenarios() { nested_scenarios_.clear(); }
+NestedScenarioConfig* ScenarioConfig::add_nested_scenarios() { nested_scenarios_.emplace_back(); return &nested_scenarios_.back(); }
+bool ScenarioConfig::ParseFromArray(const void* raw, size_t size) {
+  start_rules_.clear();
+  stop_rules_.clear();
+  upload_rules_.clear();
+  setup_rules_.clear();
+  nested_scenarios_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* scenario_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &scenario_name_);
+        break;
+      case 2 /* start_rules */:
+        start_rules_.emplace_back();
+        start_rules_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 3 /* stop_rules */:
+        stop_rules_.emplace_back();
+        stop_rules_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 4 /* upload_rules */:
+        upload_rules_.emplace_back();
+        upload_rules_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 5 /* setup_rules */:
+        setup_rules_.emplace_back();
+        setup_rules_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 6 /* trace_config */:
+        (*trace_config_).ParseFromArray(field.data(), field.size());
+        break;
+      case 7 /* nested_scenarios */:
+        nested_scenarios_.emplace_back();
+        nested_scenarios_.back().ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ScenarioConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ScenarioConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ScenarioConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: scenario_name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, scenario_name_, msg);
+  }
+
+  // Field 2: start_rules
+  for (auto& it : start_rules_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  // Field 3: stop_rules
+  for (auto& it : stop_rules_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
+  }
+
+  // Field 4: upload_rules
+  for (auto& it : upload_rules_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
+  }
+
+  // Field 5: setup_rules
+  for (auto& it : setup_rules_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
+  }
+
+  // Field 6: trace_config
+  if (_has_field_[6]) {
+    (*trace_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
+  }
+
+  // Field 7: nested_scenarios
+  for (auto& it : nested_scenarios_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(7));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+NestedScenarioConfig::NestedScenarioConfig() = default;
+NestedScenarioConfig::~NestedScenarioConfig() = default;
+NestedScenarioConfig::NestedScenarioConfig(const NestedScenarioConfig&) = default;
+NestedScenarioConfig& NestedScenarioConfig::operator=(const NestedScenarioConfig&) = default;
+NestedScenarioConfig::NestedScenarioConfig(NestedScenarioConfig&&) noexcept = default;
+NestedScenarioConfig& NestedScenarioConfig::operator=(NestedScenarioConfig&&) = default;
+
+bool NestedScenarioConfig::operator==(const NestedScenarioConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(scenario_name_, other.scenario_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(start_rules_, other.start_rules_)
+   && ::protozero::internal::gen_helpers::EqualsField(stop_rules_, other.stop_rules_)
+   && ::protozero::internal::gen_helpers::EqualsField(upload_rules_, other.upload_rules_);
+}
+
+int NestedScenarioConfig::start_rules_size() const { return static_cast<int>(start_rules_.size()); }
+void NestedScenarioConfig::clear_start_rules() { start_rules_.clear(); }
+TriggerRule* NestedScenarioConfig::add_start_rules() { start_rules_.emplace_back(); return &start_rules_.back(); }
+int NestedScenarioConfig::stop_rules_size() const { return static_cast<int>(stop_rules_.size()); }
+void NestedScenarioConfig::clear_stop_rules() { stop_rules_.clear(); }
+TriggerRule* NestedScenarioConfig::add_stop_rules() { stop_rules_.emplace_back(); return &stop_rules_.back(); }
+int NestedScenarioConfig::upload_rules_size() const { return static_cast<int>(upload_rules_.size()); }
+void NestedScenarioConfig::clear_upload_rules() { upload_rules_.clear(); }
+TriggerRule* NestedScenarioConfig::add_upload_rules() { upload_rules_.emplace_back(); return &upload_rules_.back(); }
+bool NestedScenarioConfig::ParseFromArray(const void* raw, size_t size) {
+  start_rules_.clear();
+  stop_rules_.clear();
+  upload_rules_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* scenario_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &scenario_name_);
+        break;
+      case 2 /* start_rules */:
+        start_rules_.emplace_back();
+        start_rules_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 3 /* stop_rules */:
+        stop_rules_.emplace_back();
+        stop_rules_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 4 /* upload_rules */:
+        upload_rules_.emplace_back();
+        upload_rules_.back().ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string NestedScenarioConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> NestedScenarioConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void NestedScenarioConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: scenario_name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, scenario_name_, msg);
+  }
+
+  // Field 2: start_rules
+  for (auto& it : start_rules_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  // Field 3: stop_rules
+  for (auto& it : stop_rules_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
+  }
+
+  // Field 4: upload_rules
+  for (auto& it : upload_rules_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/chrome/v8_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/chrome/v8_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+V8Config::V8Config() = default;
+V8Config::~V8Config() = default;
+V8Config::V8Config(const V8Config&) = default;
+V8Config& V8Config::operator=(const V8Config&) = default;
+V8Config::V8Config(V8Config&&) noexcept = default;
+V8Config& V8Config::operator=(V8Config&&) = default;
+
+bool V8Config::operator==(const V8Config& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(log_script_sources_, other.log_script_sources_)
+   && ::protozero::internal::gen_helpers::EqualsField(log_instructions_, other.log_instructions_);
+}
+
+bool V8Config::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* log_script_sources */:
+        field.get(&log_script_sources_);
+        break;
+      case 2 /* log_instructions */:
+        field.get(&log_instructions_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string V8Config::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> V8Config::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void V8Config::Serialize(::protozero::Message* msg) const {
+  // Field 1: log_script_sources
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, log_script_sources_, msg);
+  }
+
+  // Field 2: log_instructions
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, log_instructions_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/data_source_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/system_info/system_info.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+DataSourceConfig::DataSourceConfig() = default;
+DataSourceConfig::~DataSourceConfig() = default;
+DataSourceConfig::DataSourceConfig(const DataSourceConfig&) = default;
+DataSourceConfig& DataSourceConfig::operator=(const DataSourceConfig&) = default;
+DataSourceConfig::DataSourceConfig(DataSourceConfig&&) noexcept = default;
+DataSourceConfig& DataSourceConfig::operator=(DataSourceConfig&&) = default;
+
+bool DataSourceConfig::operator==(const DataSourceConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(target_buffer_, other.target_buffer_)
+   && ::protozero::internal::gen_helpers::EqualsField(trace_duration_ms_, other.trace_duration_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(prefer_suspend_clock_for_duration_, other.prefer_suspend_clock_for_duration_)
+   && ::protozero::internal::gen_helpers::EqualsField(stop_timeout_ms_, other.stop_timeout_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(enable_extra_guardrails_, other.enable_extra_guardrails_)
+   && ::protozero::internal::gen_helpers::EqualsField(session_initiator_, other.session_initiator_)
+   && ::protozero::internal::gen_helpers::EqualsField(tracing_session_id_, other.tracing_session_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(ftrace_config_, other.ftrace_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(inode_file_config_, other.inode_file_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(process_stats_config_, other.process_stats_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(sys_stats_config_, other.sys_stats_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(heapprofd_config_, other.heapprofd_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(java_hprof_config_, other.java_hprof_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(android_power_config_, other.android_power_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(android_log_config_, other.android_log_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(gpu_counter_config_, other.gpu_counter_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(android_game_intervention_list_config_, other.android_game_intervention_list_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(packages_list_config_, other.packages_list_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(perf_event_config_, other.perf_event_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(vulkan_memory_config_, other.vulkan_memory_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(track_event_config_, other.track_event_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(android_polled_state_config_, other.android_polled_state_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(android_system_property_config_, other.android_system_property_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(statsd_tracing_config_, other.statsd_tracing_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(system_info_config_, other.system_info_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(chrome_config_, other.chrome_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(v8_config_, other.v8_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(interceptor_config_, other.interceptor_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(network_packet_trace_config_, other.network_packet_trace_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(surfaceflinger_layers_config_, other.surfaceflinger_layers_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(surfaceflinger_transactions_config_, other.surfaceflinger_transactions_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(android_sdk_sysprop_guard_config_, other.android_sdk_sysprop_guard_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(etw_config_, other.etw_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(protolog_config_, other.protolog_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(android_input_event_config_, other.android_input_event_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(pixel_modem_config_, other.pixel_modem_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(legacy_config_, other.legacy_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(for_testing_, other.for_testing_);
+}
+
+bool DataSourceConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 2 /* target_buffer */:
+        field.get(&target_buffer_);
+        break;
+      case 3 /* trace_duration_ms */:
+        field.get(&trace_duration_ms_);
+        break;
+      case 122 /* prefer_suspend_clock_for_duration */:
+        field.get(&prefer_suspend_clock_for_duration_);
+        break;
+      case 7 /* stop_timeout_ms */:
+        field.get(&stop_timeout_ms_);
+        break;
+      case 6 /* enable_extra_guardrails */:
+        field.get(&enable_extra_guardrails_);
+        break;
+      case 8 /* session_initiator */:
+        field.get(&session_initiator_);
+        break;
+      case 4 /* tracing_session_id */:
+        field.get(&tracing_session_id_);
+        break;
+      case 100 /* ftrace_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &ftrace_config_);
+        break;
+      case 102 /* inode_file_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &inode_file_config_);
+        break;
+      case 103 /* process_stats_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &process_stats_config_);
+        break;
+      case 104 /* sys_stats_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &sys_stats_config_);
+        break;
+      case 105 /* heapprofd_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &heapprofd_config_);
+        break;
+      case 110 /* java_hprof_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &java_hprof_config_);
+        break;
+      case 106 /* android_power_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &android_power_config_);
+        break;
+      case 107 /* android_log_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &android_log_config_);
+        break;
+      case 108 /* gpu_counter_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &gpu_counter_config_);
+        break;
+      case 116 /* android_game_intervention_list_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &android_game_intervention_list_config_);
+        break;
+      case 109 /* packages_list_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &packages_list_config_);
+        break;
+      case 111 /* perf_event_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &perf_event_config_);
+        break;
+      case 112 /* vulkan_memory_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &vulkan_memory_config_);
+        break;
+      case 113 /* track_event_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &track_event_config_);
+        break;
+      case 114 /* android_polled_state_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &android_polled_state_config_);
+        break;
+      case 118 /* android_system_property_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &android_system_property_config_);
+        break;
+      case 117 /* statsd_tracing_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &statsd_tracing_config_);
+        break;
+      case 119 /* system_info_config */:
+        (*system_info_config_).ParseFromArray(field.data(), field.size());
+        break;
+      case 101 /* chrome_config */:
+        (*chrome_config_).ParseFromArray(field.data(), field.size());
+        break;
+      case 127 /* v8_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &v8_config_);
+        break;
+      case 115 /* interceptor_config */:
+        (*interceptor_config_).ParseFromArray(field.data(), field.size());
+        break;
+      case 120 /* network_packet_trace_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &network_packet_trace_config_);
+        break;
+      case 121 /* surfaceflinger_layers_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &surfaceflinger_layers_config_);
+        break;
+      case 123 /* surfaceflinger_transactions_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &surfaceflinger_transactions_config_);
+        break;
+      case 124 /* android_sdk_sysprop_guard_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &android_sdk_sysprop_guard_config_);
+        break;
+      case 125 /* etw_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &etw_config_);
+        break;
+      case 126 /* protolog_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &protolog_config_);
+        break;
+      case 128 /* android_input_event_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &android_input_event_config_);
+        break;
+      case 129 /* pixel_modem_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &pixel_modem_config_);
+        break;
+      case 1000 /* legacy_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &legacy_config_);
+        break;
+      case 1001 /* for_testing */:
+        (*for_testing_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string DataSourceConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> DataSourceConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void DataSourceConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
+  }
+
+  // Field 2: target_buffer
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, target_buffer_, msg);
+  }
+
+  // Field 3: trace_duration_ms
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, trace_duration_ms_, msg);
+  }
+
+  // Field 122: prefer_suspend_clock_for_duration
+  if (_has_field_[122]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(122, prefer_suspend_clock_for_duration_, msg);
+  }
+
+  // Field 7: stop_timeout_ms
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(7, stop_timeout_ms_, msg);
+  }
+
+  // Field 6: enable_extra_guardrails
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(6, enable_extra_guardrails_, msg);
+  }
+
+  // Field 8: session_initiator
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(8, session_initiator_, msg);
+  }
+
+  // Field 4: tracing_session_id
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, tracing_session_id_, msg);
+  }
+
+  // Field 100: ftrace_config
+  if (_has_field_[100]) {
+    msg->AppendString(100, ftrace_config_);
+  }
+
+  // Field 102: inode_file_config
+  if (_has_field_[102]) {
+    msg->AppendString(102, inode_file_config_);
+  }
+
+  // Field 103: process_stats_config
+  if (_has_field_[103]) {
+    msg->AppendString(103, process_stats_config_);
+  }
+
+  // Field 104: sys_stats_config
+  if (_has_field_[104]) {
+    msg->AppendString(104, sys_stats_config_);
+  }
+
+  // Field 105: heapprofd_config
+  if (_has_field_[105]) {
+    msg->AppendString(105, heapprofd_config_);
+  }
+
+  // Field 110: java_hprof_config
+  if (_has_field_[110]) {
+    msg->AppendString(110, java_hprof_config_);
+  }
+
+  // Field 106: android_power_config
+  if (_has_field_[106]) {
+    msg->AppendString(106, android_power_config_);
+  }
+
+  // Field 107: android_log_config
+  if (_has_field_[107]) {
+    msg->AppendString(107, android_log_config_);
+  }
+
+  // Field 108: gpu_counter_config
+  if (_has_field_[108]) {
+    msg->AppendString(108, gpu_counter_config_);
+  }
+
+  // Field 116: android_game_intervention_list_config
+  if (_has_field_[116]) {
+    msg->AppendString(116, android_game_intervention_list_config_);
+  }
+
+  // Field 109: packages_list_config
+  if (_has_field_[109]) {
+    msg->AppendString(109, packages_list_config_);
+  }
+
+  // Field 111: perf_event_config
+  if (_has_field_[111]) {
+    msg->AppendString(111, perf_event_config_);
+  }
+
+  // Field 112: vulkan_memory_config
+  if (_has_field_[112]) {
+    msg->AppendString(112, vulkan_memory_config_);
+  }
+
+  // Field 113: track_event_config
+  if (_has_field_[113]) {
+    msg->AppendString(113, track_event_config_);
+  }
+
+  // Field 114: android_polled_state_config
+  if (_has_field_[114]) {
+    msg->AppendString(114, android_polled_state_config_);
+  }
+
+  // Field 118: android_system_property_config
+  if (_has_field_[118]) {
+    msg->AppendString(118, android_system_property_config_);
+  }
+
+  // Field 117: statsd_tracing_config
+  if (_has_field_[117]) {
+    msg->AppendString(117, statsd_tracing_config_);
+  }
+
+  // Field 119: system_info_config
+  if (_has_field_[119]) {
+    (*system_info_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(119));
+  }
+
+  // Field 101: chrome_config
+  if (_has_field_[101]) {
+    (*chrome_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(101));
+  }
+
+  // Field 127: v8_config
+  if (_has_field_[127]) {
+    msg->AppendString(127, v8_config_);
+  }
+
+  // Field 115: interceptor_config
+  if (_has_field_[115]) {
+    (*interceptor_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(115));
+  }
+
+  // Field 120: network_packet_trace_config
+  if (_has_field_[120]) {
+    msg->AppendString(120, network_packet_trace_config_);
+  }
+
+  // Field 121: surfaceflinger_layers_config
+  if (_has_field_[121]) {
+    msg->AppendString(121, surfaceflinger_layers_config_);
+  }
+
+  // Field 123: surfaceflinger_transactions_config
+  if (_has_field_[123]) {
+    msg->AppendString(123, surfaceflinger_transactions_config_);
+  }
+
+  // Field 124: android_sdk_sysprop_guard_config
+  if (_has_field_[124]) {
+    msg->AppendString(124, android_sdk_sysprop_guard_config_);
+  }
+
+  // Field 125: etw_config
+  if (_has_field_[125]) {
+    msg->AppendString(125, etw_config_);
+  }
+
+  // Field 126: protolog_config
+  if (_has_field_[126]) {
+    msg->AppendString(126, protolog_config_);
+  }
+
+  // Field 128: android_input_event_config
+  if (_has_field_[128]) {
+    msg->AppendString(128, android_input_event_config_);
+  }
+
+  // Field 129: pixel_modem_config
+  if (_has_field_[129]) {
+    msg->AppendString(129, pixel_modem_config_);
+  }
+
+  // Field 1000: legacy_config
+  if (_has_field_[1000]) {
+    ::protozero::internal::gen_helpers::SerializeString(1000, legacy_config_, msg);
+  }
+
+  // Field 1001: for_testing
+  if (_has_field_[1001]) {
+    (*for_testing_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1001));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/etw/etw_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/etw/etw_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+EtwConfig::EtwConfig() = default;
+EtwConfig::~EtwConfig() = default;
+EtwConfig::EtwConfig(const EtwConfig&) = default;
+EtwConfig& EtwConfig::operator=(const EtwConfig&) = default;
+EtwConfig::EtwConfig(EtwConfig&&) noexcept = default;
+EtwConfig& EtwConfig::operator=(EtwConfig&&) = default;
+
+bool EtwConfig::operator==(const EtwConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(kernel_flags_, other.kernel_flags_);
+}
+
+bool EtwConfig::ParseFromArray(const void* raw, size_t size) {
+  kernel_flags_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* kernel_flags */:
+        kernel_flags_.emplace_back();
+        field.get(&kernel_flags_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string EtwConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> EtwConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void EtwConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: kernel_flags
+  for (auto& it : kernel_flags_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/interceptor_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+InterceptorConfig::InterceptorConfig() = default;
+InterceptorConfig::~InterceptorConfig() = default;
+InterceptorConfig::InterceptorConfig(const InterceptorConfig&) = default;
+InterceptorConfig& InterceptorConfig::operator=(const InterceptorConfig&) = default;
+InterceptorConfig::InterceptorConfig(InterceptorConfig&&) noexcept = default;
+InterceptorConfig& InterceptorConfig::operator=(InterceptorConfig&&) = default;
+
+bool InterceptorConfig::operator==(const InterceptorConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(console_config_, other.console_config_);
+}
+
+bool InterceptorConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 100 /* console_config */:
+        (*console_config_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string InterceptorConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> InterceptorConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void InterceptorConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
+  }
+
+  // Field 100: console_config
+  if (_has_field_[100]) {
+    (*console_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(100));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/stress_test_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/stress_test_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/trace_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/system_info/system_info.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/track_event/track_event_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/sys_stats/sys_stats_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/perf_event_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/perf_events.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/java_hprof_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/heapprofd_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/process_stats/process_stats_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/statsd_tracing_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/atom_ids.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/power/android_power_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/inode_file/inode_file_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/gpu/vulkan_memory_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/gpu/gpu_counter_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/ftrace/ftrace_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/etw/etw_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/chrome/v8_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_transactions_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_layers_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/protolog_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/protolog_common.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/pixel_modem_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/packages_list_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/network_trace_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_sdk_sysprop_guard_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_system_property_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_polled_state_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_log_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_input_event_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_game_intervention_list_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+StressTestConfig::StressTestConfig() = default;
+StressTestConfig::~StressTestConfig() = default;
+StressTestConfig::StressTestConfig(const StressTestConfig&) = default;
+StressTestConfig& StressTestConfig::operator=(const StressTestConfig&) = default;
+StressTestConfig::StressTestConfig(StressTestConfig&&) noexcept = default;
+StressTestConfig& StressTestConfig::operator=(StressTestConfig&&) = default;
+
+bool StressTestConfig::operator==(const StressTestConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(trace_config_, other.trace_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(shmem_size_kb_, other.shmem_size_kb_)
+   && ::protozero::internal::gen_helpers::EqualsField(shmem_page_size_kb_, other.shmem_page_size_kb_)
+   && ::protozero::internal::gen_helpers::EqualsField(num_processes_, other.num_processes_)
+   && ::protozero::internal::gen_helpers::EqualsField(num_threads_, other.num_threads_)
+   && ::protozero::internal::gen_helpers::EqualsField(max_events_, other.max_events_)
+   && ::protozero::internal::gen_helpers::EqualsField(nesting_, other.nesting_)
+   && ::protozero::internal::gen_helpers::EqualsField(steady_state_timings_, other.steady_state_timings_)
+   && ::protozero::internal::gen_helpers::EqualsField(burst_period_ms_, other.burst_period_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(burst_duration_ms_, other.burst_duration_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(burst_timings_, other.burst_timings_);
+}
+
+bool StressTestConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* trace_config */:
+        (*trace_config_).ParseFromArray(field.data(), field.size());
+        break;
+      case 2 /* shmem_size_kb */:
+        field.get(&shmem_size_kb_);
+        break;
+      case 3 /* shmem_page_size_kb */:
+        field.get(&shmem_page_size_kb_);
+        break;
+      case 4 /* num_processes */:
+        field.get(&num_processes_);
+        break;
+      case 5 /* num_threads */:
+        field.get(&num_threads_);
+        break;
+      case 6 /* max_events */:
+        field.get(&max_events_);
+        break;
+      case 7 /* nesting */:
+        field.get(&nesting_);
+        break;
+      case 8 /* steady_state_timings */:
+        (*steady_state_timings_).ParseFromArray(field.data(), field.size());
+        break;
+      case 9 /* burst_period_ms */:
+        field.get(&burst_period_ms_);
+        break;
+      case 10 /* burst_duration_ms */:
+        field.get(&burst_duration_ms_);
+        break;
+      case 11 /* burst_timings */:
+        (*burst_timings_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string StressTestConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> StressTestConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void StressTestConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: trace_config
+  if (_has_field_[1]) {
+    (*trace_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  // Field 2: shmem_size_kb
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, shmem_size_kb_, msg);
+  }
+
+  // Field 3: shmem_page_size_kb
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, shmem_page_size_kb_, msg);
+  }
+
+  // Field 4: num_processes
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, num_processes_, msg);
+  }
+
+  // Field 5: num_threads
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, num_threads_, msg);
+  }
+
+  // Field 6: max_events
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, max_events_, msg);
+  }
+
+  // Field 7: nesting
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(7, nesting_, msg);
+  }
+
+  // Field 8: steady_state_timings
+  if (_has_field_[8]) {
+    (*steady_state_timings_).Serialize(msg->BeginNestedMessage<::protozero::Message>(8));
+  }
+
+  // Field 9: burst_period_ms
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(9, burst_period_ms_, msg);
+  }
+
+  // Field 10: burst_duration_ms
+  if (_has_field_[10]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(10, burst_duration_ms_, msg);
+  }
+
+  // Field 11: burst_timings
+  if (_has_field_[11]) {
+    (*burst_timings_).Serialize(msg->BeginNestedMessage<::protozero::Message>(11));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+StressTestConfig_WriterTiming::StressTestConfig_WriterTiming() = default;
+StressTestConfig_WriterTiming::~StressTestConfig_WriterTiming() = default;
+StressTestConfig_WriterTiming::StressTestConfig_WriterTiming(const StressTestConfig_WriterTiming&) = default;
+StressTestConfig_WriterTiming& StressTestConfig_WriterTiming::operator=(const StressTestConfig_WriterTiming&) = default;
+StressTestConfig_WriterTiming::StressTestConfig_WriterTiming(StressTestConfig_WriterTiming&&) noexcept = default;
+StressTestConfig_WriterTiming& StressTestConfig_WriterTiming::operator=(StressTestConfig_WriterTiming&&) = default;
+
+bool StressTestConfig_WriterTiming::operator==(const StressTestConfig_WriterTiming& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(payload_mean_, other.payload_mean_)
+   && ::protozero::internal::gen_helpers::EqualsField(payload_stddev_, other.payload_stddev_)
+   && ::protozero::internal::gen_helpers::EqualsField(rate_mean_, other.rate_mean_)
+   && ::protozero::internal::gen_helpers::EqualsField(rate_stddev_, other.rate_stddev_)
+   && ::protozero::internal::gen_helpers::EqualsField(payload_write_time_ms_, other.payload_write_time_ms_);
+}
+
+bool StressTestConfig_WriterTiming::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* payload_mean */:
+        field.get(&payload_mean_);
+        break;
+      case 2 /* payload_stddev */:
+        field.get(&payload_stddev_);
+        break;
+      case 3 /* rate_mean */:
+        field.get(&rate_mean_);
+        break;
+      case 4 /* rate_stddev */:
+        field.get(&rate_stddev_);
+        break;
+      case 5 /* payload_write_time_ms */:
+        field.get(&payload_write_time_ms_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string StressTestConfig_WriterTiming::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> StressTestConfig_WriterTiming::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void StressTestConfig_WriterTiming::Serialize(::protozero::Message* msg) const {
+  // Field 1: payload_mean
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeFixed(1, payload_mean_, msg);
+  }
+
+  // Field 2: payload_stddev
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeFixed(2, payload_stddev_, msg);
+  }
+
+  // Field 3: rate_mean
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeFixed(3, rate_mean_, msg);
+  }
+
+  // Field 4: rate_stddev
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeFixed(4, rate_stddev_, msg);
+  }
+
+  // Field 5: payload_write_time_ms
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, payload_write_time_ms_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/test_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+TestConfig::TestConfig() = default;
+TestConfig::~TestConfig() = default;
+TestConfig::TestConfig(const TestConfig&) = default;
+TestConfig& TestConfig::operator=(const TestConfig&) = default;
+TestConfig::TestConfig(TestConfig&&) noexcept = default;
+TestConfig& TestConfig::operator=(TestConfig&&) = default;
+
+bool TestConfig::operator==(const TestConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(message_count_, other.message_count_)
+   && ::protozero::internal::gen_helpers::EqualsField(max_messages_per_second_, other.max_messages_per_second_)
+   && ::protozero::internal::gen_helpers::EqualsField(seed_, other.seed_)
+   && ::protozero::internal::gen_helpers::EqualsField(message_size_, other.message_size_)
+   && ::protozero::internal::gen_helpers::EqualsField(send_batch_on_register_, other.send_batch_on_register_)
+   && ::protozero::internal::gen_helpers::EqualsField(dummy_fields_, other.dummy_fields_);
+}
+
+bool TestConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* message_count */:
+        field.get(&message_count_);
+        break;
+      case 2 /* max_messages_per_second */:
+        field.get(&max_messages_per_second_);
+        break;
+      case 3 /* seed */:
+        field.get(&seed_);
+        break;
+      case 4 /* message_size */:
+        field.get(&message_size_);
+        break;
+      case 5 /* send_batch_on_register */:
+        field.get(&send_batch_on_register_);
+        break;
+      case 6 /* dummy_fields */:
+        (*dummy_fields_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TestConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TestConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TestConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: message_count
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, message_count_, msg);
+  }
+
+  // Field 2: max_messages_per_second
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, max_messages_per_second_, msg);
+  }
+
+  // Field 3: seed
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, seed_, msg);
+  }
+
+  // Field 4: message_size
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, message_size_, msg);
+  }
+
+  // Field 5: send_batch_on_register
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, send_batch_on_register_, msg);
+  }
+
+  // Field 6: dummy_fields
+  if (_has_field_[6]) {
+    (*dummy_fields_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TestConfig_DummyFields::TestConfig_DummyFields() = default;
+TestConfig_DummyFields::~TestConfig_DummyFields() = default;
+TestConfig_DummyFields::TestConfig_DummyFields(const TestConfig_DummyFields&) = default;
+TestConfig_DummyFields& TestConfig_DummyFields::operator=(const TestConfig_DummyFields&) = default;
+TestConfig_DummyFields::TestConfig_DummyFields(TestConfig_DummyFields&&) noexcept = default;
+TestConfig_DummyFields& TestConfig_DummyFields::operator=(TestConfig_DummyFields&&) = default;
+
+bool TestConfig_DummyFields::operator==(const TestConfig_DummyFields& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(field_uint32_, other.field_uint32_)
+   && ::protozero::internal::gen_helpers::EqualsField(field_int32_, other.field_int32_)
+   && ::protozero::internal::gen_helpers::EqualsField(field_uint64_, other.field_uint64_)
+   && ::protozero::internal::gen_helpers::EqualsField(field_int64_, other.field_int64_)
+   && ::protozero::internal::gen_helpers::EqualsField(field_fixed64_, other.field_fixed64_)
+   && ::protozero::internal::gen_helpers::EqualsField(field_sfixed64_, other.field_sfixed64_)
+   && ::protozero::internal::gen_helpers::EqualsField(field_fixed32_, other.field_fixed32_)
+   && ::protozero::internal::gen_helpers::EqualsField(field_sfixed32_, other.field_sfixed32_)
+   && ::protozero::internal::gen_helpers::EqualsField(field_double_, other.field_double_)
+   && ::protozero::internal::gen_helpers::EqualsField(field_float_, other.field_float_)
+   && ::protozero::internal::gen_helpers::EqualsField(field_sint64_, other.field_sint64_)
+   && ::protozero::internal::gen_helpers::EqualsField(field_sint32_, other.field_sint32_)
+   && ::protozero::internal::gen_helpers::EqualsField(field_string_, other.field_string_)
+   && ::protozero::internal::gen_helpers::EqualsField(field_bytes_, other.field_bytes_);
+}
+
+bool TestConfig_DummyFields::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* field_uint32 */:
+        field.get(&field_uint32_);
+        break;
+      case 2 /* field_int32 */:
+        field.get(&field_int32_);
+        break;
+      case 3 /* field_uint64 */:
+        field.get(&field_uint64_);
+        break;
+      case 4 /* field_int64 */:
+        field.get(&field_int64_);
+        break;
+      case 5 /* field_fixed64 */:
+        field.get(&field_fixed64_);
+        break;
+      case 6 /* field_sfixed64 */:
+        field.get(&field_sfixed64_);
+        break;
+      case 7 /* field_fixed32 */:
+        field.get(&field_fixed32_);
+        break;
+      case 8 /* field_sfixed32 */:
+        field.get(&field_sfixed32_);
+        break;
+      case 9 /* field_double */:
+        field.get(&field_double_);
+        break;
+      case 10 /* field_float */:
+        field.get(&field_float_);
+        break;
+      case 11 /* field_sint64 */:
+        field.get_signed(&field_sint64_);
+        break;
+      case 12 /* field_sint32 */:
+        field.get_signed(&field_sint32_);
+        break;
+      case 13 /* field_string */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &field_string_);
+        break;
+      case 14 /* field_bytes */:
+        field.get(&field_bytes_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TestConfig_DummyFields::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TestConfig_DummyFields::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TestConfig_DummyFields::Serialize(::protozero::Message* msg) const {
+  // Field 1: field_uint32
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, field_uint32_, msg);
+  }
+
+  // Field 2: field_int32
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, field_int32_, msg);
+  }
+
+  // Field 3: field_uint64
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, field_uint64_, msg);
+  }
+
+  // Field 4: field_int64
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, field_int64_, msg);
+  }
+
+  // Field 5: field_fixed64
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeFixed(5, field_fixed64_, msg);
+  }
+
+  // Field 6: field_sfixed64
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeFixed(6, field_sfixed64_, msg);
+  }
+
+  // Field 7: field_fixed32
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeFixed(7, field_fixed32_, msg);
+  }
+
+  // Field 8: field_sfixed32
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeFixed(8, field_sfixed32_, msg);
+  }
+
+  // Field 9: field_double
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeFixed(9, field_double_, msg);
+  }
+
+  // Field 10: field_float
+  if (_has_field_[10]) {
+    ::protozero::internal::gen_helpers::SerializeFixed(10, field_float_, msg);
+  }
+
+  // Field 11: field_sint64
+  if (_has_field_[11]) {
+    ::protozero::internal::gen_helpers::SerializeSignedVarInt(11, field_sint64_, msg);
+  }
+
+  // Field 12: field_sint32
+  if (_has_field_[12]) {
+    ::protozero::internal::gen_helpers::SerializeSignedVarInt(12, field_sint32_, msg);
+  }
+
+  // Field 13: field_string
+  if (_has_field_[13]) {
+    ::protozero::internal::gen_helpers::SerializeString(13, field_string_, msg);
+  }
+
+  // Field 14: field_bytes
+  if (_has_field_[14]) {
+    ::protozero::internal::gen_helpers::SerializeString(14, field_bytes_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/trace_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/trace_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/system_info/system_info.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/track_event/track_event_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/sys_stats/sys_stats_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/perf_event_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/perf_events.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/java_hprof_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/heapprofd_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/process_stats/process_stats_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/statsd_tracing_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/atom_ids.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/power/android_power_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/inode_file/inode_file_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/gpu/vulkan_memory_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/gpu/gpu_counter_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/ftrace/ftrace_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/etw/etw_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/chrome/v8_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_transactions_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_layers_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/protolog_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/protolog_common.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/pixel_modem_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/packages_list_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/network_trace_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_sdk_sysprop_guard_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_system_property_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_polled_state_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_log_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_input_event_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_game_intervention_list_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+TraceConfig::TraceConfig() = default;
+TraceConfig::~TraceConfig() = default;
+TraceConfig::TraceConfig(const TraceConfig&) = default;
+TraceConfig& TraceConfig::operator=(const TraceConfig&) = default;
+TraceConfig::TraceConfig(TraceConfig&&) noexcept = default;
+TraceConfig& TraceConfig::operator=(TraceConfig&&) = default;
+
+bool TraceConfig::operator==(const TraceConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(buffers_, other.buffers_)
+   && ::protozero::internal::gen_helpers::EqualsField(data_sources_, other.data_sources_)
+   && ::protozero::internal::gen_helpers::EqualsField(builtin_data_sources_, other.builtin_data_sources_)
+   && ::protozero::internal::gen_helpers::EqualsField(duration_ms_, other.duration_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(prefer_suspend_clock_for_duration_, other.prefer_suspend_clock_for_duration_)
+   && ::protozero::internal::gen_helpers::EqualsField(enable_extra_guardrails_, other.enable_extra_guardrails_)
+   && ::protozero::internal::gen_helpers::EqualsField(lockdown_mode_, other.lockdown_mode_)
+   && ::protozero::internal::gen_helpers::EqualsField(producers_, other.producers_)
+   && ::protozero::internal::gen_helpers::EqualsField(statsd_metadata_, other.statsd_metadata_)
+   && ::protozero::internal::gen_helpers::EqualsField(write_into_file_, other.write_into_file_)
+   && ::protozero::internal::gen_helpers::EqualsField(output_path_, other.output_path_)
+   && ::protozero::internal::gen_helpers::EqualsField(file_write_period_ms_, other.file_write_period_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(max_file_size_bytes_, other.max_file_size_bytes_)
+   && ::protozero::internal::gen_helpers::EqualsField(guardrail_overrides_, other.guardrail_overrides_)
+   && ::protozero::internal::gen_helpers::EqualsField(deferred_start_, other.deferred_start_)
+   && ::protozero::internal::gen_helpers::EqualsField(flush_period_ms_, other.flush_period_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(flush_timeout_ms_, other.flush_timeout_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(data_source_stop_timeout_ms_, other.data_source_stop_timeout_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(notify_traceur_, other.notify_traceur_)
+   && ::protozero::internal::gen_helpers::EqualsField(bugreport_score_, other.bugreport_score_)
+   && ::protozero::internal::gen_helpers::EqualsField(bugreport_filename_, other.bugreport_filename_)
+   && ::protozero::internal::gen_helpers::EqualsField(trigger_config_, other.trigger_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(activate_triggers_, other.activate_triggers_)
+   && ::protozero::internal::gen_helpers::EqualsField(incremental_state_config_, other.incremental_state_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(allow_user_build_tracing_, other.allow_user_build_tracing_)
+   && ::protozero::internal::gen_helpers::EqualsField(unique_session_name_, other.unique_session_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(compression_type_, other.compression_type_)
+   && ::protozero::internal::gen_helpers::EqualsField(incident_report_config_, other.incident_report_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(statsd_logging_, other.statsd_logging_)
+   && ::protozero::internal::gen_helpers::EqualsField(trace_uuid_msb_, other.trace_uuid_msb_)
+   && ::protozero::internal::gen_helpers::EqualsField(trace_uuid_lsb_, other.trace_uuid_lsb_)
+   && ::protozero::internal::gen_helpers::EqualsField(trace_filter_, other.trace_filter_)
+   && ::protozero::internal::gen_helpers::EqualsField(android_report_config_, other.android_report_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(cmd_trace_start_delay_, other.cmd_trace_start_delay_);
+}
+
+int TraceConfig::buffers_size() const { return static_cast<int>(buffers_.size()); }
+void TraceConfig::clear_buffers() { buffers_.clear(); }
+TraceConfig_BufferConfig* TraceConfig::add_buffers() { buffers_.emplace_back(); return &buffers_.back(); }
+int TraceConfig::data_sources_size() const { return static_cast<int>(data_sources_.size()); }
+void TraceConfig::clear_data_sources() { data_sources_.clear(); }
+TraceConfig_DataSource* TraceConfig::add_data_sources() { data_sources_.emplace_back(); return &data_sources_.back(); }
+int TraceConfig::producers_size() const { return static_cast<int>(producers_.size()); }
+void TraceConfig::clear_producers() { producers_.clear(); }
+TraceConfig_ProducerConfig* TraceConfig::add_producers() { producers_.emplace_back(); return &producers_.back(); }
+bool TraceConfig::ParseFromArray(const void* raw, size_t size) {
+  buffers_.clear();
+  data_sources_.clear();
+  producers_.clear();
+  activate_triggers_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* buffers */:
+        buffers_.emplace_back();
+        buffers_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 2 /* data_sources */:
+        data_sources_.emplace_back();
+        data_sources_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 20 /* builtin_data_sources */:
+        (*builtin_data_sources_).ParseFromArray(field.data(), field.size());
+        break;
+      case 3 /* duration_ms */:
+        field.get(&duration_ms_);
+        break;
+      case 36 /* prefer_suspend_clock_for_duration */:
+        field.get(&prefer_suspend_clock_for_duration_);
+        break;
+      case 4 /* enable_extra_guardrails */:
+        field.get(&enable_extra_guardrails_);
+        break;
+      case 5 /* lockdown_mode */:
+        field.get(&lockdown_mode_);
+        break;
+      case 6 /* producers */:
+        producers_.emplace_back();
+        producers_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 7 /* statsd_metadata */:
+        (*statsd_metadata_).ParseFromArray(field.data(), field.size());
+        break;
+      case 8 /* write_into_file */:
+        field.get(&write_into_file_);
+        break;
+      case 29 /* output_path */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &output_path_);
+        break;
+      case 9 /* file_write_period_ms */:
+        field.get(&file_write_period_ms_);
+        break;
+      case 10 /* max_file_size_bytes */:
+        field.get(&max_file_size_bytes_);
+        break;
+      case 11 /* guardrail_overrides */:
+        (*guardrail_overrides_).ParseFromArray(field.data(), field.size());
+        break;
+      case 12 /* deferred_start */:
+        field.get(&deferred_start_);
+        break;
+      case 13 /* flush_period_ms */:
+        field.get(&flush_period_ms_);
+        break;
+      case 14 /* flush_timeout_ms */:
+        field.get(&flush_timeout_ms_);
+        break;
+      case 23 /* data_source_stop_timeout_ms */:
+        field.get(&data_source_stop_timeout_ms_);
+        break;
+      case 16 /* notify_traceur */:
+        field.get(&notify_traceur_);
+        break;
+      case 30 /* bugreport_score */:
+        field.get(&bugreport_score_);
+        break;
+      case 38 /* bugreport_filename */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &bugreport_filename_);
+        break;
+      case 17 /* trigger_config */:
+        (*trigger_config_).ParseFromArray(field.data(), field.size());
+        break;
+      case 18 /* activate_triggers */:
+        activate_triggers_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &activate_triggers_.back());
+        break;
+      case 21 /* incremental_state_config */:
+        (*incremental_state_config_).ParseFromArray(field.data(), field.size());
+        break;
+      case 19 /* allow_user_build_tracing */:
+        field.get(&allow_user_build_tracing_);
+        break;
+      case 22 /* unique_session_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &unique_session_name_);
+        break;
+      case 24 /* compression_type */:
+        field.get(&compression_type_);
+        break;
+      case 25 /* incident_report_config */:
+        (*incident_report_config_).ParseFromArray(field.data(), field.size());
+        break;
+      case 31 /* statsd_logging */:
+        field.get(&statsd_logging_);
+        break;
+      case 27 /* trace_uuid_msb */:
+        field.get(&trace_uuid_msb_);
+        break;
+      case 28 /* trace_uuid_lsb */:
+        field.get(&trace_uuid_lsb_);
+        break;
+      case 33 /* trace_filter */:
+        (*trace_filter_).ParseFromArray(field.data(), field.size());
+        break;
+      case 34 /* android_report_config */:
+        (*android_report_config_).ParseFromArray(field.data(), field.size());
+        break;
+      case 35 /* cmd_trace_start_delay */:
+        (*cmd_trace_start_delay_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: buffers
+  for (auto& it : buffers_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  // Field 2: data_sources
+  for (auto& it : data_sources_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  // Field 20: builtin_data_sources
+  if (_has_field_[20]) {
+    (*builtin_data_sources_).Serialize(msg->BeginNestedMessage<::protozero::Message>(20));
+  }
+
+  // Field 3: duration_ms
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, duration_ms_, msg);
+  }
+
+  // Field 36: prefer_suspend_clock_for_duration
+  if (_has_field_[36]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(36, prefer_suspend_clock_for_duration_, msg);
+  }
+
+  // Field 4: enable_extra_guardrails
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, enable_extra_guardrails_, msg);
+  }
+
+  // Field 5: lockdown_mode
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, lockdown_mode_, msg);
+  }
+
+  // Field 6: producers
+  for (auto& it : producers_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
+  }
+
+  // Field 7: statsd_metadata
+  if (_has_field_[7]) {
+    (*statsd_metadata_).Serialize(msg->BeginNestedMessage<::protozero::Message>(7));
+  }
+
+  // Field 8: write_into_file
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(8, write_into_file_, msg);
+  }
+
+  // Field 29: output_path
+  if (_has_field_[29]) {
+    ::protozero::internal::gen_helpers::SerializeString(29, output_path_, msg);
+  }
+
+  // Field 9: file_write_period_ms
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(9, file_write_period_ms_, msg);
+  }
+
+  // Field 10: max_file_size_bytes
+  if (_has_field_[10]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(10, max_file_size_bytes_, msg);
+  }
+
+  // Field 11: guardrail_overrides
+  if (_has_field_[11]) {
+    (*guardrail_overrides_).Serialize(msg->BeginNestedMessage<::protozero::Message>(11));
+  }
+
+  // Field 12: deferred_start
+  if (_has_field_[12]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(12, deferred_start_, msg);
+  }
+
+  // Field 13: flush_period_ms
+  if (_has_field_[13]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(13, flush_period_ms_, msg);
+  }
+
+  // Field 14: flush_timeout_ms
+  if (_has_field_[14]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(14, flush_timeout_ms_, msg);
+  }
+
+  // Field 23: data_source_stop_timeout_ms
+  if (_has_field_[23]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(23, data_source_stop_timeout_ms_, msg);
+  }
+
+  // Field 16: notify_traceur
+  if (_has_field_[16]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(16, notify_traceur_, msg);
+  }
+
+  // Field 30: bugreport_score
+  if (_has_field_[30]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(30, bugreport_score_, msg);
+  }
+
+  // Field 38: bugreport_filename
+  if (_has_field_[38]) {
+    ::protozero::internal::gen_helpers::SerializeString(38, bugreport_filename_, msg);
+  }
+
+  // Field 17: trigger_config
+  if (_has_field_[17]) {
+    (*trigger_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(17));
+  }
+
+  // Field 18: activate_triggers
+  for (auto& it : activate_triggers_) {
+    ::protozero::internal::gen_helpers::SerializeString(18, it, msg);
+  }
+
+  // Field 21: incremental_state_config
+  if (_has_field_[21]) {
+    (*incremental_state_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(21));
+  }
+
+  // Field 19: allow_user_build_tracing
+  if (_has_field_[19]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(19, allow_user_build_tracing_, msg);
+  }
+
+  // Field 22: unique_session_name
+  if (_has_field_[22]) {
+    ::protozero::internal::gen_helpers::SerializeString(22, unique_session_name_, msg);
+  }
+
+  // Field 24: compression_type
+  if (_has_field_[24]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(24, compression_type_, msg);
+  }
+
+  // Field 25: incident_report_config
+  if (_has_field_[25]) {
+    (*incident_report_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(25));
+  }
+
+  // Field 31: statsd_logging
+  if (_has_field_[31]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(31, statsd_logging_, msg);
+  }
+
+  // Field 27: trace_uuid_msb
+  if (_has_field_[27]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(27, trace_uuid_msb_, msg);
+  }
+
+  // Field 28: trace_uuid_lsb
+  if (_has_field_[28]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(28, trace_uuid_lsb_, msg);
+  }
+
+  // Field 33: trace_filter
+  if (_has_field_[33]) {
+    (*trace_filter_).Serialize(msg->BeginNestedMessage<::protozero::Message>(33));
+  }
+
+  // Field 34: android_report_config
+  if (_has_field_[34]) {
+    (*android_report_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(34));
+  }
+
+  // Field 35: cmd_trace_start_delay
+  if (_has_field_[35]) {
+    (*cmd_trace_start_delay_).Serialize(msg->BeginNestedMessage<::protozero::Message>(35));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TraceConfig_CmdTraceStartDelay::TraceConfig_CmdTraceStartDelay() = default;
+TraceConfig_CmdTraceStartDelay::~TraceConfig_CmdTraceStartDelay() = default;
+TraceConfig_CmdTraceStartDelay::TraceConfig_CmdTraceStartDelay(const TraceConfig_CmdTraceStartDelay&) = default;
+TraceConfig_CmdTraceStartDelay& TraceConfig_CmdTraceStartDelay::operator=(const TraceConfig_CmdTraceStartDelay&) = default;
+TraceConfig_CmdTraceStartDelay::TraceConfig_CmdTraceStartDelay(TraceConfig_CmdTraceStartDelay&&) noexcept = default;
+TraceConfig_CmdTraceStartDelay& TraceConfig_CmdTraceStartDelay::operator=(TraceConfig_CmdTraceStartDelay&&) = default;
+
+bool TraceConfig_CmdTraceStartDelay::operator==(const TraceConfig_CmdTraceStartDelay& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(min_delay_ms_, other.min_delay_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(max_delay_ms_, other.max_delay_ms_);
+}
+
+bool TraceConfig_CmdTraceStartDelay::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* min_delay_ms */:
+        field.get(&min_delay_ms_);
+        break;
+      case 2 /* max_delay_ms */:
+        field.get(&max_delay_ms_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceConfig_CmdTraceStartDelay::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_CmdTraceStartDelay::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_CmdTraceStartDelay::Serialize(::protozero::Message* msg) const {
+  // Field 1: min_delay_ms
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, min_delay_ms_, msg);
+  }
+
+  // Field 2: max_delay_ms
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, max_delay_ms_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TraceConfig_AndroidReportConfig::TraceConfig_AndroidReportConfig() = default;
+TraceConfig_AndroidReportConfig::~TraceConfig_AndroidReportConfig() = default;
+TraceConfig_AndroidReportConfig::TraceConfig_AndroidReportConfig(const TraceConfig_AndroidReportConfig&) = default;
+TraceConfig_AndroidReportConfig& TraceConfig_AndroidReportConfig::operator=(const TraceConfig_AndroidReportConfig&) = default;
+TraceConfig_AndroidReportConfig::TraceConfig_AndroidReportConfig(TraceConfig_AndroidReportConfig&&) noexcept = default;
+TraceConfig_AndroidReportConfig& TraceConfig_AndroidReportConfig::operator=(TraceConfig_AndroidReportConfig&&) = default;
+
+bool TraceConfig_AndroidReportConfig::operator==(const TraceConfig_AndroidReportConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(reporter_service_package_, other.reporter_service_package_)
+   && ::protozero::internal::gen_helpers::EqualsField(reporter_service_class_, other.reporter_service_class_)
+   && ::protozero::internal::gen_helpers::EqualsField(skip_report_, other.skip_report_)
+   && ::protozero::internal::gen_helpers::EqualsField(use_pipe_in_framework_for_testing_, other.use_pipe_in_framework_for_testing_);
+}
+
+bool TraceConfig_AndroidReportConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* reporter_service_package */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &reporter_service_package_);
+        break;
+      case 2 /* reporter_service_class */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &reporter_service_class_);
+        break;
+      case 3 /* skip_report */:
+        field.get(&skip_report_);
+        break;
+      case 4 /* use_pipe_in_framework_for_testing */:
+        field.get(&use_pipe_in_framework_for_testing_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceConfig_AndroidReportConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_AndroidReportConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_AndroidReportConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: reporter_service_package
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, reporter_service_package_, msg);
+  }
+
+  // Field 2: reporter_service_class
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, reporter_service_class_, msg);
+  }
+
+  // Field 3: skip_report
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, skip_report_, msg);
+  }
+
+  // Field 4: use_pipe_in_framework_for_testing
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, use_pipe_in_framework_for_testing_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TraceConfig_TraceFilter::TraceConfig_TraceFilter() = default;
+TraceConfig_TraceFilter::~TraceConfig_TraceFilter() = default;
+TraceConfig_TraceFilter::TraceConfig_TraceFilter(const TraceConfig_TraceFilter&) = default;
+TraceConfig_TraceFilter& TraceConfig_TraceFilter::operator=(const TraceConfig_TraceFilter&) = default;
+TraceConfig_TraceFilter::TraceConfig_TraceFilter(TraceConfig_TraceFilter&&) noexcept = default;
+TraceConfig_TraceFilter& TraceConfig_TraceFilter::operator=(TraceConfig_TraceFilter&&) = default;
+
+bool TraceConfig_TraceFilter::operator==(const TraceConfig_TraceFilter& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(bytecode_, other.bytecode_)
+   && ::protozero::internal::gen_helpers::EqualsField(bytecode_v2_, other.bytecode_v2_)
+   && ::protozero::internal::gen_helpers::EqualsField(string_filter_chain_, other.string_filter_chain_);
+}
+
+bool TraceConfig_TraceFilter::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* bytecode */:
+        field.get(&bytecode_);
+        break;
+      case 2 /* bytecode_v2 */:
+        field.get(&bytecode_v2_);
+        break;
+      case 3 /* string_filter_chain */:
+        (*string_filter_chain_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceConfig_TraceFilter::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_TraceFilter::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_TraceFilter::Serialize(::protozero::Message* msg) const {
+  // Field 1: bytecode
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, bytecode_, msg);
+  }
+
+  // Field 2: bytecode_v2
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, bytecode_v2_, msg);
+  }
+
+  // Field 3: string_filter_chain
+  if (_has_field_[3]) {
+    (*string_filter_chain_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TraceConfig_TraceFilter_StringFilterChain::TraceConfig_TraceFilter_StringFilterChain() = default;
+TraceConfig_TraceFilter_StringFilterChain::~TraceConfig_TraceFilter_StringFilterChain() = default;
+TraceConfig_TraceFilter_StringFilterChain::TraceConfig_TraceFilter_StringFilterChain(const TraceConfig_TraceFilter_StringFilterChain&) = default;
+TraceConfig_TraceFilter_StringFilterChain& TraceConfig_TraceFilter_StringFilterChain::operator=(const TraceConfig_TraceFilter_StringFilterChain&) = default;
+TraceConfig_TraceFilter_StringFilterChain::TraceConfig_TraceFilter_StringFilterChain(TraceConfig_TraceFilter_StringFilterChain&&) noexcept = default;
+TraceConfig_TraceFilter_StringFilterChain& TraceConfig_TraceFilter_StringFilterChain::operator=(TraceConfig_TraceFilter_StringFilterChain&&) = default;
+
+bool TraceConfig_TraceFilter_StringFilterChain::operator==(const TraceConfig_TraceFilter_StringFilterChain& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(rules_, other.rules_);
+}
+
+int TraceConfig_TraceFilter_StringFilterChain::rules_size() const { return static_cast<int>(rules_.size()); }
+void TraceConfig_TraceFilter_StringFilterChain::clear_rules() { rules_.clear(); }
+TraceConfig_TraceFilter_StringFilterRule* TraceConfig_TraceFilter_StringFilterChain::add_rules() { rules_.emplace_back(); return &rules_.back(); }
+bool TraceConfig_TraceFilter_StringFilterChain::ParseFromArray(const void* raw, size_t size) {
+  rules_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* rules */:
+        rules_.emplace_back();
+        rules_.back().ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceConfig_TraceFilter_StringFilterChain::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_TraceFilter_StringFilterChain::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_TraceFilter_StringFilterChain::Serialize(::protozero::Message* msg) const {
+  // Field 1: rules
+  for (auto& it : rules_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TraceConfig_TraceFilter_StringFilterRule::TraceConfig_TraceFilter_StringFilterRule() = default;
+TraceConfig_TraceFilter_StringFilterRule::~TraceConfig_TraceFilter_StringFilterRule() = default;
+TraceConfig_TraceFilter_StringFilterRule::TraceConfig_TraceFilter_StringFilterRule(const TraceConfig_TraceFilter_StringFilterRule&) = default;
+TraceConfig_TraceFilter_StringFilterRule& TraceConfig_TraceFilter_StringFilterRule::operator=(const TraceConfig_TraceFilter_StringFilterRule&) = default;
+TraceConfig_TraceFilter_StringFilterRule::TraceConfig_TraceFilter_StringFilterRule(TraceConfig_TraceFilter_StringFilterRule&&) noexcept = default;
+TraceConfig_TraceFilter_StringFilterRule& TraceConfig_TraceFilter_StringFilterRule::operator=(TraceConfig_TraceFilter_StringFilterRule&&) = default;
+
+bool TraceConfig_TraceFilter_StringFilterRule::operator==(const TraceConfig_TraceFilter_StringFilterRule& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(policy_, other.policy_)
+   && ::protozero::internal::gen_helpers::EqualsField(regex_pattern_, other.regex_pattern_)
+   && ::protozero::internal::gen_helpers::EqualsField(atrace_payload_starts_with_, other.atrace_payload_starts_with_);
+}
+
+bool TraceConfig_TraceFilter_StringFilterRule::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* policy */:
+        field.get(&policy_);
+        break;
+      case 2 /* regex_pattern */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &regex_pattern_);
+        break;
+      case 3 /* atrace_payload_starts_with */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &atrace_payload_starts_with_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceConfig_TraceFilter_StringFilterRule::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_TraceFilter_StringFilterRule::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_TraceFilter_StringFilterRule::Serialize(::protozero::Message* msg) const {
+  // Field 1: policy
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, policy_, msg);
+  }
+
+  // Field 2: regex_pattern
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, regex_pattern_, msg);
+  }
+
+  // Field 3: atrace_payload_starts_with
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeString(3, atrace_payload_starts_with_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TraceConfig_IncidentReportConfig::TraceConfig_IncidentReportConfig() = default;
+TraceConfig_IncidentReportConfig::~TraceConfig_IncidentReportConfig() = default;
+TraceConfig_IncidentReportConfig::TraceConfig_IncidentReportConfig(const TraceConfig_IncidentReportConfig&) = default;
+TraceConfig_IncidentReportConfig& TraceConfig_IncidentReportConfig::operator=(const TraceConfig_IncidentReportConfig&) = default;
+TraceConfig_IncidentReportConfig::TraceConfig_IncidentReportConfig(TraceConfig_IncidentReportConfig&&) noexcept = default;
+TraceConfig_IncidentReportConfig& TraceConfig_IncidentReportConfig::operator=(TraceConfig_IncidentReportConfig&&) = default;
+
+bool TraceConfig_IncidentReportConfig::operator==(const TraceConfig_IncidentReportConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(destination_package_, other.destination_package_)
+   && ::protozero::internal::gen_helpers::EqualsField(destination_class_, other.destination_class_)
+   && ::protozero::internal::gen_helpers::EqualsField(privacy_level_, other.privacy_level_)
+   && ::protozero::internal::gen_helpers::EqualsField(skip_incidentd_, other.skip_incidentd_)
+   && ::protozero::internal::gen_helpers::EqualsField(skip_dropbox_, other.skip_dropbox_);
+}
+
+bool TraceConfig_IncidentReportConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* destination_package */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &destination_package_);
+        break;
+      case 2 /* destination_class */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &destination_class_);
+        break;
+      case 3 /* privacy_level */:
+        field.get(&privacy_level_);
+        break;
+      case 5 /* skip_incidentd */:
+        field.get(&skip_incidentd_);
+        break;
+      case 4 /* skip_dropbox */:
+        field.get(&skip_dropbox_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceConfig_IncidentReportConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_IncidentReportConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_IncidentReportConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: destination_package
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, destination_package_, msg);
+  }
+
+  // Field 2: destination_class
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, destination_class_, msg);
+  }
+
+  // Field 3: privacy_level
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, privacy_level_, msg);
+  }
+
+  // Field 5: skip_incidentd
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, skip_incidentd_, msg);
+  }
+
+  // Field 4: skip_dropbox
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, skip_dropbox_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TraceConfig_IncrementalStateConfig::TraceConfig_IncrementalStateConfig() = default;
+TraceConfig_IncrementalStateConfig::~TraceConfig_IncrementalStateConfig() = default;
+TraceConfig_IncrementalStateConfig::TraceConfig_IncrementalStateConfig(const TraceConfig_IncrementalStateConfig&) = default;
+TraceConfig_IncrementalStateConfig& TraceConfig_IncrementalStateConfig::operator=(const TraceConfig_IncrementalStateConfig&) = default;
+TraceConfig_IncrementalStateConfig::TraceConfig_IncrementalStateConfig(TraceConfig_IncrementalStateConfig&&) noexcept = default;
+TraceConfig_IncrementalStateConfig& TraceConfig_IncrementalStateConfig::operator=(TraceConfig_IncrementalStateConfig&&) = default;
+
+bool TraceConfig_IncrementalStateConfig::operator==(const TraceConfig_IncrementalStateConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(clear_period_ms_, other.clear_period_ms_);
+}
+
+bool TraceConfig_IncrementalStateConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* clear_period_ms */:
+        field.get(&clear_period_ms_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceConfig_IncrementalStateConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_IncrementalStateConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_IncrementalStateConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: clear_period_ms
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, clear_period_ms_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TraceConfig_TriggerConfig::TraceConfig_TriggerConfig() = default;
+TraceConfig_TriggerConfig::~TraceConfig_TriggerConfig() = default;
+TraceConfig_TriggerConfig::TraceConfig_TriggerConfig(const TraceConfig_TriggerConfig&) = default;
+TraceConfig_TriggerConfig& TraceConfig_TriggerConfig::operator=(const TraceConfig_TriggerConfig&) = default;
+TraceConfig_TriggerConfig::TraceConfig_TriggerConfig(TraceConfig_TriggerConfig&&) noexcept = default;
+TraceConfig_TriggerConfig& TraceConfig_TriggerConfig::operator=(TraceConfig_TriggerConfig&&) = default;
+
+bool TraceConfig_TriggerConfig::operator==(const TraceConfig_TriggerConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(trigger_mode_, other.trigger_mode_)
+   && ::protozero::internal::gen_helpers::EqualsField(use_clone_snapshot_if_available_, other.use_clone_snapshot_if_available_)
+   && ::protozero::internal::gen_helpers::EqualsField(triggers_, other.triggers_)
+   && ::protozero::internal::gen_helpers::EqualsField(trigger_timeout_ms_, other.trigger_timeout_ms_);
+}
+
+int TraceConfig_TriggerConfig::triggers_size() const { return static_cast<int>(triggers_.size()); }
+void TraceConfig_TriggerConfig::clear_triggers() { triggers_.clear(); }
+TraceConfig_TriggerConfig_Trigger* TraceConfig_TriggerConfig::add_triggers() { triggers_.emplace_back(); return &triggers_.back(); }
+bool TraceConfig_TriggerConfig::ParseFromArray(const void* raw, size_t size) {
+  triggers_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* trigger_mode */:
+        field.get(&trigger_mode_);
+        break;
+      case 5 /* use_clone_snapshot_if_available */:
+        field.get(&use_clone_snapshot_if_available_);
+        break;
+      case 2 /* triggers */:
+        triggers_.emplace_back();
+        triggers_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 3 /* trigger_timeout_ms */:
+        field.get(&trigger_timeout_ms_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceConfig_TriggerConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_TriggerConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_TriggerConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: trigger_mode
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, trigger_mode_, msg);
+  }
+
+  // Field 5: use_clone_snapshot_if_available
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, use_clone_snapshot_if_available_, msg);
+  }
+
+  // Field 2: triggers
+  for (auto& it : triggers_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  // Field 3: trigger_timeout_ms
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, trigger_timeout_ms_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TraceConfig_TriggerConfig_Trigger::TraceConfig_TriggerConfig_Trigger() = default;
+TraceConfig_TriggerConfig_Trigger::~TraceConfig_TriggerConfig_Trigger() = default;
+TraceConfig_TriggerConfig_Trigger::TraceConfig_TriggerConfig_Trigger(const TraceConfig_TriggerConfig_Trigger&) = default;
+TraceConfig_TriggerConfig_Trigger& TraceConfig_TriggerConfig_Trigger::operator=(const TraceConfig_TriggerConfig_Trigger&) = default;
+TraceConfig_TriggerConfig_Trigger::TraceConfig_TriggerConfig_Trigger(TraceConfig_TriggerConfig_Trigger&&) noexcept = default;
+TraceConfig_TriggerConfig_Trigger& TraceConfig_TriggerConfig_Trigger::operator=(TraceConfig_TriggerConfig_Trigger&&) = default;
+
+bool TraceConfig_TriggerConfig_Trigger::operator==(const TraceConfig_TriggerConfig_Trigger& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(producer_name_regex_, other.producer_name_regex_)
+   && ::protozero::internal::gen_helpers::EqualsField(stop_delay_ms_, other.stop_delay_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(max_per_24_h_, other.max_per_24_h_)
+   && ::protozero::internal::gen_helpers::EqualsField(skip_probability_, other.skip_probability_);
+}
+
+bool TraceConfig_TriggerConfig_Trigger::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 2 /* producer_name_regex */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &producer_name_regex_);
+        break;
+      case 3 /* stop_delay_ms */:
+        field.get(&stop_delay_ms_);
+        break;
+      case 4 /* max_per_24_h */:
+        field.get(&max_per_24_h_);
+        break;
+      case 5 /* skip_probability */:
+        field.get(&skip_probability_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceConfig_TriggerConfig_Trigger::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_TriggerConfig_Trigger::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_TriggerConfig_Trigger::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
+  }
+
+  // Field 2: producer_name_regex
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, producer_name_regex_, msg);
+  }
+
+  // Field 3: stop_delay_ms
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, stop_delay_ms_, msg);
+  }
+
+  // Field 4: max_per_24_h
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, max_per_24_h_, msg);
+  }
+
+  // Field 5: skip_probability
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeFixed(5, skip_probability_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TraceConfig_GuardrailOverrides::TraceConfig_GuardrailOverrides() = default;
+TraceConfig_GuardrailOverrides::~TraceConfig_GuardrailOverrides() = default;
+TraceConfig_GuardrailOverrides::TraceConfig_GuardrailOverrides(const TraceConfig_GuardrailOverrides&) = default;
+TraceConfig_GuardrailOverrides& TraceConfig_GuardrailOverrides::operator=(const TraceConfig_GuardrailOverrides&) = default;
+TraceConfig_GuardrailOverrides::TraceConfig_GuardrailOverrides(TraceConfig_GuardrailOverrides&&) noexcept = default;
+TraceConfig_GuardrailOverrides& TraceConfig_GuardrailOverrides::operator=(TraceConfig_GuardrailOverrides&&) = default;
+
+bool TraceConfig_GuardrailOverrides::operator==(const TraceConfig_GuardrailOverrides& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(max_upload_per_day_bytes_, other.max_upload_per_day_bytes_)
+   && ::protozero::internal::gen_helpers::EqualsField(max_tracing_buffer_size_kb_, other.max_tracing_buffer_size_kb_);
+}
+
+bool TraceConfig_GuardrailOverrides::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* max_upload_per_day_bytes */:
+        field.get(&max_upload_per_day_bytes_);
+        break;
+      case 2 /* max_tracing_buffer_size_kb */:
+        field.get(&max_tracing_buffer_size_kb_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceConfig_GuardrailOverrides::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_GuardrailOverrides::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_GuardrailOverrides::Serialize(::protozero::Message* msg) const {
+  // Field 1: max_upload_per_day_bytes
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, max_upload_per_day_bytes_, msg);
+  }
+
+  // Field 2: max_tracing_buffer_size_kb
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, max_tracing_buffer_size_kb_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TraceConfig_StatsdMetadata::TraceConfig_StatsdMetadata() = default;
+TraceConfig_StatsdMetadata::~TraceConfig_StatsdMetadata() = default;
+TraceConfig_StatsdMetadata::TraceConfig_StatsdMetadata(const TraceConfig_StatsdMetadata&) = default;
+TraceConfig_StatsdMetadata& TraceConfig_StatsdMetadata::operator=(const TraceConfig_StatsdMetadata&) = default;
+TraceConfig_StatsdMetadata::TraceConfig_StatsdMetadata(TraceConfig_StatsdMetadata&&) noexcept = default;
+TraceConfig_StatsdMetadata& TraceConfig_StatsdMetadata::operator=(TraceConfig_StatsdMetadata&&) = default;
+
+bool TraceConfig_StatsdMetadata::operator==(const TraceConfig_StatsdMetadata& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(triggering_alert_id_, other.triggering_alert_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(triggering_config_uid_, other.triggering_config_uid_)
+   && ::protozero::internal::gen_helpers::EqualsField(triggering_config_id_, other.triggering_config_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(triggering_subscription_id_, other.triggering_subscription_id_);
+}
+
+bool TraceConfig_StatsdMetadata::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* triggering_alert_id */:
+        field.get(&triggering_alert_id_);
+        break;
+      case 2 /* triggering_config_uid */:
+        field.get(&triggering_config_uid_);
+        break;
+      case 3 /* triggering_config_id */:
+        field.get(&triggering_config_id_);
+        break;
+      case 4 /* triggering_subscription_id */:
+        field.get(&triggering_subscription_id_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceConfig_StatsdMetadata::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_StatsdMetadata::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_StatsdMetadata::Serialize(::protozero::Message* msg) const {
+  // Field 1: triggering_alert_id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, triggering_alert_id_, msg);
+  }
+
+  // Field 2: triggering_config_uid
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, triggering_config_uid_, msg);
+  }
+
+  // Field 3: triggering_config_id
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, triggering_config_id_, msg);
+  }
+
+  // Field 4: triggering_subscription_id
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, triggering_subscription_id_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TraceConfig_ProducerConfig::TraceConfig_ProducerConfig() = default;
+TraceConfig_ProducerConfig::~TraceConfig_ProducerConfig() = default;
+TraceConfig_ProducerConfig::TraceConfig_ProducerConfig(const TraceConfig_ProducerConfig&) = default;
+TraceConfig_ProducerConfig& TraceConfig_ProducerConfig::operator=(const TraceConfig_ProducerConfig&) = default;
+TraceConfig_ProducerConfig::TraceConfig_ProducerConfig(TraceConfig_ProducerConfig&&) noexcept = default;
+TraceConfig_ProducerConfig& TraceConfig_ProducerConfig::operator=(TraceConfig_ProducerConfig&&) = default;
+
+bool TraceConfig_ProducerConfig::operator==(const TraceConfig_ProducerConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(producer_name_, other.producer_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(shm_size_kb_, other.shm_size_kb_)
+   && ::protozero::internal::gen_helpers::EqualsField(page_size_kb_, other.page_size_kb_);
+}
+
+bool TraceConfig_ProducerConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* producer_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &producer_name_);
+        break;
+      case 2 /* shm_size_kb */:
+        field.get(&shm_size_kb_);
+        break;
+      case 3 /* page_size_kb */:
+        field.get(&page_size_kb_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceConfig_ProducerConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_ProducerConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_ProducerConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: producer_name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, producer_name_, msg);
+  }
+
+  // Field 2: shm_size_kb
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, shm_size_kb_, msg);
+  }
+
+  // Field 3: page_size_kb
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, page_size_kb_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TraceConfig_BuiltinDataSource::TraceConfig_BuiltinDataSource() = default;
+TraceConfig_BuiltinDataSource::~TraceConfig_BuiltinDataSource() = default;
+TraceConfig_BuiltinDataSource::TraceConfig_BuiltinDataSource(const TraceConfig_BuiltinDataSource&) = default;
+TraceConfig_BuiltinDataSource& TraceConfig_BuiltinDataSource::operator=(const TraceConfig_BuiltinDataSource&) = default;
+TraceConfig_BuiltinDataSource::TraceConfig_BuiltinDataSource(TraceConfig_BuiltinDataSource&&) noexcept = default;
+TraceConfig_BuiltinDataSource& TraceConfig_BuiltinDataSource::operator=(TraceConfig_BuiltinDataSource&&) = default;
+
+bool TraceConfig_BuiltinDataSource::operator==(const TraceConfig_BuiltinDataSource& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(disable_clock_snapshotting_, other.disable_clock_snapshotting_)
+   && ::protozero::internal::gen_helpers::EqualsField(disable_trace_config_, other.disable_trace_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(disable_system_info_, other.disable_system_info_)
+   && ::protozero::internal::gen_helpers::EqualsField(disable_service_events_, other.disable_service_events_)
+   && ::protozero::internal::gen_helpers::EqualsField(primary_trace_clock_, other.primary_trace_clock_)
+   && ::protozero::internal::gen_helpers::EqualsField(snapshot_interval_ms_, other.snapshot_interval_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(prefer_suspend_clock_for_snapshot_, other.prefer_suspend_clock_for_snapshot_)
+   && ::protozero::internal::gen_helpers::EqualsField(disable_chunk_usage_histograms_, other.disable_chunk_usage_histograms_);
+}
+
+bool TraceConfig_BuiltinDataSource::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* disable_clock_snapshotting */:
+        field.get(&disable_clock_snapshotting_);
+        break;
+      case 2 /* disable_trace_config */:
+        field.get(&disable_trace_config_);
+        break;
+      case 3 /* disable_system_info */:
+        field.get(&disable_system_info_);
+        break;
+      case 4 /* disable_service_events */:
+        field.get(&disable_service_events_);
+        break;
+      case 5 /* primary_trace_clock */:
+        field.get(&primary_trace_clock_);
+        break;
+      case 6 /* snapshot_interval_ms */:
+        field.get(&snapshot_interval_ms_);
+        break;
+      case 7 /* prefer_suspend_clock_for_snapshot */:
+        field.get(&prefer_suspend_clock_for_snapshot_);
+        break;
+      case 8 /* disable_chunk_usage_histograms */:
+        field.get(&disable_chunk_usage_histograms_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceConfig_BuiltinDataSource::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_BuiltinDataSource::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_BuiltinDataSource::Serialize(::protozero::Message* msg) const {
+  // Field 1: disable_clock_snapshotting
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, disable_clock_snapshotting_, msg);
+  }
+
+  // Field 2: disable_trace_config
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, disable_trace_config_, msg);
+  }
+
+  // Field 3: disable_system_info
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, disable_system_info_, msg);
+  }
+
+  // Field 4: disable_service_events
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, disable_service_events_, msg);
+  }
+
+  // Field 5: primary_trace_clock
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, primary_trace_clock_, msg);
+  }
+
+  // Field 6: snapshot_interval_ms
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, snapshot_interval_ms_, msg);
+  }
+
+  // Field 7: prefer_suspend_clock_for_snapshot
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(7, prefer_suspend_clock_for_snapshot_, msg);
+  }
+
+  // Field 8: disable_chunk_usage_histograms
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(8, disable_chunk_usage_histograms_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TraceConfig_DataSource::TraceConfig_DataSource() = default;
+TraceConfig_DataSource::~TraceConfig_DataSource() = default;
+TraceConfig_DataSource::TraceConfig_DataSource(const TraceConfig_DataSource&) = default;
+TraceConfig_DataSource& TraceConfig_DataSource::operator=(const TraceConfig_DataSource&) = default;
+TraceConfig_DataSource::TraceConfig_DataSource(TraceConfig_DataSource&&) noexcept = default;
+TraceConfig_DataSource& TraceConfig_DataSource::operator=(TraceConfig_DataSource&&) = default;
+
+bool TraceConfig_DataSource::operator==(const TraceConfig_DataSource& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(config_, other.config_)
+   && ::protozero::internal::gen_helpers::EqualsField(producer_name_filter_, other.producer_name_filter_)
+   && ::protozero::internal::gen_helpers::EqualsField(producer_name_regex_filter_, other.producer_name_regex_filter_);
+}
+
+bool TraceConfig_DataSource::ParseFromArray(const void* raw, size_t size) {
+  producer_name_filter_.clear();
+  producer_name_regex_filter_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* config */:
+        (*config_).ParseFromArray(field.data(), field.size());
+        break;
+      case 2 /* producer_name_filter */:
+        producer_name_filter_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &producer_name_filter_.back());
+        break;
+      case 3 /* producer_name_regex_filter */:
+        producer_name_regex_filter_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &producer_name_regex_filter_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceConfig_DataSource::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_DataSource::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_DataSource::Serialize(::protozero::Message* msg) const {
+  // Field 1: config
+  if (_has_field_[1]) {
+    (*config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  // Field 2: producer_name_filter
+  for (auto& it : producer_name_filter_) {
+    ::protozero::internal::gen_helpers::SerializeString(2, it, msg);
+  }
+
+  // Field 3: producer_name_regex_filter
+  for (auto& it : producer_name_regex_filter_) {
+    ::protozero::internal::gen_helpers::SerializeString(3, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TraceConfig_BufferConfig::TraceConfig_BufferConfig() = default;
+TraceConfig_BufferConfig::~TraceConfig_BufferConfig() = default;
+TraceConfig_BufferConfig::TraceConfig_BufferConfig(const TraceConfig_BufferConfig&) = default;
+TraceConfig_BufferConfig& TraceConfig_BufferConfig::operator=(const TraceConfig_BufferConfig&) = default;
+TraceConfig_BufferConfig::TraceConfig_BufferConfig(TraceConfig_BufferConfig&&) noexcept = default;
+TraceConfig_BufferConfig& TraceConfig_BufferConfig::operator=(TraceConfig_BufferConfig&&) = default;
+
+bool TraceConfig_BufferConfig::operator==(const TraceConfig_BufferConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(size_kb_, other.size_kb_)
+   && ::protozero::internal::gen_helpers::EqualsField(fill_policy_, other.fill_policy_)
+   && ::protozero::internal::gen_helpers::EqualsField(transfer_on_clone_, other.transfer_on_clone_)
+   && ::protozero::internal::gen_helpers::EqualsField(clear_before_clone_, other.clear_before_clone_);
+}
+
+bool TraceConfig_BufferConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* size_kb */:
+        field.get(&size_kb_);
+        break;
+      case 4 /* fill_policy */:
+        field.get(&fill_policy_);
+        break;
+      case 5 /* transfer_on_clone */:
+        field.get(&transfer_on_clone_);
+        break;
+      case 6 /* clear_before_clone */:
+        field.get(&clear_before_clone_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceConfig_BufferConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_BufferConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_BufferConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: size_kb
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, size_kb_, msg);
+  }
+
+  // Field 4: fill_policy
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, fill_policy_, msg);
+  }
+
+  // Field 5: transfer_on_clone
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, transfer_on_clone_, msg);
+  }
+
+  // Field 6: clear_before_clone
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(6, clear_before_clone_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/common/android_energy_consumer_descriptor.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/common/android_log_constants.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/common/builtin_clock.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/common/commit_data_request.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/common/data_source_descriptor.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/common/descriptor.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/common/ftrace_descriptor.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/common/gpu_counter_descriptor.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/common/interceptor_descriptor.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/common/observable_events.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/common/perf_events.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/common/protolog_common.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/common/sys_stats_counters.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/common/trace_stats.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/common/tracing_service_capabilities.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/common/tracing_service_state.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/common/track_event_descriptor.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/android/graphics/point.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/android/graphics/rect.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/android/winscope_extensions.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/android/protolog.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/android/shell_transition.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/android/surfaceflinger_common.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/android/surfaceflinger_layers.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/android/surfaceflinger_transactions.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/android/android_game_intervention_list.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/android/android_input_event.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/android/android_log.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/android/android_system_property.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/android/camera_event.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/android/frame_timeline_event.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/android/gpu_mem_event.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/android/graphics_frame_event.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/android/initial_display_state.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/android/network_trace.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/android/packages_list.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/android/pixel_modem_events.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/chrome/chrome_benchmark_metadata.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/chrome/chrome_metadata.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/chrome/chrome_trace_event.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/chrome/chrome_trigger.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/chrome/v8.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/gpu/gpu_counter_event.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/gpu/gpu_log.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/gpu/gpu_render_stage_event.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/gpu/vulkan_api_event.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/gpu/vulkan_memory_event.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/profiling/deobfuscation.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/profiling/heap_graph.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/profiling/profile_common.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/profiling/profile_packet.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/profiling/smaps.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_active_processes.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_application_state_info.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_content_settings_event_info.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_frame_reporter.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_histogram_sample.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_keyed_service.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_latency_info.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_legacy_ipc.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_message_pump.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_mojo_event_info.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_process_descriptor.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_thread_descriptor.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_user_event.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_window_handle_event_info.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/counter_descriptor.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/debug_annotation.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/log_message.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/pixel_modem.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/process_descriptor.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/range_of_interest.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/screenshot.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/source_location.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/task_execution.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/thread_descriptor.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/track_descriptor.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/track_event.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/interned_data/interned_data.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_active_processes.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_active_processes.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ChromeActiveProcesses::ChromeActiveProcesses() = default;
+ChromeActiveProcesses::~ChromeActiveProcesses() = default;
+ChromeActiveProcesses::ChromeActiveProcesses(const ChromeActiveProcesses&) = default;
+ChromeActiveProcesses& ChromeActiveProcesses::operator=(const ChromeActiveProcesses&) = default;
+ChromeActiveProcesses::ChromeActiveProcesses(ChromeActiveProcesses&&) noexcept = default;
+ChromeActiveProcesses& ChromeActiveProcesses::operator=(ChromeActiveProcesses&&) = default;
+
+bool ChromeActiveProcesses::operator==(const ChromeActiveProcesses& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(pid_, other.pid_);
+}
+
+bool ChromeActiveProcesses::ParseFromArray(const void* raw, size_t size) {
+  pid_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* pid */:
+        pid_.emplace_back();
+        field.get(&pid_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeActiveProcesses::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeActiveProcesses::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeActiveProcesses::Serialize(::protozero::Message* msg) const {
+  // Field 1: pid
+  for (auto& it : pid_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_application_state_info.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_application_state_info.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ChromeApplicationStateInfo::ChromeApplicationStateInfo() = default;
+ChromeApplicationStateInfo::~ChromeApplicationStateInfo() = default;
+ChromeApplicationStateInfo::ChromeApplicationStateInfo(const ChromeApplicationStateInfo&) = default;
+ChromeApplicationStateInfo& ChromeApplicationStateInfo::operator=(const ChromeApplicationStateInfo&) = default;
+ChromeApplicationStateInfo::ChromeApplicationStateInfo(ChromeApplicationStateInfo&&) noexcept = default;
+ChromeApplicationStateInfo& ChromeApplicationStateInfo::operator=(ChromeApplicationStateInfo&&) = default;
+
+bool ChromeApplicationStateInfo::operator==(const ChromeApplicationStateInfo& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(application_state_, other.application_state_);
+}
+
+bool ChromeApplicationStateInfo::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* application_state */:
+        field.get(&application_state_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeApplicationStateInfo::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeApplicationStateInfo::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeApplicationStateInfo::Serialize(::protozero::Message* msg) const {
+  // Field 1: application_state
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, application_state_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/source_location.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+CompositorTimingHistory::CompositorTimingHistory() = default;
+CompositorTimingHistory::~CompositorTimingHistory() = default;
+CompositorTimingHistory::CompositorTimingHistory(const CompositorTimingHistory&) = default;
+CompositorTimingHistory& CompositorTimingHistory::operator=(const CompositorTimingHistory&) = default;
+CompositorTimingHistory::CompositorTimingHistory(CompositorTimingHistory&&) noexcept = default;
+CompositorTimingHistory& CompositorTimingHistory::operator=(CompositorTimingHistory&&) = default;
+
+bool CompositorTimingHistory::operator==(const CompositorTimingHistory& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(begin_main_frame_queue_critical_estimate_delta_us_, other.begin_main_frame_queue_critical_estimate_delta_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(begin_main_frame_queue_not_critical_estimate_delta_us_, other.begin_main_frame_queue_not_critical_estimate_delta_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(begin_main_frame_start_to_ready_to_commit_estimate_delta_us_, other.begin_main_frame_start_to_ready_to_commit_estimate_delta_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(commit_to_ready_to_activate_estimate_delta_us_, other.commit_to_ready_to_activate_estimate_delta_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(prepare_tiles_estimate_delta_us_, other.prepare_tiles_estimate_delta_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(activate_estimate_delta_us_, other.activate_estimate_delta_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(draw_estimate_delta_us_, other.draw_estimate_delta_us_);
+}
+
+bool CompositorTimingHistory::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* begin_main_frame_queue_critical_estimate_delta_us */:
+        field.get(&begin_main_frame_queue_critical_estimate_delta_us_);
+        break;
+      case 2 /* begin_main_frame_queue_not_critical_estimate_delta_us */:
+        field.get(&begin_main_frame_queue_not_critical_estimate_delta_us_);
+        break;
+      case 3 /* begin_main_frame_start_to_ready_to_commit_estimate_delta_us */:
+        field.get(&begin_main_frame_start_to_ready_to_commit_estimate_delta_us_);
+        break;
+      case 4 /* commit_to_ready_to_activate_estimate_delta_us */:
+        field.get(&commit_to_ready_to_activate_estimate_delta_us_);
+        break;
+      case 5 /* prepare_tiles_estimate_delta_us */:
+        field.get(&prepare_tiles_estimate_delta_us_);
+        break;
+      case 6 /* activate_estimate_delta_us */:
+        field.get(&activate_estimate_delta_us_);
+        break;
+      case 7 /* draw_estimate_delta_us */:
+        field.get(&draw_estimate_delta_us_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string CompositorTimingHistory::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> CompositorTimingHistory::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void CompositorTimingHistory::Serialize(::protozero::Message* msg) const {
+  // Field 1: begin_main_frame_queue_critical_estimate_delta_us
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, begin_main_frame_queue_critical_estimate_delta_us_, msg);
+  }
+
+  // Field 2: begin_main_frame_queue_not_critical_estimate_delta_us
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, begin_main_frame_queue_not_critical_estimate_delta_us_, msg);
+  }
+
+  // Field 3: begin_main_frame_start_to_ready_to_commit_estimate_delta_us
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, begin_main_frame_start_to_ready_to_commit_estimate_delta_us_, msg);
+  }
+
+  // Field 4: commit_to_ready_to_activate_estimate_delta_us
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, commit_to_ready_to_activate_estimate_delta_us_, msg);
+  }
+
+  // Field 5: prepare_tiles_estimate_delta_us
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, prepare_tiles_estimate_delta_us_, msg);
+  }
+
+  // Field 6: activate_estimate_delta_us
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, activate_estimate_delta_us_, msg);
+  }
+
+  // Field 7: draw_estimate_delta_us
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(7, draw_estimate_delta_us_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+BeginFrameSourceState::BeginFrameSourceState() = default;
+BeginFrameSourceState::~BeginFrameSourceState() = default;
+BeginFrameSourceState::BeginFrameSourceState(const BeginFrameSourceState&) = default;
+BeginFrameSourceState& BeginFrameSourceState::operator=(const BeginFrameSourceState&) = default;
+BeginFrameSourceState::BeginFrameSourceState(BeginFrameSourceState&&) noexcept = default;
+BeginFrameSourceState& BeginFrameSourceState::operator=(BeginFrameSourceState&&) = default;
+
+bool BeginFrameSourceState::operator==(const BeginFrameSourceState& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(source_id_, other.source_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(paused_, other.paused_)
+   && ::protozero::internal::gen_helpers::EqualsField(num_observers_, other.num_observers_)
+   && ::protozero::internal::gen_helpers::EqualsField(last_begin_frame_args_, other.last_begin_frame_args_);
+}
+
+bool BeginFrameSourceState::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* source_id */:
+        field.get(&source_id_);
+        break;
+      case 2 /* paused */:
+        field.get(&paused_);
+        break;
+      case 3 /* num_observers */:
+        field.get(&num_observers_);
+        break;
+      case 4 /* last_begin_frame_args */:
+        (*last_begin_frame_args_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string BeginFrameSourceState::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> BeginFrameSourceState::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void BeginFrameSourceState::Serialize(::protozero::Message* msg) const {
+  // Field 1: source_id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, source_id_, msg);
+  }
+
+  // Field 2: paused
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, paused_, msg);
+  }
+
+  // Field 3: num_observers
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, num_observers_, msg);
+  }
+
+  // Field 4: last_begin_frame_args
+  if (_has_field_[4]) {
+    (*last_begin_frame_args_).Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+BeginFrameArgs::BeginFrameArgs() = default;
+BeginFrameArgs::~BeginFrameArgs() = default;
+BeginFrameArgs::BeginFrameArgs(const BeginFrameArgs&) = default;
+BeginFrameArgs& BeginFrameArgs::operator=(const BeginFrameArgs&) = default;
+BeginFrameArgs::BeginFrameArgs(BeginFrameArgs&&) noexcept = default;
+BeginFrameArgs& BeginFrameArgs::operator=(BeginFrameArgs&&) = default;
+
+bool BeginFrameArgs::operator==(const BeginFrameArgs& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(type_, other.type_)
+   && ::protozero::internal::gen_helpers::EqualsField(source_id_, other.source_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(sequence_number_, other.sequence_number_)
+   && ::protozero::internal::gen_helpers::EqualsField(frame_time_us_, other.frame_time_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(deadline_us_, other.deadline_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(interval_delta_us_, other.interval_delta_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(on_critical_path_, other.on_critical_path_)
+   && ::protozero::internal::gen_helpers::EqualsField(animate_only_, other.animate_only_)
+   && ::protozero::internal::gen_helpers::EqualsField(source_location_iid_, other.source_location_iid_)
+   && ::protozero::internal::gen_helpers::EqualsField(source_location_, other.source_location_)
+   && ::protozero::internal::gen_helpers::EqualsField(frames_throttled_since_last_, other.frames_throttled_since_last_);
+}
+
+bool BeginFrameArgs::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* type */:
+        field.get(&type_);
+        break;
+      case 2 /* source_id */:
+        field.get(&source_id_);
+        break;
+      case 3 /* sequence_number */:
+        field.get(&sequence_number_);
+        break;
+      case 4 /* frame_time_us */:
+        field.get(&frame_time_us_);
+        break;
+      case 5 /* deadline_us */:
+        field.get(&deadline_us_);
+        break;
+      case 6 /* interval_delta_us */:
+        field.get(&interval_delta_us_);
+        break;
+      case 7 /* on_critical_path */:
+        field.get(&on_critical_path_);
+        break;
+      case 8 /* animate_only */:
+        field.get(&animate_only_);
+        break;
+      case 9 /* source_location_iid */:
+        field.get(&source_location_iid_);
+        break;
+      case 10 /* source_location */:
+        (*source_location_).ParseFromArray(field.data(), field.size());
+        break;
+      case 12 /* frames_throttled_since_last */:
+        field.get(&frames_throttled_since_last_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string BeginFrameArgs::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> BeginFrameArgs::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void BeginFrameArgs::Serialize(::protozero::Message* msg) const {
+  // Field 1: type
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, type_, msg);
+  }
+
+  // Field 2: source_id
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, source_id_, msg);
+  }
+
+  // Field 3: sequence_number
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, sequence_number_, msg);
+  }
+
+  // Field 4: frame_time_us
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, frame_time_us_, msg);
+  }
+
+  // Field 5: deadline_us
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, deadline_us_, msg);
+  }
+
+  // Field 6: interval_delta_us
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, interval_delta_us_, msg);
+  }
+
+  // Field 7: on_critical_path
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(7, on_critical_path_, msg);
+  }
+
+  // Field 8: animate_only
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(8, animate_only_, msg);
+  }
+
+  // Field 9: source_location_iid
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(9, source_location_iid_, msg);
+  }
+
+  // Field 10: source_location
+  if (_has_field_[10]) {
+    (*source_location_).Serialize(msg->BeginNestedMessage<::protozero::Message>(10));
+  }
+
+  // Field 12: frames_throttled_since_last
+  if (_has_field_[12]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(12, frames_throttled_since_last_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+BeginFrameObserverState::BeginFrameObserverState() = default;
+BeginFrameObserverState::~BeginFrameObserverState() = default;
+BeginFrameObserverState::BeginFrameObserverState(const BeginFrameObserverState&) = default;
+BeginFrameObserverState& BeginFrameObserverState::operator=(const BeginFrameObserverState&) = default;
+BeginFrameObserverState::BeginFrameObserverState(BeginFrameObserverState&&) noexcept = default;
+BeginFrameObserverState& BeginFrameObserverState::operator=(BeginFrameObserverState&&) = default;
+
+bool BeginFrameObserverState::operator==(const BeginFrameObserverState& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(dropped_begin_frame_args_, other.dropped_begin_frame_args_)
+   && ::protozero::internal::gen_helpers::EqualsField(last_begin_frame_args_, other.last_begin_frame_args_);
+}
+
+bool BeginFrameObserverState::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* dropped_begin_frame_args */:
+        field.get(&dropped_begin_frame_args_);
+        break;
+      case 2 /* last_begin_frame_args */:
+        (*last_begin_frame_args_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string BeginFrameObserverState::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> BeginFrameObserverState::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void BeginFrameObserverState::Serialize(::protozero::Message* msg) const {
+  // Field 1: dropped_begin_frame_args
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, dropped_begin_frame_args_, msg);
+  }
+
+  // Field 2: last_begin_frame_args
+  if (_has_field_[2]) {
+    (*last_begin_frame_args_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+BeginImplFrameArgs::BeginImplFrameArgs() = default;
+BeginImplFrameArgs::~BeginImplFrameArgs() = default;
+BeginImplFrameArgs::BeginImplFrameArgs(const BeginImplFrameArgs&) = default;
+BeginImplFrameArgs& BeginImplFrameArgs::operator=(const BeginImplFrameArgs&) = default;
+BeginImplFrameArgs::BeginImplFrameArgs(BeginImplFrameArgs&&) noexcept = default;
+BeginImplFrameArgs& BeginImplFrameArgs::operator=(BeginImplFrameArgs&&) = default;
+
+bool BeginImplFrameArgs::operator==(const BeginImplFrameArgs& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(updated_at_us_, other.updated_at_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(finished_at_us_, other.finished_at_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(state_, other.state_)
+   && ::protozero::internal::gen_helpers::EqualsField(current_args_, other.current_args_)
+   && ::protozero::internal::gen_helpers::EqualsField(last_args_, other.last_args_)
+   && ::protozero::internal::gen_helpers::EqualsField(timestamps_in_us_, other.timestamps_in_us_);
+}
+
+bool BeginImplFrameArgs::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* updated_at_us */:
+        field.get(&updated_at_us_);
+        break;
+      case 2 /* finished_at_us */:
+        field.get(&finished_at_us_);
+        break;
+      case 3 /* state */:
+        field.get(&state_);
+        break;
+      case 4 /* current_args */:
+        (*current_args_).ParseFromArray(field.data(), field.size());
+        break;
+      case 5 /* last_args */:
+        (*last_args_).ParseFromArray(field.data(), field.size());
+        break;
+      case 6 /* timestamps_in_us */:
+        (*timestamps_in_us_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string BeginImplFrameArgs::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> BeginImplFrameArgs::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void BeginImplFrameArgs::Serialize(::protozero::Message* msg) const {
+  // Field 1: updated_at_us
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, updated_at_us_, msg);
+  }
+
+  // Field 2: finished_at_us
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, finished_at_us_, msg);
+  }
+
+  // Field 3: state
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, state_, msg);
+  }
+
+  // Field 4: current_args
+  if (_has_field_[4]) {
+    (*current_args_).Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
+  }
+
+  // Field 5: last_args
+  if (_has_field_[5]) {
+    (*last_args_).Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
+  }
+
+  // Field 6: timestamps_in_us
+  if (_has_field_[6]) {
+    (*timestamps_in_us_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+BeginImplFrameArgs_TimestampsInUs::BeginImplFrameArgs_TimestampsInUs() = default;
+BeginImplFrameArgs_TimestampsInUs::~BeginImplFrameArgs_TimestampsInUs() = default;
+BeginImplFrameArgs_TimestampsInUs::BeginImplFrameArgs_TimestampsInUs(const BeginImplFrameArgs_TimestampsInUs&) = default;
+BeginImplFrameArgs_TimestampsInUs& BeginImplFrameArgs_TimestampsInUs::operator=(const BeginImplFrameArgs_TimestampsInUs&) = default;
+BeginImplFrameArgs_TimestampsInUs::BeginImplFrameArgs_TimestampsInUs(BeginImplFrameArgs_TimestampsInUs&&) noexcept = default;
+BeginImplFrameArgs_TimestampsInUs& BeginImplFrameArgs_TimestampsInUs::operator=(BeginImplFrameArgs_TimestampsInUs&&) = default;
+
+bool BeginImplFrameArgs_TimestampsInUs::operator==(const BeginImplFrameArgs_TimestampsInUs& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(interval_delta_, other.interval_delta_)
+   && ::protozero::internal::gen_helpers::EqualsField(now_to_deadline_delta_, other.now_to_deadline_delta_)
+   && ::protozero::internal::gen_helpers::EqualsField(frame_time_to_now_delta_, other.frame_time_to_now_delta_)
+   && ::protozero::internal::gen_helpers::EqualsField(frame_time_to_deadline_delta_, other.frame_time_to_deadline_delta_)
+   && ::protozero::internal::gen_helpers::EqualsField(now_, other.now_)
+   && ::protozero::internal::gen_helpers::EqualsField(frame_time_, other.frame_time_)
+   && ::protozero::internal::gen_helpers::EqualsField(deadline_, other.deadline_);
+}
+
+bool BeginImplFrameArgs_TimestampsInUs::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* interval_delta */:
+        field.get(&interval_delta_);
+        break;
+      case 2 /* now_to_deadline_delta */:
+        field.get(&now_to_deadline_delta_);
+        break;
+      case 3 /* frame_time_to_now_delta */:
+        field.get(&frame_time_to_now_delta_);
+        break;
+      case 4 /* frame_time_to_deadline_delta */:
+        field.get(&frame_time_to_deadline_delta_);
+        break;
+      case 5 /* now */:
+        field.get(&now_);
+        break;
+      case 6 /* frame_time */:
+        field.get(&frame_time_);
+        break;
+      case 7 /* deadline */:
+        field.get(&deadline_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string BeginImplFrameArgs_TimestampsInUs::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> BeginImplFrameArgs_TimestampsInUs::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void BeginImplFrameArgs_TimestampsInUs::Serialize(::protozero::Message* msg) const {
+  // Field 1: interval_delta
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, interval_delta_, msg);
+  }
+
+  // Field 2: now_to_deadline_delta
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, now_to_deadline_delta_, msg);
+  }
+
+  // Field 3: frame_time_to_now_delta
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, frame_time_to_now_delta_, msg);
+  }
+
+  // Field 4: frame_time_to_deadline_delta
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, frame_time_to_deadline_delta_, msg);
+  }
+
+  // Field 5: now
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, now_, msg);
+  }
+
+  // Field 6: frame_time
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, frame_time_, msg);
+  }
+
+  // Field 7: deadline
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(7, deadline_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+ChromeCompositorStateMachine::ChromeCompositorStateMachine() = default;
+ChromeCompositorStateMachine::~ChromeCompositorStateMachine() = default;
+ChromeCompositorStateMachine::ChromeCompositorStateMachine(const ChromeCompositorStateMachine&) = default;
+ChromeCompositorStateMachine& ChromeCompositorStateMachine::operator=(const ChromeCompositorStateMachine&) = default;
+ChromeCompositorStateMachine::ChromeCompositorStateMachine(ChromeCompositorStateMachine&&) noexcept = default;
+ChromeCompositorStateMachine& ChromeCompositorStateMachine::operator=(ChromeCompositorStateMachine&&) = default;
+
+bool ChromeCompositorStateMachine::operator==(const ChromeCompositorStateMachine& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(major_state_, other.major_state_)
+   && ::protozero::internal::gen_helpers::EqualsField(minor_state_, other.minor_state_);
+}
+
+bool ChromeCompositorStateMachine::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* major_state */:
+        (*major_state_).ParseFromArray(field.data(), field.size());
+        break;
+      case 2 /* minor_state */:
+        (*minor_state_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeCompositorStateMachine::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeCompositorStateMachine::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeCompositorStateMachine::Serialize(::protozero::Message* msg) const {
+  // Field 1: major_state
+  if (_has_field_[1]) {
+    (*major_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  // Field 2: minor_state
+  if (_has_field_[2]) {
+    (*minor_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+ChromeCompositorStateMachine_MinorState::ChromeCompositorStateMachine_MinorState() = default;
+ChromeCompositorStateMachine_MinorState::~ChromeCompositorStateMachine_MinorState() = default;
+ChromeCompositorStateMachine_MinorState::ChromeCompositorStateMachine_MinorState(const ChromeCompositorStateMachine_MinorState&) = default;
+ChromeCompositorStateMachine_MinorState& ChromeCompositorStateMachine_MinorState::operator=(const ChromeCompositorStateMachine_MinorState&) = default;
+ChromeCompositorStateMachine_MinorState::ChromeCompositorStateMachine_MinorState(ChromeCompositorStateMachine_MinorState&&) noexcept = default;
+ChromeCompositorStateMachine_MinorState& ChromeCompositorStateMachine_MinorState::operator=(ChromeCompositorStateMachine_MinorState&&) = default;
+
+bool ChromeCompositorStateMachine_MinorState::operator==(const ChromeCompositorStateMachine_MinorState& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(commit_count_, other.commit_count_)
+   && ::protozero::internal::gen_helpers::EqualsField(current_frame_number_, other.current_frame_number_)
+   && ::protozero::internal::gen_helpers::EqualsField(last_frame_number_submit_performed_, other.last_frame_number_submit_performed_)
+   && ::protozero::internal::gen_helpers::EqualsField(last_frame_number_draw_performed_, other.last_frame_number_draw_performed_)
+   && ::protozero::internal::gen_helpers::EqualsField(last_frame_number_begin_main_frame_sent_, other.last_frame_number_begin_main_frame_sent_)
+   && ::protozero::internal::gen_helpers::EqualsField(did_draw_, other.did_draw_)
+   && ::protozero::internal::gen_helpers::EqualsField(did_send_begin_main_frame_for_current_frame_, other.did_send_begin_main_frame_for_current_frame_)
+   && ::protozero::internal::gen_helpers::EqualsField(did_notify_begin_main_frame_not_expected_until_, other.did_notify_begin_main_frame_not_expected_until_)
+   && ::protozero::internal::gen_helpers::EqualsField(did_notify_begin_main_frame_not_expected_soon_, other.did_notify_begin_main_frame_not_expected_soon_)
+   && ::protozero::internal::gen_helpers::EqualsField(wants_begin_main_frame_not_expected_, other.wants_begin_main_frame_not_expected_)
+   && ::protozero::internal::gen_helpers::EqualsField(did_commit_during_frame_, other.did_commit_during_frame_)
+   && ::protozero::internal::gen_helpers::EqualsField(did_invalidate_layer_tree_frame_sink_, other.did_invalidate_layer_tree_frame_sink_)
+   && ::protozero::internal::gen_helpers::EqualsField(did_perform_impl_side_invalidaion_, other.did_perform_impl_side_invalidaion_)
+   && ::protozero::internal::gen_helpers::EqualsField(did_prepare_tiles_, other.did_prepare_tiles_)
+   && ::protozero::internal::gen_helpers::EqualsField(consecutive_checkerboard_animations_, other.consecutive_checkerboard_animations_)
+   && ::protozero::internal::gen_helpers::EqualsField(pending_submit_frames_, other.pending_submit_frames_)
+   && ::protozero::internal::gen_helpers::EqualsField(submit_frames_with_current_layer_tree_frame_sink_, other.submit_frames_with_current_layer_tree_frame_sink_)
+   && ::protozero::internal::gen_helpers::EqualsField(needs_redraw_, other.needs_redraw_)
+   && ::protozero::internal::gen_helpers::EqualsField(needs_prepare_tiles_, other.needs_prepare_tiles_)
+   && ::protozero::internal::gen_helpers::EqualsField(needs_begin_main_frame_, other.needs_begin_main_frame_)
+   && ::protozero::internal::gen_helpers::EqualsField(needs_one_begin_impl_frame_, other.needs_one_begin_impl_frame_)
+   && ::protozero::internal::gen_helpers::EqualsField(visible_, other.visible_)
+   && ::protozero::internal::gen_helpers::EqualsField(begin_frame_source_paused_, other.begin_frame_source_paused_)
+   && ::protozero::internal::gen_helpers::EqualsField(can_draw_, other.can_draw_)
+   && ::protozero::internal::gen_helpers::EqualsField(resourceless_draw_, other.resourceless_draw_)
+   && ::protozero::internal::gen_helpers::EqualsField(has_pending_tree_, other.has_pending_tree_)
+   && ::protozero::internal::gen_helpers::EqualsField(pending_tree_is_ready_for_activation_, other.pending_tree_is_ready_for_activation_)
+   && ::protozero::internal::gen_helpers::EqualsField(active_tree_needs_first_draw_, other.active_tree_needs_first_draw_)
+   && ::protozero::internal::gen_helpers::EqualsField(active_tree_is_ready_to_draw_, other.active_tree_is_ready_to_draw_)
+   && ::protozero::internal::gen_helpers::EqualsField(did_create_and_initialize_first_layer_tree_frame_sink_, other.did_create_and_initialize_first_layer_tree_frame_sink_)
+   && ::protozero::internal::gen_helpers::EqualsField(tree_priority_, other.tree_priority_)
+   && ::protozero::internal::gen_helpers::EqualsField(scroll_handler_state_, other.scroll_handler_state_)
+   && ::protozero::internal::gen_helpers::EqualsField(critical_begin_main_frame_to_activate_is_fast_, other.critical_begin_main_frame_to_activate_is_fast_)
+   && ::protozero::internal::gen_helpers::EqualsField(main_thread_missed_last_deadline_, other.main_thread_missed_last_deadline_)
+   && ::protozero::internal::gen_helpers::EqualsField(video_needs_begin_frames_, other.video_needs_begin_frames_)
+   && ::protozero::internal::gen_helpers::EqualsField(defer_begin_main_frame_, other.defer_begin_main_frame_)
+   && ::protozero::internal::gen_helpers::EqualsField(last_commit_had_no_updates_, other.last_commit_had_no_updates_)
+   && ::protozero::internal::gen_helpers::EqualsField(did_draw_in_last_frame_, other.did_draw_in_last_frame_)
+   && ::protozero::internal::gen_helpers::EqualsField(did_submit_in_last_frame_, other.did_submit_in_last_frame_)
+   && ::protozero::internal::gen_helpers::EqualsField(needs_impl_side_invalidation_, other.needs_impl_side_invalidation_)
+   && ::protozero::internal::gen_helpers::EqualsField(current_pending_tree_is_impl_side_, other.current_pending_tree_is_impl_side_)
+   && ::protozero::internal::gen_helpers::EqualsField(previous_pending_tree_was_impl_side_, other.previous_pending_tree_was_impl_side_)
+   && ::protozero::internal::gen_helpers::EqualsField(processing_animation_worklets_for_active_tree_, other.processing_animation_worklets_for_active_tree_)
+   && ::protozero::internal::gen_helpers::EqualsField(processing_animation_worklets_for_pending_tree_, other.processing_animation_worklets_for_pending_tree_)
+   && ::protozero::internal::gen_helpers::EqualsField(processing_paint_worklets_for_pending_tree_, other.processing_paint_worklets_for_pending_tree_);
+}
+
+bool ChromeCompositorStateMachine_MinorState::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* commit_count */:
+        field.get(&commit_count_);
+        break;
+      case 2 /* current_frame_number */:
+        field.get(&current_frame_number_);
+        break;
+      case 3 /* last_frame_number_submit_performed */:
+        field.get(&last_frame_number_submit_performed_);
+        break;
+      case 4 /* last_frame_number_draw_performed */:
+        field.get(&last_frame_number_draw_performed_);
+        break;
+      case 5 /* last_frame_number_begin_main_frame_sent */:
+        field.get(&last_frame_number_begin_main_frame_sent_);
+        break;
+      case 6 /* did_draw */:
+        field.get(&did_draw_);
+        break;
+      case 7 /* did_send_begin_main_frame_for_current_frame */:
+        field.get(&did_send_begin_main_frame_for_current_frame_);
+        break;
+      case 8 /* did_notify_begin_main_frame_not_expected_until */:
+        field.get(&did_notify_begin_main_frame_not_expected_until_);
+        break;
+      case 9 /* did_notify_begin_main_frame_not_expected_soon */:
+        field.get(&did_notify_begin_main_frame_not_expected_soon_);
+        break;
+      case 10 /* wants_begin_main_frame_not_expected */:
+        field.get(&wants_begin_main_frame_not_expected_);
+        break;
+      case 11 /* did_commit_during_frame */:
+        field.get(&did_commit_during_frame_);
+        break;
+      case 12 /* did_invalidate_layer_tree_frame_sink */:
+        field.get(&did_invalidate_layer_tree_frame_sink_);
+        break;
+      case 13 /* did_perform_impl_side_invalidaion */:
+        field.get(&did_perform_impl_side_invalidaion_);
+        break;
+      case 14 /* did_prepare_tiles */:
+        field.get(&did_prepare_tiles_);
+        break;
+      case 15 /* consecutive_checkerboard_animations */:
+        field.get(&consecutive_checkerboard_animations_);
+        break;
+      case 16 /* pending_submit_frames */:
+        field.get(&pending_submit_frames_);
+        break;
+      case 17 /* submit_frames_with_current_layer_tree_frame_sink */:
+        field.get(&submit_frames_with_current_layer_tree_frame_sink_);
+        break;
+      case 18 /* needs_redraw */:
+        field.get(&needs_redraw_);
+        break;
+      case 19 /* needs_prepare_tiles */:
+        field.get(&needs_prepare_tiles_);
+        break;
+      case 20 /* needs_begin_main_frame */:
+        field.get(&needs_begin_main_frame_);
+        break;
+      case 21 /* needs_one_begin_impl_frame */:
+        field.get(&needs_one_begin_impl_frame_);
+        break;
+      case 22 /* visible */:
+        field.get(&visible_);
+        break;
+      case 23 /* begin_frame_source_paused */:
+        field.get(&begin_frame_source_paused_);
+        break;
+      case 24 /* can_draw */:
+        field.get(&can_draw_);
+        break;
+      case 25 /* resourceless_draw */:
+        field.get(&resourceless_draw_);
+        break;
+      case 26 /* has_pending_tree */:
+        field.get(&has_pending_tree_);
+        break;
+      case 27 /* pending_tree_is_ready_for_activation */:
+        field.get(&pending_tree_is_ready_for_activation_);
+        break;
+      case 28 /* active_tree_needs_first_draw */:
+        field.get(&active_tree_needs_first_draw_);
+        break;
+      case 29 /* active_tree_is_ready_to_draw */:
+        field.get(&active_tree_is_ready_to_draw_);
+        break;
+      case 30 /* did_create_and_initialize_first_layer_tree_frame_sink */:
+        field.get(&did_create_and_initialize_first_layer_tree_frame_sink_);
+        break;
+      case 31 /* tree_priority */:
+        field.get(&tree_priority_);
+        break;
+      case 32 /* scroll_handler_state */:
+        field.get(&scroll_handler_state_);
+        break;
+      case 33 /* critical_begin_main_frame_to_activate_is_fast */:
+        field.get(&critical_begin_main_frame_to_activate_is_fast_);
+        break;
+      case 34 /* main_thread_missed_last_deadline */:
+        field.get(&main_thread_missed_last_deadline_);
+        break;
+      case 36 /* video_needs_begin_frames */:
+        field.get(&video_needs_begin_frames_);
+        break;
+      case 37 /* defer_begin_main_frame */:
+        field.get(&defer_begin_main_frame_);
+        break;
+      case 38 /* last_commit_had_no_updates */:
+        field.get(&last_commit_had_no_updates_);
+        break;
+      case 39 /* did_draw_in_last_frame */:
+        field.get(&did_draw_in_last_frame_);
+        break;
+      case 40 /* did_submit_in_last_frame */:
+        field.get(&did_submit_in_last_frame_);
+        break;
+      case 41 /* needs_impl_side_invalidation */:
+        field.get(&needs_impl_side_invalidation_);
+        break;
+      case 42 /* current_pending_tree_is_impl_side */:
+        field.get(&current_pending_tree_is_impl_side_);
+        break;
+      case 43 /* previous_pending_tree_was_impl_side */:
+        field.get(&previous_pending_tree_was_impl_side_);
+        break;
+      case 44 /* processing_animation_worklets_for_active_tree */:
+        field.get(&processing_animation_worklets_for_active_tree_);
+        break;
+      case 45 /* processing_animation_worklets_for_pending_tree */:
+        field.get(&processing_animation_worklets_for_pending_tree_);
+        break;
+      case 46 /* processing_paint_worklets_for_pending_tree */:
+        field.get(&processing_paint_worklets_for_pending_tree_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeCompositorStateMachine_MinorState::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeCompositorStateMachine_MinorState::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeCompositorStateMachine_MinorState::Serialize(::protozero::Message* msg) const {
+  // Field 1: commit_count
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, commit_count_, msg);
+  }
+
+  // Field 2: current_frame_number
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, current_frame_number_, msg);
+  }
+
+  // Field 3: last_frame_number_submit_performed
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, last_frame_number_submit_performed_, msg);
+  }
+
+  // Field 4: last_frame_number_draw_performed
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, last_frame_number_draw_performed_, msg);
+  }
+
+  // Field 5: last_frame_number_begin_main_frame_sent
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, last_frame_number_begin_main_frame_sent_, msg);
+  }
+
+  // Field 6: did_draw
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(6, did_draw_, msg);
+  }
+
+  // Field 7: did_send_begin_main_frame_for_current_frame
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(7, did_send_begin_main_frame_for_current_frame_, msg);
+  }
+
+  // Field 8: did_notify_begin_main_frame_not_expected_until
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(8, did_notify_begin_main_frame_not_expected_until_, msg);
+  }
+
+  // Field 9: did_notify_begin_main_frame_not_expected_soon
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(9, did_notify_begin_main_frame_not_expected_soon_, msg);
+  }
+
+  // Field 10: wants_begin_main_frame_not_expected
+  if (_has_field_[10]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(10, wants_begin_main_frame_not_expected_, msg);
+  }
+
+  // Field 11: did_commit_during_frame
+  if (_has_field_[11]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(11, did_commit_during_frame_, msg);
+  }
+
+  // Field 12: did_invalidate_layer_tree_frame_sink
+  if (_has_field_[12]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(12, did_invalidate_layer_tree_frame_sink_, msg);
+  }
+
+  // Field 13: did_perform_impl_side_invalidaion
+  if (_has_field_[13]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(13, did_perform_impl_side_invalidaion_, msg);
+  }
+
+  // Field 14: did_prepare_tiles
+  if (_has_field_[14]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(14, did_prepare_tiles_, msg);
+  }
+
+  // Field 15: consecutive_checkerboard_animations
+  if (_has_field_[15]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(15, consecutive_checkerboard_animations_, msg);
+  }
+
+  // Field 16: pending_submit_frames
+  if (_has_field_[16]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(16, pending_submit_frames_, msg);
+  }
+
+  // Field 17: submit_frames_with_current_layer_tree_frame_sink
+  if (_has_field_[17]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(17, submit_frames_with_current_layer_tree_frame_sink_, msg);
+  }
+
+  // Field 18: needs_redraw
+  if (_has_field_[18]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(18, needs_redraw_, msg);
+  }
+
+  // Field 19: needs_prepare_tiles
+  if (_has_field_[19]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(19, needs_prepare_tiles_, msg);
+  }
+
+  // Field 20: needs_begin_main_frame
+  if (_has_field_[20]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(20, needs_begin_main_frame_, msg);
+  }
+
+  // Field 21: needs_one_begin_impl_frame
+  if (_has_field_[21]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(21, needs_one_begin_impl_frame_, msg);
+  }
+
+  // Field 22: visible
+  if (_has_field_[22]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(22, visible_, msg);
+  }
+
+  // Field 23: begin_frame_source_paused
+  if (_has_field_[23]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(23, begin_frame_source_paused_, msg);
+  }
+
+  // Field 24: can_draw
+  if (_has_field_[24]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(24, can_draw_, msg);
+  }
+
+  // Field 25: resourceless_draw
+  if (_has_field_[25]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(25, resourceless_draw_, msg);
+  }
+
+  // Field 26: has_pending_tree
+  if (_has_field_[26]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(26, has_pending_tree_, msg);
+  }
+
+  // Field 27: pending_tree_is_ready_for_activation
+  if (_has_field_[27]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(27, pending_tree_is_ready_for_activation_, msg);
+  }
+
+  // Field 28: active_tree_needs_first_draw
+  if (_has_field_[28]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(28, active_tree_needs_first_draw_, msg);
+  }
+
+  // Field 29: active_tree_is_ready_to_draw
+  if (_has_field_[29]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(29, active_tree_is_ready_to_draw_, msg);
+  }
+
+  // Field 30: did_create_and_initialize_first_layer_tree_frame_sink
+  if (_has_field_[30]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(30, did_create_and_initialize_first_layer_tree_frame_sink_, msg);
+  }
+
+  // Field 31: tree_priority
+  if (_has_field_[31]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(31, tree_priority_, msg);
+  }
+
+  // Field 32: scroll_handler_state
+  if (_has_field_[32]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(32, scroll_handler_state_, msg);
+  }
+
+  // Field 33: critical_begin_main_frame_to_activate_is_fast
+  if (_has_field_[33]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(33, critical_begin_main_frame_to_activate_is_fast_, msg);
+  }
+
+  // Field 34: main_thread_missed_last_deadline
+  if (_has_field_[34]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(34, main_thread_missed_last_deadline_, msg);
+  }
+
+  // Field 36: video_needs_begin_frames
+  if (_has_field_[36]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(36, video_needs_begin_frames_, msg);
+  }
+
+  // Field 37: defer_begin_main_frame
+  if (_has_field_[37]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(37, defer_begin_main_frame_, msg);
+  }
+
+  // Field 38: last_commit_had_no_updates
+  if (_has_field_[38]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(38, last_commit_had_no_updates_, msg);
+  }
+
+  // Field 39: did_draw_in_last_frame
+  if (_has_field_[39]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(39, did_draw_in_last_frame_, msg);
+  }
+
+  // Field 40: did_submit_in_last_frame
+  if (_has_field_[40]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(40, did_submit_in_last_frame_, msg);
+  }
+
+  // Field 41: needs_impl_side_invalidation
+  if (_has_field_[41]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(41, needs_impl_side_invalidation_, msg);
+  }
+
+  // Field 42: current_pending_tree_is_impl_side
+  if (_has_field_[42]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(42, current_pending_tree_is_impl_side_, msg);
+  }
+
+  // Field 43: previous_pending_tree_was_impl_side
+  if (_has_field_[43]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(43, previous_pending_tree_was_impl_side_, msg);
+  }
+
+  // Field 44: processing_animation_worklets_for_active_tree
+  if (_has_field_[44]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(44, processing_animation_worklets_for_active_tree_, msg);
+  }
+
+  // Field 45: processing_animation_worklets_for_pending_tree
+  if (_has_field_[45]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(45, processing_animation_worklets_for_pending_tree_, msg);
+  }
+
+  // Field 46: processing_paint_worklets_for_pending_tree
+  if (_has_field_[46]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(46, processing_paint_worklets_for_pending_tree_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+ChromeCompositorStateMachine_MajorState::ChromeCompositorStateMachine_MajorState() = default;
+ChromeCompositorStateMachine_MajorState::~ChromeCompositorStateMachine_MajorState() = default;
+ChromeCompositorStateMachine_MajorState::ChromeCompositorStateMachine_MajorState(const ChromeCompositorStateMachine_MajorState&) = default;
+ChromeCompositorStateMachine_MajorState& ChromeCompositorStateMachine_MajorState::operator=(const ChromeCompositorStateMachine_MajorState&) = default;
+ChromeCompositorStateMachine_MajorState::ChromeCompositorStateMachine_MajorState(ChromeCompositorStateMachine_MajorState&&) noexcept = default;
+ChromeCompositorStateMachine_MajorState& ChromeCompositorStateMachine_MajorState::operator=(ChromeCompositorStateMachine_MajorState&&) = default;
+
+bool ChromeCompositorStateMachine_MajorState::operator==(const ChromeCompositorStateMachine_MajorState& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(next_action_, other.next_action_)
+   && ::protozero::internal::gen_helpers::EqualsField(begin_impl_frame_state_, other.begin_impl_frame_state_)
+   && ::protozero::internal::gen_helpers::EqualsField(begin_main_frame_state_, other.begin_main_frame_state_)
+   && ::protozero::internal::gen_helpers::EqualsField(layer_tree_frame_sink_state_, other.layer_tree_frame_sink_state_)
+   && ::protozero::internal::gen_helpers::EqualsField(forced_redraw_state_, other.forced_redraw_state_);
+}
+
+bool ChromeCompositorStateMachine_MajorState::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* next_action */:
+        field.get(&next_action_);
+        break;
+      case 2 /* begin_impl_frame_state */:
+        field.get(&begin_impl_frame_state_);
+        break;
+      case 3 /* begin_main_frame_state */:
+        field.get(&begin_main_frame_state_);
+        break;
+      case 4 /* layer_tree_frame_sink_state */:
+        field.get(&layer_tree_frame_sink_state_);
+        break;
+      case 5 /* forced_redraw_state */:
+        field.get(&forced_redraw_state_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeCompositorStateMachine_MajorState::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeCompositorStateMachine_MajorState::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeCompositorStateMachine_MajorState::Serialize(::protozero::Message* msg) const {
+  // Field 1: next_action
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, next_action_, msg);
+  }
+
+  // Field 2: begin_impl_frame_state
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, begin_impl_frame_state_, msg);
+  }
+
+  // Field 3: begin_main_frame_state
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, begin_main_frame_state_, msg);
+  }
+
+  // Field 4: layer_tree_frame_sink_state
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, layer_tree_frame_sink_state_, msg);
+  }
+
+  // Field 5: forced_redraw_state
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, forced_redraw_state_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+ChromeCompositorSchedulerState::ChromeCompositorSchedulerState() = default;
+ChromeCompositorSchedulerState::~ChromeCompositorSchedulerState() = default;
+ChromeCompositorSchedulerState::ChromeCompositorSchedulerState(const ChromeCompositorSchedulerState&) = default;
+ChromeCompositorSchedulerState& ChromeCompositorSchedulerState::operator=(const ChromeCompositorSchedulerState&) = default;
+ChromeCompositorSchedulerState::ChromeCompositorSchedulerState(ChromeCompositorSchedulerState&&) noexcept = default;
+ChromeCompositorSchedulerState& ChromeCompositorSchedulerState::operator=(ChromeCompositorSchedulerState&&) = default;
+
+bool ChromeCompositorSchedulerState::operator==(const ChromeCompositorSchedulerState& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(state_machine_, other.state_machine_)
+   && ::protozero::internal::gen_helpers::EqualsField(observing_begin_frame_source_, other.observing_begin_frame_source_)
+   && ::protozero::internal::gen_helpers::EqualsField(begin_impl_frame_deadline_task_, other.begin_impl_frame_deadline_task_)
+   && ::protozero::internal::gen_helpers::EqualsField(pending_begin_frame_task_, other.pending_begin_frame_task_)
+   && ::protozero::internal::gen_helpers::EqualsField(skipped_last_frame_missed_exceeded_deadline_, other.skipped_last_frame_missed_exceeded_deadline_)
+   && ::protozero::internal::gen_helpers::EqualsField(inside_action_, other.inside_action_)
+   && ::protozero::internal::gen_helpers::EqualsField(deadline_mode_, other.deadline_mode_)
+   && ::protozero::internal::gen_helpers::EqualsField(deadline_us_, other.deadline_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(deadline_scheduled_at_us_, other.deadline_scheduled_at_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(now_us_, other.now_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(now_to_deadline_delta_us_, other.now_to_deadline_delta_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(now_to_deadline_scheduled_at_delta_us_, other.now_to_deadline_scheduled_at_delta_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(begin_impl_frame_args_, other.begin_impl_frame_args_)
+   && ::protozero::internal::gen_helpers::EqualsField(begin_frame_observer_state_, other.begin_frame_observer_state_)
+   && ::protozero::internal::gen_helpers::EqualsField(begin_frame_source_state_, other.begin_frame_source_state_)
+   && ::protozero::internal::gen_helpers::EqualsField(compositor_timing_history_, other.compositor_timing_history_);
+}
+
+bool ChromeCompositorSchedulerState::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* state_machine */:
+        (*state_machine_).ParseFromArray(field.data(), field.size());
+        break;
+      case 2 /* observing_begin_frame_source */:
+        field.get(&observing_begin_frame_source_);
+        break;
+      case 3 /* begin_impl_frame_deadline_task */:
+        field.get(&begin_impl_frame_deadline_task_);
+        break;
+      case 4 /* pending_begin_frame_task */:
+        field.get(&pending_begin_frame_task_);
+        break;
+      case 5 /* skipped_last_frame_missed_exceeded_deadline */:
+        field.get(&skipped_last_frame_missed_exceeded_deadline_);
+        break;
+      case 7 /* inside_action */:
+        field.get(&inside_action_);
+        break;
+      case 8 /* deadline_mode */:
+        field.get(&deadline_mode_);
+        break;
+      case 9 /* deadline_us */:
+        field.get(&deadline_us_);
+        break;
+      case 10 /* deadline_scheduled_at_us */:
+        field.get(&deadline_scheduled_at_us_);
+        break;
+      case 11 /* now_us */:
+        field.get(&now_us_);
+        break;
+      case 12 /* now_to_deadline_delta_us */:
+        field.get(&now_to_deadline_delta_us_);
+        break;
+      case 13 /* now_to_deadline_scheduled_at_delta_us */:
+        field.get(&now_to_deadline_scheduled_at_delta_us_);
+        break;
+      case 14 /* begin_impl_frame_args */:
+        (*begin_impl_frame_args_).ParseFromArray(field.data(), field.size());
+        break;
+      case 15 /* begin_frame_observer_state */:
+        (*begin_frame_observer_state_).ParseFromArray(field.data(), field.size());
+        break;
+      case 16 /* begin_frame_source_state */:
+        (*begin_frame_source_state_).ParseFromArray(field.data(), field.size());
+        break;
+      case 17 /* compositor_timing_history */:
+        (*compositor_timing_history_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeCompositorSchedulerState::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeCompositorSchedulerState::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeCompositorSchedulerState::Serialize(::protozero::Message* msg) const {
+  // Field 1: state_machine
+  if (_has_field_[1]) {
+    (*state_machine_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  // Field 2: observing_begin_frame_source
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, observing_begin_frame_source_, msg);
+  }
+
+  // Field 3: begin_impl_frame_deadline_task
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, begin_impl_frame_deadline_task_, msg);
+  }
+
+  // Field 4: pending_begin_frame_task
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, pending_begin_frame_task_, msg);
+  }
+
+  // Field 5: skipped_last_frame_missed_exceeded_deadline
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, skipped_last_frame_missed_exceeded_deadline_, msg);
+  }
+
+  // Field 7: inside_action
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(7, inside_action_, msg);
+  }
+
+  // Field 8: deadline_mode
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(8, deadline_mode_, msg);
+  }
+
+  // Field 9: deadline_us
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(9, deadline_us_, msg);
+  }
+
+  // Field 10: deadline_scheduled_at_us
+  if (_has_field_[10]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(10, deadline_scheduled_at_us_, msg);
+  }
+
+  // Field 11: now_us
+  if (_has_field_[11]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(11, now_us_, msg);
+  }
+
+  // Field 12: now_to_deadline_delta_us
+  if (_has_field_[12]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(12, now_to_deadline_delta_us_, msg);
+  }
+
+  // Field 13: now_to_deadline_scheduled_at_delta_us
+  if (_has_field_[13]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(13, now_to_deadline_scheduled_at_delta_us_, msg);
+  }
+
+  // Field 14: begin_impl_frame_args
+  if (_has_field_[14]) {
+    (*begin_impl_frame_args_).Serialize(msg->BeginNestedMessage<::protozero::Message>(14));
+  }
+
+  // Field 15: begin_frame_observer_state
+  if (_has_field_[15]) {
+    (*begin_frame_observer_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(15));
+  }
+
+  // Field 16: begin_frame_source_state
+  if (_has_field_[16]) {
+    (*begin_frame_source_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(16));
+  }
+
+  // Field 17: compositor_timing_history
+  if (_has_field_[17]) {
+    (*compositor_timing_history_).Serialize(msg->BeginNestedMessage<::protozero::Message>(17));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_content_settings_event_info.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_content_settings_event_info.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ChromeContentSettingsEventInfo::ChromeContentSettingsEventInfo() = default;
+ChromeContentSettingsEventInfo::~ChromeContentSettingsEventInfo() = default;
+ChromeContentSettingsEventInfo::ChromeContentSettingsEventInfo(const ChromeContentSettingsEventInfo&) = default;
+ChromeContentSettingsEventInfo& ChromeContentSettingsEventInfo::operator=(const ChromeContentSettingsEventInfo&) = default;
+ChromeContentSettingsEventInfo::ChromeContentSettingsEventInfo(ChromeContentSettingsEventInfo&&) noexcept = default;
+ChromeContentSettingsEventInfo& ChromeContentSettingsEventInfo::operator=(ChromeContentSettingsEventInfo&&) = default;
+
+bool ChromeContentSettingsEventInfo::operator==(const ChromeContentSettingsEventInfo& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(number_of_exceptions_, other.number_of_exceptions_);
+}
+
+bool ChromeContentSettingsEventInfo::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* number_of_exceptions */:
+        field.get(&number_of_exceptions_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeContentSettingsEventInfo::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeContentSettingsEventInfo::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeContentSettingsEventInfo::Serialize(::protozero::Message* msg) const {
+  // Field 1: number_of_exceptions
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, number_of_exceptions_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_frame_reporter.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_frame_reporter.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ChromeFrameReporter::ChromeFrameReporter() = default;
+ChromeFrameReporter::~ChromeFrameReporter() = default;
+ChromeFrameReporter::ChromeFrameReporter(const ChromeFrameReporter&) = default;
+ChromeFrameReporter& ChromeFrameReporter::operator=(const ChromeFrameReporter&) = default;
+ChromeFrameReporter::ChromeFrameReporter(ChromeFrameReporter&&) noexcept = default;
+ChromeFrameReporter& ChromeFrameReporter::operator=(ChromeFrameReporter&&) = default;
+
+bool ChromeFrameReporter::operator==(const ChromeFrameReporter& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(state_, other.state_)
+   && ::protozero::internal::gen_helpers::EqualsField(reason_, other.reason_)
+   && ::protozero::internal::gen_helpers::EqualsField(frame_source_, other.frame_source_)
+   && ::protozero::internal::gen_helpers::EqualsField(frame_sequence_, other.frame_sequence_)
+   && ::protozero::internal::gen_helpers::EqualsField(affects_smoothness_, other.affects_smoothness_)
+   && ::protozero::internal::gen_helpers::EqualsField(scroll_state_, other.scroll_state_)
+   && ::protozero::internal::gen_helpers::EqualsField(has_main_animation_, other.has_main_animation_)
+   && ::protozero::internal::gen_helpers::EqualsField(has_compositor_animation_, other.has_compositor_animation_)
+   && ::protozero::internal::gen_helpers::EqualsField(has_smooth_input_main_, other.has_smooth_input_main_)
+   && ::protozero::internal::gen_helpers::EqualsField(has_missing_content_, other.has_missing_content_)
+   && ::protozero::internal::gen_helpers::EqualsField(layer_tree_host_id_, other.layer_tree_host_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(has_high_latency_, other.has_high_latency_)
+   && ::protozero::internal::gen_helpers::EqualsField(frame_type_, other.frame_type_)
+   && ::protozero::internal::gen_helpers::EqualsField(high_latency_contribution_stage_, other.high_latency_contribution_stage_);
+}
+
+bool ChromeFrameReporter::ParseFromArray(const void* raw, size_t size) {
+  high_latency_contribution_stage_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* state */:
+        field.get(&state_);
+        break;
+      case 2 /* reason */:
+        field.get(&reason_);
+        break;
+      case 3 /* frame_source */:
+        field.get(&frame_source_);
+        break;
+      case 4 /* frame_sequence */:
+        field.get(&frame_sequence_);
+        break;
+      case 5 /* affects_smoothness */:
+        field.get(&affects_smoothness_);
+        break;
+      case 6 /* scroll_state */:
+        field.get(&scroll_state_);
+        break;
+      case 7 /* has_main_animation */:
+        field.get(&has_main_animation_);
+        break;
+      case 8 /* has_compositor_animation */:
+        field.get(&has_compositor_animation_);
+        break;
+      case 9 /* has_smooth_input_main */:
+        field.get(&has_smooth_input_main_);
+        break;
+      case 10 /* has_missing_content */:
+        field.get(&has_missing_content_);
+        break;
+      case 11 /* layer_tree_host_id */:
+        field.get(&layer_tree_host_id_);
+        break;
+      case 12 /* has_high_latency */:
+        field.get(&has_high_latency_);
+        break;
+      case 13 /* frame_type */:
+        field.get(&frame_type_);
+        break;
+      case 14 /* high_latency_contribution_stage */:
+        high_latency_contribution_stage_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &high_latency_contribution_stage_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeFrameReporter::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeFrameReporter::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeFrameReporter::Serialize(::protozero::Message* msg) const {
+  // Field 1: state
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, state_, msg);
+  }
+
+  // Field 2: reason
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, reason_, msg);
+  }
+
+  // Field 3: frame_source
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, frame_source_, msg);
+  }
+
+  // Field 4: frame_sequence
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, frame_sequence_, msg);
+  }
+
+  // Field 5: affects_smoothness
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, affects_smoothness_, msg);
+  }
+
+  // Field 6: scroll_state
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, scroll_state_, msg);
+  }
+
+  // Field 7: has_main_animation
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(7, has_main_animation_, msg);
+  }
+
+  // Field 8: has_compositor_animation
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(8, has_compositor_animation_, msg);
+  }
+
+  // Field 9: has_smooth_input_main
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(9, has_smooth_input_main_, msg);
+  }
+
+  // Field 10: has_missing_content
+  if (_has_field_[10]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(10, has_missing_content_, msg);
+  }
+
+  // Field 11: layer_tree_host_id
+  if (_has_field_[11]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(11, layer_tree_host_id_, msg);
+  }
+
+  // Field 12: has_high_latency
+  if (_has_field_[12]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(12, has_high_latency_, msg);
+  }
+
+  // Field 13: frame_type
+  if (_has_field_[13]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(13, frame_type_, msg);
+  }
+
+  // Field 14: high_latency_contribution_stage
+  for (auto& it : high_latency_contribution_stage_) {
+    ::protozero::internal::gen_helpers::SerializeString(14, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_histogram_sample.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_histogram_sample.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ChromeHistogramSample::ChromeHistogramSample() = default;
+ChromeHistogramSample::~ChromeHistogramSample() = default;
+ChromeHistogramSample::ChromeHistogramSample(const ChromeHistogramSample&) = default;
+ChromeHistogramSample& ChromeHistogramSample::operator=(const ChromeHistogramSample&) = default;
+ChromeHistogramSample::ChromeHistogramSample(ChromeHistogramSample&&) noexcept = default;
+ChromeHistogramSample& ChromeHistogramSample::operator=(ChromeHistogramSample&&) = default;
+
+bool ChromeHistogramSample::operator==(const ChromeHistogramSample& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_hash_, other.name_hash_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(sample_, other.sample_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_iid_, other.name_iid_);
+}
+
+bool ChromeHistogramSample::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name_hash */:
+        field.get(&name_hash_);
+        break;
+      case 2 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 3 /* sample */:
+        field.get(&sample_);
+        break;
+      case 4 /* name_iid */:
+        field.get(&name_iid_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeHistogramSample::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeHistogramSample::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeHistogramSample::Serialize(::protozero::Message* msg) const {
+  // Field 1: name_hash
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, name_hash_, msg);
+  }
+
+  // Field 2: name
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, name_, msg);
+  }
+
+  // Field 3: sample
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, sample_, msg);
+  }
+
+  // Field 4: name_iid
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, name_iid_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+HistogramName::HistogramName() = default;
+HistogramName::~HistogramName() = default;
+HistogramName::HistogramName(const HistogramName&) = default;
+HistogramName& HistogramName::operator=(const HistogramName&) = default;
+HistogramName::HistogramName(HistogramName&&) noexcept = default;
+HistogramName& HistogramName::operator=(HistogramName&&) = default;
+
+bool HistogramName::operator==(const HistogramName& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(iid_, other.iid_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_);
+}
+
+bool HistogramName::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* iid */:
+        field.get(&iid_);
+        break;
+      case 2 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string HistogramName::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> HistogramName::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void HistogramName::Serialize(::protozero::Message* msg) const {
+  // Field 1: iid
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, iid_, msg);
+  }
+
+  // Field 2: name
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, name_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_keyed_service.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_keyed_service.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ChromeKeyedService::ChromeKeyedService() = default;
+ChromeKeyedService::~ChromeKeyedService() = default;
+ChromeKeyedService::ChromeKeyedService(const ChromeKeyedService&) = default;
+ChromeKeyedService& ChromeKeyedService::operator=(const ChromeKeyedService&) = default;
+ChromeKeyedService::ChromeKeyedService(ChromeKeyedService&&) noexcept = default;
+ChromeKeyedService& ChromeKeyedService::operator=(ChromeKeyedService&&) = default;
+
+bool ChromeKeyedService::operator==(const ChromeKeyedService& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_);
+}
+
+bool ChromeKeyedService::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeKeyedService::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeKeyedService::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeKeyedService::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_latency_info.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_latency_info.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ChromeLatencyInfo::ChromeLatencyInfo() = default;
+ChromeLatencyInfo::~ChromeLatencyInfo() = default;
+ChromeLatencyInfo::ChromeLatencyInfo(const ChromeLatencyInfo&) = default;
+ChromeLatencyInfo& ChromeLatencyInfo::operator=(const ChromeLatencyInfo&) = default;
+ChromeLatencyInfo::ChromeLatencyInfo(ChromeLatencyInfo&&) noexcept = default;
+ChromeLatencyInfo& ChromeLatencyInfo::operator=(ChromeLatencyInfo&&) = default;
+
+bool ChromeLatencyInfo::operator==(const ChromeLatencyInfo& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(trace_id_, other.trace_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(step_, other.step_)
+   && ::protozero::internal::gen_helpers::EqualsField(frame_tree_node_id_, other.frame_tree_node_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(component_info_, other.component_info_)
+   && ::protozero::internal::gen_helpers::EqualsField(is_coalesced_, other.is_coalesced_)
+   && ::protozero::internal::gen_helpers::EqualsField(gesture_scroll_id_, other.gesture_scroll_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(touch_id_, other.touch_id_);
+}
+
+int ChromeLatencyInfo::component_info_size() const { return static_cast<int>(component_info_.size()); }
+void ChromeLatencyInfo::clear_component_info() { component_info_.clear(); }
+ChromeLatencyInfo_ComponentInfo* ChromeLatencyInfo::add_component_info() { component_info_.emplace_back(); return &component_info_.back(); }
+bool ChromeLatencyInfo::ParseFromArray(const void* raw, size_t size) {
+  component_info_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* trace_id */:
+        field.get(&trace_id_);
+        break;
+      case 2 /* step */:
+        field.get(&step_);
+        break;
+      case 3 /* frame_tree_node_id */:
+        field.get(&frame_tree_node_id_);
+        break;
+      case 4 /* component_info */:
+        component_info_.emplace_back();
+        component_info_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 5 /* is_coalesced */:
+        field.get(&is_coalesced_);
+        break;
+      case 6 /* gesture_scroll_id */:
+        field.get(&gesture_scroll_id_);
+        break;
+      case 7 /* touch_id */:
+        field.get(&touch_id_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeLatencyInfo::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeLatencyInfo::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeLatencyInfo::Serialize(::protozero::Message* msg) const {
+  // Field 1: trace_id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, trace_id_, msg);
+  }
+
+  // Field 2: step
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, step_, msg);
+  }
+
+  // Field 3: frame_tree_node_id
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, frame_tree_node_id_, msg);
+  }
+
+  // Field 4: component_info
+  for (auto& it : component_info_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
+  }
+
+  // Field 5: is_coalesced
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, is_coalesced_, msg);
+  }
+
+  // Field 6: gesture_scroll_id
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, gesture_scroll_id_, msg);
+  }
+
+  // Field 7: touch_id
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(7, touch_id_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+ChromeLatencyInfo_ComponentInfo::ChromeLatencyInfo_ComponentInfo() = default;
+ChromeLatencyInfo_ComponentInfo::~ChromeLatencyInfo_ComponentInfo() = default;
+ChromeLatencyInfo_ComponentInfo::ChromeLatencyInfo_ComponentInfo(const ChromeLatencyInfo_ComponentInfo&) = default;
+ChromeLatencyInfo_ComponentInfo& ChromeLatencyInfo_ComponentInfo::operator=(const ChromeLatencyInfo_ComponentInfo&) = default;
+ChromeLatencyInfo_ComponentInfo::ChromeLatencyInfo_ComponentInfo(ChromeLatencyInfo_ComponentInfo&&) noexcept = default;
+ChromeLatencyInfo_ComponentInfo& ChromeLatencyInfo_ComponentInfo::operator=(ChromeLatencyInfo_ComponentInfo&&) = default;
+
+bool ChromeLatencyInfo_ComponentInfo::operator==(const ChromeLatencyInfo_ComponentInfo& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(component_type_, other.component_type_)
+   && ::protozero::internal::gen_helpers::EqualsField(time_us_, other.time_us_);
+}
+
+bool ChromeLatencyInfo_ComponentInfo::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* component_type */:
+        field.get(&component_type_);
+        break;
+      case 2 /* time_us */:
+        field.get(&time_us_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeLatencyInfo_ComponentInfo::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeLatencyInfo_ComponentInfo::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeLatencyInfo_ComponentInfo::Serialize(::protozero::Message* msg) const {
+  // Field 1: component_type
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, component_type_, msg);
+  }
+
+  // Field 2: time_us
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, time_us_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_legacy_ipc.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_legacy_ipc.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ChromeLegacyIpc::ChromeLegacyIpc() = default;
+ChromeLegacyIpc::~ChromeLegacyIpc() = default;
+ChromeLegacyIpc::ChromeLegacyIpc(const ChromeLegacyIpc&) = default;
+ChromeLegacyIpc& ChromeLegacyIpc::operator=(const ChromeLegacyIpc&) = default;
+ChromeLegacyIpc::ChromeLegacyIpc(ChromeLegacyIpc&&) noexcept = default;
+ChromeLegacyIpc& ChromeLegacyIpc::operator=(ChromeLegacyIpc&&) = default;
+
+bool ChromeLegacyIpc::operator==(const ChromeLegacyIpc& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(message_class_, other.message_class_)
+   && ::protozero::internal::gen_helpers::EqualsField(message_line_, other.message_line_);
+}
+
+bool ChromeLegacyIpc::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* message_class */:
+        field.get(&message_class_);
+        break;
+      case 2 /* message_line */:
+        field.get(&message_line_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeLegacyIpc::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeLegacyIpc::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeLegacyIpc::Serialize(::protozero::Message* msg) const {
+  // Field 1: message_class
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, message_class_, msg);
+  }
+
+  // Field 2: message_line
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, message_line_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_message_pump.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_message_pump.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ChromeMessagePump::ChromeMessagePump() = default;
+ChromeMessagePump::~ChromeMessagePump() = default;
+ChromeMessagePump::ChromeMessagePump(const ChromeMessagePump&) = default;
+ChromeMessagePump& ChromeMessagePump::operator=(const ChromeMessagePump&) = default;
+ChromeMessagePump::ChromeMessagePump(ChromeMessagePump&&) noexcept = default;
+ChromeMessagePump& ChromeMessagePump::operator=(ChromeMessagePump&&) = default;
+
+bool ChromeMessagePump::operator==(const ChromeMessagePump& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(sent_messages_in_queue_, other.sent_messages_in_queue_)
+   && ::protozero::internal::gen_helpers::EqualsField(io_handler_location_iid_, other.io_handler_location_iid_);
+}
+
+bool ChromeMessagePump::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* sent_messages_in_queue */:
+        field.get(&sent_messages_in_queue_);
+        break;
+      case 2 /* io_handler_location_iid */:
+        field.get(&io_handler_location_iid_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeMessagePump::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeMessagePump::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeMessagePump::Serialize(::protozero::Message* msg) const {
+  // Field 1: sent_messages_in_queue
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, sent_messages_in_queue_, msg);
+  }
+
+  // Field 2: io_handler_location_iid
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, io_handler_location_iid_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_mojo_event_info.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_mojo_event_info.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ChromeMojoEventInfo::ChromeMojoEventInfo() = default;
+ChromeMojoEventInfo::~ChromeMojoEventInfo() = default;
+ChromeMojoEventInfo::ChromeMojoEventInfo(const ChromeMojoEventInfo&) = default;
+ChromeMojoEventInfo& ChromeMojoEventInfo::operator=(const ChromeMojoEventInfo&) = default;
+ChromeMojoEventInfo::ChromeMojoEventInfo(ChromeMojoEventInfo&&) noexcept = default;
+ChromeMojoEventInfo& ChromeMojoEventInfo::operator=(ChromeMojoEventInfo&&) = default;
+
+bool ChromeMojoEventInfo::operator==(const ChromeMojoEventInfo& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(watcher_notify_interface_tag_, other.watcher_notify_interface_tag_)
+   && ::protozero::internal::gen_helpers::EqualsField(ipc_hash_, other.ipc_hash_)
+   && ::protozero::internal::gen_helpers::EqualsField(mojo_interface_tag_, other.mojo_interface_tag_)
+   && ::protozero::internal::gen_helpers::EqualsField(mojo_interface_method_iid_, other.mojo_interface_method_iid_)
+   && ::protozero::internal::gen_helpers::EqualsField(is_reply_, other.is_reply_)
+   && ::protozero::internal::gen_helpers::EqualsField(payload_size_, other.payload_size_)
+   && ::protozero::internal::gen_helpers::EqualsField(data_num_bytes_, other.data_num_bytes_);
+}
+
+bool ChromeMojoEventInfo::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* watcher_notify_interface_tag */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &watcher_notify_interface_tag_);
+        break;
+      case 2 /* ipc_hash */:
+        field.get(&ipc_hash_);
+        break;
+      case 3 /* mojo_interface_tag */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &mojo_interface_tag_);
+        break;
+      case 4 /* mojo_interface_method_iid */:
+        field.get(&mojo_interface_method_iid_);
+        break;
+      case 5 /* is_reply */:
+        field.get(&is_reply_);
+        break;
+      case 6 /* payload_size */:
+        field.get(&payload_size_);
+        break;
+      case 7 /* data_num_bytes */:
+        field.get(&data_num_bytes_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeMojoEventInfo::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeMojoEventInfo::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeMojoEventInfo::Serialize(::protozero::Message* msg) const {
+  // Field 1: watcher_notify_interface_tag
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, watcher_notify_interface_tag_, msg);
+  }
+
+  // Field 2: ipc_hash
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, ipc_hash_, msg);
+  }
+
+  // Field 3: mojo_interface_tag
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeString(3, mojo_interface_tag_, msg);
+  }
+
+  // Field 4: mojo_interface_method_iid
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, mojo_interface_method_iid_, msg);
+  }
+
+  // Field 5: is_reply
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, is_reply_, msg);
+  }
+
+  // Field 6: payload_size
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, payload_size_, msg);
+  }
+
+  // Field 7: data_num_bytes
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(7, data_num_bytes_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_process_descriptor.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_process_descriptor.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ChromeProcessDescriptor::ChromeProcessDescriptor() = default;
+ChromeProcessDescriptor::~ChromeProcessDescriptor() = default;
+ChromeProcessDescriptor::ChromeProcessDescriptor(const ChromeProcessDescriptor&) = default;
+ChromeProcessDescriptor& ChromeProcessDescriptor::operator=(const ChromeProcessDescriptor&) = default;
+ChromeProcessDescriptor::ChromeProcessDescriptor(ChromeProcessDescriptor&&) noexcept = default;
+ChromeProcessDescriptor& ChromeProcessDescriptor::operator=(ChromeProcessDescriptor&&) = default;
+
+bool ChromeProcessDescriptor::operator==(const ChromeProcessDescriptor& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(process_type_, other.process_type_)
+   && ::protozero::internal::gen_helpers::EqualsField(process_priority_, other.process_priority_)
+   && ::protozero::internal::gen_helpers::EqualsField(legacy_sort_index_, other.legacy_sort_index_)
+   && ::protozero::internal::gen_helpers::EqualsField(host_app_package_name_, other.host_app_package_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(crash_trace_id_, other.crash_trace_id_);
+}
+
+bool ChromeProcessDescriptor::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* process_type */:
+        field.get(&process_type_);
+        break;
+      case 2 /* process_priority */:
+        field.get(&process_priority_);
+        break;
+      case 3 /* legacy_sort_index */:
+        field.get(&legacy_sort_index_);
+        break;
+      case 4 /* host_app_package_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &host_app_package_name_);
+        break;
+      case 5 /* crash_trace_id */:
+        field.get(&crash_trace_id_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeProcessDescriptor::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeProcessDescriptor::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeProcessDescriptor::Serialize(::protozero::Message* msg) const {
+  // Field 1: process_type
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, process_type_, msg);
+  }
+
+  // Field 2: process_priority
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, process_priority_, msg);
+  }
+
+  // Field 3: legacy_sort_index
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, legacy_sort_index_, msg);
+  }
+
+  // Field 4: host_app_package_name
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeString(4, host_app_package_name_, msg);
+  }
+
+  // Field 5: crash_trace_id
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, crash_trace_id_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ChromeRendererSchedulerState::ChromeRendererSchedulerState() = default;
+ChromeRendererSchedulerState::~ChromeRendererSchedulerState() = default;
+ChromeRendererSchedulerState::ChromeRendererSchedulerState(const ChromeRendererSchedulerState&) = default;
+ChromeRendererSchedulerState& ChromeRendererSchedulerState::operator=(const ChromeRendererSchedulerState&) = default;
+ChromeRendererSchedulerState::ChromeRendererSchedulerState(ChromeRendererSchedulerState&&) noexcept = default;
+ChromeRendererSchedulerState& ChromeRendererSchedulerState::operator=(ChromeRendererSchedulerState&&) = default;
+
+bool ChromeRendererSchedulerState::operator==(const ChromeRendererSchedulerState& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(rail_mode_, other.rail_mode_)
+   && ::protozero::internal::gen_helpers::EqualsField(is_backgrounded_, other.is_backgrounded_)
+   && ::protozero::internal::gen_helpers::EqualsField(is_hidden_, other.is_hidden_);
+}
+
+bool ChromeRendererSchedulerState::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* rail_mode */:
+        field.get(&rail_mode_);
+        break;
+      case 2 /* is_backgrounded */:
+        field.get(&is_backgrounded_);
+        break;
+      case 3 /* is_hidden */:
+        field.get(&is_hidden_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeRendererSchedulerState::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeRendererSchedulerState::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeRendererSchedulerState::Serialize(::protozero::Message* msg) const {
+  // Field 1: rail_mode
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, rail_mode_, msg);
+  }
+
+  // Field 2: is_backgrounded
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, is_backgrounded_, msg);
+  }
+
+  // Field 3: is_hidden
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, is_hidden_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_thread_descriptor.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_thread_descriptor.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ChromeThreadDescriptor::ChromeThreadDescriptor() = default;
+ChromeThreadDescriptor::~ChromeThreadDescriptor() = default;
+ChromeThreadDescriptor::ChromeThreadDescriptor(const ChromeThreadDescriptor&) = default;
+ChromeThreadDescriptor& ChromeThreadDescriptor::operator=(const ChromeThreadDescriptor&) = default;
+ChromeThreadDescriptor::ChromeThreadDescriptor(ChromeThreadDescriptor&&) noexcept = default;
+ChromeThreadDescriptor& ChromeThreadDescriptor::operator=(ChromeThreadDescriptor&&) = default;
+
+bool ChromeThreadDescriptor::operator==(const ChromeThreadDescriptor& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(thread_type_, other.thread_type_)
+   && ::protozero::internal::gen_helpers::EqualsField(legacy_sort_index_, other.legacy_sort_index_);
+}
+
+bool ChromeThreadDescriptor::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* thread_type */:
+        field.get(&thread_type_);
+        break;
+      case 2 /* legacy_sort_index */:
+        field.get(&legacy_sort_index_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeThreadDescriptor::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeThreadDescriptor::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeThreadDescriptor::Serialize(::protozero::Message* msg) const {
+  // Field 1: thread_type
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, thread_type_, msg);
+  }
+
+  // Field 2: legacy_sort_index
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, legacy_sort_index_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_user_event.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_user_event.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ChromeUserEvent::ChromeUserEvent() = default;
+ChromeUserEvent::~ChromeUserEvent() = default;
+ChromeUserEvent::ChromeUserEvent(const ChromeUserEvent&) = default;
+ChromeUserEvent& ChromeUserEvent::operator=(const ChromeUserEvent&) = default;
+ChromeUserEvent::ChromeUserEvent(ChromeUserEvent&&) noexcept = default;
+ChromeUserEvent& ChromeUserEvent::operator=(ChromeUserEvent&&) = default;
+
+bool ChromeUserEvent::operator==(const ChromeUserEvent& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(action_, other.action_)
+   && ::protozero::internal::gen_helpers::EqualsField(action_hash_, other.action_hash_);
+}
+
+bool ChromeUserEvent::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* action */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &action_);
+        break;
+      case 2 /* action_hash */:
+        field.get(&action_hash_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeUserEvent::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeUserEvent::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeUserEvent::Serialize(::protozero::Message* msg) const {
+  // Field 1: action
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, action_, msg);
+  }
+
+  // Field 2: action_hash
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, action_hash_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_window_handle_event_info.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_window_handle_event_info.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ChromeWindowHandleEventInfo::ChromeWindowHandleEventInfo() = default;
+ChromeWindowHandleEventInfo::~ChromeWindowHandleEventInfo() = default;
+ChromeWindowHandleEventInfo::ChromeWindowHandleEventInfo(const ChromeWindowHandleEventInfo&) = default;
+ChromeWindowHandleEventInfo& ChromeWindowHandleEventInfo::operator=(const ChromeWindowHandleEventInfo&) = default;
+ChromeWindowHandleEventInfo::ChromeWindowHandleEventInfo(ChromeWindowHandleEventInfo&&) noexcept = default;
+ChromeWindowHandleEventInfo& ChromeWindowHandleEventInfo::operator=(ChromeWindowHandleEventInfo&&) = default;
+
+bool ChromeWindowHandleEventInfo::operator==(const ChromeWindowHandleEventInfo& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(dpi_, other.dpi_)
+   && ::protozero::internal::gen_helpers::EqualsField(message_id_, other.message_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(hwnd_ptr_, other.hwnd_ptr_);
+}
+
+bool ChromeWindowHandleEventInfo::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* dpi */:
+        field.get(&dpi_);
+        break;
+      case 2 /* message_id */:
+        field.get(&message_id_);
+        break;
+      case 3 /* hwnd_ptr */:
+        field.get(&hwnd_ptr_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeWindowHandleEventInfo::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeWindowHandleEventInfo::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeWindowHandleEventInfo::Serialize(::protozero::Message* msg) const {
+  // Field 1: dpi
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, dpi_, msg);
+  }
+
+  // Field 2: message_id
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, message_id_, msg);
+  }
+
+  // Field 3: hwnd_ptr
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeFixed(3, hwnd_ptr_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/counter_descriptor.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/counter_descriptor.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+CounterDescriptor::CounterDescriptor() = default;
+CounterDescriptor::~CounterDescriptor() = default;
+CounterDescriptor::CounterDescriptor(const CounterDescriptor&) = default;
+CounterDescriptor& CounterDescriptor::operator=(const CounterDescriptor&) = default;
+CounterDescriptor::CounterDescriptor(CounterDescriptor&&) noexcept = default;
+CounterDescriptor& CounterDescriptor::operator=(CounterDescriptor&&) = default;
+
+bool CounterDescriptor::operator==(const CounterDescriptor& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(type_, other.type_)
+   && ::protozero::internal::gen_helpers::EqualsField(categories_, other.categories_)
+   && ::protozero::internal::gen_helpers::EqualsField(unit_, other.unit_)
+   && ::protozero::internal::gen_helpers::EqualsField(unit_name_, other.unit_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(unit_multiplier_, other.unit_multiplier_)
+   && ::protozero::internal::gen_helpers::EqualsField(is_incremental_, other.is_incremental_);
+}
+
+bool CounterDescriptor::ParseFromArray(const void* raw, size_t size) {
+  categories_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* type */:
+        field.get(&type_);
+        break;
+      case 2 /* categories */:
+        categories_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &categories_.back());
+        break;
+      case 3 /* unit */:
+        field.get(&unit_);
+        break;
+      case 6 /* unit_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &unit_name_);
+        break;
+      case 4 /* unit_multiplier */:
+        field.get(&unit_multiplier_);
+        break;
+      case 5 /* is_incremental */:
+        field.get(&is_incremental_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string CounterDescriptor::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> CounterDescriptor::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void CounterDescriptor::Serialize(::protozero::Message* msg) const {
+  // Field 1: type
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, type_, msg);
+  }
+
+  // Field 2: categories
+  for (auto& it : categories_) {
+    ::protozero::internal::gen_helpers::SerializeString(2, it, msg);
+  }
+
+  // Field 3: unit
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, unit_, msg);
+  }
+
+  // Field 6: unit_name
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeString(6, unit_name_, msg);
+  }
+
+  // Field 4: unit_multiplier
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, unit_multiplier_, msg);
+  }
+
+  // Field 5: is_incremental
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, is_incremental_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/debug_annotation.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/debug_annotation.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+DebugAnnotationValueTypeName::DebugAnnotationValueTypeName() = default;
+DebugAnnotationValueTypeName::~DebugAnnotationValueTypeName() = default;
+DebugAnnotationValueTypeName::DebugAnnotationValueTypeName(const DebugAnnotationValueTypeName&) = default;
+DebugAnnotationValueTypeName& DebugAnnotationValueTypeName::operator=(const DebugAnnotationValueTypeName&) = default;
+DebugAnnotationValueTypeName::DebugAnnotationValueTypeName(DebugAnnotationValueTypeName&&) noexcept = default;
+DebugAnnotationValueTypeName& DebugAnnotationValueTypeName::operator=(DebugAnnotationValueTypeName&&) = default;
+
+bool DebugAnnotationValueTypeName::operator==(const DebugAnnotationValueTypeName& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(iid_, other.iid_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_);
+}
+
+bool DebugAnnotationValueTypeName::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* iid */:
+        field.get(&iid_);
+        break;
+      case 2 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string DebugAnnotationValueTypeName::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> DebugAnnotationValueTypeName::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void DebugAnnotationValueTypeName::Serialize(::protozero::Message* msg) const {
+  // Field 1: iid
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, iid_, msg);
+  }
+
+  // Field 2: name
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, name_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+DebugAnnotationName::DebugAnnotationName() = default;
+DebugAnnotationName::~DebugAnnotationName() = default;
+DebugAnnotationName::DebugAnnotationName(const DebugAnnotationName&) = default;
+DebugAnnotationName& DebugAnnotationName::operator=(const DebugAnnotationName&) = default;
+DebugAnnotationName::DebugAnnotationName(DebugAnnotationName&&) noexcept = default;
+DebugAnnotationName& DebugAnnotationName::operator=(DebugAnnotationName&&) = default;
+
+bool DebugAnnotationName::operator==(const DebugAnnotationName& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(iid_, other.iid_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_);
+}
+
+bool DebugAnnotationName::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* iid */:
+        field.get(&iid_);
+        break;
+      case 2 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string DebugAnnotationName::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> DebugAnnotationName::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void DebugAnnotationName::Serialize(::protozero::Message* msg) const {
+  // Field 1: iid
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, iid_, msg);
+  }
+
+  // Field 2: name
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, name_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+DebugAnnotation::DebugAnnotation() = default;
+DebugAnnotation::~DebugAnnotation() = default;
+DebugAnnotation::DebugAnnotation(const DebugAnnotation&) = default;
+DebugAnnotation& DebugAnnotation::operator=(const DebugAnnotation&) = default;
+DebugAnnotation::DebugAnnotation(DebugAnnotation&&) noexcept = default;
+DebugAnnotation& DebugAnnotation::operator=(DebugAnnotation&&) = default;
+
+bool DebugAnnotation::operator==(const DebugAnnotation& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_iid_, other.name_iid_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(bool_value_, other.bool_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(uint_value_, other.uint_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(int_value_, other.int_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(double_value_, other.double_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(pointer_value_, other.pointer_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(nested_value_, other.nested_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(legacy_json_value_, other.legacy_json_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(string_value_, other.string_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(string_value_iid_, other.string_value_iid_)
+   && ::protozero::internal::gen_helpers::EqualsField(proto_type_name_, other.proto_type_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(proto_type_name_iid_, other.proto_type_name_iid_)
+   && ::protozero::internal::gen_helpers::EqualsField(proto_value_, other.proto_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(dict_entries_, other.dict_entries_)
+   && ::protozero::internal::gen_helpers::EqualsField(array_values_, other.array_values_);
+}
+
+int DebugAnnotation::dict_entries_size() const { return static_cast<int>(dict_entries_.size()); }
+void DebugAnnotation::clear_dict_entries() { dict_entries_.clear(); }
+DebugAnnotation* DebugAnnotation::add_dict_entries() { dict_entries_.emplace_back(); return &dict_entries_.back(); }
+int DebugAnnotation::array_values_size() const { return static_cast<int>(array_values_.size()); }
+void DebugAnnotation::clear_array_values() { array_values_.clear(); }
+DebugAnnotation* DebugAnnotation::add_array_values() { array_values_.emplace_back(); return &array_values_.back(); }
+bool DebugAnnotation::ParseFromArray(const void* raw, size_t size) {
+  dict_entries_.clear();
+  array_values_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name_iid */:
+        field.get(&name_iid_);
+        break;
+      case 10 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 2 /* bool_value */:
+        field.get(&bool_value_);
+        break;
+      case 3 /* uint_value */:
+        field.get(&uint_value_);
+        break;
+      case 4 /* int_value */:
+        field.get(&int_value_);
+        break;
+      case 5 /* double_value */:
+        field.get(&double_value_);
+        break;
+      case 7 /* pointer_value */:
+        field.get(&pointer_value_);
+        break;
+      case 8 /* nested_value */:
+        (*nested_value_).ParseFromArray(field.data(), field.size());
+        break;
+      case 9 /* legacy_json_value */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &legacy_json_value_);
+        break;
+      case 6 /* string_value */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &string_value_);
+        break;
+      case 17 /* string_value_iid */:
+        field.get(&string_value_iid_);
+        break;
+      case 16 /* proto_type_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &proto_type_name_);
+        break;
+      case 13 /* proto_type_name_iid */:
+        field.get(&proto_type_name_iid_);
+        break;
+      case 14 /* proto_value */:
+        field.get(&proto_value_);
+        break;
+      case 11 /* dict_entries */:
+        dict_entries_.emplace_back();
+        dict_entries_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 12 /* array_values */:
+        array_values_.emplace_back();
+        array_values_.back().ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string DebugAnnotation::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> DebugAnnotation::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void DebugAnnotation::Serialize(::protozero::Message* msg) const {
+  // Field 1: name_iid
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, name_iid_, msg);
+  }
+
+  // Field 10: name
+  if (_has_field_[10]) {
+    ::protozero::internal::gen_helpers::SerializeString(10, name_, msg);
+  }
+
+  // Field 2: bool_value
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, bool_value_, msg);
+  }
+
+  // Field 3: uint_value
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, uint_value_, msg);
+  }
+
+  // Field 4: int_value
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, int_value_, msg);
+  }
+
+  // Field 5: double_value
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeFixed(5, double_value_, msg);
+  }
+
+  // Field 7: pointer_value
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(7, pointer_value_, msg);
+  }
+
+  // Field 8: nested_value
+  if (_has_field_[8]) {
+    (*nested_value_).Serialize(msg->BeginNestedMessage<::protozero::Message>(8));
+  }
+
+  // Field 9: legacy_json_value
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeString(9, legacy_json_value_, msg);
+  }
+
+  // Field 6: string_value
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeString(6, string_value_, msg);
+  }
+
+  // Field 17: string_value_iid
+  if (_has_field_[17]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(17, string_value_iid_, msg);
+  }
+
+  // Field 16: proto_type_name
+  if (_has_field_[16]) {
+    ::protozero::internal::gen_helpers::SerializeString(16, proto_type_name_, msg);
+  }
+
+  // Field 13: proto_type_name_iid
+  if (_has_field_[13]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(13, proto_type_name_iid_, msg);
+  }
+
+  // Field 14: proto_value
+  if (_has_field_[14]) {
+    ::protozero::internal::gen_helpers::SerializeString(14, proto_value_, msg);
+  }
+
+  // Field 11: dict_entries
+  for (auto& it : dict_entries_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(11));
+  }
+
+  // Field 12: array_values
+  for (auto& it : array_values_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(12));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+DebugAnnotation_NestedValue::DebugAnnotation_NestedValue() = default;
+DebugAnnotation_NestedValue::~DebugAnnotation_NestedValue() = default;
+DebugAnnotation_NestedValue::DebugAnnotation_NestedValue(const DebugAnnotation_NestedValue&) = default;
+DebugAnnotation_NestedValue& DebugAnnotation_NestedValue::operator=(const DebugAnnotation_NestedValue&) = default;
+DebugAnnotation_NestedValue::DebugAnnotation_NestedValue(DebugAnnotation_NestedValue&&) noexcept = default;
+DebugAnnotation_NestedValue& DebugAnnotation_NestedValue::operator=(DebugAnnotation_NestedValue&&) = default;
+
+bool DebugAnnotation_NestedValue::operator==(const DebugAnnotation_NestedValue& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(nested_type_, other.nested_type_)
+   && ::protozero::internal::gen_helpers::EqualsField(dict_keys_, other.dict_keys_)
+   && ::protozero::internal::gen_helpers::EqualsField(dict_values_, other.dict_values_)
+   && ::protozero::internal::gen_helpers::EqualsField(array_values_, other.array_values_)
+   && ::protozero::internal::gen_helpers::EqualsField(int_value_, other.int_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(double_value_, other.double_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(bool_value_, other.bool_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(string_value_, other.string_value_);
+}
+
+int DebugAnnotation_NestedValue::dict_values_size() const { return static_cast<int>(dict_values_.size()); }
+void DebugAnnotation_NestedValue::clear_dict_values() { dict_values_.clear(); }
+DebugAnnotation_NestedValue* DebugAnnotation_NestedValue::add_dict_values() { dict_values_.emplace_back(); return &dict_values_.back(); }
+int DebugAnnotation_NestedValue::array_values_size() const { return static_cast<int>(array_values_.size()); }
+void DebugAnnotation_NestedValue::clear_array_values() { array_values_.clear(); }
+DebugAnnotation_NestedValue* DebugAnnotation_NestedValue::add_array_values() { array_values_.emplace_back(); return &array_values_.back(); }
+bool DebugAnnotation_NestedValue::ParseFromArray(const void* raw, size_t size) {
+  dict_keys_.clear();
+  dict_values_.clear();
+  array_values_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* nested_type */:
+        field.get(&nested_type_);
+        break;
+      case 2 /* dict_keys */:
+        dict_keys_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &dict_keys_.back());
+        break;
+      case 3 /* dict_values */:
+        dict_values_.emplace_back();
+        dict_values_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 4 /* array_values */:
+        array_values_.emplace_back();
+        array_values_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 5 /* int_value */:
+        field.get(&int_value_);
+        break;
+      case 6 /* double_value */:
+        field.get(&double_value_);
+        break;
+      case 7 /* bool_value */:
+        field.get(&bool_value_);
+        break;
+      case 8 /* string_value */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &string_value_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string DebugAnnotation_NestedValue::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> DebugAnnotation_NestedValue::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void DebugAnnotation_NestedValue::Serialize(::protozero::Message* msg) const {
+  // Field 1: nested_type
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, nested_type_, msg);
+  }
+
+  // Field 2: dict_keys
+  for (auto& it : dict_keys_) {
+    ::protozero::internal::gen_helpers::SerializeString(2, it, msg);
+  }
+
+  // Field 3: dict_values
+  for (auto& it : dict_values_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
+  }
+
+  // Field 4: array_values
+  for (auto& it : array_values_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
+  }
+
+  // Field 5: int_value
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, int_value_, msg);
+  }
+
+  // Field 6: double_value
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeFixed(6, double_value_, msg);
+  }
+
+  // Field 7: bool_value
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(7, bool_value_, msg);
+  }
+
+  // Field 8: string_value
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeString(8, string_value_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/log_message.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/log_message.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+LogMessageBody::LogMessageBody() = default;
+LogMessageBody::~LogMessageBody() = default;
+LogMessageBody::LogMessageBody(const LogMessageBody&) = default;
+LogMessageBody& LogMessageBody::operator=(const LogMessageBody&) = default;
+LogMessageBody::LogMessageBody(LogMessageBody&&) noexcept = default;
+LogMessageBody& LogMessageBody::operator=(LogMessageBody&&) = default;
+
+bool LogMessageBody::operator==(const LogMessageBody& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(iid_, other.iid_)
+   && ::protozero::internal::gen_helpers::EqualsField(body_, other.body_);
+}
+
+bool LogMessageBody::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* iid */:
+        field.get(&iid_);
+        break;
+      case 2 /* body */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &body_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string LogMessageBody::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> LogMessageBody::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void LogMessageBody::Serialize(::protozero::Message* msg) const {
+  // Field 1: iid
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, iid_, msg);
+  }
+
+  // Field 2: body
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, body_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+LogMessage::LogMessage() = default;
+LogMessage::~LogMessage() = default;
+LogMessage::LogMessage(const LogMessage&) = default;
+LogMessage& LogMessage::operator=(const LogMessage&) = default;
+LogMessage::LogMessage(LogMessage&&) noexcept = default;
+LogMessage& LogMessage::operator=(LogMessage&&) = default;
+
+bool LogMessage::operator==(const LogMessage& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(source_location_iid_, other.source_location_iid_)
+   && ::protozero::internal::gen_helpers::EqualsField(body_iid_, other.body_iid_)
+   && ::protozero::internal::gen_helpers::EqualsField(prio_, other.prio_);
+}
+
+bool LogMessage::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* source_location_iid */:
+        field.get(&source_location_iid_);
+        break;
+      case 2 /* body_iid */:
+        field.get(&body_iid_);
+        break;
+      case 3 /* prio */:
+        field.get(&prio_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string LogMessage::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> LogMessage::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void LogMessage::Serialize(::protozero::Message* msg) const {
+  // Field 1: source_location_iid
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, source_location_iid_, msg);
+  }
+
+  // Field 2: body_iid
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, body_iid_, msg);
+  }
+
+  // Field 3: prio
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, prio_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/pixel_modem.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/pixel_modem.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+PixelModemEventInsight::PixelModemEventInsight() = default;
+PixelModemEventInsight::~PixelModemEventInsight() = default;
+PixelModemEventInsight::PixelModemEventInsight(const PixelModemEventInsight&) = default;
+PixelModemEventInsight& PixelModemEventInsight::operator=(const PixelModemEventInsight&) = default;
+PixelModemEventInsight::PixelModemEventInsight(PixelModemEventInsight&&) noexcept = default;
+PixelModemEventInsight& PixelModemEventInsight::operator=(PixelModemEventInsight&&) = default;
+
+bool PixelModemEventInsight::operator==(const PixelModemEventInsight& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(detokenized_message_, other.detokenized_message_);
+}
+
+bool PixelModemEventInsight::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* detokenized_message */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &detokenized_message_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string PixelModemEventInsight::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> PixelModemEventInsight::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void PixelModemEventInsight::Serialize(::protozero::Message* msg) const {
+  // Field 1: detokenized_message
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, detokenized_message_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/process_descriptor.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/process_descriptor.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ProcessDescriptor::ProcessDescriptor() = default;
+ProcessDescriptor::~ProcessDescriptor() = default;
+ProcessDescriptor::ProcessDescriptor(const ProcessDescriptor&) = default;
+ProcessDescriptor& ProcessDescriptor::operator=(const ProcessDescriptor&) = default;
+ProcessDescriptor::ProcessDescriptor(ProcessDescriptor&&) noexcept = default;
+ProcessDescriptor& ProcessDescriptor::operator=(ProcessDescriptor&&) = default;
+
+bool ProcessDescriptor::operator==(const ProcessDescriptor& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(pid_, other.pid_)
+   && ::protozero::internal::gen_helpers::EqualsField(cmdline_, other.cmdline_)
+   && ::protozero::internal::gen_helpers::EqualsField(process_name_, other.process_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(process_priority_, other.process_priority_)
+   && ::protozero::internal::gen_helpers::EqualsField(start_timestamp_ns_, other.start_timestamp_ns_)
+   && ::protozero::internal::gen_helpers::EqualsField(chrome_process_type_, other.chrome_process_type_)
+   && ::protozero::internal::gen_helpers::EqualsField(legacy_sort_index_, other.legacy_sort_index_)
+   && ::protozero::internal::gen_helpers::EqualsField(process_labels_, other.process_labels_);
+}
+
+bool ProcessDescriptor::ParseFromArray(const void* raw, size_t size) {
+  cmdline_.clear();
+  process_labels_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* pid */:
+        field.get(&pid_);
+        break;
+      case 2 /* cmdline */:
+        cmdline_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &cmdline_.back());
+        break;
+      case 6 /* process_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &process_name_);
+        break;
+      case 5 /* process_priority */:
+        field.get(&process_priority_);
+        break;
+      case 7 /* start_timestamp_ns */:
+        field.get(&start_timestamp_ns_);
+        break;
+      case 4 /* chrome_process_type */:
+        field.get(&chrome_process_type_);
+        break;
+      case 3 /* legacy_sort_index */:
+        field.get(&legacy_sort_index_);
+        break;
+      case 8 /* process_labels */:
+        process_labels_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &process_labels_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ProcessDescriptor::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ProcessDescriptor::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ProcessDescriptor::Serialize(::protozero::Message* msg) const {
+  // Field 1: pid
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, pid_, msg);
+  }
+
+  // Field 2: cmdline
+  for (auto& it : cmdline_) {
+    ::protozero::internal::gen_helpers::SerializeString(2, it, msg);
+  }
+
+  // Field 6: process_name
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeString(6, process_name_, msg);
+  }
+
+  // Field 5: process_priority
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, process_priority_, msg);
+  }
+
+  // Field 7: start_timestamp_ns
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(7, start_timestamp_ns_, msg);
+  }
+
+  // Field 4: chrome_process_type
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, chrome_process_type_, msg);
+  }
+
+  // Field 3: legacy_sort_index
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, legacy_sort_index_, msg);
+  }
+
+  // Field 8: process_labels
+  for (auto& it : process_labels_) {
+    ::protozero::internal::gen_helpers::SerializeString(8, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/range_of_interest.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/range_of_interest.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+TrackEventRangeOfInterest::TrackEventRangeOfInterest() = default;
+TrackEventRangeOfInterest::~TrackEventRangeOfInterest() = default;
+TrackEventRangeOfInterest::TrackEventRangeOfInterest(const TrackEventRangeOfInterest&) = default;
+TrackEventRangeOfInterest& TrackEventRangeOfInterest::operator=(const TrackEventRangeOfInterest&) = default;
+TrackEventRangeOfInterest::TrackEventRangeOfInterest(TrackEventRangeOfInterest&&) noexcept = default;
+TrackEventRangeOfInterest& TrackEventRangeOfInterest::operator=(TrackEventRangeOfInterest&&) = default;
+
+bool TrackEventRangeOfInterest::operator==(const TrackEventRangeOfInterest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(start_us_, other.start_us_);
+}
+
+bool TrackEventRangeOfInterest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* start_us */:
+        field.get(&start_us_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TrackEventRangeOfInterest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TrackEventRangeOfInterest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TrackEventRangeOfInterest::Serialize(::protozero::Message* msg) const {
+  // Field 1: start_us
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, start_us_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/screenshot.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/screenshot.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+Screenshot::Screenshot() = default;
+Screenshot::~Screenshot() = default;
+Screenshot::Screenshot(const Screenshot&) = default;
+Screenshot& Screenshot::operator=(const Screenshot&) = default;
+Screenshot::Screenshot(Screenshot&&) noexcept = default;
+Screenshot& Screenshot::operator=(Screenshot&&) = default;
+
+bool Screenshot::operator==(const Screenshot& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(jpg_image_, other.jpg_image_);
+}
+
+bool Screenshot::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* jpg_image */:
+        field.get(&jpg_image_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string Screenshot::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> Screenshot::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void Screenshot::Serialize(::protozero::Message* msg) const {
+  // Field 1: jpg_image
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, jpg_image_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/source_location.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/source_location.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+SourceLocation::SourceLocation() = default;
+SourceLocation::~SourceLocation() = default;
+SourceLocation::SourceLocation(const SourceLocation&) = default;
+SourceLocation& SourceLocation::operator=(const SourceLocation&) = default;
+SourceLocation::SourceLocation(SourceLocation&&) noexcept = default;
+SourceLocation& SourceLocation::operator=(SourceLocation&&) = default;
+
+bool SourceLocation::operator==(const SourceLocation& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(iid_, other.iid_)
+   && ::protozero::internal::gen_helpers::EqualsField(file_name_, other.file_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(function_name_, other.function_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(line_number_, other.line_number_);
+}
+
+bool SourceLocation::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* iid */:
+        field.get(&iid_);
+        break;
+      case 2 /* file_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &file_name_);
+        break;
+      case 3 /* function_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &function_name_);
+        break;
+      case 4 /* line_number */:
+        field.get(&line_number_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string SourceLocation::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> SourceLocation::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void SourceLocation::Serialize(::protozero::Message* msg) const {
+  // Field 1: iid
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, iid_, msg);
+  }
+
+  // Field 2: file_name
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, file_name_, msg);
+  }
+
+  // Field 3: function_name
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeString(3, function_name_, msg);
+  }
+
+  // Field 4: line_number
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, line_number_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+UnsymbolizedSourceLocation::UnsymbolizedSourceLocation() = default;
+UnsymbolizedSourceLocation::~UnsymbolizedSourceLocation() = default;
+UnsymbolizedSourceLocation::UnsymbolizedSourceLocation(const UnsymbolizedSourceLocation&) = default;
+UnsymbolizedSourceLocation& UnsymbolizedSourceLocation::operator=(const UnsymbolizedSourceLocation&) = default;
+UnsymbolizedSourceLocation::UnsymbolizedSourceLocation(UnsymbolizedSourceLocation&&) noexcept = default;
+UnsymbolizedSourceLocation& UnsymbolizedSourceLocation::operator=(UnsymbolizedSourceLocation&&) = default;
+
+bool UnsymbolizedSourceLocation::operator==(const UnsymbolizedSourceLocation& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(iid_, other.iid_)
+   && ::protozero::internal::gen_helpers::EqualsField(mapping_id_, other.mapping_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(rel_pc_, other.rel_pc_);
+}
+
+bool UnsymbolizedSourceLocation::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* iid */:
+        field.get(&iid_);
+        break;
+      case 2 /* mapping_id */:
+        field.get(&mapping_id_);
+        break;
+      case 3 /* rel_pc */:
+        field.get(&rel_pc_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string UnsymbolizedSourceLocation::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> UnsymbolizedSourceLocation::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void UnsymbolizedSourceLocation::Serialize(::protozero::Message* msg) const {
+  // Field 1: iid
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, iid_, msg);
+  }
+
+  // Field 2: mapping_id
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, mapping_id_, msg);
+  }
+
+  // Field 3: rel_pc
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, rel_pc_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/task_execution.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/task_execution.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+TaskExecution::TaskExecution() = default;
+TaskExecution::~TaskExecution() = default;
+TaskExecution::TaskExecution(const TaskExecution&) = default;
+TaskExecution& TaskExecution::operator=(const TaskExecution&) = default;
+TaskExecution::TaskExecution(TaskExecution&&) noexcept = default;
+TaskExecution& TaskExecution::operator=(TaskExecution&&) = default;
+
+bool TaskExecution::operator==(const TaskExecution& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(posted_from_iid_, other.posted_from_iid_);
+}
+
+bool TaskExecution::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* posted_from_iid */:
+        field.get(&posted_from_iid_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TaskExecution::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TaskExecution::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TaskExecution::Serialize(::protozero::Message* msg) const {
+  // Field 1: posted_from_iid
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, posted_from_iid_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/thread_descriptor.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/thread_descriptor.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ThreadDescriptor::ThreadDescriptor() = default;
+ThreadDescriptor::~ThreadDescriptor() = default;
+ThreadDescriptor::ThreadDescriptor(const ThreadDescriptor&) = default;
+ThreadDescriptor& ThreadDescriptor::operator=(const ThreadDescriptor&) = default;
+ThreadDescriptor::ThreadDescriptor(ThreadDescriptor&&) noexcept = default;
+ThreadDescriptor& ThreadDescriptor::operator=(ThreadDescriptor&&) = default;
+
+bool ThreadDescriptor::operator==(const ThreadDescriptor& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(pid_, other.pid_)
+   && ::protozero::internal::gen_helpers::EqualsField(tid_, other.tid_)
+   && ::protozero::internal::gen_helpers::EqualsField(thread_name_, other.thread_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(chrome_thread_type_, other.chrome_thread_type_)
+   && ::protozero::internal::gen_helpers::EqualsField(reference_timestamp_us_, other.reference_timestamp_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(reference_thread_time_us_, other.reference_thread_time_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(reference_thread_instruction_count_, other.reference_thread_instruction_count_)
+   && ::protozero::internal::gen_helpers::EqualsField(legacy_sort_index_, other.legacy_sort_index_);
+}
+
+bool ThreadDescriptor::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* pid */:
+        field.get(&pid_);
+        break;
+      case 2 /* tid */:
+        field.get(&tid_);
+        break;
+      case 5 /* thread_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &thread_name_);
+        break;
+      case 4 /* chrome_thread_type */:
+        field.get(&chrome_thread_type_);
+        break;
+      case 6 /* reference_timestamp_us */:
+        field.get(&reference_timestamp_us_);
+        break;
+      case 7 /* reference_thread_time_us */:
+        field.get(&reference_thread_time_us_);
+        break;
+      case 8 /* reference_thread_instruction_count */:
+        field.get(&reference_thread_instruction_count_);
+        break;
+      case 3 /* legacy_sort_index */:
+        field.get(&legacy_sort_index_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ThreadDescriptor::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ThreadDescriptor::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ThreadDescriptor::Serialize(::protozero::Message* msg) const {
+  // Field 1: pid
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, pid_, msg);
+  }
+
+  // Field 2: tid
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, tid_, msg);
+  }
+
+  // Field 5: thread_name
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeString(5, thread_name_, msg);
+  }
+
+  // Field 4: chrome_thread_type
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, chrome_thread_type_, msg);
+  }
+
+  // Field 6: reference_timestamp_us
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, reference_timestamp_us_, msg);
+  }
+
+  // Field 7: reference_thread_time_us
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(7, reference_thread_time_us_, msg);
+  }
+
+  // Field 8: reference_thread_instruction_count
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(8, reference_thread_instruction_count_, msg);
+  }
+
+  // Field 3: legacy_sort_index
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, legacy_sort_index_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/track_descriptor.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/counter_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/thread_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/process_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_thread_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_process_descriptor.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+TrackDescriptor::TrackDescriptor() = default;
+TrackDescriptor::~TrackDescriptor() = default;
+TrackDescriptor::TrackDescriptor(const TrackDescriptor&) = default;
+TrackDescriptor& TrackDescriptor::operator=(const TrackDescriptor&) = default;
+TrackDescriptor::TrackDescriptor(TrackDescriptor&&) noexcept = default;
+TrackDescriptor& TrackDescriptor::operator=(TrackDescriptor&&) = default;
+
+bool TrackDescriptor::operator==(const TrackDescriptor& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(uuid_, other.uuid_)
+   && ::protozero::internal::gen_helpers::EqualsField(parent_uuid_, other.parent_uuid_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(process_, other.process_)
+   && ::protozero::internal::gen_helpers::EqualsField(chrome_process_, other.chrome_process_)
+   && ::protozero::internal::gen_helpers::EqualsField(thread_, other.thread_)
+   && ::protozero::internal::gen_helpers::EqualsField(chrome_thread_, other.chrome_thread_)
+   && ::protozero::internal::gen_helpers::EqualsField(counter_, other.counter_)
+   && ::protozero::internal::gen_helpers::EqualsField(disallow_merging_with_system_tracks_, other.disallow_merging_with_system_tracks_);
+}
+
+bool TrackDescriptor::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* uuid */:
+        field.get(&uuid_);
+        break;
+      case 5 /* parent_uuid */:
+        field.get(&parent_uuid_);
+        break;
+      case 2 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 3 /* process */:
+        (*process_).ParseFromArray(field.data(), field.size());
+        break;
+      case 6 /* chrome_process */:
+        (*chrome_process_).ParseFromArray(field.data(), field.size());
+        break;
+      case 4 /* thread */:
+        (*thread_).ParseFromArray(field.data(), field.size());
+        break;
+      case 7 /* chrome_thread */:
+        (*chrome_thread_).ParseFromArray(field.data(), field.size());
+        break;
+      case 8 /* counter */:
+        (*counter_).ParseFromArray(field.data(), field.size());
+        break;
+      case 9 /* disallow_merging_with_system_tracks */:
+        field.get(&disallow_merging_with_system_tracks_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TrackDescriptor::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TrackDescriptor::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TrackDescriptor::Serialize(::protozero::Message* msg) const {
+  // Field 1: uuid
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, uuid_, msg);
+  }
+
+  // Field 5: parent_uuid
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, parent_uuid_, msg);
+  }
+
+  // Field 2: name
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, name_, msg);
+  }
+
+  // Field 3: process
+  if (_has_field_[3]) {
+    (*process_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
+  }
+
+  // Field 6: chrome_process
+  if (_has_field_[6]) {
+    (*chrome_process_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
+  }
+
+  // Field 4: thread
+  if (_has_field_[4]) {
+    (*thread_).Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
+  }
+
+  // Field 7: chrome_thread
+  if (_has_field_[7]) {
+    (*chrome_thread_).Serialize(msg->BeginNestedMessage<::protozero::Message>(7));
+  }
+
+  // Field 8: counter
+  if (_has_field_[8]) {
+    (*counter_).Serialize(msg->BeginNestedMessage<::protozero::Message>(8));
+  }
+
+  // Field 9: disallow_merging_with_system_tracks
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(9, disallow_merging_with_system_tracks_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/track_event.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_event.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/source_location.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/screenshot.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/pixel_modem.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_window_handle_event_info.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_user_event.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_mojo_event_info.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_message_pump.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_legacy_ipc.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_latency_info.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_keyed_service.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_histogram_sample.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_frame_reporter.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_content_settings_event_info.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_application_state_info.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_active_processes.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/task_execution.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/log_message.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/debug_annotation.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+EventName::EventName() = default;
+EventName::~EventName() = default;
+EventName::EventName(const EventName&) = default;
+EventName& EventName::operator=(const EventName&) = default;
+EventName::EventName(EventName&&) noexcept = default;
+EventName& EventName::operator=(EventName&&) = default;
+
+bool EventName::operator==(const EventName& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(iid_, other.iid_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_);
+}
+
+bool EventName::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* iid */:
+        field.get(&iid_);
+        break;
+      case 2 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string EventName::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> EventName::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void EventName::Serialize(::protozero::Message* msg) const {
+  // Field 1: iid
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, iid_, msg);
+  }
+
+  // Field 2: name
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, name_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+EventCategory::EventCategory() = default;
+EventCategory::~EventCategory() = default;
+EventCategory::EventCategory(const EventCategory&) = default;
+EventCategory& EventCategory::operator=(const EventCategory&) = default;
+EventCategory::EventCategory(EventCategory&&) noexcept = default;
+EventCategory& EventCategory::operator=(EventCategory&&) = default;
+
+bool EventCategory::operator==(const EventCategory& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(iid_, other.iid_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_);
+}
+
+bool EventCategory::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* iid */:
+        field.get(&iid_);
+        break;
+      case 2 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string EventCategory::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> EventCategory::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void EventCategory::Serialize(::protozero::Message* msg) const {
+  // Field 1: iid
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, iid_, msg);
+  }
+
+  // Field 2: name
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, name_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TrackEventDefaults::TrackEventDefaults() = default;
+TrackEventDefaults::~TrackEventDefaults() = default;
+TrackEventDefaults::TrackEventDefaults(const TrackEventDefaults&) = default;
+TrackEventDefaults& TrackEventDefaults::operator=(const TrackEventDefaults&) = default;
+TrackEventDefaults::TrackEventDefaults(TrackEventDefaults&&) noexcept = default;
+TrackEventDefaults& TrackEventDefaults::operator=(TrackEventDefaults&&) = default;
+
+bool TrackEventDefaults::operator==(const TrackEventDefaults& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(track_uuid_, other.track_uuid_)
+   && ::protozero::internal::gen_helpers::EqualsField(extra_counter_track_uuids_, other.extra_counter_track_uuids_)
+   && ::protozero::internal::gen_helpers::EqualsField(extra_double_counter_track_uuids_, other.extra_double_counter_track_uuids_);
+}
+
+bool TrackEventDefaults::ParseFromArray(const void* raw, size_t size) {
+  extra_counter_track_uuids_.clear();
+  extra_double_counter_track_uuids_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 11 /* track_uuid */:
+        field.get(&track_uuid_);
+        break;
+      case 31 /* extra_counter_track_uuids */:
+        extra_counter_track_uuids_.emplace_back();
+        field.get(&extra_counter_track_uuids_.back());
+        break;
+      case 45 /* extra_double_counter_track_uuids */:
+        extra_double_counter_track_uuids_.emplace_back();
+        field.get(&extra_double_counter_track_uuids_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TrackEventDefaults::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TrackEventDefaults::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TrackEventDefaults::Serialize(::protozero::Message* msg) const {
+  // Field 11: track_uuid
+  if (_has_field_[11]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(11, track_uuid_, msg);
+  }
+
+  // Field 31: extra_counter_track_uuids
+  for (auto& it : extra_counter_track_uuids_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(31, it, msg);
+  }
+
+  // Field 45: extra_double_counter_track_uuids
+  for (auto& it : extra_double_counter_track_uuids_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(45, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TrackEvent::TrackEvent() = default;
+TrackEvent::~TrackEvent() = default;
+TrackEvent::TrackEvent(const TrackEvent&) = default;
+TrackEvent& TrackEvent::operator=(const TrackEvent&) = default;
+TrackEvent::TrackEvent(TrackEvent&&) noexcept = default;
+TrackEvent& TrackEvent::operator=(TrackEvent&&) = default;
+
+bool TrackEvent::operator==(const TrackEvent& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(category_iids_, other.category_iids_)
+   && ::protozero::internal::gen_helpers::EqualsField(categories_, other.categories_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_iid_, other.name_iid_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(type_, other.type_)
+   && ::protozero::internal::gen_helpers::EqualsField(track_uuid_, other.track_uuid_)
+   && ::protozero::internal::gen_helpers::EqualsField(counter_value_, other.counter_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(double_counter_value_, other.double_counter_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(extra_counter_track_uuids_, other.extra_counter_track_uuids_)
+   && ::protozero::internal::gen_helpers::EqualsField(extra_counter_values_, other.extra_counter_values_)
+   && ::protozero::internal::gen_helpers::EqualsField(extra_double_counter_track_uuids_, other.extra_double_counter_track_uuids_)
+   && ::protozero::internal::gen_helpers::EqualsField(extra_double_counter_values_, other.extra_double_counter_values_)
+   && ::protozero::internal::gen_helpers::EqualsField(flow_ids_old_, other.flow_ids_old_)
+   && ::protozero::internal::gen_helpers::EqualsField(flow_ids_, other.flow_ids_)
+   && ::protozero::internal::gen_helpers::EqualsField(terminating_flow_ids_old_, other.terminating_flow_ids_old_)
+   && ::protozero::internal::gen_helpers::EqualsField(terminating_flow_ids_, other.terminating_flow_ids_)
+   && ::protozero::internal::gen_helpers::EqualsField(debug_annotations_, other.debug_annotations_)
+   && ::protozero::internal::gen_helpers::EqualsField(task_execution_, other.task_execution_)
+   && ::protozero::internal::gen_helpers::EqualsField(log_message_, other.log_message_)
+   && ::protozero::internal::gen_helpers::EqualsField(cc_scheduler_state_, other.cc_scheduler_state_)
+   && ::protozero::internal::gen_helpers::EqualsField(chrome_user_event_, other.chrome_user_event_)
+   && ::protozero::internal::gen_helpers::EqualsField(chrome_keyed_service_, other.chrome_keyed_service_)
+   && ::protozero::internal::gen_helpers::EqualsField(chrome_legacy_ipc_, other.chrome_legacy_ipc_)
+   && ::protozero::internal::gen_helpers::EqualsField(chrome_histogram_sample_, other.chrome_histogram_sample_)
+   && ::protozero::internal::gen_helpers::EqualsField(chrome_latency_info_, other.chrome_latency_info_)
+   && ::protozero::internal::gen_helpers::EqualsField(chrome_frame_reporter_, other.chrome_frame_reporter_)
+   && ::protozero::internal::gen_helpers::EqualsField(chrome_application_state_info_, other.chrome_application_state_info_)
+   && ::protozero::internal::gen_helpers::EqualsField(chrome_renderer_scheduler_state_, other.chrome_renderer_scheduler_state_)
+   && ::protozero::internal::gen_helpers::EqualsField(chrome_window_handle_event_info_, other.chrome_window_handle_event_info_)
+   && ::protozero::internal::gen_helpers::EqualsField(chrome_content_settings_event_info_, other.chrome_content_settings_event_info_)
+   && ::protozero::internal::gen_helpers::EqualsField(chrome_active_processes_, other.chrome_active_processes_)
+   && ::protozero::internal::gen_helpers::EqualsField(screenshot_, other.screenshot_)
+   && ::protozero::internal::gen_helpers::EqualsField(pixel_modem_event_insight_, other.pixel_modem_event_insight_)
+   && ::protozero::internal::gen_helpers::EqualsField(source_location_, other.source_location_)
+   && ::protozero::internal::gen_helpers::EqualsField(source_location_iid_, other.source_location_iid_)
+   && ::protozero::internal::gen_helpers::EqualsField(chrome_message_pump_, other.chrome_message_pump_)
+   && ::protozero::internal::gen_helpers::EqualsField(chrome_mojo_event_info_, other.chrome_mojo_event_info_)
+   && ::protozero::internal::gen_helpers::EqualsField(timestamp_delta_us_, other.timestamp_delta_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(timestamp_absolute_us_, other.timestamp_absolute_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(thread_time_delta_us_, other.thread_time_delta_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(thread_time_absolute_us_, other.thread_time_absolute_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(thread_instruction_count_delta_, other.thread_instruction_count_delta_)
+   && ::protozero::internal::gen_helpers::EqualsField(thread_instruction_count_absolute_, other.thread_instruction_count_absolute_)
+   && ::protozero::internal::gen_helpers::EqualsField(legacy_event_, other.legacy_event_);
+}
+
+int TrackEvent::debug_annotations_size() const { return static_cast<int>(debug_annotations_.size()); }
+void TrackEvent::clear_debug_annotations() { debug_annotations_.clear(); }
+DebugAnnotation* TrackEvent::add_debug_annotations() { debug_annotations_.emplace_back(); return &debug_annotations_.back(); }
+bool TrackEvent::ParseFromArray(const void* raw, size_t size) {
+  category_iids_.clear();
+  categories_.clear();
+  extra_counter_track_uuids_.clear();
+  extra_counter_values_.clear();
+  extra_double_counter_track_uuids_.clear();
+  extra_double_counter_values_.clear();
+  flow_ids_old_.clear();
+  flow_ids_.clear();
+  terminating_flow_ids_old_.clear();
+  terminating_flow_ids_.clear();
+  debug_annotations_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 3 /* category_iids */:
+        category_iids_.emplace_back();
+        field.get(&category_iids_.back());
+        break;
+      case 22 /* categories */:
+        categories_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &categories_.back());
+        break;
+      case 10 /* name_iid */:
+        field.get(&name_iid_);
+        break;
+      case 23 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 9 /* type */:
+        field.get(&type_);
+        break;
+      case 11 /* track_uuid */:
+        field.get(&track_uuid_);
+        break;
+      case 30 /* counter_value */:
+        field.get(&counter_value_);
+        break;
+      case 44 /* double_counter_value */:
+        field.get(&double_counter_value_);
+        break;
+      case 31 /* extra_counter_track_uuids */:
+        extra_counter_track_uuids_.emplace_back();
+        field.get(&extra_counter_track_uuids_.back());
+        break;
+      case 12 /* extra_counter_values */:
+        extra_counter_values_.emplace_back();
+        field.get(&extra_counter_values_.back());
+        break;
+      case 45 /* extra_double_counter_track_uuids */:
+        extra_double_counter_track_uuids_.emplace_back();
+        field.get(&extra_double_counter_track_uuids_.back());
+        break;
+      case 46 /* extra_double_counter_values */:
+        extra_double_counter_values_.emplace_back();
+        field.get(&extra_double_counter_values_.back());
+        break;
+      case 36 /* flow_ids_old */:
+        flow_ids_old_.emplace_back();
+        field.get(&flow_ids_old_.back());
+        break;
+      case 47 /* flow_ids */:
+        flow_ids_.emplace_back();
+        field.get(&flow_ids_.back());
+        break;
+      case 42 /* terminating_flow_ids_old */:
+        terminating_flow_ids_old_.emplace_back();
+        field.get(&terminating_flow_ids_old_.back());
+        break;
+      case 48 /* terminating_flow_ids */:
+        terminating_flow_ids_.emplace_back();
+        field.get(&terminating_flow_ids_.back());
+        break;
+      case 4 /* debug_annotations */:
+        debug_annotations_.emplace_back();
+        debug_annotations_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 5 /* task_execution */:
+        (*task_execution_).ParseFromArray(field.data(), field.size());
+        break;
+      case 21 /* log_message */:
+        (*log_message_).ParseFromArray(field.data(), field.size());
+        break;
+      case 24 /* cc_scheduler_state */:
+        (*cc_scheduler_state_).ParseFromArray(field.data(), field.size());
+        break;
+      case 25 /* chrome_user_event */:
+        (*chrome_user_event_).ParseFromArray(field.data(), field.size());
+        break;
+      case 26 /* chrome_keyed_service */:
+        (*chrome_keyed_service_).ParseFromArray(field.data(), field.size());
+        break;
+      case 27 /* chrome_legacy_ipc */:
+        (*chrome_legacy_ipc_).ParseFromArray(field.data(), field.size());
+        break;
+      case 28 /* chrome_histogram_sample */:
+        (*chrome_histogram_sample_).ParseFromArray(field.data(), field.size());
+        break;
+      case 29 /* chrome_latency_info */:
+        (*chrome_latency_info_).ParseFromArray(field.data(), field.size());
+        break;
+      case 32 /* chrome_frame_reporter */:
+        (*chrome_frame_reporter_).ParseFromArray(field.data(), field.size());
+        break;
+      case 39 /* chrome_application_state_info */:
+        (*chrome_application_state_info_).ParseFromArray(field.data(), field.size());
+        break;
+      case 40 /* chrome_renderer_scheduler_state */:
+        (*chrome_renderer_scheduler_state_).ParseFromArray(field.data(), field.size());
+        break;
+      case 41 /* chrome_window_handle_event_info */:
+        (*chrome_window_handle_event_info_).ParseFromArray(field.data(), field.size());
+        break;
+      case 43 /* chrome_content_settings_event_info */:
+        (*chrome_content_settings_event_info_).ParseFromArray(field.data(), field.size());
+        break;
+      case 49 /* chrome_active_processes */:
+        (*chrome_active_processes_).ParseFromArray(field.data(), field.size());
+        break;
+      case 50 /* screenshot */:
+        (*screenshot_).ParseFromArray(field.data(), field.size());
+        break;
+      case 51 /* pixel_modem_event_insight */:
+        (*pixel_modem_event_insight_).ParseFromArray(field.data(), field.size());
+        break;
+      case 33 /* source_location */:
+        (*source_location_).ParseFromArray(field.data(), field.size());
+        break;
+      case 34 /* source_location_iid */:
+        field.get(&source_location_iid_);
+        break;
+      case 35 /* chrome_message_pump */:
+        (*chrome_message_pump_).ParseFromArray(field.data(), field.size());
+        break;
+      case 38 /* chrome_mojo_event_info */:
+        (*chrome_mojo_event_info_).ParseFromArray(field.data(), field.size());
+        break;
+      case 1 /* timestamp_delta_us */:
+        field.get(&timestamp_delta_us_);
+        break;
+      case 16 /* timestamp_absolute_us */:
+        field.get(&timestamp_absolute_us_);
+        break;
+      case 2 /* thread_time_delta_us */:
+        field.get(&thread_time_delta_us_);
+        break;
+      case 17 /* thread_time_absolute_us */:
+        field.get(&thread_time_absolute_us_);
+        break;
+      case 8 /* thread_instruction_count_delta */:
+        field.get(&thread_instruction_count_delta_);
+        break;
+      case 20 /* thread_instruction_count_absolute */:
+        field.get(&thread_instruction_count_absolute_);
+        break;
+      case 6 /* legacy_event */:
+        (*legacy_event_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TrackEvent::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TrackEvent::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TrackEvent::Serialize(::protozero::Message* msg) const {
+  // Field 3: category_iids
+  for (auto& it : category_iids_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, it, msg);
+  }
+
+  // Field 22: categories
+  for (auto& it : categories_) {
+    ::protozero::internal::gen_helpers::SerializeString(22, it, msg);
+  }
+
+  // Field 10: name_iid
+  if (_has_field_[10]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(10, name_iid_, msg);
+  }
+
+  // Field 23: name
+  if (_has_field_[23]) {
+    ::protozero::internal::gen_helpers::SerializeString(23, name_, msg);
+  }
+
+  // Field 9: type
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(9, type_, msg);
+  }
+
+  // Field 11: track_uuid
+  if (_has_field_[11]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(11, track_uuid_, msg);
+  }
+
+  // Field 30: counter_value
+  if (_has_field_[30]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(30, counter_value_, msg);
+  }
+
+  // Field 44: double_counter_value
+  if (_has_field_[44]) {
+    ::protozero::internal::gen_helpers::SerializeFixed(44, double_counter_value_, msg);
+  }
+
+  // Field 31: extra_counter_track_uuids
+  for (auto& it : extra_counter_track_uuids_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(31, it, msg);
+  }
+
+  // Field 12: extra_counter_values
+  for (auto& it : extra_counter_values_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(12, it, msg);
+  }
+
+  // Field 45: extra_double_counter_track_uuids
+  for (auto& it : extra_double_counter_track_uuids_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(45, it, msg);
+  }
+
+  // Field 46: extra_double_counter_values
+  for (auto& it : extra_double_counter_values_) {
+    ::protozero::internal::gen_helpers::SerializeFixed(46, it, msg);
+  }
+
+  // Field 36: flow_ids_old
+  for (auto& it : flow_ids_old_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(36, it, msg);
+  }
+
+  // Field 47: flow_ids
+  for (auto& it : flow_ids_) {
+    ::protozero::internal::gen_helpers::SerializeFixed(47, it, msg);
+  }
+
+  // Field 42: terminating_flow_ids_old
+  for (auto& it : terminating_flow_ids_old_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(42, it, msg);
+  }
+
+  // Field 48: terminating_flow_ids
+  for (auto& it : terminating_flow_ids_) {
+    ::protozero::internal::gen_helpers::SerializeFixed(48, it, msg);
+  }
+
+  // Field 4: debug_annotations
+  for (auto& it : debug_annotations_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
+  }
+
+  // Field 5: task_execution
+  if (_has_field_[5]) {
+    (*task_execution_).Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
+  }
+
+  // Field 21: log_message
+  if (_has_field_[21]) {
+    (*log_message_).Serialize(msg->BeginNestedMessage<::protozero::Message>(21));
+  }
+
+  // Field 24: cc_scheduler_state
+  if (_has_field_[24]) {
+    (*cc_scheduler_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(24));
+  }
+
+  // Field 25: chrome_user_event
+  if (_has_field_[25]) {
+    (*chrome_user_event_).Serialize(msg->BeginNestedMessage<::protozero::Message>(25));
+  }
+
+  // Field 26: chrome_keyed_service
+  if (_has_field_[26]) {
+    (*chrome_keyed_service_).Serialize(msg->BeginNestedMessage<::protozero::Message>(26));
+  }
+
+  // Field 27: chrome_legacy_ipc
+  if (_has_field_[27]) {
+    (*chrome_legacy_ipc_).Serialize(msg->BeginNestedMessage<::protozero::Message>(27));
+  }
+
+  // Field 28: chrome_histogram_sample
+  if (_has_field_[28]) {
+    (*chrome_histogram_sample_).Serialize(msg->BeginNestedMessage<::protozero::Message>(28));
+  }
+
+  // Field 29: chrome_latency_info
+  if (_has_field_[29]) {
+    (*chrome_latency_info_).Serialize(msg->BeginNestedMessage<::protozero::Message>(29));
+  }
+
+  // Field 32: chrome_frame_reporter
+  if (_has_field_[32]) {
+    (*chrome_frame_reporter_).Serialize(msg->BeginNestedMessage<::protozero::Message>(32));
+  }
+
+  // Field 39: chrome_application_state_info
+  if (_has_field_[39]) {
+    (*chrome_application_state_info_).Serialize(msg->BeginNestedMessage<::protozero::Message>(39));
+  }
+
+  // Field 40: chrome_renderer_scheduler_state
+  if (_has_field_[40]) {
+    (*chrome_renderer_scheduler_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(40));
+  }
+
+  // Field 41: chrome_window_handle_event_info
+  if (_has_field_[41]) {
+    (*chrome_window_handle_event_info_).Serialize(msg->BeginNestedMessage<::protozero::Message>(41));
+  }
+
+  // Field 43: chrome_content_settings_event_info
+  if (_has_field_[43]) {
+    (*chrome_content_settings_event_info_).Serialize(msg->BeginNestedMessage<::protozero::Message>(43));
+  }
+
+  // Field 49: chrome_active_processes
+  if (_has_field_[49]) {
+    (*chrome_active_processes_).Serialize(msg->BeginNestedMessage<::protozero::Message>(49));
+  }
+
+  // Field 50: screenshot
+  if (_has_field_[50]) {
+    (*screenshot_).Serialize(msg->BeginNestedMessage<::protozero::Message>(50));
+  }
+
+  // Field 51: pixel_modem_event_insight
+  if (_has_field_[51]) {
+    (*pixel_modem_event_insight_).Serialize(msg->BeginNestedMessage<::protozero::Message>(51));
+  }
+
+  // Field 33: source_location
+  if (_has_field_[33]) {
+    (*source_location_).Serialize(msg->BeginNestedMessage<::protozero::Message>(33));
+  }
+
+  // Field 34: source_location_iid
+  if (_has_field_[34]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(34, source_location_iid_, msg);
+  }
+
+  // Field 35: chrome_message_pump
+  if (_has_field_[35]) {
+    (*chrome_message_pump_).Serialize(msg->BeginNestedMessage<::protozero::Message>(35));
+  }
+
+  // Field 38: chrome_mojo_event_info
+  if (_has_field_[38]) {
+    (*chrome_mojo_event_info_).Serialize(msg->BeginNestedMessage<::protozero::Message>(38));
+  }
+
+  // Field 1: timestamp_delta_us
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, timestamp_delta_us_, msg);
+  }
+
+  // Field 16: timestamp_absolute_us
+  if (_has_field_[16]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(16, timestamp_absolute_us_, msg);
+  }
+
+  // Field 2: thread_time_delta_us
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, thread_time_delta_us_, msg);
+  }
+
+  // Field 17: thread_time_absolute_us
+  if (_has_field_[17]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(17, thread_time_absolute_us_, msg);
+  }
+
+  // Field 8: thread_instruction_count_delta
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(8, thread_instruction_count_delta_, msg);
+  }
+
+  // Field 20: thread_instruction_count_absolute
+  if (_has_field_[20]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(20, thread_instruction_count_absolute_, msg);
+  }
+
+  // Field 6: legacy_event
+  if (_has_field_[6]) {
+    (*legacy_event_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TrackEvent_LegacyEvent::TrackEvent_LegacyEvent() = default;
+TrackEvent_LegacyEvent::~TrackEvent_LegacyEvent() = default;
+TrackEvent_LegacyEvent::TrackEvent_LegacyEvent(const TrackEvent_LegacyEvent&) = default;
+TrackEvent_LegacyEvent& TrackEvent_LegacyEvent::operator=(const TrackEvent_LegacyEvent&) = default;
+TrackEvent_LegacyEvent::TrackEvent_LegacyEvent(TrackEvent_LegacyEvent&&) noexcept = default;
+TrackEvent_LegacyEvent& TrackEvent_LegacyEvent::operator=(TrackEvent_LegacyEvent&&) = default;
+
+bool TrackEvent_LegacyEvent::operator==(const TrackEvent_LegacyEvent& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_iid_, other.name_iid_)
+   && ::protozero::internal::gen_helpers::EqualsField(phase_, other.phase_)
+   && ::protozero::internal::gen_helpers::EqualsField(duration_us_, other.duration_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(thread_duration_us_, other.thread_duration_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(thread_instruction_delta_, other.thread_instruction_delta_)
+   && ::protozero::internal::gen_helpers::EqualsField(unscoped_id_, other.unscoped_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(local_id_, other.local_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(global_id_, other.global_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(id_scope_, other.id_scope_)
+   && ::protozero::internal::gen_helpers::EqualsField(use_async_tts_, other.use_async_tts_)
+   && ::protozero::internal::gen_helpers::EqualsField(bind_id_, other.bind_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(bind_to_enclosing_, other.bind_to_enclosing_)
+   && ::protozero::internal::gen_helpers::EqualsField(flow_direction_, other.flow_direction_)
+   && ::protozero::internal::gen_helpers::EqualsField(instant_event_scope_, other.instant_event_scope_)
+   && ::protozero::internal::gen_helpers::EqualsField(pid_override_, other.pid_override_)
+   && ::protozero::internal::gen_helpers::EqualsField(tid_override_, other.tid_override_);
+}
+
+bool TrackEvent_LegacyEvent::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name_iid */:
+        field.get(&name_iid_);
+        break;
+      case 2 /* phase */:
+        field.get(&phase_);
+        break;
+      case 3 /* duration_us */:
+        field.get(&duration_us_);
+        break;
+      case 4 /* thread_duration_us */:
+        field.get(&thread_duration_us_);
+        break;
+      case 15 /* thread_instruction_delta */:
+        field.get(&thread_instruction_delta_);
+        break;
+      case 6 /* unscoped_id */:
+        field.get(&unscoped_id_);
+        break;
+      case 10 /* local_id */:
+        field.get(&local_id_);
+        break;
+      case 11 /* global_id */:
+        field.get(&global_id_);
+        break;
+      case 7 /* id_scope */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &id_scope_);
+        break;
+      case 9 /* use_async_tts */:
+        field.get(&use_async_tts_);
+        break;
+      case 8 /* bind_id */:
+        field.get(&bind_id_);
+        break;
+      case 12 /* bind_to_enclosing */:
+        field.get(&bind_to_enclosing_);
+        break;
+      case 13 /* flow_direction */:
+        field.get(&flow_direction_);
+        break;
+      case 14 /* instant_event_scope */:
+        field.get(&instant_event_scope_);
+        break;
+      case 18 /* pid_override */:
+        field.get(&pid_override_);
+        break;
+      case 19 /* tid_override */:
+        field.get(&tid_override_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TrackEvent_LegacyEvent::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TrackEvent_LegacyEvent::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TrackEvent_LegacyEvent::Serialize(::protozero::Message* msg) const {
+  // Field 1: name_iid
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, name_iid_, msg);
+  }
+
+  // Field 2: phase
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, phase_, msg);
+  }
+
+  // Field 3: duration_us
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, duration_us_, msg);
+  }
+
+  // Field 4: thread_duration_us
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, thread_duration_us_, msg);
+  }
+
+  // Field 15: thread_instruction_delta
+  if (_has_field_[15]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(15, thread_instruction_delta_, msg);
+  }
+
+  // Field 6: unscoped_id
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, unscoped_id_, msg);
+  }
+
+  // Field 10: local_id
+  if (_has_field_[10]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(10, local_id_, msg);
+  }
+
+  // Field 11: global_id
+  if (_has_field_[11]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(11, global_id_, msg);
+  }
+
+  // Field 7: id_scope
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeString(7, id_scope_, msg);
+  }
+
+  // Field 9: use_async_tts
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(9, use_async_tts_, msg);
+  }
+
+  // Field 8: bind_id
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(8, bind_id_, msg);
+  }
+
+  // Field 12: bind_to_enclosing
+  if (_has_field_[12]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(12, bind_to_enclosing_, msg);
+  }
+
+  // Field 13: flow_direction
+  if (_has_field_[13]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(13, flow_direction_, msg);
+  }
+
+  // Field 14: instant_event_scope
+  if (_has_field_[14]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(14, instant_event_scope_, msg);
+  }
+
+  // Field 18: pid_override
+  if (_has_field_[18]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(18, pid_override_, msg);
+  }
+
+  // Field 19: tid_override
+  if (_has_field_[19]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(19, tid_override_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/android_game_intervention_list_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/android_input_event_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/android_log_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/android_polled_state_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/android_sdk_sysprop_guard_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/android_system_property_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/network_trace_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/packages_list_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/pixel_modem_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/protolog_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/surfaceflinger_layers_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/surfaceflinger_transactions_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/ftrace/ftrace_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/gpu/gpu_counter_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/gpu/vulkan_memory_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/inode_file/inode_file_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/interceptors/console_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/power/android_power_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/process_stats/process_stats_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/profiling/heapprofd_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/profiling/java_hprof_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/profiling/perf_event_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/statsd/atom_ids.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/statsd/statsd_tracing_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/sys_stats/sys_stats_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/system_info/system_info.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/track_event/track_event_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/chrome/chrome_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/chrome/scenario_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/chrome/v8_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/data_source_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/etw/etw_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/interceptor_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/stress_test_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/test_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/trace_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/clock_snapshot.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/trace_uuid.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/trigger.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/system_info.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/etw/etw.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/etw/etw_event.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/etw/etw_event_bundle.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/filesystem/inode_file_map.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ftrace_event.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ftrace_event_bundle.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ftrace_stats.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/test_bundle_wrapper.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/generic.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/android_fs.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/binder.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/block.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/cgroup.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/clk.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/cma.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/compaction.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/cpuhp.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/cros_ec.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/dma_fence.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/dmabuf_heap.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/dpu.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/drm.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ext4.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/f2fs.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/fastrpc.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/fence.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/filemap.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ftrace.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/g2d.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/google_icc_trace.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/google_irm_trace.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/gpu_mem.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/gpu_scheduler.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/hyp.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/i2c.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ion.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ipi.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/irq.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/kmem.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/kvm.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/lowmemorykiller.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/lwis.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/mali.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/mdss.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/mm_event.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/net.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/oom.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/panel.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/perf_trace_counters.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/power.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/printk.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/raw_syscalls.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/regulator.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/rpm.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/samsung.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/sched.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/scm.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/sde.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/signal.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/skb.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/sock.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/sync.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/synthetic.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/systrace.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/task.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/tcp.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/thermal.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/trusty.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ufs.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/v4l2.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/virtio_gpu.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/virtio_video.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/vmscan.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/workqueue.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/perfetto/perfetto_metatrace.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/perfetto/tracing_service_event.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/power/android_energy_estimation_breakdown.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/power/android_entity_state_residency.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/power/battery_counters.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/power/power_rails.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ps/process_stats.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ps/process_tree.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/statsd/statsd_atom.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/sys_stats/sys_stats.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/system_info/cpu_info.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/translation/translation_table.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/remote_clock_sync.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/trace_packet_defaults.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/test_event.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/test_extensions.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/trace_packet.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/trace.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/extension_descriptor.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/memory_graph.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ui_state.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: src/tracing/trace_writer_base.cc
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
+
+namespace perfetto {
+
+// This destructor needs to be defined in a dedicated translation unit and
+// cannot be merged together with the other ones in virtual_destructors.cc.
+// This is because trace_writer_base.h/cc  is part of a separate target
+// (src/public:common) that is linked also by other part of the codebase.
+
+TraceWriterBase::~TraceWriterBase() = default;
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/core/clock_snapshots.cc
+// gen_amalgamated begin header: include/perfetto/tracing/core/clock_snapshots.h
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_CORE_CLOCK_SNAPSHOTS_H_
+#define INCLUDE_PERFETTO_TRACING_CORE_CLOCK_SNAPSHOTS_H_
+
+#include <cstdint>
+#include <vector>
+
+namespace perfetto {
+struct ClockReading {
+  ClockReading(uint32_t _clock_id, uint64_t _timestamp)
+      : clock_id(_clock_id), timestamp(_timestamp) {}
+  ClockReading() = default;
+
+  // Identifier of the clock domain (of type protos::pbzero::BuiltinClock).
+  uint32_t clock_id = 0;
+  // Clock reading as uint64_t.
+  uint64_t timestamp = 0;
+};
+
+using ClockSnapshotVector = std::vector<ClockReading>;
+
+// Takes snapshots of clock readings of all supported built-in clocks.
+ClockSnapshotVector CaptureClockSnapshots();
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_CORE_CLOCK_SNAPSHOTS_H_
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/core/clock_snapshots.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.pbzero.h"
+
+namespace perfetto {
+
+ClockSnapshotVector CaptureClockSnapshots() {
+  ClockSnapshotVector snapshot_data;
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) && \
+    !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) &&   \
+    !PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
+  struct {
+    clockid_t id;
+    protos::pbzero::BuiltinClock type;
+    struct timespec ts;
+  } clocks[] = {
+      {CLOCK_BOOTTIME, protos::pbzero::BUILTIN_CLOCK_BOOTTIME, {0, 0}},
+      {CLOCK_REALTIME_COARSE,
+       protos::pbzero::BUILTIN_CLOCK_REALTIME_COARSE,
+       {0, 0}},
+      {CLOCK_MONOTONIC_COARSE,
+       protos::pbzero::BUILTIN_CLOCK_MONOTONIC_COARSE,
+       {0, 0}},
+      {CLOCK_REALTIME, protos::pbzero::BUILTIN_CLOCK_REALTIME, {0, 0}},
+      {CLOCK_MONOTONIC, protos::pbzero::BUILTIN_CLOCK_MONOTONIC, {0, 0}},
+      {CLOCK_MONOTONIC_RAW,
+       protos::pbzero::BUILTIN_CLOCK_MONOTONIC_RAW,
+       {0, 0}},
+  };
+  // First snapshot all the clocks as atomically as we can.
+  for (auto& clock : clocks) {
+    if (clock_gettime(clock.id, &clock.ts) == -1)
+      PERFETTO_DLOG("clock_gettime failed for clock %d", clock.id);
+  }
+  for (auto& clock : clocks) {
+    snapshot_data.push_back(ClockReading(
+        static_cast<uint32_t>(clock.type),
+        static_cast<uint64_t>(base::FromPosixTimespec(clock.ts).count())));
+  }
+#else  // OS_APPLE || OS_WIN && OS_NACL
+  auto wall_time_ns = static_cast<uint64_t>(base::GetWallTimeNs().count());
+  // The default trace clock is boot time, so we always need to emit a path to
+  // it. However since we don't actually have a boot time source on these
+  // platforms, pretend that wall time equals boot time.
+  snapshot_data.push_back(
+      ClockReading(protos::pbzero::BUILTIN_CLOCK_BOOTTIME, wall_time_ns));
+  snapshot_data.push_back(
+      ClockReading(protos::pbzero::BUILTIN_CLOCK_MONOTONIC, wall_time_ns));
+#endif
+
+#if PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_X86_64)
+  // X86-specific but OS-independent TSC clocksource
+  snapshot_data.push_back(
+      ClockReading(protos::pbzero::BUILTIN_CLOCK_TSC, base::Rdtsc()));
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_X86_64)
+
+  return snapshot_data;
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/core/id_allocator.cc
+// gen_amalgamated begin header: src/tracing/core/id_allocator.h
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACING_CORE_ID_ALLOCATOR_H_
+#define SRC_TRACING_CORE_ID_ALLOCATOR_H_
+
+#include <stdint.h>
+
+#include <cstddef>
+#include <type_traits>
+#include <vector>
+
+namespace perfetto {
+
+// Handles assigment of IDs (int types) from a fixed-size pool.
+// Zero is not considered a valid ID.
+// The base class takes always a uint32_t and the derived class casts and checks
+// bounds at compile time. This is to avoid bloating code with different
+// instances of the main class for each size.
+class IdAllocatorGeneric {
+ public:
+  // |max_id| is inclusive.
+  explicit IdAllocatorGeneric(uint32_t max_id);
+  ~IdAllocatorGeneric();
+
+  // Returns an ID in the range [1, max_id] or 0 if no more ids are available.
+  uint32_t AllocateGeneric();
+  void FreeGeneric(uint32_t);
+
+  bool IsEmpty() const;
+
+ private:
+  IdAllocatorGeneric(const IdAllocatorGeneric&) = delete;
+  IdAllocatorGeneric& operator=(const IdAllocatorGeneric&) = delete;
+
+  const uint32_t max_id_;
+  uint32_t last_id_ = 0;
+  std::vector<bool> ids_;
+};
+
+template <typename T = uint32_t>
+class IdAllocator : public IdAllocatorGeneric {
+ public:
+  explicit IdAllocator(T end) : IdAllocatorGeneric(end) {
+    static_assert(std::is_integral<T>::value && std::is_unsigned<T>::value,
+                  "T must be an unsigned integer");
+    static_assert(sizeof(T) <= sizeof(uint32_t), "T is too big");
+  }
+
+  T Allocate() { return static_cast<T>(AllocateGeneric()); }
+
+  // Tries to allocate `n` IDs. Returns a vector of `n` valid IDs or an empty
+  // vector, if not enough IDs are available.
+  std::vector<T> AllocateMultiple(size_t n) {
+    std::vector<T> res;
+    res.reserve(n);
+    for (size_t i = 0; i < n; i++) {
+      T id = Allocate();
+      if (id) {
+        res.push_back(id);
+      } else {
+        for (T free_id : res) {
+          Free(free_id);
+        }
+        return {};
+      }
+    }
+    return res;
+  }
+
+  void Free(T id) { FreeGeneric(id); }
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_CORE_ID_ALLOCATOR_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/core/id_allocator.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+
+namespace perfetto {
+
+IdAllocatorGeneric::IdAllocatorGeneric(uint32_t max_id) : max_id_(max_id) {
+  PERFETTO_DCHECK(max_id > 1);
+}
+
+IdAllocatorGeneric::~IdAllocatorGeneric() = default;
+
+uint32_t IdAllocatorGeneric::AllocateGeneric() {
+  for (uint32_t ignored = 1; ignored <= max_id_; ignored++) {
+    last_id_ = last_id_ < max_id_ ? last_id_ + 1 : 1;
+    const auto id = last_id_;
+
+    // 0 is never a valid ID. So if we are looking for |id| == N and there are
+    // N or less elements in the vector, they must necessarily be all < N.
+    // e.g. if |id| == 4 and size() == 4, the vector will contain IDs 0,1,2,3.
+    if (id >= ids_.size()) {
+      ids_.resize(id + 1);
+      ids_[id] = true;
+      return id;
+    }
+
+    if (!ids_[id]) {
+      ids_[id] = true;
+      return id;
+    }
+  }
+  return 0;
+}
+
+void IdAllocatorGeneric::FreeGeneric(uint32_t id) {
+  if (id == 0 || id >= ids_.size() || !ids_[id]) {
+    PERFETTO_DFATAL("Invalid id.");
+    return;
+  }
+  ids_[id] = false;
+}
+
+bool IdAllocatorGeneric::IsEmpty() const {
+  for (auto id : ids_) {
+    if (id)
+      return false;
+  }
+  return true;
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/core/in_process_shared_memory.cc
+// gen_amalgamated begin header: src/tracing/core/in_process_shared_memory.h
+// gen_amalgamated begin header: include/perfetto/ext/tracing/core/shared_memory.h
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_H_
+#define INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_H_
+
+#include <stddef.h>
+
+#include <memory>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
+
+namespace perfetto {
+
+// An abstract interface that models the shared memory region shared between
+// Service and Producer. The concrete implementation of this is up to the
+// transport layer. This can be as simple as a malloc()-ed buffer, if both
+// Producer and Service are hosted in the same process, or some posix shared
+// memory for the out-of-process case (see src/unix_rpc).
+// Both this class and the Factory are subclassed by the transport layer, which
+// will attach platform specific fields to it (e.g., a unix file descriptor).
+class PERFETTO_EXPORT_COMPONENT SharedMemory {
+ public:
+  class PERFETTO_EXPORT_COMPONENT Factory {
+   public:
+    virtual ~Factory();
+    virtual std::unique_ptr<SharedMemory> CreateSharedMemory(size_t) = 0;
+  };
+
+  // The transport layer is expected to tear down the resource associated to
+  // this object region when destroyed.
+  virtual ~SharedMemory();
+
+  virtual void* start() const = 0;
+  virtual size_t size() const = 0;
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_H_
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACING_CORE_IN_PROCESS_SHARED_MEMORY_H_
+#define SRC_TRACING_CORE_IN_PROCESS_SHARED_MEMORY_H_
+
+#include <memory>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/paged_memory.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
+
+namespace perfetto {
+
+// An implementation of the ShareMemory interface that allocates memory that can
+// only be shared intra-process.
+class InProcessSharedMemory : public SharedMemory {
+ public:
+  static constexpr size_t kDefaultSize = 128 * 1024;
+
+  // Default ctor used for intra-process shmem between a producer and the
+  // service.
+  explicit InProcessSharedMemory(size_t size)
+      : mem_(base::PagedMemory::Allocate(size)) {}
+  ~InProcessSharedMemory() override;
+
+  static std::unique_ptr<InProcessSharedMemory> Create(
+      size_t size = kDefaultSize) {
+    return std::make_unique<InProcessSharedMemory>(size);
+  }
+
+  // SharedMemory implementation.
+  void* start() const override;
+  size_t size() const override;
+
+  class Factory : public SharedMemory::Factory {
+   public:
+    ~Factory() override;
+    std::unique_ptr<SharedMemory> CreateSharedMemory(size_t size) override {
+      return InProcessSharedMemory::Create(size);
+    }
+  };
+
+ private:
+  base::PagedMemory mem_;
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_CORE_IN_PROCESS_SHARED_MEMORY_H_
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/core/in_process_shared_memory.h"
+
+namespace perfetto {
+
+InProcessSharedMemory::~InProcessSharedMemory() = default;
+InProcessSharedMemory::Factory::~Factory() = default;
+
+void* InProcessSharedMemory::start() const {
+  return mem_.Get();
+}
+size_t InProcessSharedMemory::size() const {
+  return mem_.size();
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/core/null_trace_writer.cc
+// gen_amalgamated begin header: src/tracing/core/null_trace_writer.h
+// gen_amalgamated begin header: include/perfetto/ext/tracing/core/trace_writer.h
+// gen_amalgamated begin header: include/perfetto/ext/tracing/core/basic_types.h
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_BASIC_TYPES_H_
+#define INCLUDE_PERFETTO_EXT_TRACING_CORE_BASIC_TYPES_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/sys_types.h"
+
+namespace perfetto {
+
+// Unique within the scope of the tracing service.
+using TracingSessionID = uint64_t;
+
+// Unique within the scope of the tracing service.
+using ProducerID = uint16_t;
+
+// Unique within the scope of the tracing service.
+using DataSourceInstanceID = uint64_t;
+
+// Unique within the scope of a Producer.
+using WriterID = uint16_t;
+
+// Unique within the scope of the tracing service.
+using FlushRequestID = uint64_t;
+
+// Combines Producer and Writer ID in one word which can be used as key for
+// hashtables and other data structures.
+using ProducerAndWriterID = uint32_t;
+
+inline ProducerAndWriterID MkProducerAndWriterID(ProducerID p, WriterID w) {
+  static_assert(
+      sizeof(ProducerID) + sizeof(WriterID) == sizeof(ProducerAndWriterID),
+      "MkProducerAndWriterID() and GetProducerAndWriterID() need updating");
+  return (static_cast<ProducerAndWriterID>(p) << (sizeof(WriterID) * 8)) | w;
+}
+
+inline void GetProducerAndWriterID(ProducerAndWriterID x,
+                                   ProducerID* p,
+                                   WriterID* w) {
+  static constexpr auto mask = (1ull << (sizeof(WriterID) * 8)) - 1;
+  *w = static_cast<WriterID>(x & mask);
+  *p = static_cast<ProducerID>(x >> (sizeof(WriterID) * 8));
+}
+
+// We need one FD per producer and we are not going to be able to keep > 64k FDs
+// open in the service.
+static constexpr ProducerID kMaxProducerID = static_cast<ProducerID>(-1);
+
+// 1024 Writers per producer seems a resonable bound. This reduces the ability
+// to memory-DoS the service by having to keep track of too many writer IDs.
+static constexpr WriterID kMaxWriterID = static_cast<WriterID>((1 << 10) - 1);
+
+// Unique within the scope of a {ProducerID, WriterID} tuple.
+using ChunkID = uint32_t;
+static constexpr ChunkID kMaxChunkID = static_cast<ChunkID>(-1);
+
+// Unique within the scope of the tracing service.
+using BufferID = uint16_t;
+
+// Target buffer ID for SharedMemoryArbiter. Values up to max uint16_t are
+// equivalent to a bound BufferID. Values above max uint16_t are reservation IDs
+// for the target buffer of a startup trace writer. Reservation IDs will be
+// translated to actual BufferIDs after they are bound by
+// SharedMemoryArbiter::BindStartupTargetBuffer().
+// TODO(mohitms): Delete this type and use `struct {uint16 ; uint16;}` instead.
+using MaybeUnboundBufferID = uint32_t;
+
+// Keep this in sync with SharedMemoryABI::PageHeader::target_buffer.
+static constexpr BufferID kMaxTraceBufferID = static_cast<BufferID>(-1);
+
+// Unique within the scope of a tracing session.
+using PacketSequenceID = uint32_t;
+// Used for extra packets emitted by the service, such as statistics.
+static constexpr PacketSequenceID kServicePacketSequenceID = 1;
+static constexpr PacketSequenceID kMaxPacketSequenceID =
+    static_cast<PacketSequenceID>(-1);
+
+constexpr uint32_t kDefaultFlushTimeoutMs = 5000;
+
+// The special id 0xffff..ffff represents the tracing session with the highest
+// bugreport score. This is used for CloneSession(kBugreportSessionId).
+constexpr TracingSessionID kBugreportSessionId =
+    static_cast<TracingSessionID>(-1);
+
+// The ID of a machine in a multi-machine tracing session.
+using MachineID = base::MachineID;
+constexpr MachineID kDefaultMachineID = base::kDefaultMachineID;
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_BASIC_TYPES_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_WRITER_H_
+#define INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_WRITER_H_
+
+#include <functional>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
+
+namespace perfetto {
+
+namespace protos {
+namespace pbzero {
+class TracePacket;
+}  // namespace pbzero
+}  // namespace protos
+
+// See comments in include/perfetto/tracing/trace_writer_base.h
+class PERFETTO_EXPORT_COMPONENT TraceWriter : public TraceWriterBase {
+ public:
+  using TracePacketHandle =
+      protozero::MessageHandle<protos::pbzero::TracePacket>;
+
+  TraceWriter();
+  ~TraceWriter() override;
+
+  virtual WriterID writer_id() const = 0;
+
+ private:
+  TraceWriter(const TraceWriter&) = delete;
+  TraceWriter& operator=(const TraceWriter&) = delete;
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_WRITER_H_
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACING_CORE_NULL_TRACE_WRITER_H_
+#define SRC_TRACING_CORE_NULL_TRACE_WRITER_H_
+
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/root_message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_null_delegate.h"
+
+namespace perfetto {
+
+// A specialization of TraceWriter which no-ops all the writes routing them
+// into a fixed region of memory
+// See //include/perfetto/ext/tracing/core/trace_writer.h for docs.
+class NullTraceWriter : public TraceWriter {
+ public:
+  NullTraceWriter();
+  ~NullTraceWriter() override;
+
+  // TraceWriter implementation. See documentation in trace_writer.h.
+  // TracePacketHandle is defined in trace_writer.h
+  TracePacketHandle NewTracePacket() override;
+  void FinishTracePacket() override;
+  void Flush(std::function<void()> callback = {}) override;
+  WriterID writer_id() const override;
+  uint64_t written() const override;
+
+ private:
+  NullTraceWriter(const NullTraceWriter&) = delete;
+  NullTraceWriter& operator=(const NullTraceWriter&) = delete;
+
+  protozero::ScatteredStreamWriterNullDelegate delegate_;
+  protozero::ScatteredStreamWriter stream_;
+
+  // The packet returned via NewTracePacket(). It is owned by this class,
+  // TracePacketHandle has just a pointer to it.
+  std::unique_ptr<protozero::RootMessage<protos::pbzero::TracePacket>>
+      cur_packet_;
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_CORE_NULL_TRACE_WRITER_H_
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/core/null_trace_writer.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
+
+namespace perfetto {
+
+NullTraceWriter::NullTraceWriter() : delegate_(4096), stream_(&delegate_) {
+  cur_packet_.reset(new protozero::RootMessage<protos::pbzero::TracePacket>());
+  cur_packet_->Finalize();  // To avoid the DCHECK in NewTracePacket().
+}
+
+NullTraceWriter::~NullTraceWriter() {}
+
+void NullTraceWriter::Flush(std::function<void()> callback) {
+  // Flush() cannot be called in the middle of a TracePacket.
+  PERFETTO_CHECK(cur_packet_->is_finalized());
+
+  if (callback)
+    callback();
+}
+
+NullTraceWriter::TracePacketHandle NullTraceWriter::NewTracePacket() {
+  // If we hit this, the caller is calling NewTracePacket() without having
+  // finalized the previous packet.
+  PERFETTO_DCHECK(cur_packet_->is_finalized());
+  cur_packet_->Reset(&stream_);
+  return TraceWriter::TracePacketHandle(cur_packet_.get());
+}
+
+void NullTraceWriter::FinishTracePacket() {
+  cur_packet_->Finalize();
+}
+
+WriterID NullTraceWriter::writer_id() const {
+  return 0;
+}
+
+uint64_t NullTraceWriter::written() const {
+  return 0;
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/core/shared_memory_abi.cc
+// gen_amalgamated begin header: include/perfetto/ext/tracing/core/shared_memory_abi.h
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_ABI_H_
+#define INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_ABI_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <array>
+#include <atomic>
+#include <bitset>
+#include <thread>
+#include <type_traits>
+#include <utility>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+
+// This file defines the binary interface of the memory buffers shared between
+// Producer and Service. This is a long-term stable ABI and has to be backwards
+// compatible to deal with mismatching Producer and Service versions.
+//
+// Overview
+// --------
+// SMB := "Shared Memory Buffer".
+// In the most typical case of a multi-process architecture (i.e. Producer and
+// Service are hosted by different processes), a Producer means almost always
+// a "client process producing data" (almost: in some cases a process might host
+// > 1 Producer, if it links two libraries, independent of each other, that both
+// use Perfetto tracing).
+// The Service has one SMB for each Producer.
+// A producer has one or (typically) more data sources. They all share the same
+// SMB.
+// The SMB is a staging area to decouple data sources living in the Producer
+// and allow them to do non-blocking async writes.
+// The SMB is *not* the ultimate logging buffer seen by the Consumer. That one
+// is larger (~MBs) and not shared with Producers.
+// Each SMB is small, typically few KB. Its size is configurable by the producer
+// within a max limit of ~MB (see kMaxShmSize in tracing_service_impl.cc).
+// The SMB is partitioned into fixed-size Page(s). The size of the Pages are
+// determined by each Producer at connection time and cannot be changed.
+// Hence, different producers can have SMB(s) that have a different Page size
+// from each other, but the page size will be constant throughout all the
+// lifetime of the SMB.
+// Page(s) are partitioned by the Producer into variable size Chunk(s):
+//
+// +------------+      +--------------------------+
+// | Producer 1 |  <-> |      SMB 1 [~32K - 1MB]  |
+// +------------+      +--------+--------+--------+
+//                     |  Page  |  Page  |  Page  |
+//                     +--------+--------+--------+
+//                     | Chunk  |        | Chunk  |
+//                     +--------+  Chunk +--------+ <----+
+//                     | Chunk  |        | Chunk  |      |
+//                     +--------+--------+--------+      +---------------------+
+//                                                       |       Service       |
+// +------------+      +--------------------------+      +---------------------+
+// | Producer 2 |  <-> |      SMB 2 [~32K - 1MB]  |     /| large ring buffers  |
+// +------------+      +--------+--------+--------+ <--+ | (100K - several MB) |
+//                     |  Page  |  Page  |  Page  |      +---------------------+
+//                     +--------+--------+--------+
+//                     | Chunk  |        | Chunk  |
+//                     +--------+  Chunk +--------+
+//                     | Chunk  |        | Chunk  |
+//                     +--------+--------+--------+
+//
+// * Sizes of both SMB and ring buffers are purely indicative and decided at
+// configuration time by the Producer (for SMB sizes) and the Consumer (for the
+// final ring buffer size).
+
+// Page
+// ----
+// A page is a portion of the shared memory buffer and defines the granularity
+// of the interaction between the Producer and tracing Service. When scanning
+// the shared memory buffer to determine if something should be moved to the
+// central logging buffers, the Service most of the times looks at and moves
+// whole pages. Similarly, the Producer sends an IPC to invite the Service to
+// drain the shared memory buffer only when a whole page is filled.
+// Having fixed the total SMB size (hence the total memory overhead), the page
+// size is a triangular tradeoff between:
+// 1) IPC traffic: smaller pages -> more IPCs.
+// 2) Producer lock freedom: larger pages -> larger chunks -> data sources can
+//    write more data without needing to swap chunks and synchronize.
+// 3) Risk of write-starving the SMB: larger pages -> higher chance that the
+//    Service won't manage to drain them and the SMB remains full.
+// The page size, on the other side, has no implications on wasted memory due to
+// fragmentations (see Chunk below).
+// The size of the page is chosen by the Service at connection time and stays
+// fixed throughout all the lifetime of the Producer. Different producers (i.e.
+// ~ different client processes) can use different page sizes.
+// The page size must be an integer multiple of 4k (this is to allow VM page
+// stealing optimizations) and obviously has to be an integer divisor of the
+// total SMB size.
+
+// Chunk
+// -----
+// A chunk is a portion of a Page which is written and handled by a Producer.
+// A chunk contains a linear sequence of TracePacket(s) (the root proto).
+// A chunk cannot be written concurrently by two data sources. Protobufs must be
+// encoded as contiguous byte streams and cannot be interleaved. Therefore, on
+// the Producer side, a chunk is almost always owned exclusively by one thread
+// (% extremely peculiar slow-path cases).
+// Chunks are essentially single-writer single-thread lock-free arenas. Locking
+// happens only when a Chunk is full and a new one needs to be acquired.
+// Locking happens only within the scope of a Producer process. There is no
+// inter-process locking. The Producer cannot lock the Service and viceversa.
+// In the worst case, any of the two can starve the SMB, by marking all chunks
+// as either being read or written. But that has the only side effect of
+// losing the trace data.
+// The Producer can decide to partition each page into a number of limited
+// configurations (e.g., 1 page == 1 chunk, 1 page == 2 chunks and so on).
+
+// TracePacket
+// -----------
+// Is the atom of tracing. Putting aside pages and chunks a trace is merely a
+// sequence of TracePacket(s). TracePacket is the root protobuf message.
+// A TracePacket can span across several chunks (hence even across several
+// pages). A TracePacket can therefore be >> chunk size, >> page size and even
+// >> SMB size. The Chunk header carries metadata to deal with the TracePacket
+// splitting case.
+
+// Use only explicitly-sized types below. DO NOT use size_t or any architecture
+// dependent size (e.g. size_t) in the struct fields. This buffer will be read
+// and written by processes that have a different bitness in the same OS.
+// Instead it's fine to assume little-endianess. Big-endian is a dream we are
+// not currently pursuing.
+
+class SharedMemoryABI {
+ public:
+  static constexpr size_t kMinPageSize = 4 * 1024;
+
+  // This is due to Chunk::size being 16 bits.
+  static constexpr size_t kMaxPageSize = 64 * 1024;
+
+  // "14" is the max number that can be encoded in a 32 bit atomic word using
+  // 2 state bits per Chunk and leaving 4 bits for the page layout.
+  // See PageLayout below.
+  static constexpr size_t kMaxChunksPerPage = 14;
+
+  // Each TracePacket fragment in the Chunk is prefixed by a VarInt stating its
+  // size that is up to 4 bytes long. Since the size is often known after the
+  // fragment has been filled, the VarInt is often redundantly encoded (see
+  // proto_utils.h) to be exactly 4 bytes.
+  static constexpr size_t kPacketHeaderSize = 4;
+
+  // TraceWriter specifies this invalid packet/fragment size to signal to the
+  // service that a packet should be discarded, because the TraceWriter couldn't
+  // write its remaining fragments (e.g. because the SMB was exhausted).
+  static constexpr size_t kPacketSizeDropPacket =
+      protozero::proto_utils::kMaxMessageLength;
+
+  // Chunk states and transitions:
+  //    kChunkFree  <----------------+
+  //         |  (Producer)           |
+  //         V                       |
+  //  kChunkBeingWritten             |
+  //         |  (Producer)           |
+  //         V                       |
+  //  kChunkComplete                 |
+  //         |  (Service)            |
+  //         V                       |
+  //  kChunkBeingRead                |
+  //        |   (Service)            |
+  //        +------------------------+
+  //
+  // The ABI has an "emulation mode" for transports where shared memory isn't
+  // supported. In this mode, kChunkBeingRead is skipped. A chunk in the
+  // kChunkComplete state is released as free after the producer serializes
+  // chunk content to the protobuf message.
+  enum ChunkState : uint32_t {
+    // The Chunk is free. The Service shall never touch it, the Producer can
+    // acquire it and transition it into kChunkBeingWritten.
+    kChunkFree = 0,
+
+    // The Chunk is being used by the Producer and is not complete yet.
+    // The Service shall never touch kChunkBeingWritten pages.
+    kChunkBeingWritten = 1,
+
+    // The Service is moving the page into its non-shared ring buffer. The
+    // Producer shall never touch kChunkBeingRead pages.
+    kChunkBeingRead = 2,
+
+    // The Producer is done writing the page and won't touch it again. The
+    // Service can now move it to its non-shared ring buffer.
+    // kAllChunksComplete relies on this being == 3.
+    kChunkComplete = 3,
+  };
+  static constexpr const char* kChunkStateStr[] = {"Free", "BeingWritten",
+                                                   "BeingRead", "Complete"};
+
+  enum PageLayout : uint32_t {
+    // The page is fully free and has not been partitioned yet.
+    kPageNotPartitioned = 0,
+
+    // TODO(primiano): Aligning a chunk @ 16 bytes could allow to use faster
+    // intrinsics based on quad-word moves. Do the math and check what is the
+    // fragmentation loss.
+
+    // align4(X) := the largest integer N s.t. (N % 4) == 0 && N <= X.
+    // 8 == sizeof(PageHeader).
+    kPageDiv1 = 1,   // Only one chunk of size: PAGE_SIZE - 8.
+    kPageDiv2 = 2,   // Two chunks of size: align4((PAGE_SIZE - 8) / 2).
+    kPageDiv4 = 3,   // Four chunks of size: align4((PAGE_SIZE - 8) / 4).
+    kPageDiv7 = 4,   // Seven chunks of size: align4((PAGE_SIZE - 8) / 7).
+    kPageDiv14 = 5,  // Fourteen chunks of size: align4((PAGE_SIZE - 8) / 14).
+
+    // The rationale for 7 and 14 above is to maximize the page usage for the
+    // likely case of |page_size| == 4096:
+    // (((4096 - 8) / 14) % 4) == 0, while (((4096 - 8) / 16 % 4)) == 3. So
+    // Div16 would waste 3 * 16 = 48 bytes per page for chunk alignment gaps.
+
+    kPageDivReserved1 = 6,
+    kPageDivReserved2 = 7,
+    kNumPageLayouts = 8,
+  };
+
+  // Keep this consistent with the PageLayout enum above.
+  static constexpr uint32_t kNumChunksForLayout[] = {0, 1, 2, 4, 7, 14, 0, 0};
+
+  enum class ShmemMode {
+    // The default mode, where the shared buffer is visible to both the producer
+    // and the service.
+    kDefault,
+
+    // The emulation mode, used for producer ports without shared memory. The
+    // state transitions are all done in the producer process.
+    kShmemEmulation,
+  };
+
+  // Layout of a Page.
+  // +===================================================+
+  // | Page header [8 bytes]                             |
+  // | Tells how many chunks there are, how big they are |
+  // | and their state (free, read, write, complete).    |
+  // +===================================================+
+  // +***************************************************+
+  // | Chunk #0 header [8 bytes]                         |
+  // | Tells how many packets there are and whether the  |
+  // | whether the 1st and last ones are fragmented.     |
+  // | Also has a chunk id to reassemble fragments.    |
+  // +***************************************************+
+  // +---------------------------------------------------+
+  // | Packet #0 size [varint, up to 4 bytes]            |
+  // + - - - - - - - - - - - - - - - - - - - - - - - - - +
+  // | Packet #0 payload                                 |
+  // | A TracePacket protobuf message                    |
+  // +---------------------------------------------------+
+  //                         ...
+  // + . . . . . . . . . . . . . . . . . . . . . . . . . +
+  // |      Optional padding to maintain aligment        |
+  // + . . . . . . . . . . . . . . . . . . . . . . . . . +
+  // +---------------------------------------------------+
+  // | Packet #N size [varint, up to 4 bytes]            |
+  // + - - - - - - - - - - - - - - - - - - - - - - - - - +
+  // | Packet #N payload                                 |
+  // | A TracePacket protobuf message                    |
+  // +---------------------------------------------------+
+  //                         ...
+  // +***************************************************+
+  // | Chunk #M header [8 bytes]                         |
+  //                         ...
+
+  // Alignment applies to start offset only. The Chunk size is *not* aligned.
+  static constexpr uint32_t kChunkAlignment = 4;
+  static constexpr uint32_t kChunkShift = 2;
+  static constexpr uint32_t kChunkMask = 0x3;
+  static constexpr uint32_t kLayoutMask = 0x70000000;
+  static constexpr uint32_t kLayoutShift = 28;
+  static constexpr uint32_t kAllChunksMask = 0x0FFFFFFF;
+
+  // This assumes that kChunkComplete == 3.
+  static constexpr uint32_t kAllChunksComplete = 0x0FFFFFFF;
+  static constexpr uint32_t kAllChunksFree = 0;
+  static constexpr size_t kInvalidPageIdx = static_cast<size_t>(-1);
+
+  // There is one page header per page, at the beginning of the page.
+  struct PageHeader {
+    // |layout| bits:
+    // [31] [30:28] [27:26] ... [1:0]
+    //  |      |       |     |    |
+    //  |      |       |     |    +---------- ChunkState[0]
+    //  |      |       |     +--------------- ChunkState[12..1]
+    //  |      |       +--------------------- ChunkState[13]
+    //  |      +----------------------------- PageLayout (0 == page fully free)
+    //  +------------------------------------ Reserved for future use
+    std::atomic<uint32_t> layout;
+
+    // If we'll ever going to use this in the future it might come handy
+    // reviving the kPageBeingPartitioned logic (look in git log, it was there
+    // at some point in the past).
+    uint32_t reserved;
+  };
+
+  // There is one Chunk header per chunk (hence PageLayout per page) at the
+  // beginning of each chunk.
+  struct ChunkHeader {
+    enum Flags : uint8_t {
+      // If set, the first TracePacket in the chunk is partial and continues
+      // from |chunk_id| - 1 (within the same |writer_id|).
+      kFirstPacketContinuesFromPrevChunk = 1 << 0,
+
+      // If set, the last TracePacket in the chunk is partial and continues on
+      // |chunk_id| + 1 (within the same |writer_id|).
+      kLastPacketContinuesOnNextChunk = 1 << 1,
+
+      // If set, the last (fragmented) TracePacket in the chunk has holes (even
+      // if the chunk is marked as kChunkComplete) that need to be patched
+      // out-of-band before the chunk can be read.
+      kChunkNeedsPatching = 1 << 2,
+    };
+
+    struct Packets {
+      // Number of valid TracePacket protobuf messages contained in the chunk.
+      // Each TracePacket is prefixed by its own size. This field is
+      // monotonically updated by the Producer with release store semantic when
+      // the packet at position |count| is started. This last packet may not be
+      // considered complete until |count| is incremented for the subsequent
+      // packet or the chunk is completed.
+      uint16_t count : 10;
+      static constexpr size_t kMaxCount = (1 << 10) - 1;
+
+      // See Flags above.
+      uint16_t flags : 6;
+    };
+
+    // A monotonic counter of the chunk within the scoped of a |writer_id|.
+    // The tuple (ProducerID, WriterID, ChunkID) allows to figure out if two
+    // chunks are contiguous (and hence a trace packets spanning across them can
+    // be glued) or we had some holes due to the ring buffer wrapping.
+    // This is set only when transitioning from kChunkFree to kChunkBeingWritten
+    // and remains unchanged throughout the remaining lifetime of the chunk.
+    std::atomic<uint32_t> chunk_id;
+
+    // ID of the writer, unique within the producer.
+    // Like |chunk_id|, this is set only when transitioning from kChunkFree to
+    // kChunkBeingWritten.
+    std::atomic<uint16_t> writer_id;
+
+    // There is no ProducerID here. The service figures that out from the IPC
+    // channel, which is unspoofable.
+
+    // Updated with release-store semantics.
+    std::atomic<Packets> packets;
+  };
+
+  class Chunk {
+   public:
+    Chunk();  // Constructs an invalid chunk.
+
+    // Chunk is move-only, to document the scope of the Acquire/Release
+    // TryLock operations below.
+    Chunk(const Chunk&) = delete;
+    Chunk operator=(const Chunk&) = delete;
+    Chunk(Chunk&&) noexcept;
+    Chunk& operator=(Chunk&&);
+
+    uint8_t* begin() const { return begin_; }
+    uint8_t* end() const { return begin_ + size_; }
+
+    // Size, including Chunk header.
+    size_t size() const { return size_; }
+
+    // Begin of the first packet (or packet fragment).
+    uint8_t* payload_begin() const { return begin_ + sizeof(ChunkHeader); }
+    size_t payload_size() const {
+      PERFETTO_DCHECK(size_ >= sizeof(ChunkHeader));
+      return size_ - sizeof(ChunkHeader);
+    }
+
+    bool is_valid() const { return begin_ && size_; }
+
+    // Index of the chunk within the page [0..13] (13 comes from kPageDiv14).
+    uint8_t chunk_idx() const { return chunk_idx_; }
+
+    ChunkHeader* header() { return reinterpret_cast<ChunkHeader*>(begin_); }
+
+    uint16_t writer_id() {
+      return header()->writer_id.load(std::memory_order_relaxed);
+    }
+
+    // Returns the count of packets and the flags with acquire-load semantics.
+    std::pair<uint16_t, uint8_t> GetPacketCountAndFlags() {
+      auto packets = header()->packets.load(std::memory_order_acquire);
+      const uint16_t packets_count = packets.count;
+      const uint8_t packets_flags = packets.flags;
+      return std::make_pair(packets_count, packets_flags);
+    }
+
+    // Increases |packets.count| with release semantics (note, however, that the
+    // packet count is incremented *before* starting writing a packet). Returns
+    // the new packet count. The increment is atomic but NOT race-free (i.e. no
+    // CAS). Only the Producer is supposed to perform this increment, and it's
+    // supposed to do that in a thread-safe way (holding a lock). A Chunk cannot
+    // be shared by multiple Producer threads without locking. The packet count
+    // is cleared by TryAcquireChunk(), when passing the new header for the
+    // chunk.
+    uint16_t IncrementPacketCount() {
+      ChunkHeader* chunk_header = header();
+      auto packets = chunk_header->packets.load(std::memory_order_relaxed);
+      packets.count++;
+      chunk_header->packets.store(packets, std::memory_order_release);
+      return packets.count;
+    }
+
+    // Flags are cleared by TryAcquireChunk(), by passing the new header for
+    // the chunk, or through ClearNeedsPatchingFlag.
+    void SetFlag(ChunkHeader::Flags flag) {
+      ChunkHeader* chunk_header = header();
+      auto packets = chunk_header->packets.load(std::memory_order_relaxed);
+      packets.flags |= flag;
+      chunk_header->packets.store(packets, std::memory_order_release);
+    }
+
+    // This flag can only be cleared by the producer while it is still holding
+    // on to the chunk - i.e. while the chunk is still in state
+    // ChunkState::kChunkBeingWritten and hasn't been transitioned to
+    // ChunkState::kChunkComplete. This is ok, because the service is oblivious
+    // to the needs patching flag before the chunk is released as complete.
+    void ClearNeedsPatchingFlag() {
+      ChunkHeader* chunk_header = header();
+      auto packets = chunk_header->packets.load(std::memory_order_relaxed);
+      packets.flags &= ~ChunkHeader::kChunkNeedsPatching;
+      chunk_header->packets.store(packets, std::memory_order_release);
+    }
+
+   private:
+    friend class SharedMemoryABI;
+    Chunk(uint8_t* begin, uint16_t size, uint8_t chunk_idx);
+
+    // Don't add extra fields, keep the move operator fast.
+    uint8_t* begin_ = nullptr;
+    uint16_t size_ = 0;
+    uint8_t chunk_idx_ = 0;
+
+   public:
+    static constexpr size_t kMaxSize = 1ULL << sizeof(size_) * 8;
+  };
+
+  // Construct an instance from an existing shared memory buffer.
+  SharedMemoryABI(uint8_t* start,
+                  size_t size,
+                  size_t page_size,
+                  ShmemMode mode);
+  SharedMemoryABI();
+
+  void Initialize(uint8_t* start,
+                  size_t size,
+                  size_t page_size,
+                  ShmemMode mode);
+
+  uint8_t* start() const { return start_; }
+  uint8_t* end() const { return start_ + size_; }
+  size_t size() const { return size_; }
+  size_t page_size() const { return page_size_; }
+  size_t num_pages() const { return num_pages_; }
+  bool is_valid() { return num_pages() > 0; }
+
+  uint8_t* page_start(size_t page_idx) {
+    PERFETTO_DCHECK(page_idx < num_pages_);
+    return start_ + page_size_ * page_idx;
+  }
+
+  PageHeader* page_header(size_t page_idx) {
+    return reinterpret_cast<PageHeader*>(page_start(page_idx));
+  }
+
+  // Returns true if the page is fully clear and has not been partitioned yet.
+  // The state of the page can change at any point after this returns (or even
+  // before). The Producer should use this only as a hint to decide out whether
+  // it should TryPartitionPage() or acquire an individual chunk.
+  bool is_page_free(size_t page_idx) {
+    return page_header(page_idx)->layout.load(std::memory_order_relaxed) == 0;
+  }
+
+  // Returns true if all chunks in the page are kChunkComplete. As above, this
+  // is advisory only. The Service is supposed to use this only to decide
+  // whether to TryAcquireAllChunksForReading() or not.
+  bool is_page_complete(size_t page_idx) {
+    auto layout = page_header(page_idx)->layout.load(std::memory_order_relaxed);
+    const uint32_t num_chunks = GetNumChunksForLayout(layout);
+    if (num_chunks == 0)
+      return false;  // Non partitioned pages cannot be complete.
+    return (layout & kAllChunksMask) ==
+           (kAllChunksComplete & ((1 << (num_chunks * kChunkShift)) - 1));
+  }
+
+  // For testing / debugging only.
+  std::string page_header_dbg(size_t page_idx) {
+    uint32_t x = page_header(page_idx)->layout.load(std::memory_order_relaxed);
+    return std::bitset<32>(x).to_string();
+  }
+
+  // Returns the page layout, which is a bitmap that specifies the chunking
+  // layout of the page and each chunk's current state. Reads with an
+  // acquire-load semantic to ensure a producer's writes corresponding to an
+  // update of the layout (e.g. clearing a chunk's header) are observed
+  // consistently.
+  uint32_t GetPageLayout(size_t page_idx) {
+    return page_header(page_idx)->layout.load(std::memory_order_acquire);
+  }
+
+  // Returns a bitmap in which each bit is set if the corresponding Chunk exists
+  // in the page (according to the page layout) and is free. If the page is not
+  // partitioned it returns 0 (as if the page had no free chunks).
+  uint32_t GetFreeChunks(size_t page_idx);
+
+  // Tries to atomically partition a page with the given |layout|. Returns true
+  // if the page was free and has been partitioned with the given |layout|,
+  // false if the page wasn't free anymore by the time we got there.
+  // If succeeds all the chunks are atomically set in the kChunkFree state.
+  bool TryPartitionPage(size_t page_idx, PageLayout layout);
+
+  // Tries to atomically mark a single chunk within the page as
+  // kChunkBeingWritten. Returns an invalid chunk if the page is not partitioned
+  // or the chunk is not in the kChunkFree state. If succeeds sets the chunk
+  // header to |header|.
+  Chunk TryAcquireChunkForWriting(size_t page_idx,
+                                  size_t chunk_idx,
+                                  const ChunkHeader* header) {
+    return TryAcquireChunk(page_idx, chunk_idx, kChunkBeingWritten, header);
+  }
+
+  // Similar to TryAcquireChunkForWriting. Fails if the chunk isn't in the
+  // kChunkComplete state.
+  Chunk TryAcquireChunkForReading(size_t page_idx, size_t chunk_idx) {
+    return TryAcquireChunk(page_idx, chunk_idx, kChunkBeingRead, nullptr);
+  }
+
+  // The caller must have successfully TryAcquireAllChunksForReading() or it
+  // needs to guarantee that the chunk is already in the kChunkBeingWritten
+  // state.
+  Chunk GetChunkUnchecked(size_t page_idx,
+                          uint32_t page_layout,
+                          size_t chunk_idx);
+
+  // Creates a Chunk by adopting the given buffer (|data| and |size|) and chunk
+  // index. This is used for chunk data passed over the wire (e.g. tcp or
+  // vsock). The chunk should *not* be freed to the shared memory.
+  static Chunk MakeChunkFromSerializedData(uint8_t* data,
+                                           uint16_t size,
+                                           uint8_t chunk_idx) {
+    return Chunk(data, size, chunk_idx);
+  }
+
+  // Puts a chunk into the kChunkComplete state. Returns the page index.
+  size_t ReleaseChunkAsComplete(Chunk chunk) {
+    return ReleaseChunk(std::move(chunk), kChunkComplete);
+  }
+
+  // Puts a chunk into the kChunkFree state. Returns the page index.
+  size_t ReleaseChunkAsFree(Chunk chunk) {
+    return ReleaseChunk(std::move(chunk), kChunkFree);
+  }
+
+  ChunkState GetChunkState(size_t page_idx, size_t chunk_idx) {
+    PageHeader* phdr = page_header(page_idx);
+    uint32_t layout = phdr->layout.load(std::memory_order_relaxed);
+    return GetChunkStateFromLayout(layout, chunk_idx);
+  }
+
+  std::pair<size_t, size_t> GetPageAndChunkIndex(const Chunk& chunk);
+
+  uint16_t GetChunkSizeForLayout(uint32_t page_layout) const {
+    return chunk_sizes_[(page_layout & kLayoutMask) >> kLayoutShift];
+  }
+
+  static ChunkState GetChunkStateFromLayout(uint32_t page_layout,
+                                            size_t chunk_idx) {
+    return static_cast<ChunkState>((page_layout >> (chunk_idx * kChunkShift)) &
+                                   kChunkMask);
+  }
+
+  static constexpr uint32_t GetNumChunksForLayout(uint32_t page_layout) {
+    return kNumChunksForLayout[(page_layout & kLayoutMask) >> kLayoutShift];
+  }
+
+  // Returns a bitmap in which each bit is set if the corresponding Chunk exists
+  // in the page (according to the page layout) and is not free. If the page is
+  // not partitioned it returns 0 (as if the page had no used chunks). Bit N
+  // corresponds to Chunk N.
+  static uint32_t GetUsedChunks(uint32_t page_layout) {
+    const uint32_t num_chunks = GetNumChunksForLayout(page_layout);
+    uint32_t res = 0;
+    for (uint32_t i = 0; i < num_chunks; i++) {
+      res |= ((page_layout & kChunkMask) != kChunkFree) ? (1 << i) : 0;
+      page_layout >>= kChunkShift;
+    }
+    return res;
+  }
+
+ private:
+  SharedMemoryABI(const SharedMemoryABI&) = delete;
+  SharedMemoryABI& operator=(const SharedMemoryABI&) = delete;
+
+  Chunk TryAcquireChunk(size_t page_idx,
+                        size_t chunk_idx,
+                        ChunkState,
+                        const ChunkHeader*);
+  size_t ReleaseChunk(Chunk chunk, ChunkState);
+
+  uint8_t* start_ = nullptr;
+  size_t size_ = 0;
+  size_t page_size_ = 0;
+  bool use_shmem_emulation_ = false;
+  size_t num_pages_ = 0;
+  std::array<uint16_t, kNumPageLayouts> chunk_sizes_;
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_ABI_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an "AS
+ * IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <sys/mman.h>
+#endif
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
+
+namespace perfetto {
+
+namespace {
+
+constexpr int kRetryAttempts = 64;
+
+inline void WaitBeforeNextAttempt(int attempt) {
+  if (attempt < kRetryAttempts / 2) {
+    std::this_thread::yield();
+  } else {
+    base::SleepMicroseconds((unsigned(attempt) / 10) * 1000);
+  }
+}
+
+// Returns the largest 4-bytes aligned chunk size <= |page_size| / |divider|
+// for each divider in PageLayout.
+constexpr size_t GetChunkSize(size_t page_size, size_t divider) {
+  return ((page_size - sizeof(SharedMemoryABI::PageHeader)) / divider) & ~3UL;
+}
+
+// Initializer for the const |chunk_sizes_| array.
+std::array<uint16_t, SharedMemoryABI::kNumPageLayouts> InitChunkSizes(
+    size_t page_size) {
+  static_assert(SharedMemoryABI::kNumPageLayouts ==
+                    base::ArraySize(SharedMemoryABI::kNumChunksForLayout),
+                "kNumPageLayouts out of date");
+  std::array<uint16_t, SharedMemoryABI::kNumPageLayouts> res = {};
+  for (size_t i = 0; i < SharedMemoryABI::kNumPageLayouts; i++) {
+    size_t num_chunks = SharedMemoryABI::kNumChunksForLayout[i];
+    size_t size = num_chunks == 0 ? 0 : GetChunkSize(page_size, num_chunks);
+    PERFETTO_CHECK(size <= std::numeric_limits<uint16_t>::max());
+    res[i] = static_cast<uint16_t>(size);
+  }
+  return res;
+}
+
+inline void ClearChunkHeader(SharedMemoryABI::ChunkHeader* header) {
+  header->writer_id.store(0u, std::memory_order_relaxed);
+  header->chunk_id.store(0u, std::memory_order_relaxed);
+  header->packets.store({}, std::memory_order_release);
+}
+
+}  // namespace
+
+SharedMemoryABI::SharedMemoryABI() = default;
+
+SharedMemoryABI::SharedMemoryABI(uint8_t* start,
+                                 size_t size,
+                                 size_t page_size,
+                                 ShmemMode mode) {
+  Initialize(start, size, page_size, mode);
+}
+
+void SharedMemoryABI::Initialize(uint8_t* start,
+                                 size_t size,
+                                 size_t page_size,
+                                 ShmemMode mode) {
+  start_ = start;
+  size_ = size;
+  page_size_ = page_size;
+  use_shmem_emulation_ = mode == ShmemMode::kShmemEmulation;
+  num_pages_ = size / page_size;
+  chunk_sizes_ = InitChunkSizes(page_size);
+  static_assert(sizeof(PageHeader) == 8, "PageHeader size");
+  static_assert(sizeof(ChunkHeader) == 8, "ChunkHeader size");
+  static_assert(sizeof(ChunkHeader::chunk_id) == sizeof(ChunkID),
+                "ChunkID size");
+
+  static_assert(sizeof(ChunkHeader::Packets) == 2, "ChunkHeader::Packets size");
+  static_assert(alignof(ChunkHeader) == kChunkAlignment,
+                "ChunkHeader alignment");
+
+  // In theory std::atomic does not guarantee that the underlying type
+  // consists only of the actual atomic word. Theoretically it could have
+  // locks or other state. In practice most implementations just implement
+  // them without extra state. The code below overlays the atomic into the
+  // SMB, hence relies on this implementation detail. This should be fine
+  // pragmatically (Chrome's base makes the same assumption), but let's have a
+  // check for this.
+  static_assert(sizeof(std::atomic<uint32_t>) == sizeof(uint32_t) &&
+                    sizeof(std::atomic<uint16_t>) == sizeof(uint16_t),
+                "Incompatible STL <atomic> implementation");
+
+  // Chec that the kAllChunks(Complete,Free) are consistent with the
+  // ChunkState enum values.
+
+  // These must be zero because rely on zero-initialized memory being
+  // interpreted as "free".
+  static_assert(kChunkFree == 0 && kAllChunksFree == 0,
+                "kChunkFree/kAllChunksFree and must be 0");
+
+  static_assert((kAllChunksComplete & kChunkMask) == kChunkComplete,
+                "kAllChunksComplete out of sync with kChunkComplete");
+
+  // Check the consistency of the kMax... constants.
+  static_assert(sizeof(ChunkHeader::writer_id) == sizeof(WriterID),
+                "WriterID size");
+  ChunkHeader chunk_header{};
+  chunk_header.chunk_id.store(static_cast<uint32_t>(-1));
+  PERFETTO_CHECK(chunk_header.chunk_id.load() == kMaxChunkID);
+
+  chunk_header.writer_id.store(static_cast<uint16_t>(-1));
+  PERFETTO_CHECK(kMaxWriterID <= chunk_header.writer_id.load());
+
+  PERFETTO_CHECK(page_size >= kMinPageSize);
+  PERFETTO_CHECK(page_size <= kMaxPageSize);
+  PERFETTO_CHECK(page_size % kMinPageSize == 0);
+  PERFETTO_CHECK(reinterpret_cast<uintptr_t>(start) % kMinPageSize == 0);
+  PERFETTO_CHECK(size % page_size == 0);
+}
+
+SharedMemoryABI::Chunk SharedMemoryABI::GetChunkUnchecked(size_t page_idx,
+                                                          uint32_t page_layout,
+                                                          size_t chunk_idx) {
+  const size_t num_chunks = GetNumChunksForLayout(page_layout);
+  PERFETTO_DCHECK(chunk_idx < num_chunks);
+  // Compute the chunk virtual address and write it into |chunk|.
+  const uint16_t chunk_size = GetChunkSizeForLayout(page_layout);
+  size_t chunk_offset_in_page = sizeof(PageHeader) + chunk_idx * chunk_size;
+
+  Chunk chunk(page_start(page_idx) + chunk_offset_in_page, chunk_size,
+              static_cast<uint8_t>(chunk_idx));
+  PERFETTO_DCHECK(chunk.end() <= end());
+  return chunk;
+}
+
+SharedMemoryABI::Chunk SharedMemoryABI::TryAcquireChunk(
+    size_t page_idx,
+    size_t chunk_idx,
+    ChunkState desired_chunk_state,
+    const ChunkHeader* header) {
+  PERFETTO_DCHECK(desired_chunk_state == kChunkBeingRead ||
+                  desired_chunk_state == kChunkBeingWritten);
+  PageHeader* phdr = page_header(page_idx);
+  for (int attempt = 0; attempt < kRetryAttempts; attempt++) {
+    uint32_t layout = phdr->layout.load(std::memory_order_acquire);
+    const size_t num_chunks = GetNumChunksForLayout(layout);
+
+    // The page layout has changed (or the page is free).
+    if (chunk_idx >= num_chunks)
+      return Chunk();
+
+    // Verify that the chunk is still in a state that allows the transition to
+    // |desired_chunk_state|. The only allowed transitions are:
+    // 1. kChunkFree -> kChunkBeingWritten (Producer).
+    // 2. kChunkComplete -> kChunkBeingRead (Service).
+    ChunkState expected_chunk_state =
+        desired_chunk_state == kChunkBeingWritten ? kChunkFree : kChunkComplete;
+    auto cur_chunk_state = (layout >> (chunk_idx * kChunkShift)) & kChunkMask;
+    if (cur_chunk_state != expected_chunk_state)
+      return Chunk();
+
+    uint32_t next_layout = layout;
+    next_layout &= ~(kChunkMask << (chunk_idx * kChunkShift));
+    next_layout |= (desired_chunk_state << (chunk_idx * kChunkShift));
+    if (phdr->layout.compare_exchange_strong(layout, next_layout,
+                                             std::memory_order_acq_rel)) {
+      // Compute the chunk virtual address and write it into |chunk|.
+      Chunk chunk = GetChunkUnchecked(page_idx, layout, chunk_idx);
+      if (desired_chunk_state == kChunkBeingWritten) {
+        PERFETTO_DCHECK(header);
+        ChunkHeader* new_header = chunk.header();
+        new_header->writer_id.store(header->writer_id,
+                                    std::memory_order_relaxed);
+        new_header->chunk_id.store(header->chunk_id, std::memory_order_relaxed);
+        new_header->packets.store(header->packets, std::memory_order_release);
+      }
+      return chunk;
+    }
+    WaitBeforeNextAttempt(attempt);
+  }
+  return Chunk();  // All our attempts failed.
+}
+
+bool SharedMemoryABI::TryPartitionPage(size_t page_idx, PageLayout layout) {
+  PERFETTO_DCHECK(layout >= kPageDiv1 && layout <= kPageDiv14);
+  uint32_t expected_layout = 0;  // Free page.
+  uint32_t next_layout = (layout << kLayoutShift) & kLayoutMask;
+  PageHeader* phdr = page_header(page_idx);
+  if (!phdr->layout.compare_exchange_strong(expected_layout, next_layout,
+                                            std::memory_order_acq_rel)) {
+    return false;
+  }
+  return true;
+}
+
+uint32_t SharedMemoryABI::GetFreeChunks(size_t page_idx) {
+  uint32_t layout =
+      page_header(page_idx)->layout.load(std::memory_order_relaxed);
+  const uint32_t num_chunks = GetNumChunksForLayout(layout);
+  uint32_t res = 0;
+  for (uint32_t i = 0; i < num_chunks; i++) {
+    res |= ((layout & kChunkMask) == kChunkFree) ? (1 << i) : 0;
+    layout >>= kChunkShift;
+  }
+  return res;
+}
+
+size_t SharedMemoryABI::ReleaseChunk(Chunk chunk,
+                                     ChunkState desired_chunk_state) {
+  PERFETTO_DCHECK(desired_chunk_state == kChunkComplete ||
+                  desired_chunk_state == kChunkFree);
+
+  size_t page_idx;
+  size_t chunk_idx;
+  std::tie(page_idx, chunk_idx) = GetPageAndChunkIndex(chunk);
+
+  // Reset header fields, so that the service can identify when the chunk's
+  // header has been initialized by the producer.
+  if (desired_chunk_state == kChunkFree)
+    ClearChunkHeader(chunk.header());
+
+  for (int attempt = 0; attempt < kRetryAttempts; attempt++) {
+    PageHeader* phdr = page_header(page_idx);
+    uint32_t layout = phdr->layout.load(std::memory_order_relaxed);
+    const size_t page_chunk_size = GetChunkSizeForLayout(layout);
+
+    // TODO(primiano): this should not be a CHECK, because a malicious producer
+    // could crash us by putting the chunk in an invalid state. This should
+    // gracefully fail. Keep a CHECK until then.
+    PERFETTO_CHECK(chunk.size() == page_chunk_size);
+    const uint32_t chunk_state = GetChunkStateFromLayout(layout, chunk_idx);
+
+    // Verify that the chunk is still in a state that allows the transition to
+    // |desired_chunk_state|. The only allowed transitions are:
+    // 1. kChunkBeingWritten -> kChunkComplete (Producer).
+    // 2. kChunkBeingRead -> kChunkFree (Service).
+    // Or in the emulation mode, the allowed transitions are:
+    // 1. kChunkBeingWritten -> kChunkComplete (Producer).
+    // 2. kChunkComplete -> kChunkFree (Producer).
+    ChunkState expected_chunk_state;
+    if (desired_chunk_state == kChunkComplete) {
+      expected_chunk_state = kChunkBeingWritten;
+    } else {
+      expected_chunk_state =
+          use_shmem_emulation_ ? kChunkComplete : kChunkBeingRead;
+    }
+
+    // TODO(primiano): should not be a CHECK (same rationale of comment above).
+    PERFETTO_CHECK(chunk_state == expected_chunk_state);
+    uint32_t next_layout = layout;
+    next_layout &= ~(kChunkMask << (chunk_idx * kChunkShift));
+    next_layout |= (desired_chunk_state << (chunk_idx * kChunkShift));
+
+    // If we are freeing a chunk and all the other chunks in the page are free
+    // we should de-partition the page and mark it as clear.
+    if ((next_layout & kAllChunksMask) == kAllChunksFree)
+      next_layout = 0;
+
+    if (phdr->layout.compare_exchange_strong(layout, next_layout,
+                                             std::memory_order_acq_rel)) {
+      return page_idx;
+    }
+    WaitBeforeNextAttempt(attempt);
+  }
+  // Too much contention on this page. Give up. This page will be left pending
+  // forever but there isn't much more we can do at this point.
+  PERFETTO_DFATAL("Too much contention on page.");
+  return kInvalidPageIdx;
+}
+
+SharedMemoryABI::Chunk::Chunk() = default;
+
+SharedMemoryABI::Chunk::Chunk(uint8_t* begin, uint16_t size, uint8_t chunk_idx)
+    : begin_(begin), size_(size), chunk_idx_(chunk_idx) {
+  PERFETTO_CHECK(reinterpret_cast<uintptr_t>(begin) % kChunkAlignment == 0);
+  PERFETTO_CHECK(size > 0);
+}
+
+SharedMemoryABI::Chunk::Chunk(Chunk&& o) noexcept {
+  *this = std::move(o);
+}
+
+SharedMemoryABI::Chunk& SharedMemoryABI::Chunk::operator=(Chunk&& o) {
+  begin_ = o.begin_;
+  size_ = o.size_;
+  chunk_idx_ = o.chunk_idx_;
+  o.begin_ = nullptr;
+  o.size_ = 0;
+  o.chunk_idx_ = 0;
+  return *this;
+}
+
+std::pair<size_t, size_t> SharedMemoryABI::GetPageAndChunkIndex(
+    const Chunk& chunk) {
+  PERFETTO_DCHECK(chunk.is_valid());
+  PERFETTO_DCHECK(chunk.begin() >= start_);
+  PERFETTO_DCHECK(chunk.end() <= start_ + size_);
+
+  // TODO(primiano): The divisions below could be avoided if we cached
+  // |page_shift_|.
+  const uintptr_t rel_addr = static_cast<uintptr_t>(chunk.begin() - start_);
+  const size_t page_idx = rel_addr / page_size_;
+  const size_t offset = rel_addr % page_size_;
+  PERFETTO_DCHECK(offset >= sizeof(PageHeader));
+  PERFETTO_DCHECK(offset % kChunkAlignment == 0);
+  PERFETTO_DCHECK((offset - sizeof(PageHeader)) % chunk.size() == 0);
+  const size_t chunk_idx = (offset - sizeof(PageHeader)) / chunk.size();
+  PERFETTO_DCHECK(chunk_idx < kMaxChunksPerPage);
+  PERFETTO_DCHECK(chunk_idx < GetNumChunksForLayout(GetPageLayout(page_idx)));
+  return std::make_pair(page_idx, chunk_idx);
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/core/shared_memory_arbiter_impl.cc
+// gen_amalgamated begin header: src/tracing/core/shared_memory_arbiter_impl.h
+// gen_amalgamated begin header: include/perfetto/ext/tracing/core/shared_memory_arbiter.h
+// gen_amalgamated begin header: include/perfetto/ext/tracing/core/tracing_service.h
+// gen_amalgamated begin header: include/perfetto/ext/tracing/core/trace_packet.h
+// gen_amalgamated begin header: include/perfetto/ext/tracing/core/slice.h
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_SLICE_H_
+#define INCLUDE_PERFETTO_EXT_TRACING_CORE_SLICE_H_
+
+#include <stddef.h>
+#include <string.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+
+namespace perfetto {
+
+// A simple wrapper around a virtually contiguous memory range that contains a
+// TracePacket, or just a portion of it.
+struct Slice {
+  Slice() : start(nullptr), size(0) {}
+  Slice(const void* st, size_t sz) : start(st), size(sz) {}
+  Slice(Slice&& other) noexcept = default;
+
+  // Create a Slice which owns |size| bytes of memory.
+  static Slice Allocate(size_t size) {
+    Slice slice;
+    slice.own_data_.reset(new uint8_t[size]);
+    slice.start = &slice.own_data_[0];
+    slice.size = size;
+    return slice;
+  }
+
+  static Slice TakeOwnership(std::unique_ptr<uint8_t[]> buf, size_t size) {
+    Slice slice;
+    slice.own_data_ = std::move(buf);
+    slice.start = &slice.own_data_[0];
+    slice.size = size;
+    return slice;
+  }
+
+  uint8_t* own_data() {
+    PERFETTO_DCHECK(own_data_);
+    return own_data_.get();
+  }
+
+  const void* start;
+  size_t size;
+
+ private:
+  Slice(const Slice&) = delete;
+  void operator=(const Slice&) = delete;
+
+  std::unique_ptr<uint8_t[]> own_data_;
+};
+
+// TODO(primiano): most TracePacket(s) fit in a slice or two. We need something
+// a bit more clever here that has inline capacity for 2 slices and then uses a
+// std::forward_list or a std::vector for the less likely cases.
+using Slices = std::vector<Slice>;
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_SLICE_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_PACKET_H_
+#define INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_PACKET_H_
+
+#include <stddef.h>
+#include <memory>
+#include <optional>
+#include <tuple>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/slice.h"
+
+namespace perfetto {
+
+// A wrapper around a byte buffer that contains a protobuf-encoded TracePacket
+// (see trace_packet.proto). The TracePacket is decoded only if the Consumer
+// requests that. This is to allow Consumer(s) to just stream the packet over
+// the network or save it to a file without wasting time decoding it and without
+// needing to depend on libprotobuf or the trace_packet.pb.h header.
+// If the packets are saved / streamed and not just consumed locally, consumers
+// should ensure to preserve the unknown fields in the proto. A consumer, in
+// fact, might have an older version .proto which is newer on the producer.
+class PERFETTO_EXPORT_COMPONENT TracePacket {
+ public:
+  using const_iterator = Slices::const_iterator;
+
+  // The field id of protos::Trace::packet, static_assert()-ed in the unittest.
+  static constexpr uint32_t kPacketFieldNumber = 1;
+
+  // Maximum size of the preamble returned by GetProtoPreamble().
+  static constexpr size_t kMaxPreambleBytes = 8;
+
+  TracePacket();
+  ~TracePacket();
+  TracePacket(TracePacket&&) noexcept;
+  TracePacket& operator=(TracePacket&&);
+
+  // Accesses all the raw slices in the packet, for saving them to file/network.
+  const Slices& slices() const { return slices_; }
+
+  // Mutator, used only by the service and tests.
+  void AddSlice(Slice);
+
+  // Does not copy / take ownership of the memory of the slice. The TracePacket
+  // will be valid only as long as the original buffer is valid.
+  void AddSlice(const void* start, size_t size);
+
+  // Total size of all slices.
+  size_t size() const { return size_; }
+
+  // Generates a protobuf preamble suitable to represent this packet as a
+  // repeated field within a root trace.proto message.
+  // Returns a pointer to a buffer, owned by this class, containing the preamble
+  // and its size.
+  std::tuple<char*, size_t> GetProtoPreamble();
+
+  // Returns the raw protobuf bytes of the slices, all stitched together into
+  // a string. Only for testing.
+  std::string GetRawBytesForTesting();
+
+  // Remembers the buffer index where this packet was taken from. This is
+  // usually populated for packets from a TraceBuffer, not synthetic ones.
+  std::optional<uint32_t> buffer_index_for_stats() const {
+    if (buffer_index_for_stats_ == 0)
+      return std::nullopt;
+    return buffer_index_for_stats_ - 1;
+  }
+  void set_buffer_index_for_stats(uint32_t v) {
+    buffer_index_for_stats_ = v + 1;
+  }
+
+ private:
+  TracePacket(const TracePacket&) = delete;
+  TracePacket& operator=(const TracePacket&) = delete;
+
+  Slices slices_;     // Not owned.
+  size_t size_ = 0;   // SUM(slice.size for slice in slices_).
+
+  // Internally we store index+1, and use 0 for the "not set" case.
+  uint32_t buffer_index_for_stats_ = 0;
+  char preamble_[kMaxPreambleBytes];  // Deliberately not initialized.
+
+  // Remember to update the move operators and their unittest if adding new
+  // fields. ConsumerIPCClientImpl::OnReadBuffersResponse() relies on
+  // std::move(TracePacket) to clear up the moved-from instance.
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_PACKET_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACING_SERVICE_H_
+#define INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACING_SERVICE_H_
+
+#include <stdint.h>
+
+#include <functional>
+#include <memory>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/sys_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/buffer_exhausted_policy.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/clock_snapshots.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/flush_flags.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+
+namespace perfetto {
+
+namespace base {
+class TaskRunner;
+}  // namespace base
+
+class Consumer;
+class Producer;
+class SharedMemoryArbiter;
+class TraceWriter;
+class ClientIdentity;
+
+// TODO: for the moment this assumes that all the calls happen on the same
+// thread/sequence. Not sure this will be the case long term in Chrome.
+
+// The API for the Producer port of the Service.
+// Subclassed by:
+// 1. The tracing_service_impl.cc business logic when returning it in response
+//    to the ConnectProducer() method.
+// 2. The transport layer (e.g., src/ipc) when the producer and
+//    the service don't talk locally but via some IPC mechanism.
+class PERFETTO_EXPORT_COMPONENT ProducerEndpoint {
+ public:
+  virtual ~ProducerEndpoint();
+
+  // Disconnects the endpoint from the service, while keeping the shared memory
+  // valid. After calling this, the endpoint will no longer call any methods
+  // on the Producer.
+  virtual void Disconnect() = 0;
+
+  // Called by the Producer to (un)register data sources. Data sources are
+  // identified by their name (i.e. DataSourceDescriptor.name)
+  virtual void RegisterDataSource(const DataSourceDescriptor&) = 0;
+  virtual void UpdateDataSource(const DataSourceDescriptor&) = 0;
+  virtual void UnregisterDataSource(const std::string& name) = 0;
+
+  // Associate the trace writer with the given |writer_id| with
+  // |target_buffer|. The service may use this information to retrieve and
+  // copy uncommitted chunks written by the trace writer into its associated
+  // buffer, e.g. when a producer process crashes or when a flush is
+  // necessary.
+  virtual void RegisterTraceWriter(uint32_t writer_id,
+                                   uint32_t target_buffer) = 0;
+
+  // Remove the association of the trace writer previously created via
+  // RegisterTraceWriter.
+  virtual void UnregisterTraceWriter(uint32_t writer_id) = 0;
+
+  // Called by the Producer to signal that some pages in the shared memory
+  // buffer (shared between Service and Producer) have changed.
+  // When the Producer and the Service are hosted in the same process and
+  // hence potentially live on the same task runner, This method must call
+  // TracingServiceImpl's CommitData synchronously, without any PostTask()s,
+  // if on the same thread. This is to avoid a deadlock where the Producer
+  // exhausts its SMB and stalls waiting for the service to catch up with
+  // reads, but the Service never gets to that because it lives on the same
+  // thread.
+  using CommitDataCallback = std::function<void()>;
+  virtual void CommitData(const CommitDataRequest&,
+                          CommitDataCallback callback = {}) = 0;
+
+  virtual SharedMemory* shared_memory() const = 0;
+
+  // Size of shared memory buffer pages. It's always a multiple of 4K.
+  // See shared_memory_abi.h
+  virtual size_t shared_buffer_page_size_kb() const = 0;
+
+  // Creates a trace writer, which allows to create events, handling the
+  // underying shared memory buffer and signalling to the Service. This method
+  // is thread-safe but the returned object is not. A TraceWriter should be
+  // used only from a single thread, or the caller has to handle sequencing
+  // via a mutex or equivalent. This method can only be called if
+  // TracingService::ConnectProducer was called with |in_process=true|.
+  // Args:
+  // |target_buffer| is the target buffer ID where the data produced by the
+  // writer should be stored by the tracing service. This value is passed
+  // upon creation of the data source (StartDataSource()) in the
+  // DataSourceConfig.target_buffer().
+  virtual std::unique_ptr<TraceWriter> CreateTraceWriter(
+      BufferID target_buffer,
+      BufferExhaustedPolicy buffer_exhausted_policy =
+          BufferExhaustedPolicy::kDefault) = 0;
+
+  // TODO(eseckler): Also expose CreateStartupTraceWriter() ?
+
+  // In some cases you can access the producer's SharedMemoryArbiter (for
+  // example if TracingService::ConnectProducer is called with
+  // |in_process=true|). The SharedMemoryArbiter can be used to create
+  // TraceWriters which is able to directly commit chunks. For the
+  // |in_process=true| case this can be done without going through an IPC layer.
+  virtual SharedMemoryArbiter* MaybeSharedMemoryArbiter() = 0;
+
+  // Whether the service accepted a shared memory buffer provided by the
+  // producer.
+  virtual bool IsShmemProvidedByProducer() const = 0;
+
+  // Called in response to a Producer::Flush(request_id) call after all data
+  // for the flush request has been committed.
+  virtual void NotifyFlushComplete(FlushRequestID) = 0;
+
+  // Called in response to one or more Producer::StartDataSource(),
+  // if the data source registered setting the flag
+  // DataSourceDescriptor.will_notify_on_start.
+  virtual void NotifyDataSourceStarted(DataSourceInstanceID) = 0;
+
+  // Called in response to one or more Producer::StopDataSource(),
+  // if the data source registered setting the flag
+  // DataSourceDescriptor.will_notify_on_stop.
+  virtual void NotifyDataSourceStopped(DataSourceInstanceID) = 0;
+
+  // This informs the service to activate any of these triggers if any tracing
+  // session was waiting for them.
+  virtual void ActivateTriggers(const std::vector<std::string>&) = 0;
+
+  // Emits a synchronization barrier to linearize with the service. When
+  // |callback| is invoked, the caller has the guarantee that the service has
+  // seen and processed all the requests sent by this producer prior to the
+  // Sync() call. Used mainly in tests.
+  virtual void Sync(std::function<void()> callback) = 0;
+};  // class ProducerEndpoint.
+
+// The API for the Consumer port of the Service.
+// Subclassed by:
+// 1. The tracing_service_impl.cc business logic when returning it in response
+// to
+//    the ConnectConsumer() method.
+// 2. The transport layer (e.g., src/ipc) when the consumer and
+//    the service don't talk locally but via some IPC mechanism.
+class PERFETTO_EXPORT_COMPONENT ConsumerEndpoint {
+ public:
+  virtual ~ConsumerEndpoint();
+
+  // Enables tracing with the given TraceConfig. The ScopedFile argument is
+  // used only when TraceConfig.write_into_file == true.
+  // If TraceConfig.deferred_start == true data sources are configured via
+  // SetupDataSource() but are not started until StartTracing() is called.
+  // This is to support pre-initialization and fast triggering of traces.
+  // The ScopedFile argument is used only when TraceConfig.write_into_file
+  // == true.
+  virtual void EnableTracing(const TraceConfig&,
+                             base::ScopedFile = base::ScopedFile()) = 0;
+
+  // Update the trace config of an existing tracing session; only a subset
+  // of options can be changed mid-session. Currently the only
+  // supported functionality is expanding the list of producer_name_filters()
+  // (or removing the filter entirely) for existing data sources.
+  virtual void ChangeTraceConfig(const TraceConfig&) = 0;
+
+  // Starts all data sources configured in the trace config. This is used only
+  // after calling EnableTracing() with TraceConfig.deferred_start=true.
+  // It's a no-op if called after a regular EnableTracing(), without setting
+  // deferred_start.
+  virtual void StartTracing() = 0;
+
+  virtual void DisableTracing() = 0;
+
+  // Clones an existing tracing session and attaches to it. The session is
+  // cloned in read-only mode and can only be used to read a snapshot of an
+  // existing tracing session. Will invoke Consumer::OnSessionCloned().
+  // If TracingSessionID == kBugreportSessionId (0xff...ff) the session with the
+  // highest bugreport score is cloned (if any exists).
+  struct CloneSessionArgs {
+    // If set, the trace filter will not have effect on the cloned session.
+    // Used for bugreports.
+    bool skip_trace_filter = false;
+
+    // If set, affects the generation of the FlushFlags::CloneTarget to be set
+    // to kBugreport when requesting the flush to the producers.
+    bool for_bugreport = false;
+  };
+  virtual void CloneSession(TracingSessionID, CloneSessionArgs) = 0;
+
+  // Requests all data sources to flush their data immediately and invokes the
+  // passed callback once all of them have acked the flush (in which case
+  // the callback argument |success| will be true) or |timeout_ms| are elapsed
+  // (in which case |success| will be false).
+  // If |timeout_ms| is 0 the TraceConfig's flush_timeout_ms is used, or,
+  // if that one is not set (or is set to 0), kDefaultFlushTimeoutMs (5s) is
+  // used.
+  using FlushCallback = std::function<void(bool /*success*/)>;
+  virtual void Flush(uint32_t timeout_ms,
+                     FlushCallback callback,
+                     FlushFlags) = 0;
+
+  // This is required for legacy out-of-repo clients like arctraceservice which
+  // use the 2-version parameter.
+  inline void Flush(uint32_t timeout_ms, FlushCallback callback) {
+    Flush(timeout_ms, std::move(callback), FlushFlags());
+  }
+
+  // Tracing data will be delivered invoking Consumer::OnTraceData().
+  virtual void ReadBuffers() = 0;
+
+  virtual void FreeBuffers() = 0;
+
+  // Will call OnDetach().
+  virtual void Detach(const std::string& key) = 0;
+
+  // Will call OnAttach().
+  virtual void Attach(const std::string& key) = 0;
+
+  // Will call OnTraceStats().
+  virtual void GetTraceStats() = 0;
+
+  // Start or stop observing events of selected types. |events_mask| specifies
+  // the types of events to observe in a bitmask of ObservableEvents::Type.
+  // To disable observing, pass 0.
+  // Will call OnObservableEvents() repeatedly whenever an event of an enabled
+  // ObservableEventType occurs.
+  // TODO(eseckler): Extend this to support producers & data sources.
+  virtual void ObserveEvents(uint32_t events_mask) = 0;
+
+  // Used to obtain the list of connected data sources and other info about
+  // the tracing service.
+  struct QueryServiceStateArgs {
+    // If set, only the TracingServiceState.tracing_sessions is filled.
+    bool sessions_only = false;
+  };
+  using QueryServiceStateCallback =
+      std::function<void(bool success, const TracingServiceState&)>;
+  virtual void QueryServiceState(QueryServiceStateArgs,
+                                 QueryServiceStateCallback) = 0;
+
+  // Used for feature detection. Makes sense only when the consumer and the
+  // service talk over IPC and can be from different versions.
+  using QueryCapabilitiesCallback =
+      std::function<void(const TracingServiceCapabilities&)>;
+  virtual void QueryCapabilities(QueryCapabilitiesCallback) = 0;
+
+  // If any tracing session with TraceConfig.bugreport_score > 0 is running,
+  // this will pick the highest-score one, stop it and save it into a fixed
+  // path (See kBugreportTracePath).
+  // The callback is invoked when the file has been saved, in case of success,
+  // or whenever an error occurs.
+  // Args:
+  // - success: if true, an eligible trace was found and saved into file.
+  //            If false, either there was no eligible trace running or
+  //            something else failed (See |msg|).
+  // - msg: human readable diagnostic messages to debug failures.
+  using SaveTraceForBugreportCallback =
+      std::function<void(bool /*success*/, const std::string& /*msg*/)>;
+  virtual void SaveTraceForBugreport(SaveTraceForBugreportCallback) = 0;
+};  // class ConsumerEndpoint.
+
+struct PERFETTO_EXPORT_COMPONENT TracingServiceInitOpts {
+  // Function used by tracing service to compress packets. Takes a pointer to
+  // a vector of TracePackets and replaces the packets in the vector with
+  // compressed ones.
+  using CompressorFn = void (*)(std::vector<TracePacket>*);
+  CompressorFn compressor_fn = nullptr;
+
+  // Whether the relay endpoint is enabled on producer transport(s).
+  bool enable_relay_endpoint = false;
+};
+
+// The API for the Relay port of the Service. Subclassed by the
+// tracing_service_impl.cc business logic when returning it in response to the
+// ConnectRelayClient() method.
+class PERFETTO_EXPORT_COMPONENT RelayEndpoint {
+ public:
+  virtual ~RelayEndpoint();
+
+  // A snapshot of client and host clocks.
+  struct SyncClockSnapshot {
+    ClockSnapshotVector client_clock_snapshots;
+    ClockSnapshotVector host_clock_snapshots;
+  };
+
+  enum class SyncMode : uint32_t { PING = 1, UPDATE = 2 };
+  virtual void SyncClocks(SyncMode sync_mode,
+                          ClockSnapshotVector client_clocks,
+                          ClockSnapshotVector host_clocks) = 0;
+  virtual void Disconnect() = 0;
+};
+
+// The public API of the tracing Service business logic.
+//
+// Exposed to:
+// 1. The transport layer (e.g., src/unix_rpc/unix_service_host.cc),
+//    which forwards commands received from a remote producer or consumer to
+//    the actual service implementation.
+// 2. Tests.
+//
+// Subclassed by:
+//   The service business logic in src/core/tracing_service_impl.cc.
+class PERFETTO_EXPORT_COMPONENT TracingService {
+ public:
+  using ProducerEndpoint = perfetto::ProducerEndpoint;
+  using ConsumerEndpoint = perfetto::ConsumerEndpoint;
+  using RelayEndpoint = perfetto::RelayEndpoint;
+  using InitOpts = TracingServiceInitOpts;
+
+  // Default sizes used by the service implementation and client library.
+  static constexpr size_t kDefaultShmPageSize = 4096ul;
+  static constexpr size_t kDefaultShmSize = 256 * 1024ul;
+
+  enum class ProducerSMBScrapingMode {
+    // Use service's default setting for SMB scraping. Currently, the default
+    // mode is to disable SMB scraping, but this may change in the future.
+    kDefault,
+
+    // Enable scraping of uncommitted chunks in producers' shared memory
+    // buffers.
+    kEnabled,
+
+    // Disable scraping of uncommitted chunks in producers' shared memory
+    // buffers.
+    kDisabled
+  };
+
+  // Implemented in src/core/tracing_service_impl.cc . CompressorFn can be
+  // nullptr, in which case TracingService will not support compression.
+  static std::unique_ptr<TracingService> CreateInstance(
+      std::unique_ptr<SharedMemory::Factory>,
+      base::TaskRunner*,
+      InitOpts init_opts = {});
+
+  virtual ~TracingService();
+
+  // Connects a Producer instance and obtains a ProducerEndpoint, which is
+  // essentially a 1:1 channel between one Producer and the Service.
+  //
+  // The caller has to guarantee that the passed Producer will be alive as long
+  // as the returned ProducerEndpoint is alive. Both the passed Producer and the
+  // returned ProducerEndpoint must live on the same task runner of the service,
+  // specifically:
+  // 1) The Service will call Producer::* methods on the Service's task runner.
+  // 2) The Producer should call ProducerEndpoint::* methods only on the
+  //    service's task runner, except for ProducerEndpoint::CreateTraceWriter(),
+  //    which can be called on any thread. To disconnect just destroy the
+  //    returned ProducerEndpoint object. It is safe to destroy the Producer
+  //    once the Producer::OnDisconnect() has been invoked.
+  //
+  // |uid| is the trusted user id of the producer process, used by the consumers
+  // for validating the origin of trace data. |shared_memory_size_hint_bytes|
+  // and |shared_memory_page_size_hint_bytes| are optional hints on the size of
+  // the shared memory buffer and its pages. The service can ignore the hints
+  // (e.g., if the hints are unreasonably large or other sizes were configured
+  // in a tracing session's config). |in_process| enables the ProducerEndpoint
+  // to manage its own shared memory and enables use of
+  // |ProducerEndpoint::CreateTraceWriter|.
+  //
+  // The producer can optionally provide a non-null |shm|, which the service
+  // will adopt for the connection to the producer, provided it is correctly
+  // sized. In this case, |shared_memory_page_size_hint_bytes| indicates the
+  // page size used in this SMB. The producer can use this mechanism to record
+  // tracing data to an SMB even before the tracing session is started by the
+  // service. This is used in Chrome to implement startup tracing. If the buffer
+  // is incorrectly sized, the service will discard the SMB and allocate a new
+  // one, provided to the producer via ProducerEndpoint::shared_memory() after
+  // OnTracingSetup(). To verify that the service accepted the SMB, the producer
+  // may check via ProducerEndpoint::IsShmemProvidedByProducer(). If the service
+  // accepted the SMB, the producer can then commit any data that is already in
+  // the SMB after the tracing session was started by the service via
+  // Producer::StartDataSource(). The |shm| will also be rejected when
+  // connecting to a service that is too old (pre Android-11).
+  //
+  // Can return null in the unlikely event that service has too many producers
+  // connected.
+  virtual std::unique_ptr<ProducerEndpoint> ConnectProducer(
+      Producer*,
+      const ClientIdentity& client_identity,
+      const std::string& name,
+      size_t shared_memory_size_hint_bytes = 0,
+      bool in_process = false,
+      ProducerSMBScrapingMode smb_scraping_mode =
+          ProducerSMBScrapingMode::kDefault,
+      size_t shared_memory_page_size_hint_bytes = 0,
+      std::unique_ptr<SharedMemory> shm = nullptr,
+      const std::string& sdk_version = {}) = 0;
+
+  // Connects a Consumer instance and obtains a ConsumerEndpoint, which is
+  // essentially a 1:1 channel between one Consumer and the Service.
+  // The caller has to guarantee that the passed Consumer will be alive as long
+  // as the returned ConsumerEndpoint is alive.
+  // To disconnect just destroy the returned ConsumerEndpoint object. It is safe
+  // to destroy the Consumer once the Consumer::OnDisconnect() has been invoked.
+  virtual std::unique_ptr<ConsumerEndpoint> ConnectConsumer(Consumer*,
+                                                            uid_t) = 0;
+
+  // Enable/disable scraping of chunks in the shared memory buffer. If enabled,
+  // the service will copy uncommitted but non-empty chunks from the SMB when
+  // flushing (e.g. to handle unresponsive producers or producers unable to
+  // flush their active chunks), on producer disconnect (e.g. to recover data
+  // from crashed producers), and after disabling a tracing session (e.g. to
+  // gather data from producers that didn't stop their data sources in time).
+  //
+  // This feature is currently used by Chrome.
+  virtual void SetSMBScrapingEnabled(bool enabled) = 0;
+
+  using RelayClientID = std::pair<base::MachineID, /*client ID*/ uint64_t>;
+  // Connects a remote RelayClient instance and obtains a RelayEndpoint, which
+  // is a 1:1 channel between one RelayClient and the Service. To disconnect
+  // just call Disconnect() of the RelayEndpoint instance. The relay client is
+  // connected using an identifier of MachineID and client ID. The service
+  // doesn't hold an object that represents the client because the relay port
+  // only has a client-to-host SyncClock() method.
+  //
+  // TODO(chinglinyu): connect the relay client using a RelayClient* object when
+  // we need host-to-client RPC method.
+  virtual std::unique_ptr<RelayEndpoint> ConnectRelayClient(RelayClientID) = 0;
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACING_SERVICE_H_
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_ARBITER_H_
+#define INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_ARBITER_H_
+
+#include <stddef.h>
+
+#include <functional>
+#include <memory>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/buffer_exhausted_policy.h"
+
+namespace perfetto {
+
+namespace base {
+class TaskRunner;
+}
+
+class SharedMemory;
+class TraceWriter;
+
+// Used by the Producer-side of the transport layer to vend TraceWriters
+// from the SharedMemory it receives from the Service-side.
+class PERFETTO_EXPORT_COMPONENT SharedMemoryArbiter {
+ public:
+  using ShmemMode = SharedMemoryABI::ShmemMode;
+
+  virtual ~SharedMemoryArbiter();
+
+  // Creates a new TraceWriter and assigns it a new WriterID. The WriterID is
+  // written in each chunk header owned by a given TraceWriter and is used by
+  // the Service to reconstruct TracePackets written by the same TraceWriter.
+  // Returns null impl of TraceWriter if all WriterID slots are exhausted. The
+  // writer will commit to the provided |target_buffer|. If the arbiter was
+  // created via CreateUnbound() or CreateStartupTraceWriter() is later used,
+  // only BufferExhaustedPolicy::kDrop is supported.
+  virtual std::unique_ptr<TraceWriter> CreateTraceWriter(
+      BufferID target_buffer,
+      BufferExhaustedPolicy buffer_exhausted_policy =
+          BufferExhaustedPolicy::kDefault) = 0;
+
+  // Creates a TraceWriter that will commit to the target buffer with the given
+  // reservation ID (creating a new reservation for this ID if none exists yet).
+  // The buffer reservation should be bound to an actual BufferID via
+  // BindStartupTargetBuffer() once the actual BufferID is known. Calling this
+  // method may transition the arbiter into unbound state (see state diagram in
+  // SharedMemoryArbiterImpl's class comment) and requires that all (past and
+  // future) TraceWriters are created with BufferExhaustedPolicy::kDrop.
+  //
+  // While any unbound buffer reservation exists, all commits will be buffered
+  // until all reservations were bound. Thus, until all reservations are bound,
+  // the data written to the SMB will not be consumed by the service - the SMB
+  // size should be chosen with this in mind. Startup writers always use
+  // BufferExhaustedPolicy::kDrop, as we cannot feasibly stall while not
+  // flushing to the service.
+  //
+  // The |target_buffer_reservation_id| should be greater than 0 but can
+  // otherwise be freely chosen by the producer and is only used to translate
+  // packets into the actual buffer id once
+  // BindStartupTargetBuffer(reservation_id) is called. For example, Chrome uses
+  // startup tracing not only for the first, but also subsequent tracing
+  // sessions (to enable tracing in the browser process before it instructs the
+  // tracing service to start tracing asynchronously, minimizing trace data loss
+  // in the meantime), and increments the reservation ID between sessions.
+  // Similarly, if more than a single target buffer per session is required
+  // (e.g. for two different data sources), different reservation IDs should be
+  // chosen for different target buffers.
+  virtual std::unique_ptr<TraceWriter> CreateStartupTraceWriter(
+      uint16_t target_buffer_reservation_id) = 0;
+
+  // Should only be called on unbound SharedMemoryArbiters. Binds the arbiter to
+  // the provided ProducerEndpoint and TaskRunner. Should be called only once
+  // and on the provided |TaskRunner|. Usually called by the producer (i.e., no
+  // specific data source) once it connects to the service. Both the endpoint
+  // and task runner should remain valid for the remainder of the arbiter's
+  // lifetime.
+  virtual void BindToProducerEndpoint(TracingService::ProducerEndpoint*,
+                                      base::TaskRunner*) = 0;
+
+  // Binds commits from TraceWriters created via CreateStartupTraceWriter() with
+  // the given |target_buffer_reservation_id| to |target_buffer_id|. May only be
+  // called once per |target_buffer_reservation_id|. Should be called on the
+  // arbiter's TaskRunner, and after BindToProducerEndpoint() was called.
+  // Usually, it is called by a specific data source, after it received its
+  // configuration (including the target buffer ID) from the service.
+  virtual void BindStartupTargetBuffer(uint16_t target_buffer_reservation_id,
+                                       BufferID target_buffer_id) = 0;
+
+  // Treat the reservation as resolved to an invalid buffer. Commits for this
+  // reservation will be flushed to the service ASAP. The service will free
+  // committed chunks but otherwise ignore them. The producer can call this
+  // method, for example, if connection to the tracing service failed or the
+  // session was stopped concurrently before the connection was established.
+  virtual void AbortStartupTracingForReservation(
+      uint16_t target_buffer_reservation_id) = 0;
+
+  // Notifies the service that all data for the given FlushRequestID has been
+  // committed in the shared memory buffer. Should only be called while bound.
+  virtual void NotifyFlushComplete(FlushRequestID) = 0;
+
+  // Sets the duration during which commits are batched. Args:
+  // |batch_commits_duration_ms|: The length of the period, during which commits
+  // by all trace writers are accumulated, before being sent to the service.
+  // When the period ends, all accumulated commits are flushed. On the first
+  // commit after the last flush, another delayed flush is scheduled to run in
+  // |batch_commits_duration_ms|. If an immediate flush occurs (via
+  // FlushPendingCommitDataRequests()) during a batching period, any
+  // accumulated commits up to that point will be sent to the service
+  // immediately. And when the batching period ends, the commits that occurred
+  // after the immediate flush will also be sent to the service.
+  //
+  // If the duration has already been set to a non-zero value before this method
+  // is called, and there is already a scheduled flush with the previously-set
+  // duration, the new duration will take effect after the scheduled flush
+  // occurs.
+  //
+  // If |batch_commits_duration_ms| is non-zero, batched data that hasn't been
+  // sent could be lost at the end of a tracing session. To avoid this,
+  // producers should make sure that FlushPendingCommitDataRequests is called
+  // after the last TraceWriter write and before the service has stopped
+  // listening for commits from the tracing session's data sources (i.e.
+  // data sources should stop asynchronously, see
+  // DataSourceDescriptor.will_notify_on_stop=true).
+  virtual void SetBatchCommitsDuration(uint32_t batch_commits_duration_ms) = 0;
+
+  // Called to enable direct producer-side patching of chunks that have not yet
+  // been committed to the service. The return value indicates whether direct
+  // patching was successfully enabled. It will be true if
+  // SharedMemoryArbiter::SetDirectSMBPatchingSupportedByService has been called
+  // and false otherwise.
+  virtual bool EnableDirectSMBPatching() = 0;
+
+  // When the producer and service live in separate processes, this method
+  // should be called if the producer receives an
+  // InitializeConnectionResponse.direct_smb_patching_supported set to true by
+  // the service (see producer_port.proto) .
+  //
+  // In the in-process case, the service will always support direct SMB patching
+  // and this method should always be called.
+  virtual void SetDirectSMBPatchingSupportedByService() = 0;
+
+  // Forces an immediate commit of the completed packets, without waiting for
+  // the next task or for a batching period to end. Should only be called while
+  // bound.
+  virtual void FlushPendingCommitDataRequests(
+      std::function<void()> callback = {}) = 0;
+
+  // Attempts to shut down this arbiter. This function prevents new trace
+  // writers from being created for this this arbiter, but if there are any
+  // existing trace writers, the shutdown cannot proceed and this funtion
+  // returns false. The caller should not delete the arbiter before all of its
+  // associated trace writers have been destroyed and this function returns
+  // true.
+  virtual bool TryShutdown() = 0;
+
+  // Create a bound arbiter instance. Args:
+  // |SharedMemory|: the shared memory buffer to use.
+  // |page_size|: a multiple of 4KB that defines the granularity of tracing
+  // pages. See tradeoff considerations in shared_memory_abi.h.
+  // |ProducerEndpoint|: The service's producer endpoint used e.g. to commit
+  // chunks and register trace writers.
+  // |TaskRunner|: Task runner for perfetto's main thread, which executes the
+  // OnPagesCompleteCallback and IPC calls to the |ProducerEndpoint|.
+  //
+  // Implemented in src/core/shared_memory_arbiter_impl.cc.
+  static std::unique_ptr<SharedMemoryArbiter> CreateInstance(
+      SharedMemory*,
+      size_t page_size,
+      ShmemMode,
+      TracingService::ProducerEndpoint*,
+      base::TaskRunner*);
+
+  // Create an unbound arbiter instance, which should later be bound to a
+  // ProducerEndpoint and TaskRunner by calling BindToProducerEndpoint(). The
+  // returned arbiter will ONLY support trace writers with
+  // BufferExhaustedPolicy::kDrop.
+  //
+  // An unbound SharedMemoryArbiter can be used to write to a producer-created
+  // SharedMemory buffer before the producer connects to the tracing service.
+  // The producer can then pass this SMB to the service when it connects (see
+  // TracingService::ConnectProducer).
+  //
+  // To trace into the SMB before the service starts the tracing session, trace
+  // writers can be obtained via CreateStartupTraceWriter() and later associated
+  // with a target buffer via BindStartupTargetBuffer(), once the target buffer
+  // is known.
+  //
+  // Implemented in src/core/shared_memory_arbiter_impl.cc. See CreateInstance()
+  // for comments about the arguments.
+  static std::unique_ptr<SharedMemoryArbiter>
+  CreateUnboundInstance(SharedMemory*, size_t page_size, ShmemMode mode);
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_ARBITER_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACING_CORE_SHARED_MEMORY_ARBITER_IMPL_H_
+#define SRC_TRACING_CORE_SHARED_MEMORY_ARBITER_IMPL_H_
+
+#include <stdint.h>
+
+#include <functional>
+#include <map>
+#include <memory>
+#include <mutex>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+// gen_amalgamated expanded: #include "src/tracing/core/id_allocator.h"
+
+namespace perfetto {
+
+class PatchList;
+class Patch;
+class TraceWriter;
+class TraceWriterImpl;
+
+namespace base {
+class TaskRunner;
+}  // namespace base
+
+// This class handles the shared memory buffer on the producer side. It is used
+// to obtain thread-local chunks and to partition pages from several threads.
+// There is one arbiter instance per Producer.
+// This class is thread-safe and uses locks to do so. Data sources are supposed
+// to interact with this sporadically, only when they run out of space on their
+// current thread-local chunk.
+//
+// The arbiter can become "unbound" as a consequence of:
+//  (a) being created without an endpoint
+//  (b) CreateStartupTraceWriter calls after creation (whether created with or
+//      without endpoint).
+//
+// Entering the unbound state is only supported if all trace writers are created
+// in kDrop mode. In the unbound state, the arbiter buffers commit messages
+// until all trace writers are bound to a target buffer.
+//
+// The following state transitions are possible:
+//
+//   CreateInstance()
+//    |
+//    |  CreateUnboundInstance()
+//    |    |
+//    |    |
+//    |    V
+//    |  [ !fully_bound_, !endpoint_, 0 unbound buffer reservations ]
+//    |      |     |
+//    |      |     | CreateStartupTraceWriter(buf)
+//    |      |     |  buffer reservations += buf
+//    |      |     |
+//    |      |     |             ----
+//    |      |     |            |    | CreateStartupTraceWriter(buf)
+//    |      |     |            |    |  buffer reservations += buf
+//    |      |     V            |    V
+//    |      |   [ !fully_bound_, !endpoint_, >=1 unbound buffer reservations ]
+//    |      |                                                |
+//    |      |                       BindToProducerEndpoint() |
+//    |      |                                                |
+//    |      | BindToProducerEndpoint()                       |
+//    |      |                                                V
+//    |      |   [ !fully_bound_, endpoint_, >=1 unbound buffer reservations ]
+//    |      |   A    |    A                               |     A
+//    |      |   |    |    |                               |     |
+//    |      |   |     ----                                |     |
+//    |      |   |    CreateStartupTraceWriter(buf)        |     |
+//    |      |   |     buffer reservations += buf          |     |
+//    |      |   |                                         |     |
+//    |      |   | CreateStartupTraceWriter(buf)           |     |
+//    |      |   |  where buf is not yet bound             |     |
+//    |      |   |  buffer reservations += buf             |     | (yes)
+//    |      |   |                                         |     |
+//    |      |   |        BindStartupTargetBuffer(buf, id) |-----
+//    |      |   |           buffer reservations -= buf    | reservations > 0?
+//    |      |   |                                         |
+//    |      |   |                                         | (no)
+//    |      V   |                                         V
+//     --> [ fully_bound_, endpoint_, 0 unbound buffer reservations ]
+//              |    A
+//              |    | CreateStartupTraceWriter(buf)
+//              |    |  where buf is already bound
+//               ----
+class SharedMemoryArbiterImpl : public SharedMemoryArbiter {
+ public:
+  // See SharedMemoryArbiter::CreateInstance(). |start|, |size| define the
+  // boundaries of the shared memory buffer. ProducerEndpoint and TaskRunner may
+  // be |nullptr| if created unbound, see
+  // SharedMemoryArbiter::CreateUnboundInstance().
+
+  // SharedMemoryArbiterImpl(void* start,
+  //                         size_t size,
+  //                         size_t page_size,
+  //                         TracingService::ProducerEndpoint*
+  //                         producer_endpoint, base::TaskRunner* task_runner) :
+  //   SharedMemoryArbiterImpl(start, size, page_size, false, producer_endpoint,
+  //   task_runner) {
+  // }
+
+  SharedMemoryArbiterImpl(void* start,
+                          size_t size,
+                          ShmemMode mode,
+                          size_t page_size,
+                          TracingService::ProducerEndpoint*,
+                          base::TaskRunner*);
+
+  // Returns a new Chunk to write tracing data. Depending on the provided
+  // BufferExhaustedPolicy, this may return an invalid chunk if no valid free
+  // chunk could be found in the SMB.
+  SharedMemoryABI::Chunk GetNewChunk(const SharedMemoryABI::ChunkHeader&,
+                                     BufferExhaustedPolicy);
+
+  // Puts back a Chunk that has been completed and sends a request to the
+  // service to move it to the central tracing buffer. |target_buffer| is the
+  // absolute trace buffer ID where the service should move the chunk onto (the
+  // producer is just to copy back the same number received in the
+  // DataSourceConfig upon the StartDataSource() reques).
+  // PatchList is a pointer to the list of patches for previous chunks. The
+  // first patched entries will be removed from the patched list and sent over
+  // to the service in the same CommitData() IPC request.
+  void ReturnCompletedChunk(SharedMemoryABI::Chunk,
+                            MaybeUnboundBufferID target_buffer,
+                            PatchList*);
+
+  // Send a request to the service to apply completed patches from |patch_list|.
+  // |writer_id| is the ID of the TraceWriter that calls this method,
+  // |target_buffer| is the global trace buffer ID of its target buffer.
+  void SendPatches(WriterID writer_id,
+                   MaybeUnboundBufferID target_buffer,
+                   PatchList* patch_list);
+
+  SharedMemoryABI* shmem_abi_for_testing() { return &shmem_abi_; }
+
+  static void set_default_layout_for_testing(SharedMemoryABI::PageLayout l) {
+    default_page_layout = l;
+  }
+
+  static SharedMemoryABI::PageLayout default_page_layout_for_testing() {
+    return default_page_layout;
+  }
+
+  // SharedMemoryArbiter implementation.
+  // See include/perfetto/tracing/core/shared_memory_arbiter.h for comments.
+  std::unique_ptr<TraceWriter> CreateTraceWriter(
+      BufferID target_buffer,
+      BufferExhaustedPolicy = BufferExhaustedPolicy::kDefault) override;
+  std::unique_ptr<TraceWriter> CreateStartupTraceWriter(
+      uint16_t target_buffer_reservation_id) override;
+  void BindToProducerEndpoint(TracingService::ProducerEndpoint*,
+                              base::TaskRunner*) override;
+  void BindStartupTargetBuffer(uint16_t target_buffer_reservation_id,
+                               BufferID target_buffer_id) override;
+  void AbortStartupTracingForReservation(
+      uint16_t target_buffer_reservation_id) override;
+  void NotifyFlushComplete(FlushRequestID) override;
+
+  void SetBatchCommitsDuration(uint32_t batch_commits_duration_ms) override;
+
+  bool EnableDirectSMBPatching() override;
+
+  void SetDirectSMBPatchingSupportedByService() override;
+
+  void FlushPendingCommitDataRequests(
+      std::function<void()> callback = {}) override;
+  bool TryShutdown() override;
+
+  base::TaskRunner* task_runner() const { return task_runner_; }
+  size_t page_size() const { return shmem_abi_.page_size(); }
+  size_t num_pages() const { return shmem_abi_.num_pages(); }
+
+  base::WeakPtr<SharedMemoryArbiterImpl> GetWeakPtr() const {
+    return weak_ptr_factory_.GetWeakPtr();
+  }
+
+ private:
+  friend class TraceWriterImpl;
+  friend class StartupTraceWriterTest;
+  friend class SharedMemoryArbiterImplTest;
+
+  struct TargetBufferReservation {
+    bool resolved = false;
+    BufferID target_buffer = kInvalidBufferId;
+  };
+
+  // Placeholder for the actual target buffer ID of a startup target buffer
+  // reservation ID in |target_buffer_reservations_|.
+  static constexpr BufferID kInvalidBufferId = 0;
+
+  static SharedMemoryABI::PageLayout default_page_layout;
+
+  SharedMemoryArbiterImpl(const SharedMemoryArbiterImpl&) = delete;
+  SharedMemoryArbiterImpl& operator=(const SharedMemoryArbiterImpl&) = delete;
+
+  void UpdateCommitDataRequest(SharedMemoryABI::Chunk chunk,
+                               WriterID writer_id,
+                               MaybeUnboundBufferID target_buffer,
+                               PatchList* patch_list);
+
+  // Search the chunks that are being batched in |commit_data_req_| for a chunk
+  // that needs patching and that matches the provided |writer_id| and
+  // |patch.chunk_id|. If found, apply |patch| to that chunk, and if
+  // |chunk_needs_more_patching| is true, clear the needs patching flag of the
+  // chunk and mark it as complete - to allow the service to read it (and other
+  // chunks after it) during scraping. Returns true if the patch was applied,
+  // false otherwise.
+  //
+  // Note: the caller must be holding |lock_| for the duration of the call.
+  bool TryDirectPatchLocked(WriterID writer_id,
+                            const Patch& patch,
+                            bool chunk_needs_more_patching);
+  std::unique_ptr<TraceWriter> CreateTraceWriterInternal(
+      MaybeUnboundBufferID target_buffer,
+      BufferExhaustedPolicy);
+
+  // Called by the TraceWriter destructor.
+  void ReleaseWriterID(WriterID);
+
+  void BindStartupTargetBufferImpl(std::unique_lock<std::mutex> scoped_lock,
+                                   uint16_t target_buffer_reservation_id,
+                                   BufferID target_buffer_id);
+
+  // If any flush callbacks were queued up while the arbiter or any target
+  // buffer reservation was unbound, this wraps the pending callbacks into a new
+  // std::function and returns it. Otherwise returns an invalid std::function.
+  std::function<void()> TakePendingFlushCallbacksLocked();
+
+  // Replace occurrences of target buffer reservation IDs in |commit_data_req_|
+  // with their respective actual BufferIDs if they were already bound. Returns
+  // true iff all occurrences were replaced.
+  bool ReplaceCommitPlaceholderBufferIdsLocked();
+
+  // Update and return |fully_bound_| based on the arbiter's |pending_writers_|
+  // state.
+  bool UpdateFullyBoundLocked();
+
+  // Only accessed on |task_runner_| after the producer endpoint was bound.
+  TracingService::ProducerEndpoint* producer_endpoint_ = nullptr;
+
+  // Set to true when this instance runs in a emulation mode for a producer
+  // endpoint that doesn't support shared memory (e.g. vsock).
+  const bool use_shmem_emulation_ = false;
+
+  // --- Begin lock-protected members ---
+
+  std::mutex lock_;
+
+  base::TaskRunner* task_runner_ = nullptr;
+  SharedMemoryABI shmem_abi_;
+  size_t page_idx_ = 0;
+  std::unique_ptr<CommitDataRequest> commit_data_req_;
+  size_t bytes_pending_commit_ = 0;  // SUM(chunk.size() : commit_data_req_).
+  IdAllocator<WriterID> active_writer_ids_;
+  bool did_shutdown_ = false;
+
+  // Whether the arbiter itself and all startup target buffer reservations are
+  // bound. Note that this can become false again later if a new target buffer
+  // reservation is created by calling CreateStartupTraceWriter() with a new
+  // reservation id.
+  bool fully_bound_;
+
+  // Whether the arbiter was always bound. If false, the arbiter was unbound at
+  // one point in time.
+  bool was_always_bound_;
+
+  // Whether all created trace writers were created with kDrop policy.
+  bool all_writers_have_drop_policy_ = true;
+
+  // IDs of writers and their assigned target buffers that should be registered
+  // with the service after the arbiter and/or their startup target buffer is
+  // bound.
+  std::map<WriterID, MaybeUnboundBufferID> pending_writers_;
+
+  // Callbacks for flush requests issued while the arbiter or a target buffer
+  // reservation was unbound.
+  std::vector<std::function<void()>> pending_flush_callbacks_;
+
+  // See SharedMemoryArbiter::SetBatchCommitsDuration.
+  uint32_t batch_commits_duration_ms_ = 0;
+
+  // See SharedMemoryArbiter::EnableDirectSMBPatching.
+  bool direct_patching_enabled_ = false;
+
+  // See SharedMemoryArbiter::SetDirectSMBPatchingSupportedByService.
+  bool direct_patching_supported_by_service_ = false;
+
+  // Indicates whether we have already scheduled a delayed flush for the
+  // purposes of batching. Set to true at the beginning of a batching period and
+  // cleared at the end of the period. Immediate flushes that happen during a
+  // batching period will empty the |commit_data_req| (triggering an immediate
+  // IPC to the service), but will not clear this flag and the
+  // previously-scheduled delayed flush will still occur at the end of the
+  // batching period.
+  bool delayed_flush_scheduled_ = false;
+
+  // Stores target buffer reservations for writers created via
+  // CreateStartupTraceWriter(). A bound reservation sets
+  // TargetBufferReservation::resolved to true and is associated with the actual
+  // BufferID supplied in BindStartupTargetBuffer().
+  //
+  // TODO(eseckler): Clean up entries from this map. This would probably require
+  // a method in SharedMemoryArbiter that allows a producer to invalidate a
+  // reservation ID.
+  std::map<MaybeUnboundBufferID, TargetBufferReservation>
+      target_buffer_reservations_;
+
+  // --- End lock-protected members ---
+
+  // Keep at the end.
+  base::WeakPtrFactory<SharedMemoryArbiterImpl> weak_ptr_factory_;
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_CORE_SHARED_MEMORY_ARBITER_IMPL_H_
+// gen_amalgamated begin header: include/perfetto/ext/tracing/core/commit_data_request.h
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_COMMIT_DATA_REQUEST_H_
+#define INCLUDE_PERFETTO_EXT_TRACING_CORE_COMMIT_DATA_REQUEST_H_
+
+// Creates the aliases in the ::perfetto namespace, doing things like:
+// using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
+// See comments in forward_decls.h for the historical reasons of this
+// indirection layer.
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/common/commit_data_request.gen.h"
+
+#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_COMMIT_DATA_REQUEST_H_
+// gen_amalgamated begin header: src/tracing/core/trace_writer_impl.h
+// gen_amalgamated begin header: src/tracing/core/patch_list.h
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACING_CORE_PATCH_LIST_H_
+#define SRC_TRACING_CORE_PATCH_LIST_H_
+
+#include <array>
+#include <forward_list>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
+
+namespace perfetto {
+
+// Used to handle the backfilling of the headers (the |size_field|) of nested
+// messages when a proto is fragmented over several chunks. These patches are
+// sent out-of-band to the tracing service, after having returned the initial
+// chunks of the fragment.
+// TODO(crbug.com/904477): Re-disable the move constructors when all usses of
+// this class have been fixed.
+class Patch {
+ public:
+  using PatchContent = std::array<uint8_t, SharedMemoryABI::kPacketHeaderSize>;
+  Patch(ChunkID c, uint16_t o) : chunk_id(c), offset(o) {}
+  Patch(const Patch&) = default;  // For tests.
+
+  const ChunkID chunk_id;
+  const uint16_t offset;
+  PatchContent size_field{};
+
+  // |size_field| contains a varint. Any varint must start with != 0. Even in
+  // the case we want to encode a size == 0, protozero will write a redundant
+  // varint for that, that is [0x80, 0x80, 0x80, 0x00]. So the first byte is 0
+  // iff we never wrote any varint into that.
+  bool is_patched() const { return size_field[0] != 0; }
+
+  // For tests.
+  bool operator==(const Patch& o) const {
+    return chunk_id == o.chunk_id && offset == o.offset &&
+           size_field == o.size_field;
+  }
+
+ private:
+  Patch& operator=(const Patch&) = delete;
+};
+
+// Note: the protozero::Message(s) will take pointers to the |size_field| of
+// these entries. This container must guarantee that the Patch objects are never
+// moved around (i.e. cannot be a vector because of reallocations can change
+// addresses of pre-existing entries).
+class PatchList {
+ public:
+  using ListType = std::forward_list<Patch>;
+  using value_type = ListType::value_type;          // For gtest.
+  using const_iterator = ListType::const_iterator;  // For gtest.
+
+  PatchList() : last_(list_.before_begin()) {}
+
+  Patch* emplace_back(ChunkID chunk_id, uint16_t offset) {
+    last_ = list_.emplace_after(last_, chunk_id, offset);
+    return &*last_;
+  }
+
+  void pop_front() {
+    PERFETTO_DCHECK(!list_.empty());
+    list_.pop_front();
+    if (empty())
+      last_ = list_.before_begin();
+  }
+
+  const Patch& front() const {
+    PERFETTO_DCHECK(!list_.empty());
+    return list_.front();
+  }
+
+  const Patch& back() const {
+    PERFETTO_DCHECK(!list_.empty());
+    return *last_;
+  }
+
+  ListType::const_iterator begin() const { return list_.begin(); }
+  ListType::const_iterator end() const { return list_.end(); }
+  bool empty() const { return list_.empty(); }
+
+ private:
+  ListType list_;
+  ListType::iterator last_;
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_CORE_PATCH_LIST_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACING_CORE_TRACE_WRITER_IMPL_H_
+#define SRC_TRACING_CORE_TRACE_WRITER_IMPL_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/proc_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/root_message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/buffer_exhausted_policy.h"
+// gen_amalgamated expanded: #include "src/tracing/core/patch_list.h"
+
+namespace perfetto {
+
+class SharedMemoryArbiterImpl;
+
+// See //include/perfetto/ext/tracing/core/trace_writer.h for docs.
+//
+// Locking will happen only when a chunk is exhausted and a new one is
+// acquired from the arbiter.
+//
+// TODO: TraceWriter needs to keep the shared memory buffer alive (refcount?).
+// Otherwise if the shared memory buffer goes away (e.g. the Service crashes)
+// the TraceWriter will keep writing into unmapped memory.
+//
+class TraceWriterImpl : public TraceWriter,
+                        public protozero::MessageFinalizationListener,
+                        public protozero::ScatteredStreamWriter::Delegate {
+ public:
+  // TracePacketHandle is defined in trace_writer.h
+  TraceWriterImpl(SharedMemoryArbiterImpl*,
+                  WriterID,
+                  MaybeUnboundBufferID buffer_id,
+                  BufferExhaustedPolicy);
+  ~TraceWriterImpl() override;
+
+  // TraceWriter implementation. See documentation in trace_writer.h.
+  TracePacketHandle NewTracePacket() override;
+  void FinishTracePacket() override;
+  // Commits the data pending for the current chunk into the shared memory
+  // buffer and sends a CommitDataRequest() to the service.
+  // TODO(primiano): right now the |callback| will be called on the IPC thread.
+  // This is fine in the current single-thread scenario, but long-term
+  // trace_writer_impl.cc should be smarter and post it on the right thread.
+  void Flush(std::function<void()> callback = {}) override;
+  WriterID writer_id() const override;
+  uint64_t written() const override {
+    return protobuf_stream_writer_.written();
+  }
+
+  void ResetChunkForTesting() {
+    cur_chunk_ = SharedMemoryABI::Chunk();
+    cur_chunk_packet_count_inflated_ = false;
+  }
+  bool drop_packets_for_testing() const { return drop_packets_; }
+
+ private:
+  TraceWriterImpl(const TraceWriterImpl&) = delete;
+  TraceWriterImpl& operator=(const TraceWriterImpl&) = delete;
+
+  // ScatteredStreamWriter::Delegate implementation.
+  protozero::ContiguousMemoryRange GetNewBuffer() override;
+  uint8_t* AnnotatePatch(uint8_t*) override;
+
+  // MessageFinalizationListener implementation.
+  void OnMessageFinalized(protozero::Message*) override;
+
+  // Writes the size of the current fragment into the chunk.
+  //
+  // The size of nested messages inside TracePacket is written by
+  // by the user, but the size of the TracePacket fragments is written by
+  // TraceWriterImpl.
+  void FinalizeFragmentIfRequired();
+
+  // Returns |cur_chunk_| (for which is_valid() must be true) to the
+  // |shmem_arbiter|.
+  void ReturnCompletedChunk();
+
+  // The per-producer arbiter that coordinates access to the shared memory
+  // buffer from several threads.
+  SharedMemoryArbiterImpl* const shmem_arbiter_;
+
+  // ID of the current writer.
+  const WriterID id_;
+
+  // This is copied into the commit request by SharedMemoryArbiter. See comments
+  // in data_source_config.proto for |target_buffer|. If this is a reservation
+  // for a buffer ID in case of a startup trace writer, SharedMemoryArbiterImpl
+  // will also translate the reservation ID to the actual buffer ID.
+  const MaybeUnboundBufferID target_buffer_;
+
+  // Whether GetNewChunk() should stall or return an invalid chunk if the SMB is
+  // exhausted.
+  const BufferExhaustedPolicy buffer_exhausted_policy_;
+
+  // Monotonic (% wrapping) sequence id of the chunk. Together with the WriterID
+  // this allows the Service to reconstruct the linear sequence of packets.
+  ChunkID next_chunk_id_ = 0;
+
+  // The chunk we are holding onto (if any).
+  SharedMemoryABI::Chunk cur_chunk_;
+
+  // Passed to protozero message to write directly into |cur_chunk_|. It
+  // keeps track of the write pointer. It calls us back (GetNewBuffer()) when
+  // |cur_chunk_| is filled.
+  protozero::ScatteredStreamWriter protobuf_stream_writer_;
+
+  // The packet returned via NewTracePacket(). Its owned by this class,
+  // TracePacketHandle has just a pointer to it.
+  //
+  // The caller of NewTracePacket can use TakeStreamWriter() and use the stream
+  // writer directly: in that case:
+  // * cur_packet_->size() is not up to date. Only the stream writer has the
+  //   correct information.
+  // * cur_packet_->nested_message() is always nullptr.
+  // * cur_packet_->size_field() is still used to track the start of the current
+  //   fragment.
+  std::unique_ptr<protozero::RootMessage<protos::pbzero::TracePacket>>
+      cur_packet_;
+
+  // The start address of |cur_packet_| within |cur_chunk_|. Used to figure out
+  // fragments sizes when a TracePacket write is interrupted by GetNewBuffer().
+  uint8_t* cur_fragment_start_ = nullptr;
+
+  // true if we received a call to GetNewBuffer() after NewTracePacket(),
+  // false if GetNewBuffer() happened during NewTracePacket() prologue, while
+  // starting the TracePacket header.
+  bool fragmenting_packet_ = false;
+
+  // Set to |true| when the current chunk contains the maximum number of packets
+  // a chunk can contain. When this is |true|, the next packet requires starting
+  // a new chunk.
+  bool reached_max_packets_per_chunk_ = false;
+
+  // If we fail to acquire a new chunk when the arbiter operates in
+  // SharedMemory::BufferExhaustedPolicy::kDrop mode, the trace writer enters a
+  // mode in which data is written to a local garbage chunk and dropped.
+  bool drop_packets_ = false;
+
+  // Whether the trace writer should try to acquire a new chunk from the SMB
+  // when the next TracePacket is started because it filled the garbage chunk at
+  // least once since the last attempt.
+  bool retry_new_chunk_after_packet_ = false;
+
+  // Set to true if `cur_chunk_` has a packet counter that's inflated by one.
+  // The count may be inflated to convince the tracing service scraping logic
+  // that the last packet has been completed. When this is true, cur_chunk_
+  // should have at least `kExtraRoomForInflatedPacket` bytes free.
+  bool cur_chunk_packet_count_inflated_ = false;
+
+  // Points to the size field of the still open fragment we're writing to the
+  // current chunk. If the chunk was already returned, this is reset to
+  // |nullptr|. If the fragment is finalized, this is reset to |nullptr|.
+  //
+  // Note: for nested messages the field is tracked somewhere else
+  // (protozero::Message::size_field_ or PerfettoPbMsg::size_field). For the
+  // root message, protozero::Message::size_field_ is nullptr and this is used
+  // instead. This is because at the root level we deal with fragments, not
+  // logical messages.
+  uint8_t* cur_fragment_size_field_ = nullptr;
+
+  // When a packet is fragmented across different chunks, the |size_field| of
+  // the outstanding nested protobuf messages is redirected onto Patch entries
+  // in this list at the time the Chunk is returned (because at that point we
+  // have to release the ownership of the current Chunk). This list will be
+  // later sent out-of-band to the tracing service, who will patch the required
+  // chunks, if they are still around.
+  PatchList patch_list_;
+
+  // PID of the process that created the trace writer. Used for a DCHECK that
+  // aims to detect unsupported process forks while tracing.
+  const base::PlatformProcessId process_id_;
+
+  // True for the first packet on sequence. See the comment for
+  // TracePacket.first_packet_on_sequence for more details.
+  bool first_packet_on_sequence_ = true;
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_CORE_TRACE_WRITER_IMPL_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/core/shared_memory_arbiter_impl.h"
+
+#include <algorithm>
+#include <limits>
+#include <utility>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/commit_data_request.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
+// gen_amalgamated expanded: #include "src/tracing/core/null_trace_writer.h"
+// gen_amalgamated expanded: #include "src/tracing/core/trace_writer_impl.h"
+
+namespace perfetto {
+
+using Chunk = SharedMemoryABI::Chunk;
+
+namespace {
+static_assert(sizeof(BufferID) == sizeof(uint16_t),
+              "The MaybeUnboundBufferID logic requires BufferID not to grow "
+              "above uint16_t.");
+
+MaybeUnboundBufferID MakeTargetBufferIdForReservation(uint16_t reservation_id) {
+  // Reservation IDs are stored in the upper bits.
+  PERFETTO_CHECK(reservation_id > 0);
+  return static_cast<MaybeUnboundBufferID>(reservation_id) << 16;
+}
+
+bool IsReservationTargetBufferId(MaybeUnboundBufferID buffer_id) {
+  return (buffer_id >> 16) > 0;
+}
+}  // namespace
+
+// static
+SharedMemoryABI::PageLayout SharedMemoryArbiterImpl::default_page_layout =
+    SharedMemoryABI::PageLayout::kPageDiv1;
+
+// static
+std::unique_ptr<SharedMemoryArbiter> SharedMemoryArbiter::CreateInstance(
+    SharedMemory* shared_memory,
+    size_t page_size,
+    ShmemMode mode,
+    TracingService::ProducerEndpoint* producer_endpoint,
+    base::TaskRunner* task_runner) {
+  return std::unique_ptr<SharedMemoryArbiterImpl>(new SharedMemoryArbiterImpl(
+      shared_memory->start(), shared_memory->size(), mode, page_size,
+      producer_endpoint, task_runner));
+}
+
+// static
+std::unique_ptr<SharedMemoryArbiter> SharedMemoryArbiter::CreateUnboundInstance(
+    SharedMemory* shared_memory,
+    size_t page_size,
+    ShmemMode mode) {
+  return std::unique_ptr<SharedMemoryArbiterImpl>(new SharedMemoryArbiterImpl(
+      shared_memory->start(), shared_memory->size(), mode, page_size,
+      /*producer_endpoint=*/nullptr, /*task_runner=*/nullptr));
+}
+
+SharedMemoryArbiterImpl::SharedMemoryArbiterImpl(
+    void* start,
+    size_t size,
+    ShmemMode mode,
+    size_t page_size,
+    TracingService::ProducerEndpoint* producer_endpoint,
+    base::TaskRunner* task_runner)
+    : producer_endpoint_(producer_endpoint),
+      use_shmem_emulation_(mode == ShmemMode::kShmemEmulation),
+      task_runner_(task_runner),
+      shmem_abi_(reinterpret_cast<uint8_t*>(start), size, page_size, mode),
+      active_writer_ids_(kMaxWriterID),
+      fully_bound_(task_runner && producer_endpoint),
+      was_always_bound_(fully_bound_),
+      weak_ptr_factory_(this) {}
+
+Chunk SharedMemoryArbiterImpl::GetNewChunk(
+    const SharedMemoryABI::ChunkHeader& header,
+    BufferExhaustedPolicy buffer_exhausted_policy) {
+  int stall_count = 0;
+  unsigned stall_interval_us = 0;
+  bool task_runner_runs_on_current_thread = false;
+  static const unsigned kMaxStallIntervalUs = 100000;
+  static const int kLogAfterNStalls = 3;
+  static const int kFlushCommitsAfterEveryNStalls = 2;
+  static const int kAssertAtNStalls = 200;
+
+  for (;;) {
+    // TODO(primiano): Probably this lock is not really required and this code
+    // could be rewritten leveraging only the Try* atomic operations in
+    // SharedMemoryABI. But let's not be too adventurous for the moment.
+    {
+      std::unique_lock<std::mutex> scoped_lock(lock_);
+
+      // If ever unbound, we do not support stalling. In theory, we could
+      // support stalling for TraceWriters created after the arbiter and startup
+      // buffer reservations were bound, but to avoid raciness between the
+      // creation of startup writers and binding, we categorically forbid kStall
+      // mode.
+      PERFETTO_DCHECK(was_always_bound_ ||
+                      buffer_exhausted_policy == BufferExhaustedPolicy::kDrop);
+
+      task_runner_runs_on_current_thread =
+          task_runner_ && task_runner_->RunsTasksOnCurrentThread();
+
+      // If more than half of the SMB.size() is filled with completed chunks for
+      // which we haven't notified the service yet (i.e. they are still enqueued
+      // in |commit_data_req_|), force a synchronous CommitDataRequest() even if
+      // we acquire a chunk, to reduce the likeliness of stalling the writer.
+      //
+      // We can only do this if we're writing on the same thread that we access
+      // the producer endpoint on, since we cannot notify the producer endpoint
+      // to commit synchronously on a different thread. Attempting to flush
+      // synchronously on another thread will lead to subtle bugs caused by
+      // out-of-order commit requests (crbug.com/919187#c28).
+      bool should_commit_synchronously =
+          task_runner_runs_on_current_thread &&
+          buffer_exhausted_policy == BufferExhaustedPolicy::kStall &&
+          commit_data_req_ && bytes_pending_commit_ >= shmem_abi_.size() / 2;
+
+      const size_t initial_page_idx = page_idx_;
+      for (size_t i = 0; i < shmem_abi_.num_pages(); i++) {
+        page_idx_ = (initial_page_idx + i) % shmem_abi_.num_pages();
+        bool is_new_page = false;
+
+        // TODO(primiano): make the page layout dynamic.
+        auto layout = SharedMemoryArbiterImpl::default_page_layout;
+
+        if (shmem_abi_.is_page_free(page_idx_)) {
+          // TODO(primiano): Use the |size_hint| here to decide the layout.
+          is_new_page = shmem_abi_.TryPartitionPage(page_idx_, layout);
+        }
+        uint32_t free_chunks;
+        if (is_new_page) {
+          free_chunks = (1 << SharedMemoryABI::kNumChunksForLayout[layout]) - 1;
+        } else {
+          free_chunks = shmem_abi_.GetFreeChunks(page_idx_);
+        }
+
+        for (uint32_t chunk_idx = 0; free_chunks;
+             chunk_idx++, free_chunks >>= 1) {
+          if (!(free_chunks & 1))
+            continue;
+          // We found a free chunk.
+          Chunk chunk = shmem_abi_.TryAcquireChunkForWriting(
+              page_idx_, chunk_idx, &header);
+          if (!chunk.is_valid())
+            continue;
+          if (stall_count > kLogAfterNStalls) {
+            PERFETTO_LOG("Recovered from stall after %d iterations",
+                         stall_count);
+          }
+
+          if (should_commit_synchronously) {
+            // We can't flush while holding the lock.
+            scoped_lock.unlock();
+            FlushPendingCommitDataRequests();
+            return chunk;
+          } else {
+            return chunk;
+          }
+        }
+      }
+    }  // scoped_lock
+
+    if (buffer_exhausted_policy == BufferExhaustedPolicy::kDrop) {
+      PERFETTO_DLOG("Shared memory buffer exhausted, returning invalid Chunk!");
+      return Chunk();
+    }
+
+    // Stalling is not supported if we were ever unbound (see earlier comment).
+    PERFETTO_CHECK(was_always_bound_);
+
+    // All chunks are taken (either kBeingWritten by us or kBeingRead by the
+    // Service).
+    if (stall_count++ == kLogAfterNStalls) {
+      PERFETTO_LOG("Shared memory buffer overrun! Stalling");
+    }
+
+    if (stall_count == kAssertAtNStalls) {
+      PERFETTO_FATAL(
+          "Shared memory buffer max stall count exceeded; possible deadlock");
+    }
+
+    // If the IPC thread itself is stalled because the current process has
+    // filled up the SMB, we need to make sure that the service can process and
+    // purge the chunks written by our process, by flushing any pending commit
+    // requests. Because other threads in our process can continue to
+    // concurrently grab, fill and commit any chunks purged by the service, it
+    // is possible that the SMB remains full and the IPC thread remains stalled,
+    // needing to flush the concurrently queued up commits again. This is
+    // particularly likely with in-process perfetto service where the IPC thread
+    // is the service thread. To avoid remaining stalled forever in such a
+    // situation, we attempt to flush periodically after every N stalls.
+    if (stall_count % kFlushCommitsAfterEveryNStalls == 0 &&
+        task_runner_runs_on_current_thread) {
+      // TODO(primiano): sending the IPC synchronously is a temporary workaround
+      // until the backpressure logic in probes_producer is sorted out. Until
+      // then the risk is that we stall the message loop waiting for the tracing
+      // service to consume the shared memory buffer (SMB) and, for this reason,
+      // never run the task that tells the service to purge the SMB. This must
+      // happen iff we are on the IPC thread, not doing this will cause
+      // deadlocks, doing this on the wrong thread causes out-of-order data
+      // commits (crbug.com/919187#c28).
+      FlushPendingCommitDataRequests();
+    } else {
+      base::SleepMicroseconds(stall_interval_us);
+      stall_interval_us =
+          std::min(kMaxStallIntervalUs, (stall_interval_us + 1) * 8);
+    }
+  }
+}
+
+void SharedMemoryArbiterImpl::ReturnCompletedChunk(
+    Chunk chunk,
+    MaybeUnboundBufferID target_buffer,
+    PatchList* patch_list) {
+  PERFETTO_DCHECK(chunk.is_valid());
+  const WriterID writer_id = chunk.writer_id();
+  UpdateCommitDataRequest(std::move(chunk), writer_id, target_buffer,
+                          patch_list);
+}
+
+void SharedMemoryArbiterImpl::SendPatches(WriterID writer_id,
+                                          MaybeUnboundBufferID target_buffer,
+                                          PatchList* patch_list) {
+  PERFETTO_DCHECK(!patch_list->empty() && patch_list->front().is_patched());
+  UpdateCommitDataRequest(Chunk(), writer_id, target_buffer, patch_list);
+}
+
+void SharedMemoryArbiterImpl::UpdateCommitDataRequest(
+    Chunk chunk,
+    WriterID writer_id,
+    MaybeUnboundBufferID target_buffer,
+    PatchList* patch_list) {
+  // Note: chunk will be invalid if the call came from SendPatches().
+  base::TaskRunner* task_runner_to_post_delayed_callback_on = nullptr;
+  // The delay with which the flush will be posted.
+  uint32_t flush_delay_ms = 0;
+  base::WeakPtr<SharedMemoryArbiterImpl> weak_this;
+  {
+    std::lock_guard<std::mutex> scoped_lock(lock_);
+
+    if (!commit_data_req_) {
+      commit_data_req_.reset(new CommitDataRequest());
+
+      // Flushing the commit is only supported while we're |fully_bound_|. If we
+      // aren't, we'll flush when |fully_bound_| is updated.
+      if (fully_bound_ && !delayed_flush_scheduled_) {
+        weak_this = weak_ptr_factory_.GetWeakPtr();
+        task_runner_to_post_delayed_callback_on = task_runner_;
+        flush_delay_ms = batch_commits_duration_ms_;
+        delayed_flush_scheduled_ = true;
+      }
+    }
+
+    CommitDataRequest::ChunksToMove* ctm = nullptr;  // Set if chunk is valid.
+    // If a valid chunk is specified, return it and attach it to the request.
+    if (chunk.is_valid()) {
+      PERFETTO_DCHECK(chunk.writer_id() == writer_id);
+      uint8_t chunk_idx = chunk.chunk_idx();
+      bytes_pending_commit_ += chunk.size();
+      size_t page_idx;
+
+      ctm = commit_data_req_->add_chunks_to_move();
+      // If the chunk needs patching, it should not be marked as complete yet,
+      // because this would indicate to the service that the producer will not
+      // be writing to it anymore, while the producer might still apply patches
+      // to the chunk later on. In particular, when re-reading (e.g. because of
+      // periodic scraping) a completed chunk, the service expects the flags of
+      // that chunk not to be removed between reads. So, let's say the producer
+      // marked the chunk as complete here and the service then read it for the
+      // first time. If the producer then fully patched the chunk, thus removing
+      // the kChunkNeedsPatching flag, and the service re-read the chunk after
+      // the patching, the service would be thrown off by the removed flag.
+      if (direct_patching_enabled_ &&
+          (chunk.GetPacketCountAndFlags().second &
+           SharedMemoryABI::ChunkHeader::kChunkNeedsPatching)) {
+        page_idx = shmem_abi_.GetPageAndChunkIndex(std::move(chunk)).first;
+      } else {
+        // If the chunk doesn't need patching, we can mark it as complete
+        // immediately. This allows the service to read it in full while
+        // scraping, which would not be the case if the chunk was left in a
+        // kChunkBeingWritten state.
+        page_idx = shmem_abi_.ReleaseChunkAsComplete(std::move(chunk));
+      }
+
+      // DO NOT access |chunk| after this point, it has been std::move()-d
+      // above.
+      ctm->set_page(static_cast<uint32_t>(page_idx));
+      ctm->set_chunk(chunk_idx);
+      ctm->set_target_buffer(target_buffer);
+    }
+
+    // Process the completed patches for previous chunks from the |patch_list|.
+    CommitDataRequest::ChunkToPatch* last_patch_req = nullptr;
+    while (!patch_list->empty() && patch_list->front().is_patched()) {
+      Patch curr_patch = patch_list->front();
+      patch_list->pop_front();
+      // Patches for the same chunk are contiguous in the |patch_list|. So, to
+      // determine if there are any other patches that apply to the chunk that
+      // is being patched, check if the next patch in the |patch_list| applies
+      // to the same chunk.
+      bool chunk_needs_more_patching =
+          !patch_list->empty() &&
+          patch_list->front().chunk_id == curr_patch.chunk_id;
+
+      if (direct_patching_enabled_ &&
+          TryDirectPatchLocked(writer_id, curr_patch,
+                               chunk_needs_more_patching)) {
+        continue;
+      }
+
+      // The chunk that this patch applies to has already been released to the
+      // service, so it cannot be patches here. Add the patch to the commit data
+      // request, so that it can be sent to the service and applied there.
+      if (!last_patch_req ||
+          last_patch_req->chunk_id() != curr_patch.chunk_id) {
+        last_patch_req = commit_data_req_->add_chunks_to_patch();
+        last_patch_req->set_writer_id(writer_id);
+        last_patch_req->set_chunk_id(curr_patch.chunk_id);
+        last_patch_req->set_target_buffer(target_buffer);
+      }
+      auto* patch = last_patch_req->add_patches();
+      patch->set_offset(curr_patch.offset);
+      patch->set_data(&curr_patch.size_field[0], curr_patch.size_field.size());
+    }
+
+    // Patches are enqueued in the |patch_list| in order and are notified to
+    // the service when the chunk is returned. The only case when the current
+    // patch list is incomplete is if there is an unpatched entry at the head of
+    // the |patch_list| that belongs to the same ChunkID as the last one we are
+    // about to send to the service.
+    if (last_patch_req && !patch_list->empty() &&
+        patch_list->front().chunk_id == last_patch_req->chunk_id()) {
+      last_patch_req->set_has_more_patches(true);
+    }
+
+    // If the buffer is filling up or if we are given a patch for a chunk
+    // that was already sent to the service, we don't want to wait for the next
+    // delayed flush to happen and we flush immediately. Otherwise, if we
+    // accumulate the patch and a crash occurs before the patch is sent, the
+    // service will not know of the patch and won't be able to reconstruct the
+    // trace.
+    if (fully_bound_ &&
+        (last_patch_req || bytes_pending_commit_ >= shmem_abi_.size() / 2)) {
+      weak_this = weak_ptr_factory_.GetWeakPtr();
+      task_runner_to_post_delayed_callback_on = task_runner_;
+      flush_delay_ms = 0;
+    }
+  }  // scoped_lock(lock_)
+
+  // We shouldn't post tasks while locked.
+  // |task_runner_to_post_delayed_callback_on| remains valid after unlocking,
+  // because |task_runner_| is never reset.
+  if (task_runner_to_post_delayed_callback_on) {
+    task_runner_to_post_delayed_callback_on->PostDelayedTask(
+        [weak_this] {
+          if (!weak_this)
+            return;
+          {
+            std::lock_guard<std::mutex> scoped_lock(weak_this->lock_);
+            // Clear |delayed_flush_scheduled_|, allowing the next call to
+            // UpdateCommitDataRequest to start another batching period.
+            weak_this->delayed_flush_scheduled_ = false;
+          }
+          weak_this->FlushPendingCommitDataRequests();
+        },
+        flush_delay_ms);
+  }
+}
+
+bool SharedMemoryArbiterImpl::TryDirectPatchLocked(
+    WriterID writer_id,
+    const Patch& patch,
+    bool chunk_needs_more_patching) {
+  // Search the chunks that are being batched in |commit_data_req_| for a chunk
+  // that needs patching and that matches the provided |writer_id| and
+  // |patch.chunk_id|. Iterate |commit_data_req_| in reverse, since
+  // |commit_data_req_| is appended to at the end with newly-returned chunks,
+  // and patches are more likely to apply to chunks that have been returned
+  // recently.
+  SharedMemoryABI::Chunk chunk;
+  bool chunk_found = false;
+  auto& chunks_to_move = commit_data_req_->chunks_to_move();
+  for (auto ctm_it = chunks_to_move.rbegin(); ctm_it != chunks_to_move.rend();
+       ++ctm_it) {
+    uint32_t layout = shmem_abi_.GetPageLayout(ctm_it->page());
+    auto chunk_state =
+        shmem_abi_.GetChunkStateFromLayout(layout, ctm_it->chunk());
+    // Note: the subset of |commit_data_req_| chunks that still need patching is
+    // also the subset of chunks that are still being written to. The rest of
+    // the chunks in |commit_data_req_| do not need patching and have already
+    // been marked as complete.
+    if (chunk_state != SharedMemoryABI::kChunkBeingWritten)
+      continue;
+
+    chunk =
+        shmem_abi_.GetChunkUnchecked(ctm_it->page(), layout, ctm_it->chunk());
+    if (chunk.writer_id() == writer_id &&
+        chunk.header()->chunk_id.load(std::memory_order_relaxed) ==
+            patch.chunk_id) {
+      chunk_found = true;
+      break;
+    }
+  }
+
+  if (!chunk_found) {
+    // The chunk has already been committed to the service and the patch cannot
+    // be applied in the producer.
+    return false;
+  }
+
+  // Apply the patch.
+  size_t page_idx;
+  uint8_t chunk_idx;
+  std::tie(page_idx, chunk_idx) = shmem_abi_.GetPageAndChunkIndex(chunk);
+  PERFETTO_DCHECK(shmem_abi_.GetChunkState(page_idx, chunk_idx) ==
+                  SharedMemoryABI::ChunkState::kChunkBeingWritten);
+  auto chunk_begin = chunk.payload_begin();
+  uint8_t* ptr = chunk_begin + patch.offset;
+  PERFETTO_CHECK(ptr <= chunk.end() - SharedMemoryABI::kPacketHeaderSize);
+  // DCHECK that we are writing into a zero-filled size field and not into
+  // valid data. It relies on ScatteredStreamWriter::ReserveBytes() to
+  // zero-fill reservations in debug builds.
+  const char zero[SharedMemoryABI::kPacketHeaderSize]{};
+  PERFETTO_DCHECK(memcmp(ptr, &zero, SharedMemoryABI::kPacketHeaderSize) == 0);
+
+  memcpy(ptr, &patch.size_field[0], SharedMemoryABI::kPacketHeaderSize);
+
+  if (!chunk_needs_more_patching) {
+    // Mark that the chunk doesn't need more patching and mark it as complete,
+    // as the producer will not write to it anymore. This allows the service to
+    // read the chunk in full while scraping, which would not be the case if the
+    // chunk was left in a kChunkBeingWritten state.
+    chunk.ClearNeedsPatchingFlag();
+    shmem_abi_.ReleaseChunkAsComplete(std::move(chunk));
+  }
+
+  return true;
+}
+
+void SharedMemoryArbiterImpl::SetBatchCommitsDuration(
+    uint32_t batch_commits_duration_ms) {
+  std::lock_guard<std::mutex> scoped_lock(lock_);
+  batch_commits_duration_ms_ = batch_commits_duration_ms;
+}
+
+bool SharedMemoryArbiterImpl::EnableDirectSMBPatching() {
+  std::lock_guard<std::mutex> scoped_lock(lock_);
+  if (!direct_patching_supported_by_service_) {
+    return false;
+  }
+
+  return direct_patching_enabled_ = true;
+}
+
+void SharedMemoryArbiterImpl::SetDirectSMBPatchingSupportedByService() {
+  std::lock_guard<std::mutex> scoped_lock(lock_);
+  direct_patching_supported_by_service_ = true;
+}
+
+// This function is quite subtle. When making changes keep in mind these two
+// challenges:
+// 1) If the producer stalls and we happen to be on the |task_runner_| IPC
+//    thread (or, for in-process cases, on the same thread where
+//    TracingServiceImpl lives), the CommitData() call must be synchronous and
+//    not posted, to avoid deadlocks.
+// 2) When different threads hit this function, we must guarantee that we don't
+//    accidentally make commits out of order. See commit 4e4fe8f56ef and
+//    crbug.com/919187 for more context.
+void SharedMemoryArbiterImpl::FlushPendingCommitDataRequests(
+    std::function<void()> callback) {
+  std::unique_ptr<CommitDataRequest> req;
+  {
+    std::unique_lock<std::mutex> scoped_lock(lock_);
+
+    // Flushing is only supported while |fully_bound_|, and there may still be
+    // unbound startup trace writers. If so, skip the commit for now - it'll be
+    // done when |fully_bound_| is updated.
+    if (!fully_bound_) {
+      if (callback)
+        pending_flush_callbacks_.push_back(callback);
+      return;
+    }
+
+    // May be called by TraceWriterImpl on any thread.
+    base::TaskRunner* task_runner = task_runner_;
+    if (!task_runner->RunsTasksOnCurrentThread()) {
+      // We shouldn't post a task while holding a lock. |task_runner| remains
+      // valid after unlocking, because |task_runner_| is never reset.
+      scoped_lock.unlock();
+
+      auto weak_this = weak_ptr_factory_.GetWeakPtr();
+      task_runner->PostTask([weak_this, callback] {
+        if (weak_this)
+          weak_this->FlushPendingCommitDataRequests(std::move(callback));
+      });
+      return;
+    }
+
+    // |commit_data_req_| could have become a nullptr, for example when a forced
+    // sync flush happens in GetNewChunk().
+    if (commit_data_req_) {
+      // Make sure any placeholder buffer IDs from StartupWriters are replaced
+      // before sending the request.
+      bool all_placeholders_replaced =
+          ReplaceCommitPlaceholderBufferIdsLocked();
+      // We're |fully_bound_|, thus all writers are bound and all placeholders
+      // should have been replaced.
+      PERFETTO_DCHECK(all_placeholders_replaced);
+
+      // In order to allow patching in the producer we delay the kChunkComplete
+      // transition and keep batched chunks in the kChunkBeingWritten state.
+      // Since we are about to notify the service of all batched chunks, it will
+      // not be possible to apply any more patches to them and we need to move
+      // them to kChunkComplete - otherwise the service won't look at them.
+      for (auto& ctm : *commit_data_req_->mutable_chunks_to_move()) {
+        uint32_t layout = shmem_abi_.GetPageLayout(ctm.page());
+        auto chunk_state =
+            shmem_abi_.GetChunkStateFromLayout(layout, ctm.chunk());
+        // Note: the subset of |commit_data_req_| chunks that still need
+        // patching is also the subset of chunks that are still being written
+        // to. The rest of the chunks in |commit_data_req_| do not need patching
+        // and have already been marked as complete.
+        if (chunk_state == SharedMemoryABI::kChunkBeingWritten) {
+          auto chunk =
+              shmem_abi_.GetChunkUnchecked(ctm.page(), layout, ctm.chunk());
+          shmem_abi_.ReleaseChunkAsComplete(std::move(chunk));
+        }
+
+        if (use_shmem_emulation_) {
+          // When running in the emulation mode:
+          // 1. serialize the chunk data to |ctm| as we won't modify the chunk
+          // anymore.
+          // 2. free the chunk as the service won't be able to do this.
+          auto chunk =
+              shmem_abi_.GetChunkUnchecked(ctm.page(), layout, ctm.chunk());
+          PERFETTO_CHECK(chunk.is_valid());
+          ctm.set_data(chunk.begin(), chunk.size());
+          shmem_abi_.ReleaseChunkAsFree(std::move(chunk));
+        }
+      }
+
+      req = std::move(commit_data_req_);
+      bytes_pending_commit_ = 0;
+    }
+  }  // scoped_lock
+
+  if (req) {
+    producer_endpoint_->CommitData(*req, callback);
+  } else if (callback) {
+    // If |req| was nullptr, it means that an enqueued deferred commit was
+    // executed just before this. At this point send an empty commit request
+    // to the service, just to linearize with it and give the guarantee to the
+    // caller that the data has been flushed into the service.
+    producer_endpoint_->CommitData(CommitDataRequest(), std::move(callback));
+  }
+}
+
+bool SharedMemoryArbiterImpl::TryShutdown() {
+  std::lock_guard<std::mutex> scoped_lock(lock_);
+  did_shutdown_ = true;
+  // Shutdown is safe if there are no active trace writers for this arbiter.
+  return active_writer_ids_.IsEmpty();
+}
+
+std::unique_ptr<TraceWriter> SharedMemoryArbiterImpl::CreateTraceWriter(
+    BufferID target_buffer,
+    BufferExhaustedPolicy buffer_exhausted_policy) {
+  PERFETTO_CHECK(target_buffer > 0);
+  return CreateTraceWriterInternal(target_buffer, buffer_exhausted_policy);
+}
+
+std::unique_ptr<TraceWriter> SharedMemoryArbiterImpl::CreateStartupTraceWriter(
+    uint16_t target_buffer_reservation_id) {
+  return CreateTraceWriterInternal(
+      MakeTargetBufferIdForReservation(target_buffer_reservation_id),
+      BufferExhaustedPolicy::kDrop);
+}
+
+void SharedMemoryArbiterImpl::BindToProducerEndpoint(
+    TracingService::ProducerEndpoint* producer_endpoint,
+    base::TaskRunner* task_runner) {
+  PERFETTO_DCHECK(producer_endpoint && task_runner);
+  PERFETTO_DCHECK(task_runner->RunsTasksOnCurrentThread());
+
+  bool should_flush = false;
+  std::function<void()> flush_callback;
+  {
+    std::lock_guard<std::mutex> scoped_lock(lock_);
+    PERFETTO_CHECK(!fully_bound_);
+    PERFETTO_CHECK(!producer_endpoint_ && !task_runner_);
+
+    producer_endpoint_ = producer_endpoint;
+    task_runner_ = task_runner;
+
+    // Now that we're bound to a task runner, also reset the WeakPtrFactory to
+    // it. Because this code runs on the task runner, the factory's weak
+    // pointers will be valid on it.
+    weak_ptr_factory_.Reset(this);
+
+    // All writers registered so far should be startup trace writers, since
+    // the producer cannot feasibly know the target buffer for any future
+    // session yet.
+    for (const auto& entry : pending_writers_) {
+      PERFETTO_CHECK(IsReservationTargetBufferId(entry.second));
+    }
+
+    // If all buffer reservations are bound, we can flush pending commits.
+    if (UpdateFullyBoundLocked()) {
+      should_flush = true;
+      flush_callback = TakePendingFlushCallbacksLocked();
+    }
+  }  // scoped_lock
+
+  // Attempt to flush any pending commits (and run pending flush callbacks). If
+  // there are none, this will have no effect. If we ended up in a race that
+  // changed |fully_bound_| back to false, the commit will happen once we become
+  // |fully_bound_| again.
+  if (should_flush)
+    FlushPendingCommitDataRequests(flush_callback);
+}
+
+void SharedMemoryArbiterImpl::BindStartupTargetBuffer(
+    uint16_t target_buffer_reservation_id,
+    BufferID target_buffer_id) {
+  PERFETTO_DCHECK(target_buffer_id > 0);
+
+  std::unique_lock<std::mutex> scoped_lock(lock_);
+
+  // We should already be bound to an endpoint.
+  PERFETTO_CHECK(producer_endpoint_);
+  PERFETTO_CHECK(task_runner_);
+  PERFETTO_CHECK(task_runner_->RunsTasksOnCurrentThread());
+
+  BindStartupTargetBufferImpl(std::move(scoped_lock),
+                              target_buffer_reservation_id, target_buffer_id);
+}
+
+void SharedMemoryArbiterImpl::AbortStartupTracingForReservation(
+    uint16_t target_buffer_reservation_id) {
+  std::unique_lock<std::mutex> scoped_lock(lock_);
+
+  // If we are already bound to an arbiter, we may need to flush after aborting
+  // the session, and thus should be running on the arbiter's task runner.
+  if (task_runner_ && !task_runner_->RunsTasksOnCurrentThread()) {
+    // We shouldn't post tasks while locked.
+    auto* task_runner = task_runner_;
+    scoped_lock.unlock();
+
+    auto weak_this = weak_ptr_factory_.GetWeakPtr();
+    task_runner->PostTask([weak_this, target_buffer_reservation_id]() {
+      if (!weak_this)
+        return;
+      weak_this->AbortStartupTracingForReservation(
+          target_buffer_reservation_id);
+    });
+    return;
+  }
+
+  // Bind the target buffer reservation to an invalid buffer (ID 0), so that
+  // existing commits, as well as future commits (of currently acquired chunks),
+  // will be released as free free by the service but otherwise ignored (i.e.
+  // not copied into any valid target buffer).
+  BindStartupTargetBufferImpl(std::move(scoped_lock),
+                              target_buffer_reservation_id,
+                              /*target_buffer_id=*/kInvalidBufferId);
+}
+
+void SharedMemoryArbiterImpl::BindStartupTargetBufferImpl(
+    std::unique_lock<std::mutex> scoped_lock,
+    uint16_t target_buffer_reservation_id,
+    BufferID target_buffer_id) {
+  // We should already be bound to an endpoint if the target buffer is valid.
+  PERFETTO_DCHECK((producer_endpoint_ && task_runner_) ||
+                  target_buffer_id == kInvalidBufferId);
+
+  PERFETTO_DLOG("Binding startup target buffer reservation %" PRIu16
+                " to buffer %" PRIu16,
+                target_buffer_reservation_id, target_buffer_id);
+
+  MaybeUnboundBufferID reserved_id =
+      MakeTargetBufferIdForReservation(target_buffer_reservation_id);
+
+  bool should_flush = false;
+  std::function<void()> flush_callback;
+  std::vector<std::pair<WriterID, BufferID>> writers_to_register;
+
+  TargetBufferReservation& reservation =
+      target_buffer_reservations_[reserved_id];
+  PERFETTO_CHECK(!reservation.resolved);
+  reservation.resolved = true;
+  reservation.target_buffer = target_buffer_id;
+
+  // Collect trace writers associated with the reservation.
+  for (auto it = pending_writers_.begin(); it != pending_writers_.end();) {
+    if (it->second == reserved_id) {
+      // No need to register writers that have an invalid target buffer.
+      if (target_buffer_id != kInvalidBufferId) {
+        writers_to_register.push_back(
+            std::make_pair(it->first, target_buffer_id));
+      }
+      it = pending_writers_.erase(it);
+    } else {
+      it++;
+    }
+  }
+
+  // If all buffer reservations are bound, we can flush pending commits.
+  if (UpdateFullyBoundLocked()) {
+    should_flush = true;
+    flush_callback = TakePendingFlushCallbacksLocked();
+  }
+
+  scoped_lock.unlock();
+
+  // Register any newly bound trace writers with the service.
+  for (const auto& writer_and_target_buffer : writers_to_register) {
+    producer_endpoint_->RegisterTraceWriter(writer_and_target_buffer.first,
+                                            writer_and_target_buffer.second);
+  }
+
+  // Attempt to flush any pending commits (and run pending flush callbacks). If
+  // there are none, this will have no effect. If we ended up in a race that
+  // changed |fully_bound_| back to false, the commit will happen once we become
+  // |fully_bound_| again.
+  if (should_flush)
+    FlushPendingCommitDataRequests(flush_callback);
+}
+
+std::function<void()>
+SharedMemoryArbiterImpl::TakePendingFlushCallbacksLocked() {
+  if (pending_flush_callbacks_.empty())
+    return std::function<void()>();
+
+  std::vector<std::function<void()>> pending_flush_callbacks;
+  pending_flush_callbacks.swap(pending_flush_callbacks_);
+  // Capture the callback list into the lambda by copy.
+  return [pending_flush_callbacks]() {
+    for (auto& callback : pending_flush_callbacks)
+      callback();
+  };
+}
+
+void SharedMemoryArbiterImpl::NotifyFlushComplete(FlushRequestID req_id) {
+  base::TaskRunner* task_runner_to_commit_on = nullptr;
+
+  {
+    std::lock_guard<std::mutex> scoped_lock(lock_);
+    // If a commit_data_req_ exists it means that somebody else already posted a
+    // FlushPendingCommitDataRequests() task.
+    if (!commit_data_req_) {
+      commit_data_req_.reset(new CommitDataRequest());
+
+      // Flushing the commit is only supported while we're |fully_bound_|. If we
+      // aren't, we'll flush when |fully_bound_| is updated.
+      if (fully_bound_)
+        task_runner_to_commit_on = task_runner_;
+    } else {
+      // If there is another request queued and that also contains is a reply
+      // to a flush request, reply with the highest id.
+      req_id = std::max(req_id, commit_data_req_->flush_request_id());
+    }
+    commit_data_req_->set_flush_request_id(req_id);
+  }  // scoped_lock
+
+  // We shouldn't post tasks while locked. |task_runner_to_commit_on|
+  // remains valid after unlocking, because |task_runner_| is never reset.
+  if (task_runner_to_commit_on) {
+    auto weak_this = weak_ptr_factory_.GetWeakPtr();
+    task_runner_to_commit_on->PostTask([weak_this] {
+      if (weak_this)
+        weak_this->FlushPendingCommitDataRequests();
+    });
+  }
+}
+
+std::unique_ptr<TraceWriter> SharedMemoryArbiterImpl::CreateTraceWriterInternal(
+    MaybeUnboundBufferID target_buffer,
+    BufferExhaustedPolicy buffer_exhausted_policy) {
+  WriterID id;
+  base::TaskRunner* task_runner_to_register_on = nullptr;
+
+  {
+    std::lock_guard<std::mutex> scoped_lock(lock_);
+    if (did_shutdown_)
+      return std::unique_ptr<TraceWriter>(new NullTraceWriter());
+
+    id = active_writer_ids_.Allocate();
+    if (!id)
+      return std::unique_ptr<TraceWriter>(new NullTraceWriter());
+
+    PERFETTO_DCHECK(!pending_writers_.count(id));
+
+    if (IsReservationTargetBufferId(target_buffer)) {
+      // If the reservation is new, mark it as unbound in
+      // |target_buffer_reservations_|. Otherwise, if the reservation was
+      // already bound, choose the bound buffer ID now.
+      auto it_and_inserted = target_buffer_reservations_.insert(
+          {target_buffer, TargetBufferReservation()});
+      if (it_and_inserted.first->second.resolved)
+        target_buffer = it_and_inserted.first->second.target_buffer;
+    }
+
+    if (IsReservationTargetBufferId(target_buffer)) {
+      // The arbiter and/or startup buffer reservations are not bound yet, so
+      // buffer the registration of the writer until after we're bound.
+      pending_writers_[id] = target_buffer;
+
+      // Mark the arbiter as not fully bound, since we now have at least one
+      // unbound trace writer / target buffer reservation.
+      fully_bound_ = false;
+      was_always_bound_ = false;
+    } else if (target_buffer != kInvalidBufferId) {
+      // Trace writer is bound, so arbiter should be bound to an endpoint, too.
+      PERFETTO_CHECK(producer_endpoint_ && task_runner_);
+      task_runner_to_register_on = task_runner_;
+    }
+
+    // All trace writers must use kDrop policy if the arbiter ever becomes
+    // unbound.
+    bool uses_drop_policy =
+        buffer_exhausted_policy == BufferExhaustedPolicy::kDrop;
+    all_writers_have_drop_policy_ &= uses_drop_policy;
+    PERFETTO_DCHECK(fully_bound_ || uses_drop_policy);
+    PERFETTO_CHECK(fully_bound_ || all_writers_have_drop_policy_);
+    PERFETTO_CHECK(was_always_bound_ || uses_drop_policy);
+  }  // scoped_lock
+
+  // We shouldn't post tasks while locked. |task_runner_to_register_on|
+  // remains valid after unlocking, because |task_runner_| is never reset.
+  if (task_runner_to_register_on) {
+    auto weak_this = weak_ptr_factory_.GetWeakPtr();
+    task_runner_to_register_on->PostTask([weak_this, id, target_buffer] {
+      if (weak_this)
+        weak_this->producer_endpoint_->RegisterTraceWriter(id, target_buffer);
+    });
+  }
+
+  return std::unique_ptr<TraceWriter>(
+      new TraceWriterImpl(this, id, target_buffer, buffer_exhausted_policy));
+}
+
+void SharedMemoryArbiterImpl::ReleaseWriterID(WriterID id) {
+  base::TaskRunner* task_runner = nullptr;
+  {
+    std::lock_guard<std::mutex> scoped_lock(lock_);
+    active_writer_ids_.Free(id);
+
+    auto it = pending_writers_.find(id);
+    if (it != pending_writers_.end()) {
+      // Writer hasn't been bound yet and thus also not yet registered with the
+      // service.
+      pending_writers_.erase(it);
+      return;
+    }
+
+    // A trace writer from an aborted session may be destroyed before the
+    // arbiter is bound to a task runner. In that case, it was never registered
+    // with the service.
+    if (!task_runner_)
+      return;
+
+    task_runner = task_runner_;
+  }  // scoped_lock
+
+  // We shouldn't post tasks while locked. |task_runner| remains valid after
+  // unlocking, because |task_runner_| is never reset.
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  task_runner->PostTask([weak_this, id] {
+    if (weak_this)
+      weak_this->producer_endpoint_->UnregisterTraceWriter(id);
+  });
+}
+
+bool SharedMemoryArbiterImpl::ReplaceCommitPlaceholderBufferIdsLocked() {
+  if (!commit_data_req_)
+    return true;
+
+  bool all_placeholders_replaced = true;
+  for (auto& chunk : *commit_data_req_->mutable_chunks_to_move()) {
+    if (!IsReservationTargetBufferId(chunk.target_buffer()))
+      continue;
+    const auto it = target_buffer_reservations_.find(chunk.target_buffer());
+    PERFETTO_DCHECK(it != target_buffer_reservations_.end());
+    if (!it->second.resolved) {
+      all_placeholders_replaced = false;
+      continue;
+    }
+    chunk.set_target_buffer(it->second.target_buffer);
+  }
+  for (auto& chunk : *commit_data_req_->mutable_chunks_to_patch()) {
+    if (!IsReservationTargetBufferId(chunk.target_buffer()))
+      continue;
+    const auto it = target_buffer_reservations_.find(chunk.target_buffer());
+    PERFETTO_DCHECK(it != target_buffer_reservations_.end());
+    if (!it->second.resolved) {
+      all_placeholders_replaced = false;
+      continue;
+    }
+    chunk.set_target_buffer(it->second.target_buffer);
+  }
+  return all_placeholders_replaced;
+}
+
+bool SharedMemoryArbiterImpl::UpdateFullyBoundLocked() {
+  if (!producer_endpoint_) {
+    PERFETTO_DCHECK(!fully_bound_);
+    return false;
+  }
+  // We're fully bound if all target buffer reservations have a valid associated
+  // BufferID.
+  fully_bound_ = std::none_of(
+      target_buffer_reservations_.begin(), target_buffer_reservations_.end(),
+      [](std::pair<MaybeUnboundBufferID, TargetBufferReservation> entry) {
+        return !entry.second.resolved;
+      });
+  if (!fully_bound_)
+    was_always_bound_ = false;
+  return fully_bound_;
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/core/trace_packet.cc
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+
+TracePacket::TracePacket() = default;
+TracePacket::~TracePacket() = default;
+
+TracePacket::TracePacket(TracePacket&& other) noexcept {
+  *this = std::move(other);
+}
+
+TracePacket& TracePacket::operator=(TracePacket&& other) {
+  slices_ = std::move(other.slices_);
+  other.slices_.clear();
+  size_ = other.size_;
+  other.size_ = 0;
+  buffer_index_for_stats_ = other.buffer_index_for_stats_;
+  other.buffer_index_for_stats_ = 0;
+  return *this;
+}
+
+void TracePacket::AddSlice(Slice slice) {
+  size_ += slice.size;
+  slices_.push_back(std::move(slice));
+}
+
+void TracePacket::AddSlice(const void* start, size_t size) {
+  size_ += size;
+  slices_.emplace_back(start, size);
+}
+
+std::tuple<char*, size_t> TracePacket::GetProtoPreamble() {
+  using protozero::proto_utils::MakeTagLengthDelimited;
+  using protozero::proto_utils::WriteVarInt;
+  uint8_t* ptr = reinterpret_cast<uint8_t*>(&preamble_[0]);
+
+  constexpr uint8_t tag = MakeTagLengthDelimited(kPacketFieldNumber);
+  static_assert(tag < 0x80, "TracePacket tag should fit in one byte");
+  *(ptr++) = tag;
+
+  ptr = WriteVarInt(size(), ptr);
+  size_t preamble_size = reinterpret_cast<uintptr_t>(ptr) -
+                         reinterpret_cast<uintptr_t>(&preamble_[0]);
+  PERFETTO_DCHECK(preamble_size <= sizeof(preamble_));
+  return std::make_tuple(&preamble_[0], preamble_size);
+}
+
+std::string TracePacket::GetRawBytesForTesting() {
+  std::string data;
+  data.resize(size());
+  size_t pos = 0;
+  for (const Slice& slice : slices()) {
+    PERFETTO_CHECK(pos + slice.size <= data.size());
+    memcpy(&data[pos], slice.start, slice.size);
+    pos += slice.size;
+  }
+  return data;
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/core/trace_writer_impl.cc
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/core/trace_writer_impl.h"
+
+#include <string.h>
+
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_annotations.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/root_message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/static_buffer.h"
+// gen_amalgamated expanded: #include "src/tracing/core/shared_memory_arbiter_impl.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
+
+using protozero::proto_utils::kMessageLengthFieldSize;
+using protozero::proto_utils::WriteRedundantVarInt;
+using ChunkHeader = perfetto::SharedMemoryABI::ChunkHeader;
+
+namespace perfetto {
+
+namespace {
+constexpr size_t kPacketHeaderSize = SharedMemoryABI::kPacketHeaderSize;
+// The -1 is because we want to leave extra room to inflate the counter.
+constexpr size_t kMaxPacketsPerChunk = ChunkHeader::Packets::kMaxCount - 1;
+// When the packet count in a chunk is inflated, TraceWriter is always going to
+// leave this kExtraRoomForInflatedPacket bytes to write an empty trace packet
+// if it needs to.
+constexpr size_t kExtraRoomForInflatedPacket = 1;
+uint8_t g_garbage_chunk[1024];
+}  // namespace
+
+TraceWriterImpl::TraceWriterImpl(SharedMemoryArbiterImpl* shmem_arbiter,
+                                 WriterID id,
+                                 MaybeUnboundBufferID target_buffer,
+                                 BufferExhaustedPolicy buffer_exhausted_policy)
+    : shmem_arbiter_(shmem_arbiter),
+      id_(id),
+      target_buffer_(target_buffer),
+      buffer_exhausted_policy_(buffer_exhausted_policy),
+      protobuf_stream_writer_(this),
+      process_id_(base::GetProcessId()) {
+  // TODO(primiano): we could handle the case of running out of TraceWriterID(s)
+  // more gracefully and always return a no-op TracePacket in NewTracePacket().
+  PERFETTO_CHECK(id_ != 0);
+
+  cur_packet_.reset(new protozero::RootMessage<protos::pbzero::TracePacket>());
+  cur_packet_->Finalize();  // To avoid the CHECK in NewTracePacket().
+}
+
+TraceWriterImpl::~TraceWriterImpl() {
+  if (cur_chunk_.is_valid()) {
+    cur_packet_->Finalize();
+    Flush();
+  }
+  // This call may cause the shared memory arbiter (and the underlying memory)
+  // to get asynchronously deleted if this was the last trace writer targeting
+  // the arbiter and the arbiter was marked for shutdown.
+  shmem_arbiter_->ReleaseWriterID(id_);
+}
+
+void TraceWriterImpl::ReturnCompletedChunk() {
+  PERFETTO_DCHECK(cur_chunk_.is_valid());
+  if (cur_chunk_packet_count_inflated_) {
+    uint8_t zero_size = 0;
+    static_assert(sizeof zero_size == kExtraRoomForInflatedPacket);
+    PERFETTO_CHECK(protobuf_stream_writer_.bytes_available() != 0);
+    protobuf_stream_writer_.WriteBytesUnsafe(&zero_size, sizeof zero_size);
+    cur_chunk_packet_count_inflated_ = false;
+  }
+  shmem_arbiter_->ReturnCompletedChunk(std::move(cur_chunk_), target_buffer_,
+                                       &patch_list_);
+}
+
+void TraceWriterImpl::Flush(std::function<void()> callback) {
+  // Flush() cannot be called in the middle of a TracePacket.
+  PERFETTO_CHECK(cur_packet_->is_finalized());
+  // cur_packet_ is finalized: that means that the size is correct for all the
+  // nested submessages. The root fragment size however is not handled by
+  // protozero::Message::Finalize() and must be filled here.
+  FinalizeFragmentIfRequired();
+
+  if (cur_chunk_.is_valid()) {
+    ReturnCompletedChunk();
+  } else {
+    // When in stall mode, all patches should have been returned with the last
+    // chunk, since the last packet was completed. In drop_packets_ mode, this
+    // may not be the case because the packet may have been fragmenting when
+    // SMB exhaustion occurred and |cur_chunk_| became invalid. In this case,
+    // drop_packets_ should be true.
+    PERFETTO_DCHECK(patch_list_.empty() || drop_packets_);
+  }
+
+  // Always issue the Flush request, even if there is nothing to flush, just
+  // for the sake of getting the callback posted back.
+  shmem_arbiter_->FlushPendingCommitDataRequests(callback);
+  protobuf_stream_writer_.Reset({nullptr, nullptr});
+}
+
+TraceWriterImpl::TracePacketHandle TraceWriterImpl::NewTracePacket() {
+  // If we hit this, the caller is calling NewTracePacket() without having
+  // finalized the previous packet.
+  PERFETTO_CHECK(cur_packet_->is_finalized());
+  // If we hit this, this trace writer was created in a different process. This
+  // likely means that the process forked while tracing was active, and the
+  // forked child process tried to emit a trace event. This is not supported, as
+  // it would lead to two processes writing to the same tracing SMB.
+  PERFETTO_DCHECK(process_id_ == base::GetProcessId());
+
+  // Before starting a new packet, make sure that the last fragment size has ben
+  // written correctly. The root fragment size is not written by
+  // protozero::Message::Finalize().
+  FinalizeFragmentIfRequired();
+
+  fragmenting_packet_ = false;
+
+  // Reserve space for the size of the message. Note: this call might re-enter
+  // into this class invoking GetNewBuffer() if there isn't enough space or if
+  // this is the very first call to NewTracePacket().
+  static_assert(kPacketHeaderSize == kMessageLengthFieldSize,
+                "The packet header must match the Message header size");
+
+  bool was_dropping_packets = drop_packets_;
+
+  // It doesn't make sense to begin a packet that is going to fragment
+  // immediately after (8 is just an arbitrary estimation on the minimum size of
+  // a realistic packet).
+  bool chunk_too_full =
+      protobuf_stream_writer_.bytes_available() < kPacketHeaderSize + 8;
+  if (chunk_too_full || reached_max_packets_per_chunk_ ||
+      retry_new_chunk_after_packet_) {
+    protobuf_stream_writer_.Reset(GetNewBuffer());
+  }
+
+  // Send any completed patches to the service to facilitate trace data
+  // recovery by the service. This should only happen when we're completing
+  // the first packet in a chunk which was a continuation from the previous
+  // chunk, i.e. at most once per chunk.
+  if (!patch_list_.empty() && patch_list_.front().is_patched()) {
+    shmem_arbiter_->SendPatches(id_, target_buffer_, &patch_list_);
+  }
+
+  cur_packet_->Reset(&protobuf_stream_writer_);
+  uint8_t* header = protobuf_stream_writer_.ReserveBytes(kPacketHeaderSize);
+  memset(header, 0, kPacketHeaderSize);
+  cur_fragment_size_field_ = header;
+
+  TracePacketHandle handle(cur_packet_.get());
+  cur_fragment_start_ = protobuf_stream_writer_.write_ptr();
+  fragmenting_packet_ = true;
+
+  if (PERFETTO_LIKELY(!drop_packets_)) {
+    uint16_t new_packet_count;
+    if (cur_chunk_packet_count_inflated_) {
+      new_packet_count =
+          cur_chunk_.header()->packets.load(std::memory_order_relaxed).count;
+      cur_chunk_packet_count_inflated_ = false;
+    } else {
+      new_packet_count = cur_chunk_.IncrementPacketCount();
+    }
+    reached_max_packets_per_chunk_ = new_packet_count == kMaxPacketsPerChunk;
+
+    if (PERFETTO_UNLIKELY(was_dropping_packets)) {
+      // We've succeeded to get a new chunk from the SMB after we entered
+      // drop_packets_ mode. Record a marker into the new packet to indicate the
+      // data loss.
+      cur_packet_->set_previous_packet_dropped(true);
+    }
+  }
+
+  if (PERFETTO_UNLIKELY(first_packet_on_sequence_)) {
+    cur_packet_->set_first_packet_on_sequence(true);
+    first_packet_on_sequence_ = false;
+  }
+
+  handle.set_finalization_listener(this);
+
+  return handle;
+}
+
+// Called by the Message. We can get here in two cases:
+// 1. In the middle of writing a Message,
+// when |fragmenting_packet_| == true. In this case we want to update the
+// chunk header with a partial packet and start a new partial packet in the
+// new chunk.
+// 2. While calling ReserveBytes() for the packet header in NewTracePacket().
+// In this case |fragmenting_packet_| == false and we just want a new chunk
+// without creating any fragments.
+protozero::ContiguousMemoryRange TraceWriterImpl::GetNewBuffer() {
+  if (fragmenting_packet_ && drop_packets_) {
+    // We can't write the remaining data of the fragmenting packet to a new
+    // chunk, because we have already lost some of its data in the garbage
+    // chunk. Thus, we will wrap around in the garbage chunk, wait until the
+    // current packet was completed, and then attempt to get a new chunk from
+    // the SMB again. Instead, if |drop_packets_| is true and
+    // |fragmenting_packet_| is false, we try to acquire a valid chunk because
+    // the SMB exhaustion might be resolved.
+    retry_new_chunk_after_packet_ = true;
+    cur_fragment_size_field_ = nullptr;
+    cur_fragment_start_ = &g_garbage_chunk[0];
+    return protozero::ContiguousMemoryRange{
+        &g_garbage_chunk[0], &g_garbage_chunk[0] + sizeof(g_garbage_chunk)};
+  }
+
+  // Attempt to grab the next chunk before finalizing the current one, so that
+  // we know whether we need to start dropping packets before writing the
+  // current packet fragment's header.
+  ChunkHeader::Packets packets = {};
+  if (fragmenting_packet_) {
+    packets.count = 1;
+    packets.flags = ChunkHeader::kFirstPacketContinuesFromPrevChunk;
+  }
+
+  // The memory order of the stores below doesn't really matter. This |header|
+  // is just a local temporary object. The GetNewChunk() call below will copy it
+  // into the shared buffer with the proper barriers.
+  ChunkHeader header = {};
+  header.writer_id.store(id_, std::memory_order_relaxed);
+  header.chunk_id.store(next_chunk_id_, std::memory_order_relaxed);
+  header.packets.store(packets, std::memory_order_relaxed);
+
+  SharedMemoryABI::Chunk new_chunk =
+      shmem_arbiter_->GetNewChunk(header, buffer_exhausted_policy_);
+  if (!new_chunk.is_valid()) {
+    // Shared memory buffer exhausted, switch into |drop_packets_| mode. We'll
+    // drop data until the garbage chunk has been filled once and then retry.
+
+    // If we started a packet in one of the previous (valid) chunks, we need to
+    // tell the service to discard it.
+    if (fragmenting_packet_) {
+      // We can only end up here if the previous chunk was a valid chunk,
+      // because we never try to acquire a new chunk in |drop_packets_| mode
+      // while fragmenting.
+      PERFETTO_DCHECK(!drop_packets_);
+
+      // Backfill the last fragment's header with an invalid size (too large),
+      // so that the service's TraceBuffer throws out the incomplete packet.
+      // It'll restart reading from the next chunk we submit.
+      WriteRedundantVarInt(SharedMemoryABI::kPacketSizeDropPacket,
+                           cur_fragment_size_field_);
+
+      // Reset the size field, since we should not write the current packet's
+      // size anymore after this.
+      cur_fragment_size_field_ = nullptr;
+
+      // We don't set kLastPacketContinuesOnNextChunk or kChunkNeedsPatching on
+      // the last chunk, because its last fragment will be discarded anyway.
+      // However, the current packet fragment points to a valid |cur_chunk_| and
+      // may have non-finalized nested messages which will continue in the
+      // garbage chunk and currently still point into |cur_chunk_|. As we are
+      // about to return |cur_chunk_|, we need to invalidate the size fields of
+      // those nested messages. Normally we move them in the |patch_list_| (see
+      // below) but in this case, it doesn't make sense to send patches for a
+      // fragment that will be discarded for sure. Thus, we clean up any size
+      // field references into |cur_chunk_|.
+      for (auto* nested_msg = cur_packet_->nested_message(); nested_msg;
+           nested_msg = nested_msg->nested_message()) {
+        uint8_t* const cur_hdr = nested_msg->size_field();
+
+        // If this is false the protozero Message has already been instructed to
+        // write, upon Finalize(), its size into the patch list.
+        bool size_field_points_within_chunk =
+            cur_hdr >= cur_chunk_.payload_begin() &&
+            cur_hdr + kMessageLengthFieldSize <= cur_chunk_.end();
+
+        if (size_field_points_within_chunk)
+          nested_msg->set_size_field(nullptr);
+      }
+    } else if (!drop_packets_ && cur_fragment_size_field_) {
+      // If we weren't dropping packets before, we should indicate to the
+      // service that we're about to lose data. We do this by invalidating the
+      // size of the last packet in |cur_chunk_|. The service will record
+      // statistics about packets with kPacketSizeDropPacket size.
+      PERFETTO_DCHECK(cur_packet_->is_finalized());
+      PERFETTO_DCHECK(cur_chunk_.is_valid());
+
+      // |cur_fragment_size_field_| should point within |cur_chunk_|'s payload.
+      PERFETTO_DCHECK(cur_fragment_size_field_ >= cur_chunk_.payload_begin() &&
+                      cur_fragment_size_field_ + kMessageLengthFieldSize <=
+                          cur_chunk_.end());
+
+      WriteRedundantVarInt(SharedMemoryABI::kPacketSizeDropPacket,
+                           cur_fragment_size_field_);
+    }
+
+    if (cur_chunk_.is_valid()) {
+      ReturnCompletedChunk();
+    }
+
+    drop_packets_ = true;
+    cur_chunk_ = SharedMemoryABI::Chunk();  // Reset to an invalid chunk.
+    cur_chunk_packet_count_inflated_ = false;
+    reached_max_packets_per_chunk_ = false;
+    retry_new_chunk_after_packet_ = false;
+    cur_fragment_size_field_ = nullptr;
+    cur_fragment_start_ = &g_garbage_chunk[0];
+
+    PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(&g_garbage_chunk,
+                                        sizeof(g_garbage_chunk),
+                                        "nobody reads the garbage chunk")
+    return protozero::ContiguousMemoryRange{
+        &g_garbage_chunk[0], &g_garbage_chunk[0] + sizeof(g_garbage_chunk)};
+  }  // if (!new_chunk.is_valid())
+
+  PERFETTO_DCHECK(new_chunk.is_valid());
+
+  if (fragmenting_packet_) {
+    // We should not be fragmenting a packet after we exited drop_packets_ mode,
+    // because we only retry to get a new chunk when a fresh packet is started.
+    PERFETTO_DCHECK(!drop_packets_);
+
+    uint8_t* const wptr = protobuf_stream_writer_.write_ptr();
+    PERFETTO_DCHECK(wptr >= cur_fragment_start_);
+    uint32_t partial_size = static_cast<uint32_t>(wptr - cur_fragment_start_);
+    PERFETTO_DCHECK(partial_size < cur_chunk_.size());
+
+    // Backfill the packet header with the fragment size.
+    PERFETTO_DCHECK(partial_size > 0);
+    cur_chunk_.SetFlag(ChunkHeader::kLastPacketContinuesOnNextChunk);
+    WriteRedundantVarInt(partial_size, cur_fragment_size_field_);
+
+    // Descend in the stack of non-finalized nested submessages (if any) and
+    // detour their |size_field| into the |patch_list_|. At this point we have
+    // to release the chunk and they cannot write anymore into that.
+    for (auto* nested_msg = cur_packet_->nested_message(); nested_msg;
+         nested_msg = nested_msg->nested_message()) {
+      uint8_t* cur_hdr = nested_msg->size_field();
+
+      // If this is false the protozero Message has already been instructed to
+      // write, upon Finalize(), its size into the patch list.
+      bool size_field_points_within_chunk =
+          cur_hdr >= cur_chunk_.payload_begin() &&
+          cur_hdr + kMessageLengthFieldSize <= cur_chunk_.end();
+
+      if (size_field_points_within_chunk) {
+        cur_hdr = TraceWriterImpl::AnnotatePatch(cur_hdr);
+        nested_msg->set_size_field(cur_hdr);
+      } else {
+#if PERFETTO_DCHECK_IS_ON()
+        // Ensure that the size field of the message points to an element of the
+        // patch list.
+        auto patch_it = std::find_if(
+            patch_list_.begin(), patch_list_.end(),
+            [cur_hdr](const Patch& p) { return &p.size_field[0] == cur_hdr; });
+        PERFETTO_DCHECK(patch_it != patch_list_.end());
+#endif
+      }
+    }  // for(nested_msg)
+  }    // if(fragmenting_packet)
+
+  if (cur_chunk_.is_valid()) {
+    // ReturnCompletedChunk will consume the first patched entries from
+    // |patch_list_| and shrink it.
+    ReturnCompletedChunk();
+  }
+
+  // Switch to the new chunk.
+  drop_packets_ = false;
+  reached_max_packets_per_chunk_ = false;
+  retry_new_chunk_after_packet_ = false;
+  next_chunk_id_++;
+  cur_chunk_ = std::move(new_chunk);
+  cur_chunk_packet_count_inflated_ = false;
+  cur_fragment_size_field_ = nullptr;
+
+  uint8_t* payload_begin = cur_chunk_.payload_begin();
+  if (fragmenting_packet_) {
+    cur_fragment_size_field_ = payload_begin;
+    memset(payload_begin, 0, kPacketHeaderSize);
+    payload_begin += kPacketHeaderSize;
+    cur_fragment_start_ = payload_begin;
+  }
+
+  return protozero::ContiguousMemoryRange{payload_begin, cur_chunk_.end()};
+}
+
+void TraceWriterImpl::FinishTracePacket() {
+  // If we hit this, this trace writer was created in a different process. This
+  // likely means that the process forked while tracing was active, and the
+  // forked child process tried to emit a trace event. This is not supported, as
+  // it would lead to two processes writing to the same tracing SMB.
+  PERFETTO_DCHECK(process_id_ == base::GetProcessId());
+
+  FinalizeFragmentIfRequired();
+
+  cur_packet_->Reset(&protobuf_stream_writer_);
+  cur_packet_->Finalize();  // To avoid the CHECK in NewTracePacket().
+
+  // cur_chunk_packet_count_inflated_ can be true if FinishTracePacket() is
+  // called multiple times.
+  if (cur_chunk_.is_valid() && !cur_chunk_packet_count_inflated_) {
+    if (protobuf_stream_writer_.bytes_available() <
+        kExtraRoomForInflatedPacket) {
+      ReturnCompletedChunk();
+    } else {
+      cur_chunk_packet_count_inflated_ = true;
+      cur_chunk_.IncrementPacketCount();
+    }
+  }
+
+  // Send any completed patches to the service to facilitate trace data
+  // recovery by the service. This should only happen when we're completing
+  // the first packet in a chunk which was a continuation from the previous
+  // chunk, i.e. at most once per chunk.
+  if (!patch_list_.empty() && patch_list_.front().is_patched()) {
+    shmem_arbiter_->SendPatches(id_, target_buffer_, &patch_list_);
+  }
+}
+
+void TraceWriterImpl::FinalizeFragmentIfRequired() {
+  if (!cur_fragment_size_field_) {
+    return;
+  }
+  uint8_t* const wptr = protobuf_stream_writer_.write_ptr();
+  PERFETTO_DCHECK(wptr >= cur_fragment_start_);
+  uint32_t partial_size = static_cast<uint32_t>(wptr - cur_fragment_start_);
+
+  // cur_fragment_size_field_, if not nullptr, is always inside or immediately
+  // before protobuf_stream_writer_.cur_range().
+  if (partial_size < protozero::proto_utils::kMaxOneByteMessageLength &&
+      cur_fragment_size_field_ >= protobuf_stream_writer_.cur_range().begin) {
+    // This handles compaction of the root message. For nested messages, the
+    // compaction is handled by protozero::Message::Finalize().
+    protobuf_stream_writer_.Rewind(
+        partial_size, protozero::proto_utils::kMessageLengthFieldSize - 1u);
+    *cur_fragment_size_field_ = static_cast<uint8_t>(partial_size);
+  } else {
+    WriteRedundantVarInt(partial_size, cur_fragment_size_field_);
+  }
+  cur_fragment_size_field_ = nullptr;
+}
+
+uint8_t* TraceWriterImpl::AnnotatePatch(uint8_t* to_patch) {
+  if (!cur_chunk_.is_valid()) {
+    return nullptr;
+  }
+  auto offset = static_cast<uint16_t>(to_patch - cur_chunk_.payload_begin());
+  const ChunkID cur_chunk_id =
+      cur_chunk_.header()->chunk_id.load(std::memory_order_relaxed);
+  static_assert(kPatchSize == sizeof(Patch::PatchContent),
+                "Patch size mismatch");
+  Patch* patch = patch_list_.emplace_back(cur_chunk_id, offset);
+  // Check that the flag is not already set before setting it. This is not
+  // necessary, but it makes the code faster.
+  if (!(cur_chunk_.GetPacketCountAndFlags().second &
+        ChunkHeader::kChunkNeedsPatching)) {
+    cur_chunk_.SetFlag(ChunkHeader::kChunkNeedsPatching);
+  }
+  return &patch->size_field[0];
+}
+
+void TraceWriterImpl::OnMessageFinalized(protozero::Message*) {
+  TraceWriterImpl::FinishTracePacket();
+}
+
+WriterID TraceWriterImpl::writer_id() const {
+  return id_;
+}
+
+// Base class definitions.
+TraceWriter::TraceWriter() = default;
+TraceWriter::~TraceWriter() = default;
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/core/virtual_destructors.cc
+// gen_amalgamated begin header: include/perfetto/ext/tracing/core/consumer.h
+// gen_amalgamated begin header: include/perfetto/ext/tracing/core/observable_events.h
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_OBSERVABLE_EVENTS_H_
+#define INCLUDE_PERFETTO_EXT_TRACING_CORE_OBSERVABLE_EVENTS_H_
+
+// Creates the aliases in the ::perfetto namespace, doing things like:
+// using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
+// See comments in forward_decls.h for the historical reasons of this
+// indirection layer.
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/common/observable_events.gen.h"
+
+#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_OBSERVABLE_EVENTS_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_CONSUMER_H_
+#define INCLUDE_PERFETTO_EXT_TRACING_CORE_CONSUMER_H_
+
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/uuid.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/observable_events.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+namespace perfetto {
+
+class TracePacket;
+
+class PERFETTO_EXPORT_COMPONENT Consumer {
+ public:
+  virtual ~Consumer();
+
+  // Called by Service (or more typically by the transport layer, on behalf of
+  // the remote Service), once the Consumer <> Service connection has been
+  // established.
+  virtual void OnConnect() = 0;
+
+  // Called by the Service or by the transport layer if the connection with the
+  // service drops, either voluntarily (e.g., by destroying the ConsumerEndpoint
+  // obtained through Service::ConnectConsumer()) or involuntarily (e.g., if the
+  // Service process crashes).
+  virtual void OnDisconnect() = 0;
+
+  // Called by the Service after the tracing session has ended. This can happen
+  // for a variety of reasons:
+  // - The consumer explicitly called DisableTracing()
+  // - The TraceConfig's |duration_ms| has been reached.
+  // - The TraceConfig's |max_file_size_bytes| has been reached.
+  // - An error occurred while trying to enable tracing. In this case |error|
+  //   is non-empty.
+  virtual void OnTracingDisabled(const std::string& error) = 0;
+
+  // Called back by the Service (or transport layer) after invoking
+  // TracingService::ConsumerEndpoint::ReadBuffers(). This function can be
+  // called more than once. Each invocation can carry one or more
+  // TracePacket(s). Upon the last call, |has_more| is set to true (i.e.
+  // |has_more| is a !EOF).
+  virtual void OnTraceData(std::vector<TracePacket>, bool has_more) = 0;
+
+  // Called back by the Service (or transport layer) after invoking
+  // TracingService::ConsumerEndpoint::Detach().
+  // The consumer can disconnect at this point and the trace session will keep
+  // on going. A new consumer can later re-attach passing back the same |key|
+  // passed to Detach(), but only if the two requests come from the same uid.
+  virtual void OnDetach(bool success) = 0;
+
+  // Called back by the Service (or transport layer) after invoking
+  // TracingService::ConsumerEndpoint::Attach().
+  virtual void OnAttach(bool success, const TraceConfig&) = 0;
+
+  // Called back by the Service (or transport layer) after invoking
+  // TracingService::ConsumerEndpoint::GetTraceStats().
+  virtual void OnTraceStats(bool success, const TraceStats&) = 0;
+
+  // Called back by the Service (or transport layer) after invoking
+  // TracingService::ConsumerEndpoint::ObserveEvents() whenever one or more
+  // ObservableEvents of enabled event types occur.
+  virtual void OnObservableEvents(const ObservableEvents&) = 0;
+
+  // Called back by the Service (or transport layer) after invoking
+  // TracingService::ConsumerEndpoint::CloneSession().
+  // TODO(primiano): make pure virtual after various 3way patches.
+  struct OnSessionClonedArgs {
+    bool success;
+    std::string error;
+    base::Uuid uuid;  // UUID of the cloned session.
+  };
+  virtual void OnSessionCloned(const OnSessionClonedArgs&);
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_CONSUMER_H_
+// gen_amalgamated begin header: include/perfetto/ext/tracing/core/producer.h
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_PRODUCER_H_
+#define INCLUDE_PERFETTO_EXT_TRACING_CORE_PRODUCER_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/flush_flags.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+
+namespace perfetto {
+
+class SharedMemory;
+
+// A Producer is an entity that connects to the write-only port of the Service
+// and exposes the ability to produce performance data on-demand. The lifecycle
+// of a Producer is as follows:
+// 1. The producer connects to the service and advertises its data sources
+//    (e.g., the ability to get kernel ftraces, to list process stats).
+// 2. The service acknowledges the connection and sends over the SharedMemory
+//    region that will be used to exchange data (together with the signalling
+//    API TracingService::ProducerEndpoint::OnPageAcquired()/OnPageReleased()).
+// 3. At some point later on, the Service asks the Producer to turn on some of
+//    the previously registered data sources, together with some configuration
+//    parameters. This happens via the StartDataSource() callback.
+// 4. In response to that the Producer will spawn an instance of the given data
+//    source and inject its data into the shared memory buffer (obtained during
+//    OnConnect).
+// This interface is subclassed by:
+//  1. The actual producer code in the clients e.g., the ftrace reader process.
+//  2. The transport layer when interposing RPC between service and producers.
+class PERFETTO_EXPORT_COMPONENT Producer {
+ public:
+  virtual ~Producer();
+
+  // Called by Service (or more typically by the transport layer, on behalf of
+  // the remote Service), once the Producer <> Service connection has been
+  // established.
+  virtual void OnConnect() = 0;
+
+  // Called by the Service or by the transport layer if the connection with the
+  // service drops, either voluntarily (e.g., by destroying the ProducerEndpoint
+  // obtained through Service::ConnectProducer()) or involuntarily (e.g., if the
+  // Service process crashes).
+  // The Producer is expected to tear down all its data sources if this happens.
+  // Once this call returns it is possible to safely destroy the Producer
+  // instance.
+  virtual void OnDisconnect() = 0;
+
+  // Called by the Service after OnConnect but before the first DataSource is
+  // created. Can be used for any setup required before tracing begins.
+  virtual void OnTracingSetup() = 0;
+
+  // Called by muxer once StartupTracing is started. It will be called before
+  // SetupStartupTracingBlocking is returned.
+  virtual void OnStartupTracingSetup() {}
+
+  // The lifecycle methods below are always called in the following sequence:
+  // SetupDataSource  -> StartDataSource -> StopDataSource.
+  // Or, in the edge case where a trace is aborted immediately:
+  // SetupDataSource  -> StopDataSource.
+  // The Setup+Start call sequence is always guaranateed, regardless of the
+  // TraceConfig.deferred_start flags.
+  // Called by the Service to configure one of the data sources previously
+  // registered through TracingService::ProducerEndpoint::RegisterDataSource().
+  // This method is always called before StartDataSource. There is always a
+  // SetupDataSource() call before each StartDataSource() call.
+  // Args:
+  // - DataSourceInstanceID is an identifier chosen by the Service that should
+  //   be assigned to the newly created data source instance. It is used to
+  //   match the StopDataSource() request below.
+  // - DataSourceConfig is the configuration for the new data source (e.g.,
+  //   tells which trace categories to enable).
+  virtual void SetupDataSource(DataSourceInstanceID,
+                               const DataSourceConfig&) = 0;
+
+  // Called by the Service to turn on one of the data sources previously
+  // registered through TracingService::ProducerEndpoint::RegisterDataSource()
+  // and initialized through SetupDataSource().
+  // Both arguments are guaranteed to be identical to the ones passed to the
+  // prior SetupDataSource() call.
+  virtual void StartDataSource(DataSourceInstanceID,
+                               const DataSourceConfig&) = 0;
+
+  // Called by the Service to shut down an existing data source instance.
+  virtual void StopDataSource(DataSourceInstanceID) = 0;
+
+  // Called by the service to request the Producer to commit the data of the
+  // given data sources and return their chunks into the shared memory buffer.
+  // The Producer is expected to invoke NotifyFlushComplete(FlushRequestID) on
+  // the Service after the data has been committed. The producer has to either
+  // reply to the flush requests in order, or can just reply to the latest one
+  // Upon seeing a NotifyFlushComplete(N), the service will assume that all
+  // flushes < N have also been committed.
+  virtual void Flush(FlushRequestID,
+                     const DataSourceInstanceID* data_source_ids,
+                     size_t num_data_sources,
+                     FlushFlags) = 0;
+
+  // Called by the service to instruct the given data sources to stop referring
+  // to any trace contents emitted so far. The intent is that after processing
+  // this call, the rest of the trace should be parsable even if all of the
+  // packets emitted so far have been lost (for example due to ring buffer
+  // overwrites).
+  //
+  // Called only for Producers with active data sources that have opted in by
+  // setting |handles_incremental_state_clear| in their DataSourceDescriptor.
+  //
+  // The way this call is handled is up to the individual Producer
+  // implementation. Some might wish to emit invalidation markers in the trace
+  // (see TracePacket.incremental_state_cleared for an existing field), and
+  // handle them when parsing the trace.
+  virtual void ClearIncrementalState(
+      const DataSourceInstanceID* data_source_ids,
+      size_t num_data_sources) = 0;
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_PRODUCER_H_
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/consumer.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/producer.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_state.gen.h"
+
+// This translation unit contains the definitions for the destructor of pure
+// virtual interfaces for the current build target. The alternative would be
+// introducing a one-liner .cc file for each pure virtual interface, which is
+// overkill. This is for compliance with -Wweak-vtables.
+
+namespace perfetto {
+
+Consumer::~Consumer() = default;
+Producer::~Producer() = default;
+TracingService::~TracingService() = default;
+ConsumerEndpoint::~ConsumerEndpoint() = default;
+ProducerEndpoint::~ProducerEndpoint() = default;
+RelayEndpoint::~RelayEndpoint() = default;
+SharedMemory::~SharedMemory() = default;
+SharedMemory::Factory::~Factory() = default;
+SharedMemoryArbiter::~SharedMemoryArbiter() = default;
+
+// TODO(primiano): make pure virtual after various 3way patches.
+void Consumer::OnSessionCloned(const OnSessionClonedArgs&) {}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/console_interceptor.cc
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/console_interceptor.h"
+
+#include <stdarg.h>
+
+#include <algorithm>
+#include <cmath>
+#include <optional>
+#include <tuple>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_internal.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/common/interceptor_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet_defaults.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/process_descriptor.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/thread_descriptor.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_descriptor.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_event.pbzero.h"
+
+namespace perfetto {
+
+// sRGB color.
+struct ConsoleColor {
+  uint8_t r;
+  uint8_t g;
+  uint8_t b;
+};
+
+namespace {
+
+int g_output_fd_for_testing;
+
+// Google Turbo colormap.
+constexpr std::array<ConsoleColor, 16> kTurboColors = {{
+    ConsoleColor{0x30, 0x12, 0x3b},
+    ConsoleColor{0x40, 0x40, 0xa1},
+    ConsoleColor{0x46, 0x6b, 0xe3},
+    ConsoleColor{0x41, 0x93, 0xfe},
+    ConsoleColor{0x28, 0xbb, 0xeb},
+    ConsoleColor{0x17, 0xdc, 0xc2},
+    ConsoleColor{0x32, 0xf1, 0x97},
+    ConsoleColor{0x6d, 0xfd, 0x62},
+    ConsoleColor{0xa4, 0xfc, 0x3b},
+    ConsoleColor{0xcd, 0xeb, 0x34},
+    ConsoleColor{0xed, 0xcf, 0x39},
+    ConsoleColor{0xfd, 0xab, 0x33},
+    ConsoleColor{0xfa, 0x7d, 0x20},
+    ConsoleColor{0xea, 0x50, 0x0d},
+    ConsoleColor{0xd0, 0x2f, 0x04},
+    ConsoleColor{0xa9, 0x15, 0x01},
+}};
+
+constexpr size_t kHueBits = 4;
+constexpr uint32_t kMaxHue = kTurboColors.size() << kHueBits;
+constexpr uint8_t kLightness = 128u;
+constexpr ConsoleColor kWhiteColor{0xff, 0xff, 0xff};
+
+const char kDim[] = "\x1b[90m";
+const char kDefault[] = "\x1b[39m";
+const char kReset[] = "\x1b[0m";
+
+#define FMT_RGB_SET "\x1b[38;2;%d;%d;%dm"
+#define FMT_RGB_SET_BG "\x1b[48;2;%d;%d;%dm"
+
+ConsoleColor Mix(ConsoleColor a, ConsoleColor b, uint8_t ratio) {
+  return {
+      static_cast<uint8_t>(a.r + (((b.r - a.r) * ratio) >> 8)),
+      static_cast<uint8_t>(a.g + (((b.g - a.g) * ratio) >> 8)),
+      static_cast<uint8_t>(a.b + (((b.b - a.b) * ratio) >> 8)),
+  };
+}
+
+ConsoleColor HueToRGB(uint32_t hue) {
+  PERFETTO_DCHECK(hue < kMaxHue);
+  uint32_t c1 = hue >> kHueBits;
+  uint32_t c2 =
+      std::min(static_cast<uint32_t>(kTurboColors.size() - 1), c1 + 1u);
+  uint32_t ratio = hue & ((1 << kHueBits) - 1);
+  return Mix(kTurboColors[c1], kTurboColors[c2],
+             static_cast<uint8_t>(ratio | (ratio << kHueBits)));
+}
+
+uint32_t CounterToHue(uint32_t counter) {
+  // We split the hue space into 8 segments, reversing the order of bits so
+  // successive counter values will be far from each other.
+  uint32_t reversed =
+      ((counter & 0x7) >> 2) | ((counter & 0x3)) | ((counter & 0x1) << 2);
+  return reversed * kMaxHue / 8;
+}
+
+}  // namespace
+
+class ConsoleInterceptor::Delegate : public TrackEventStateTracker::Delegate {
+ public:
+  explicit Delegate(InterceptorContext&);
+  ~Delegate() override;
+
+  TrackEventStateTracker::SessionState* GetSessionState() override;
+  void OnTrackUpdated(TrackEventStateTracker::Track&) override;
+  void OnTrackEvent(const TrackEventStateTracker::Track&,
+                    const TrackEventStateTracker::ParsedTrackEvent&) override;
+
+ private:
+  using SelfHandle = LockedHandle<ConsoleInterceptor>;
+
+  InterceptorContext& context_;
+  std::optional<SelfHandle> locked_self_;
+};
+
+ConsoleInterceptor::~ConsoleInterceptor() = default;
+
+ConsoleInterceptor::ThreadLocalState::ThreadLocalState(
+    ThreadLocalStateArgs& args) {
+  if (auto self = args.GetInterceptorLocked()) {
+    start_time_ns = self->start_time_ns_;
+    use_colors = self->use_colors_;
+    fd = self->fd_;
+  }
+}
+
+ConsoleInterceptor::ThreadLocalState::~ThreadLocalState() = default;
+
+ConsoleInterceptor::Delegate::Delegate(InterceptorContext& context)
+    : context_(context) {}
+ConsoleInterceptor::Delegate::~Delegate() = default;
+
+TrackEventStateTracker::SessionState*
+ConsoleInterceptor::Delegate::GetSessionState() {
+  // When the session state is retrieved for the first time, it is cached (and
+  // kept locked) until we return from OnTracePacket. This avoids having to lock
+  // and unlock the instance multiple times per invocation.
+  if (locked_self_.has_value())
+    return &locked_self_.value()->session_state_;
+  locked_self_ =
+      std::make_optional<SelfHandle>(context_.GetInterceptorLocked());
+  return &locked_self_.value()->session_state_;
+}
+
+void ConsoleInterceptor::Delegate::OnTrackUpdated(
+    TrackEventStateTracker::Track& track) {
+  auto track_color = HueToRGB(CounterToHue(track.index));
+  std::array<char, 16> title;
+  if (!track.name.empty()) {
+    snprintf(title.data(), title.size(), "%s", track.name.c_str());
+  } else if (track.pid && track.tid) {
+    snprintf(title.data(), title.size(), "%u:%u",
+             static_cast<uint32_t>(track.pid),
+             static_cast<uint32_t>(track.tid));
+  } else if (track.pid) {
+    snprintf(title.data(), title.size(), "%" PRId64, track.pid);
+  } else {
+    snprintf(title.data(), title.size(), "%" PRIu64, track.uuid);
+  }
+  int title_width = static_cast<int>(title.size());
+
+  auto& tls = context_.GetThreadLocalState();
+  std::array<char, 128> message_prefix{};
+  size_t written = 0;
+  if (tls.use_colors) {
+    written = base::SprintfTrunc(message_prefix.data(), message_prefix.size(),
+                                 FMT_RGB_SET_BG " %s%s %-*.*s", track_color.r,
+                                 track_color.g, track_color.b, kReset, kDim,
+                                 title_width, title_width, title.data());
+  } else {
+    written = base::SprintfTrunc(message_prefix.data(), message_prefix.size(),
+                                 "%-*.*s", title_width + 2, title_width,
+                                 title.data());
+  }
+  track.user_data.assign(
+      message_prefix.begin(),
+      message_prefix.begin() + static_cast<ssize_t>(written));
+}
+
+void ConsoleInterceptor::Delegate::OnTrackEvent(
+    const TrackEventStateTracker::Track& track,
+    const TrackEventStateTracker::ParsedTrackEvent& event) {
+  // Start printing.
+  auto& tls = context_.GetThreadLocalState();
+  tls.buffer_pos = 0;
+
+  // Print timestamp and track identifier.
+  SetColor(context_, kDim);
+  Printf(context_, "[%7.3lf] %.*s",
+         static_cast<double>(event.timestamp_ns - tls.start_time_ns) / 1e9,
+         static_cast<int>(track.user_data.size()), track.user_data.data());
+
+  // Print category.
+  Printf(context_, "%-5.*s ",
+         std::min(5, static_cast<int>(event.category.size)),
+         event.category.data);
+
+  // Print stack depth.
+  for (size_t i = 0; i < event.stack_depth; i++) {
+    Printf(context_, "-  ");
+  }
+
+  // Print slice name.
+  auto slice_color = HueToRGB(event.name_hash % kMaxHue);
+  auto highlight_color = Mix(slice_color, kWhiteColor, kLightness);
+  if (event.track_event.type() == protos::pbzero::TrackEvent::TYPE_SLICE_END) {
+    SetColor(context_, kDefault);
+    Printf(context_, "} ");
+  }
+  SetColor(context_, highlight_color);
+  Printf(context_, "%.*s", static_cast<int>(event.name.size), event.name.data);
+  SetColor(context_, kReset);
+  if (event.track_event.type() ==
+      protos::pbzero::TrackEvent::TYPE_SLICE_BEGIN) {
+    SetColor(context_, kDefault);
+    Printf(context_, " {");
+  }
+
+  // Print annotations.
+  if (event.track_event.has_debug_annotations()) {
+    PrintDebugAnnotations(context_, event.track_event, slice_color,
+                          highlight_color);
+  }
+
+  // TODO(skyostil): Print typed arguments.
+
+  // Print duration for longer events.
+  constexpr uint64_t kNsPerMillisecond = 1000000u;
+  if (event.duration_ns >= 10 * kNsPerMillisecond) {
+    SetColor(context_, kDim);
+    Printf(context_, " +%" PRIu64 "ms", event.duration_ns / kNsPerMillisecond);
+  }
+  SetColor(context_, kReset);
+  Printf(context_, "\n");
+}
+
+// static
+void ConsoleInterceptor::Register() {
+  perfetto::protos::gen::InterceptorDescriptor desc;
+  desc.set_name("console");
+  Interceptor<ConsoleInterceptor>::Register(desc);
+}
+
+// static
+void ConsoleInterceptor::SetOutputFdForTesting(int fd) {
+  g_output_fd_for_testing = fd;
+}
+
+void ConsoleInterceptor::OnSetup(const SetupArgs& args) {
+  int fd = STDOUT_FILENO;
+  if (g_output_fd_for_testing)
+    fd = g_output_fd_for_testing;
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
+    !PERFETTO_BUILDFLAG(PERFETTO_OS_WASM)
+  bool use_colors = isatty(fd);
+#else
+  bool use_colors = false;
+#endif
+  const protos::gen::ConsoleConfig& config =
+      args.config.interceptor_config().console_config();
+  if (config.has_enable_colors())
+    use_colors = config.enable_colors();
+  if (config.output() == protos::gen::ConsoleConfig::OUTPUT_STDOUT) {
+    fd = STDOUT_FILENO;
+  } else if (config.output() == protos::gen::ConsoleConfig::OUTPUT_STDERR) {
+    fd = STDERR_FILENO;
+  }
+  fd_ = fd;
+  use_colors_ = use_colors;
+}
+
+void ConsoleInterceptor::OnStart(const StartArgs&) {
+  start_time_ns_ = internal::TrackEventInternal::GetTimeNs();
+}
+
+void ConsoleInterceptor::OnStop(const StopArgs&) {}
+
+// static
+void ConsoleInterceptor::OnTracePacket(InterceptorContext context) {
+  {
+    auto& tls = context.GetThreadLocalState();
+    Delegate delegate(context);
+    perfetto::protos::pbzero::TracePacket::Decoder packet(
+        context.packet_data.data, context.packet_data.size);
+    TrackEventStateTracker::ProcessTracePacket(delegate, tls.sequence_state,
+                                               packet);
+  }  // (Potential) lock scope for session state.
+  Flush(context);
+}
+
+// static
+void ConsoleInterceptor::Printf(InterceptorContext& context,
+                                const char* format,
+                                ...) {
+  auto& tls = context.GetThreadLocalState();
+  ssize_t remaining = static_cast<ssize_t>(tls.message_buffer.size()) -
+                      static_cast<ssize_t>(tls.buffer_pos);
+  int written = 0;
+  if (remaining > 0) {
+    va_list args;
+    va_start(args, format);
+    written = vsnprintf(&tls.message_buffer[tls.buffer_pos],
+                        static_cast<size_t>(remaining), format, args);
+    PERFETTO_DCHECK(written >= 0);
+    va_end(args);
+  }
+
+  // In case of buffer overflow, flush to the fd and write the latest message to
+  // it directly instead.
+  if (remaining <= 0 || written > remaining) {
+    FILE* output = (tls.fd == STDOUT_FILENO) ? stdout : stderr;
+    if (g_output_fd_for_testing) {
+      output = fdopen(dup(g_output_fd_for_testing), "w");
+    }
+    Flush(context);
+    va_list args;
+    va_start(args, format);
+    vfprintf(output, format, args);
+    va_end(args);
+    if (g_output_fd_for_testing) {
+      fclose(output);
+    }
+  } else if (written > 0) {
+    tls.buffer_pos += static_cast<size_t>(written);
+  }
+}
+
+// static
+void ConsoleInterceptor::Flush(InterceptorContext& context) {
+  auto& tls = context.GetThreadLocalState();
+  ssize_t res = base::WriteAll(tls.fd, &tls.message_buffer[0], tls.buffer_pos);
+  PERFETTO_DCHECK(res == static_cast<ssize_t>(tls.buffer_pos));
+  tls.buffer_pos = 0;
+}
+
+// static
+void ConsoleInterceptor::SetColor(InterceptorContext& context,
+                                  const ConsoleColor& color) {
+  auto& tls = context.GetThreadLocalState();
+  if (!tls.use_colors)
+    return;
+  Printf(context, FMT_RGB_SET, color.r, color.g, color.b);
+}
+
+// static
+void ConsoleInterceptor::SetColor(InterceptorContext& context,
+                                  const char* color) {
+  auto& tls = context.GetThreadLocalState();
+  if (!tls.use_colors)
+    return;
+  Printf(context, "%s", color);
+}
+
+// static
+void ConsoleInterceptor::PrintDebugAnnotations(
+    InterceptorContext& context,
+    const protos::pbzero::TrackEvent_Decoder& track_event,
+    const ConsoleColor& slice_color,
+    const ConsoleColor& highlight_color) {
+  SetColor(context, slice_color);
+  Printf(context, "(");
+
+  bool is_first = true;
+  for (auto it = track_event.debug_annotations(); it; it++) {
+    perfetto::protos::pbzero::DebugAnnotation::Decoder annotation(*it);
+    SetColor(context, slice_color);
+    if (!is_first)
+      Printf(context, ", ");
+
+    PrintDebugAnnotationName(context, annotation);
+    Printf(context, ":");
+
+    SetColor(context, highlight_color);
+    PrintDebugAnnotationValue(context, annotation);
+
+    is_first = false;
+  }
+  SetColor(context, slice_color);
+  Printf(context, ")");
+}
+
+// static
+void ConsoleInterceptor::PrintDebugAnnotationName(
+    InterceptorContext& context,
+    const perfetto::protos::pbzero::DebugAnnotation::Decoder& annotation) {
+  auto& tls = context.GetThreadLocalState();
+  protozero::ConstChars name{};
+  if (annotation.name_iid()) {
+    name.data =
+        tls.sequence_state.debug_annotation_names[annotation.name_iid()].data();
+    name.size =
+        tls.sequence_state.debug_annotation_names[annotation.name_iid()].size();
+  } else if (annotation.has_name()) {
+    name.data = annotation.name().data;
+    name.size = annotation.name().size;
+  }
+  Printf(context, "%.*s", static_cast<int>(name.size), name.data);
+}
+
+// static
+void ConsoleInterceptor::PrintDebugAnnotationValue(
+    InterceptorContext& context,
+    const perfetto::protos::pbzero::DebugAnnotation::Decoder& annotation) {
+  if (annotation.has_bool_value()) {
+    Printf(context, "%s", annotation.bool_value() ? "true" : "false");
+  } else if (annotation.has_uint_value()) {
+    Printf(context, "%" PRIu64, annotation.uint_value());
+  } else if (annotation.has_int_value()) {
+    Printf(context, "%" PRId64, annotation.int_value());
+  } else if (annotation.has_double_value()) {
+    Printf(context, "%f", annotation.double_value());
+  } else if (annotation.has_string_value()) {
+    Printf(context, "%.*s", static_cast<int>(annotation.string_value().size),
+           annotation.string_value().data);
+  } else if (annotation.has_pointer_value()) {
+    Printf(context, "%p", reinterpret_cast<void*>(annotation.pointer_value()));
+  } else if (annotation.has_legacy_json_value()) {
+    Printf(context, "%.*s",
+           static_cast<int>(annotation.legacy_json_value().size),
+           annotation.legacy_json_value().data);
+  } else if (annotation.has_dict_entries()) {
+    Printf(context, "{");
+    bool is_first = true;
+    for (auto it = annotation.dict_entries(); it; ++it) {
+      if (!is_first)
+        Printf(context, ", ");
+      perfetto::protos::pbzero::DebugAnnotation::Decoder key_value(*it);
+      PrintDebugAnnotationName(context, key_value);
+      Printf(context, ":");
+      PrintDebugAnnotationValue(context, key_value);
+      is_first = false;
+    }
+    Printf(context, "}");
+  } else if (annotation.has_array_values()) {
+    Printf(context, "[");
+    bool is_first = true;
+    for (auto it = annotation.array_values(); it; ++it) {
+      if (!is_first)
+        Printf(context, ", ");
+      perfetto::protos::pbzero::DebugAnnotation::Decoder key_value(*it);
+      PrintDebugAnnotationValue(context, key_value);
+      is_first = false;
+    }
+    Printf(context, "]");
+  } else {
+    Printf(context, "{}");
+  }
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/data_source.cc
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/data_source.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
+
+namespace perfetto {
+
+DataSourceBase::StopArgs::~StopArgs() = default;
+DataSourceBase::FlushArgs::~FlushArgs() = default;
+DataSourceBase::~DataSourceBase() = default;
+void DataSourceBase::OnSetup(const SetupArgs&) {}
+void DataSourceBase::OnStart(const StartArgs&) {}
+void DataSourceBase::OnStop(const StopArgs&) {}
+void DataSourceBase::WillClearIncrementalState(
+    const ClearIncrementalStateArgs&) {}
+void DataSourceBase::OnFlush(const FlushArgs&) {}
+
+bool DataSourceBase::CanAdoptStartupSession(
+    const DataSourceConfig& startup_config,
+    const DataSourceConfig& service_config) {
+  // Clear target buffer and tracing-service provided fields for comparison of
+  // configs for startup tracing, since these fields are not available when
+  // setting up data sources for startup tracing.
+  DataSourceConfig startup_config_stripped = startup_config;
+  DataSourceConfig service_config_stripped = service_config;
+
+  startup_config_stripped.set_target_buffer(0);
+  startup_config_stripped.set_tracing_session_id(0);
+  startup_config_stripped.set_session_initiator(
+      DataSourceConfig::SESSION_INITIATOR_UNSPECIFIED);
+  startup_config_stripped.set_trace_duration_ms(0);
+  startup_config_stripped.set_stop_timeout_ms(0);
+  startup_config_stripped.set_enable_extra_guardrails(false);
+
+  service_config_stripped.set_target_buffer(0);
+  service_config_stripped.set_tracing_session_id(0);
+  service_config_stripped.set_session_initiator(
+      DataSourceConfig::SESSION_INITIATOR_UNSPECIFIED);
+  service_config_stripped.set_trace_duration_ms(0);
+  service_config_stripped.set_stop_timeout_ms(0);
+  service_config_stripped.set_enable_extra_guardrails(false);
+
+  return startup_config_stripped == service_config_stripped;
+}
+
+namespace internal {
+
+void DataSourceType::PopulateTlsInst(
+    DataSourceInstanceThreadLocalState* tls_inst,
+    DataSourceState* instance_state,
+    uint32_t instance_index) {
+  auto* tracing_impl = TracingMuxer::Get();
+  tls_inst->muxer_id_for_testing = instance_state->muxer_id_for_testing;
+  tls_inst->backend_id = instance_state->backend_id;
+  tls_inst->backend_connection_id = instance_state->backend_connection_id;
+  tls_inst->buffer_id = instance_state->buffer_id;
+  tls_inst->startup_target_buffer_reservation =
+      instance_state->startup_target_buffer_reservation.load(
+          std::memory_order_relaxed);
+  tls_inst->data_source_instance_id = instance_state->data_source_instance_id;
+  tls_inst->is_intercepted = instance_state->interceptor_id != 0;
+  tls_inst->trace_writer = tracing_impl->CreateTraceWriter(
+      &state_, instance_index, instance_state, buffer_exhausted_policy_);
+  if (create_incremental_state_fn_) {
+    PERFETTO_DCHECK(!tls_inst->incremental_state);
+    CreateIncrementalState(tls_inst, instance_index);
+  }
+  if (create_custom_tls_fn_) {
+    tls_inst->data_source_custom_tls =
+        create_custom_tls_fn_(tls_inst, instance_index, user_arg_);
+  }
+  // Even in the case of out-of-IDs, SharedMemoryArbiterImpl returns a
+  // NullTraceWriter. The returned pointer should never be null.
+  PERFETTO_DCHECK(tls_inst->trace_writer);
+}
+
+}  // namespace internal
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/debug_annotation.cc
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/debug_annotation.h"
+
+// gen_amalgamated expanded: #include "perfetto/tracing/traced_value.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
+
+namespace perfetto {
+
+DebugAnnotation::~DebugAnnotation() = default;
+
+void DebugAnnotation::WriteIntoTracedValue(TracedValue context) const {
+  Add(context.annotation_);
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/event_context.cc
+// gen_amalgamated begin header: include/perfetto/tracing/internal/track_event_interned_fields.h
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track_event_interned_data_index.h"
+
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_INTERNED_FIELDS_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_INTERNED_FIELDS_H_
+
+namespace perfetto {
+namespace internal {
+
+// These helpers are exposed here to allow Chromium-without-client library
+// to share the interning buffers with Perfetto internals (e.g.
+// perfetto::TracedValue implementation).
+
+struct PERFETTO_EXPORT_COMPONENT InternedEventCategory
+    : public TrackEventInternedDataIndex<
+          InternedEventCategory,
+          perfetto::protos::pbzero::InternedData::kEventCategoriesFieldNumber,
+          const char*,
+          SmallInternedDataTraits> {
+  ~InternedEventCategory() override;
+
+  static void Add(protos::pbzero::InternedData* interned_data,
+                  size_t iid,
+                  const char* value,
+                  size_t length);
+};
+
+struct PERFETTO_EXPORT_COMPONENT InternedEventName
+    : public TrackEventInternedDataIndex<
+          InternedEventName,
+          perfetto::protos::pbzero::InternedData::kEventNamesFieldNumber,
+          const char*,
+          SmallInternedDataTraits> {
+  ~InternedEventName() override;
+
+  static void Add(protos::pbzero::InternedData* interned_data,
+                  size_t iid,
+                  const char* value);
+};
+
+struct PERFETTO_EXPORT_COMPONENT InternedDebugAnnotationName
+    : public TrackEventInternedDataIndex<
+          InternedDebugAnnotationName,
+          perfetto::protos::pbzero::InternedData::
+              kDebugAnnotationNamesFieldNumber,
+          const char*,
+          SmallInternedDataTraits> {
+  ~InternedDebugAnnotationName() override;
+
+  static void Add(protos::pbzero::InternedData* interned_data,
+                  size_t iid,
+                  const char* value);
+};
+
+struct PERFETTO_EXPORT_COMPONENT InternedDebugAnnotationValueTypeName
+    : public TrackEventInternedDataIndex<
+          InternedDebugAnnotationValueTypeName,
+          perfetto::protos::pbzero::InternedData::
+              kDebugAnnotationValueTypeNamesFieldNumber,
+          const char*,
+          SmallInternedDataTraits> {
+  ~InternedDebugAnnotationValueTypeName() override;
+
+  static void Add(protos::pbzero::InternedData* interned_data,
+                  size_t iid,
+                  const char* value);
+};
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_INTERNED_FIELDS_H_
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/event_context.h"
+
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_interned_fields.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_event.pbzero.h"
+
+namespace perfetto {
+
+EventContext::EventContext(
+    TraceWriterBase* trace_writer,
+    EventContext::TracePacketHandle trace_packet,
+    internal::TrackEventIncrementalState* incremental_state,
+    internal::TrackEventTlsState* tls_state)
+    : trace_writer_(trace_writer),
+      trace_packet_(std::move(trace_packet)),
+      event_(trace_packet_->set_track_event()),
+      incremental_state_(incremental_state),
+      tls_state_(tls_state) {}
+
+EventContext::~EventContext() {
+  if (!trace_packet_)
+    return;
+
+  // When the track event is finalized (i.e., the context is destroyed), we
+  // should flush any newly seen interned data to the trace. The data has
+  // earlier been written to a heap allocated protobuf message
+  // (|serialized_interned_data|). Here we just need to flush it to the main
+  // trace.
+  auto& serialized_interned_data = incremental_state_->serialized_interned_data;
+  if (PERFETTO_UNLIKELY(!serialized_interned_data.empty())) {
+    auto ranges = serialized_interned_data.GetRanges();
+    trace_packet_->AppendScatteredBytes(
+        perfetto::protos::pbzero::TracePacket::kInternedDataFieldNumber,
+        &ranges[0], ranges.size());
+
+    // Reset the message but keep one buffer allocated for future use.
+    serialized_interned_data.Reset();
+  }
+}
+
+protos::pbzero::DebugAnnotation* EventContext::AddDebugAnnotation(
+    const char* name) {
+  auto annotation = event()->add_debug_annotations();
+  annotation->set_name_iid(
+      internal::InternedDebugAnnotationName::Get(this, name));
+  return annotation;
+}
+
+protos::pbzero::DebugAnnotation* EventContext::AddDebugAnnotation(
+    ::perfetto::DynamicString name) {
+  auto annotation = event()->add_debug_annotations();
+  annotation->set_name(name.value);
+  return annotation;
+}
+
+TrackEventTlsStateUserData* EventContext::GetTlsUserData(const void* key) {
+  PERFETTO_CHECK(tls_state_);
+  PERFETTO_CHECK(key);
+  auto it = tls_state_->user_data.find(key);
+  if (it != tls_state_->user_data.end()) {
+    return it->second.get();
+  }
+  return nullptr;
+}
+
+void EventContext::SetTlsUserData(
+    const void* key,
+    std::unique_ptr<TrackEventTlsStateUserData> data) {
+  PERFETTO_CHECK(tls_state_);
+  PERFETTO_CHECK(key);
+  tls_state_->user_data[key] = std::move(data);
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/interceptor.cc
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/interceptor.h"
+
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_muxer.h"
+
+namespace perfetto {
+
+InterceptorBase::~InterceptorBase() = default;
+InterceptorBase::ThreadLocalState::~ThreadLocalState() = default;
+
+// static
+void InterceptorBase::RegisterImpl(
+    const InterceptorDescriptor& descriptor,
+    std::function<std::unique_ptr<InterceptorBase>()> factory,
+    InterceptorBase::TLSFactory tls_factory,
+    InterceptorBase::TracePacketCallback on_trace_packet) {
+  auto* tracing_impl = internal::TracingMuxer::Get();
+  tracing_impl->RegisterInterceptor(descriptor, factory, tls_factory,
+                                    on_trace_packet);
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/internal/checked_scope.cc
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/checked_scope.h"
+
+#include <utility>
+
+namespace perfetto {
+namespace internal {
+
+#if PERFETTO_DCHECK_IS_ON()
+CheckedScope::CheckedScope(CheckedScope* parent_scope)
+    : parent_scope_(parent_scope) {
+  if (parent_scope_) {
+    PERFETTO_DCHECK(parent_scope_->is_active());
+    parent_scope_->set_is_active(false);
+  }
+}
+
+CheckedScope::~CheckedScope() {
+  Reset();
+}
+
+void CheckedScope::Reset() {
+  if (!is_active_) {
+    // The only case when inactive scope could be destroyed is when Reset() was
+    // called explicitly or the contents of the object were moved away.
+    PERFETTO_DCHECK(deleted_);
+    return;
+  }
+  is_active_ = false;
+  deleted_ = true;
+  if (parent_scope_)
+    parent_scope_->set_is_active(true);
+}
+
+CheckedScope::CheckedScope(CheckedScope&& other) {
+  *this = std::move(other);
+}
+
+CheckedScope& CheckedScope::operator=(CheckedScope&& other) {
+  is_active_ = other.is_active_;
+  parent_scope_ = other.parent_scope_;
+  deleted_ = other.deleted_;
+
+  other.is_active_ = false;
+  other.parent_scope_ = nullptr;
+  other.deleted_ = true;
+
+  return *this;
+}
+#endif
+
+}  // namespace internal
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/internal/interceptor_trace_writer.cc
+// gen_amalgamated begin header: include/perfetto/tracing/internal/interceptor_trace_writer.h
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_INTERCEPTOR_TRACE_WRITER_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_INTERCEPTOR_TRACE_WRITER_H_
+
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/interceptor.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
+
+namespace perfetto {
+namespace internal {
+
+// A heap-backed trace writer used to reroute trace packets to an interceptor.
+class InterceptorTraceWriter : public TraceWriterBase {
+ public:
+  InterceptorTraceWriter(std::unique_ptr<InterceptorBase::ThreadLocalState> tls,
+                         InterceptorBase::TracePacketCallback packet_callback,
+                         DataSourceStaticState* static_state,
+                         uint32_t instance_index);
+  ~InterceptorTraceWriter() override;
+
+  // TraceWriterBase implementation.
+  protozero::MessageHandle<protos::pbzero::TracePacket> NewTracePacket()
+      override;
+  void FinishTracePacket() override;
+  void Flush(std::function<void()> callback = {}) override;
+  uint64_t written() const override;
+
+ private:
+  std::unique_ptr<InterceptorBase::ThreadLocalState> tls_;
+  InterceptorBase::TracePacketCallback packet_callback_;
+
+  protozero::HeapBuffered<protos::pbzero::TracePacket> cur_packet_;
+  uint64_t bytes_written_ = 0;
+
+  // Static state of the data source we are intercepting.
+  DataSourceStaticState* const static_state_;
+
+  // Index of the data source tracing session which we are intercepting
+  // (0...kMaxDataSourceInstances - 1). Used to look up this interceptor's
+  // session state (i.e., the Interceptor class instance) in the
+  // DataSourceStaticState::instances array.
+  const uint32_t instance_index_;
+
+  const uint32_t sequence_id_;
+
+  static std::atomic<uint32_t> next_sequence_id_;
+};
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_INTERCEPTOR_TRACE_WRITER_H_
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/interceptor_trace_writer.h"
+
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
+
+namespace perfetto {
+namespace internal {
+
+// static
+std::atomic<uint32_t> InterceptorTraceWriter::next_sequence_id_{};
+
+InterceptorTraceWriter::InterceptorTraceWriter(
+    std::unique_ptr<InterceptorBase::ThreadLocalState> tls,
+    InterceptorBase::TracePacketCallback packet_callback,
+    DataSourceStaticState* static_state,
+    uint32_t instance_index)
+    : tls_(std::move(tls)),
+      packet_callback_(std::move(packet_callback)),
+      static_state_(static_state),
+      instance_index_(instance_index),
+      sequence_id_(++next_sequence_id_) {}
+
+InterceptorTraceWriter::~InterceptorTraceWriter() = default;
+
+protozero::MessageHandle<protos::pbzero::TracePacket>
+InterceptorTraceWriter::NewTracePacket() {
+  Flush();
+  auto packet = TraceWriter::TracePacketHandle(cur_packet_.get());
+  packet->set_trusted_packet_sequence_id(sequence_id_);
+  return packet;
+}
+
+void InterceptorTraceWriter::Flush(std::function<void()> callback) {
+  if (!cur_packet_.empty()) {
+    InterceptorBase::TracePacketCallbackArgs args{};
+    args.static_state = static_state_;
+    args.instance_index = instance_index_;
+    args.tls = tls_.get();
+
+    const auto& slices = cur_packet_.GetSlices();
+    if (slices.size() == 1) {
+      // Fast path: the current packet fits into a single slice.
+      auto slice_range = slices.begin()->GetUsedRange();
+      args.packet_data = protozero::ConstBytes{
+          slice_range.begin,
+          static_cast<size_t>(slice_range.end - slice_range.begin)};
+      bytes_written_ += static_cast<uint64_t>(args.packet_data.size);
+      packet_callback_(std::move(args));
+    } else {
+      // Fallback: stitch together multiple slices.
+      auto stitched_data = cur_packet_.SerializeAsArray();
+      args.packet_data =
+          protozero::ConstBytes{stitched_data.data(), stitched_data.size()};
+      bytes_written_ += static_cast<uint64_t>(stitched_data.size());
+      packet_callback_(std::move(args));
+    }
+    cur_packet_.Reset();
+  }
+  if (callback)
+    callback();
+}
+
+void InterceptorTraceWriter::FinishTracePacket() {}
+
+uint64_t InterceptorTraceWriter::written() const {
+  return bytes_written_;
+}
+
+}  // namespace internal
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/internal/tracing_backend_fake.cc
+// gen_amalgamated begin header: include/perfetto/tracing/internal/tracing_backend_fake.h
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_TRACING_BACKEND_FAKE_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_TRACING_BACKEND_FAKE_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/tracing_backend.h"
+
+namespace perfetto {
+namespace internal {
+
+// A built-in implementation of TracingBackend that fails any attempt to create
+// a tracing session.
+class PERFETTO_EXPORT_COMPONENT TracingBackendFake : public TracingBackend {
+ public:
+  static TracingBackend* GetInstance();
+
+  // TracingBackend implementation.
+  std::unique_ptr<ProducerEndpoint> ConnectProducer(
+      const ConnectProducerArgs&) override;
+  std::unique_ptr<ConsumerEndpoint> ConnectConsumer(
+      const ConnectConsumerArgs&) override;
+
+ private:
+  TracingBackendFake();
+};
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_TRACING_BACKEND_FAKE_H_
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_backend_fake.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/consumer.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/producer.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
+
+namespace perfetto {
+namespace internal {
+
+namespace {
+
+class UnsupportedProducerEndpoint : public ProducerEndpoint {
+ public:
+  UnsupportedProducerEndpoint(Producer* producer, base::TaskRunner* task_runner)
+      : producer_(producer), task_runner_(task_runner) {
+    // The SDK will attempt to reconnect the producer, so instead we allow it
+    // to connect successfully, but never start any sessions.
+    auto weak_ptr = weak_ptr_factory_.GetWeakPtr();
+    task_runner_->PostTask([weak_ptr] {
+      if (weak_ptr && weak_ptr->connected_)
+        weak_ptr->producer_->OnConnect();
+    });
+  }
+  ~UnsupportedProducerEndpoint() override { Disconnect(); }
+
+  void Disconnect() override {
+    if (!connected_)
+      return;
+    connected_ = false;
+    producer_->OnDisconnect();
+  }
+
+  void RegisterDataSource(const DataSourceDescriptor&) override {}
+  void UpdateDataSource(const DataSourceDescriptor&) override {}
+  void UnregisterDataSource(const std::string& /*name*/) override {}
+
+  void RegisterTraceWriter(uint32_t /*writer_id*/,
+                           uint32_t /*target_buffer*/) override {}
+  void UnregisterTraceWriter(uint32_t /*writer_id*/) override {}
+
+  void CommitData(const CommitDataRequest&,
+                  CommitDataCallback callback) override {
+    if (connected_) {
+      callback();
+    }
+  }
+
+  SharedMemory* shared_memory() const override { return nullptr; }
+  size_t shared_buffer_page_size_kb() const override { return 0; }
+
+  std::unique_ptr<TraceWriter> CreateTraceWriter(
+      BufferID /*target_buffer*/,
+      BufferExhaustedPolicy) override {
+    return nullptr;
+  }
+
+  SharedMemoryArbiter* MaybeSharedMemoryArbiter() override { return nullptr; }
+  bool IsShmemProvidedByProducer() const override { return false; }
+
+  void NotifyFlushComplete(FlushRequestID) override {}
+  void NotifyDataSourceStarted(DataSourceInstanceID) override {}
+  void NotifyDataSourceStopped(DataSourceInstanceID) override {}
+  void ActivateTriggers(const std::vector<std::string>&) override {}
+
+  void Sync(std::function<void()> callback) override {
+    if (connected_) {
+      callback();
+    }
+  }
+
+ private:
+  Producer* const producer_;
+  base::TaskRunner* const task_runner_;
+  bool connected_ = true;
+  base::WeakPtrFactory<UnsupportedProducerEndpoint> weak_ptr_factory_{
+      this};  // Keep last.
+};
+
+class UnsupportedConsumerEndpoint : public ConsumerEndpoint {
+ public:
+  UnsupportedConsumerEndpoint(Consumer* consumer, base::TaskRunner* task_runner)
+      : consumer_(consumer), task_runner_(task_runner) {
+    // The SDK will not to reconnect the consumer, so we just disconnect it
+    // immediately, which will cancel the tracing session.
+    auto weak_this = weak_ptr_factory_.GetWeakPtr();
+    task_runner_->PostTask([weak_this] {
+      if (weak_this)
+        weak_this->consumer_->OnDisconnect();
+    });
+  }
+  ~UnsupportedConsumerEndpoint() override = default;
+
+  void EnableTracing(const TraceConfig&, base::ScopedFile) override {}
+  void ChangeTraceConfig(const TraceConfig&) override {}
+
+  void StartTracing() override {}
+  void DisableTracing() override {}
+
+  void Flush(uint32_t /*timeout_ms*/,
+             FlushCallback callback,
+             FlushFlags) override {
+    callback(/*success=*/false);
+  }
+
+  void ReadBuffers() override {}
+  void FreeBuffers() override {}
+
+  void Detach(const std::string& /*key*/) override {}
+  void Attach(const std::string& /*key*/) override {}
+
+  void GetTraceStats() override {}
+  void ObserveEvents(uint32_t /*events_mask*/) override {}
+  void QueryServiceState(QueryServiceStateArgs,
+                         QueryServiceStateCallback) override {}
+  void QueryCapabilities(QueryCapabilitiesCallback) override {}
+
+  void SaveTraceForBugreport(SaveTraceForBugreportCallback) override {}
+  void CloneSession(TracingSessionID, CloneSessionArgs) override {}
+
+ private:
+  Consumer* const consumer_;
+  base::TaskRunner* const task_runner_;
+  base::WeakPtrFactory<UnsupportedConsumerEndpoint> weak_ptr_factory_{
+      this};  // Keep last.
+};
+
+}  // namespace
+
+// static
+TracingBackend* TracingBackendFake::GetInstance() {
+  static auto* instance = new TracingBackendFake();
+  return instance;
+}
+
+TracingBackendFake::TracingBackendFake() = default;
+
+std::unique_ptr<ProducerEndpoint> TracingBackendFake::ConnectProducer(
+    const ConnectProducerArgs& args) {
+  return std::unique_ptr<ProducerEndpoint>(
+      new UnsupportedProducerEndpoint(args.producer, args.task_runner));
+}
+
+std::unique_ptr<ConsumerEndpoint> TracingBackendFake::ConnectConsumer(
+    const ConnectConsumerArgs& args) {
+  return std::unique_ptr<ConsumerEndpoint>(
+      new UnsupportedConsumerEndpoint(args.consumer, args.task_runner));
+}
+
+}  // namespace internal
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/internal/tracing_muxer_fake.cc
+// gen_amalgamated begin header: src/tracing/internal/tracing_muxer_fake.h
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACING_INTERNAL_TRACING_MUXER_FAKE_H_
+#define SRC_TRACING_INTERNAL_TRACING_MUXER_FAKE_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_muxer.h"
+
+namespace perfetto {
+namespace internal {
+
+// An always-fail implementation of TracingMuxer. Before tracing has been
+// initialiazed, all muxer operations will route here and fail with a helpful
+// error message. This is to avoid introducing null checks in
+// performance-critical parts of the codebase.
+class TracingMuxerFake : public TracingMuxer {
+  class FakePlatform : public Platform {
+   public:
+    ~FakePlatform() override;
+    ThreadLocalObject* GetOrCreateThreadLocalObject() override;
+    std::unique_ptr<base::TaskRunner> CreateTaskRunner(
+        const CreateTaskRunnerArgs&) override;
+    std::string GetCurrentProcessName() override;
+
+    static FakePlatform instance;
+  };
+
+ public:
+  TracingMuxerFake() : TracingMuxer(&FakePlatform::instance) {}
+  ~TracingMuxerFake() override;
+
+  static constexpr TracingMuxerFake* Get() {
+#if PERFETTO_HAS_NO_DESTROY()
+    return &instance;
+#else
+    return nullptr;
+#endif
+  }
+
+  // TracingMuxer implementation.
+  bool RegisterDataSource(const DataSourceDescriptor&,
+                          DataSourceFactory,
+                          DataSourceParams,
+                          bool,
+                          DataSourceStaticState*) override;
+  void UpdateDataSourceDescriptor(const DataSourceDescriptor&,
+                                  const DataSourceStaticState*) override;
+  std::unique_ptr<TraceWriterBase> CreateTraceWriter(
+      DataSourceStaticState*,
+      uint32_t data_source_instance_index,
+      DataSourceState*,
+      BufferExhaustedPolicy buffer_exhausted_policy) override;
+  void DestroyStoppedTraceWritersForCurrentThread() override;
+  void RegisterInterceptor(const InterceptorDescriptor&,
+                           InterceptorFactory,
+                           InterceptorBase::TLSFactory,
+                           InterceptorBase::TracePacketCallback) override;
+  void ActivateTriggers(const std::vector<std::string>&, uint32_t) override;
+
+ private:
+  static TracingMuxerFake instance;
+};
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_INTERNAL_TRACING_MUXER_FAKE_H_
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/internal/tracing_muxer_fake.h"
+
+namespace perfetto {
+namespace internal {
+namespace {
+
+PERFETTO_NORETURN void FailUninitialized() {
+  PERFETTO_FATAL(
+      "Tracing not initialized. Call perfetto::Tracing::Initialize() first.");
+}
+
+}  // namespace
+
+#if PERFETTO_HAS_NO_DESTROY()
+// static
+PERFETTO_NO_DESTROY TracingMuxerFake::FakePlatform
+    TracingMuxerFake::FakePlatform::instance{};
+// static
+PERFETTO_NO_DESTROY TracingMuxerFake TracingMuxerFake::instance{};
+#endif  // PERFETTO_HAS_NO_DESTROY()
+
+TracingMuxerFake::~TracingMuxerFake() = default;
+
+TracingMuxerFake::FakePlatform::~FakePlatform() = default;
+
+Platform::ThreadLocalObject*
+TracingMuxerFake::FakePlatform::GetOrCreateThreadLocalObject() {
+  FailUninitialized();
+}
+
+std::unique_ptr<base::TaskRunner>
+TracingMuxerFake::FakePlatform::CreateTaskRunner(const CreateTaskRunnerArgs&) {
+  FailUninitialized();
+}
+
+std::string TracingMuxerFake::FakePlatform::GetCurrentProcessName() {
+  FailUninitialized();
+}
+
+bool TracingMuxerFake::RegisterDataSource(const DataSourceDescriptor&,
+                                          DataSourceFactory,
+                                          DataSourceParams,
+                                          bool,
+                                          DataSourceStaticState*) {
+  FailUninitialized();
+}
+
+void TracingMuxerFake::UpdateDataSourceDescriptor(
+    const DataSourceDescriptor&,
+    const DataSourceStaticState*) {
+  FailUninitialized();
+}
+
+std::unique_ptr<TraceWriterBase> TracingMuxerFake::CreateTraceWriter(
+    DataSourceStaticState*,
+    uint32_t,
+    DataSourceState*,
+    BufferExhaustedPolicy) {
+  FailUninitialized();
+}
+
+void TracingMuxerFake::DestroyStoppedTraceWritersForCurrentThread() {
+  FailUninitialized();
+}
+
+void TracingMuxerFake::RegisterInterceptor(
+    const InterceptorDescriptor&,
+    InterceptorFactory,
+    InterceptorBase::TLSFactory,
+    InterceptorBase::TracePacketCallback) {
+  FailUninitialized();
+}
+
+void TracingMuxerFake::ActivateTriggers(const std::vector<std::string>&,
+                                        uint32_t) {
+  FailUninitialized();
+}
+
+}  // namespace internal
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/internal/tracing_muxer_impl.cc
+// gen_amalgamated begin header: src/tracing/internal/tracing_muxer_impl.h
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACING_INTERNAL_TRACING_MUXER_IMPL_H_
+#define SRC_TRACING_INTERNAL_TRACING_MUXER_IMPL_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <array>
+#include <atomic>
+#include <bitset>
+#include <functional>
+#include <list>
+#include <map>
+#include <memory>
+#include <set>
+#include <utility>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/consumer.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/producer.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/backend_type.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/trace_config.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_muxer.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/tracing.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/common/interceptor_descriptor.gen.h"
+
+namespace perfetto {
+
+class ConsumerEndpoint;
+class DataSourceBase;
+class ProducerEndpoint;
+class TraceWriterBase;
+class TracingBackend;
+class TracingSession;
+struct TracingInitArgs;
+
+namespace base {
+class TaskRunner;
+}
+
+namespace shlib {
+void ResetForTesting();
+}
+
+namespace test {
+class TracingMuxerImplInternalsForTest;
+}
+
+namespace internal {
+
+struct DataSourceStaticState;
+
+// This class acts as a bridge between the public API and the TracingBackend(s).
+// It exposes a simplified view of the world to the API methods handling all the
+// bookkeeping to map data source instances and trace writers to the various
+// backends. It deals with N data sources, M backends (1 backend == 1 tracing
+// service == 1 producer connection) and T concurrent tracing sessions.
+//
+// Handing data source registration and start/stop flows [producer side]:
+// ----------------------------------------------------------------------
+// 1. The API client subclasses perfetto::DataSource and calls
+//    DataSource::Register<MyDataSource>(). In turn this calls into the
+//    TracingMuxer.
+// 2. The tracing muxer iterates through all the backends (1 backend == 1
+//    service == 1 producer connection) and registers the data source on each
+//    backend.
+// 3. When any (services behind a) backend starts tracing and requests to start
+//    that specific data source, the TracingMuxerImpl constructs a new instance
+//    of MyDataSource and calls the OnStart() method.
+//
+// Controlling trace and retrieving trace data [consumer side]:
+// ------------------------------------------------------------
+// 1. The API client calls Tracing::NewTrace(), returns a RAII TracingSession
+//    object.
+// 2. NewTrace() calls into internal::TracingMuxer(Impl). TracingMuxer
+//    subclasses the TracingSession object (TracingSessionImpl) and returns it.
+// 3. The tracing muxer identifies the backend (according to the args passed to
+//    NewTrace), creates a new Consumer and connects to it.
+// 4. When the API client calls Start()/Stop()/ReadTrace() methods, the
+//    TracingMuxer forwards them to the consumer associated to the
+//    TracingSession. Likewise for callbacks coming from the consumer-side of
+//    the service.
+class TracingMuxerImpl : public TracingMuxer {
+ public:
+  // This is different than TracingSessionID because it's global across all
+  // backends. TracingSessionID is global only within the scope of one service.
+  using TracingSessionGlobalID = uint64_t;
+
+  struct RegisteredDataSource {
+    DataSourceDescriptor descriptor;
+    DataSourceFactory factory{};
+    bool supports_multiple_instances = false;
+    bool requires_callbacks_under_lock = false;
+    bool no_flush = false;
+    DataSourceStaticState* static_state = nullptr;
+  };
+
+  static void InitializeInstance(const TracingInitArgs&);
+  static void ResetForTesting();
+  static void Shutdown();
+
+  // TracingMuxer implementation.
+  bool RegisterDataSource(const DataSourceDescriptor&,
+                          DataSourceFactory,
+                          DataSourceParams,
+                          bool no_flush,
+                          DataSourceStaticState*) override;
+  void UpdateDataSourceDescriptor(const DataSourceDescriptor&,
+                                  const DataSourceStaticState*) override;
+  std::unique_ptr<TraceWriterBase> CreateTraceWriter(
+      DataSourceStaticState*,
+      uint32_t data_source_instance_index,
+      DataSourceState*,
+      BufferExhaustedPolicy buffer_exhausted_policy) override;
+  void DestroyStoppedTraceWritersForCurrentThread() override;
+  void RegisterInterceptor(const InterceptorDescriptor&,
+                           InterceptorFactory,
+                           InterceptorBase::TLSFactory,
+                           InterceptorBase::TracePacketCallback) override;
+
+  void ActivateTriggers(const std::vector<std::string>&, uint32_t) override;
+
+  std::unique_ptr<TracingSession> CreateTracingSession(
+      BackendType,
+      TracingConsumerBackend* (*system_backend_factory)());
+  std::unique_ptr<StartupTracingSession> CreateStartupTracingSession(
+      const TraceConfig& config,
+      Tracing::SetupStartupTracingOpts);
+  std::unique_ptr<StartupTracingSession> CreateStartupTracingSessionBlocking(
+      const TraceConfig& config,
+      Tracing::SetupStartupTracingOpts);
+
+  // Producer-side bookkeeping methods.
+  void UpdateDataSourcesOnAllBackends();
+  void SetupDataSource(TracingBackendId,
+                       uint32_t backend_connection_id,
+                       DataSourceInstanceID,
+                       const DataSourceConfig&);
+  void StartDataSource(TracingBackendId, DataSourceInstanceID);
+  void StopDataSource_AsyncBegin(TracingBackendId, DataSourceInstanceID);
+  void ClearDataSourceIncrementalState(TracingBackendId, DataSourceInstanceID);
+  void SyncProducersForTesting();
+
+  // Consumer-side bookkeeping methods.
+  void SetupTracingSession(TracingSessionGlobalID,
+                           const std::shared_ptr<TraceConfig>&,
+                           base::ScopedFile trace_fd = base::ScopedFile());
+  void StartTracingSession(TracingSessionGlobalID);
+  void ChangeTracingSessionConfig(TracingSessionGlobalID, const TraceConfig&);
+  void StopTracingSession(TracingSessionGlobalID);
+  void DestroyTracingSession(TracingSessionGlobalID);
+  void FlushTracingSession(TracingSessionGlobalID,
+                           uint32_t,
+                           std::function<void(bool)>);
+  void ReadTracingSessionData(
+      TracingSessionGlobalID,
+      std::function<void(TracingSession::ReadTraceCallbackArgs)>);
+  void GetTraceStats(TracingSessionGlobalID,
+                     TracingSession::GetTraceStatsCallback);
+  void QueryServiceState(TracingSessionGlobalID,
+                         TracingSession::QueryServiceStateCallback);
+
+  // Sets the batching period to |batch_commits_duration_ms| on the backends
+  // with type |backend_type|.
+  void SetBatchCommitsDurationForTesting(uint32_t batch_commits_duration_ms,
+                                         BackendType backend_type);
+
+  // Enables direct SMB patching on the backends with type |backend_type| (see
+  // SharedMemoryArbiter::EnableDirectSMBPatching). Returns true if the
+  // operation succeeded for all backends with type |backend_type|, false
+  // otherwise.
+  bool EnableDirectSMBPatchingForTesting(BackendType backend_type);
+
+  void SetMaxProducerReconnectionsForTesting(uint32_t count);
+
+ private:
+  friend class test::TracingMuxerImplInternalsForTest;
+  friend void shlib::ResetForTesting();
+
+  // For each TracingBackend we create and register one ProducerImpl instance.
+  // This talks to the producer-side of the service, gets start/stop requests
+  // from it and routes them to the registered data sources.
+  // One ProducerImpl == one backend == one tracing service.
+  // This class is needed to disambiguate callbacks coming from different
+  // services. TracingMuxerImpl can't directly implement the Producer interface
+  // because the Producer virtual methods don't allow to identify the service.
+  class ProducerImpl : public Producer {
+   public:
+    ProducerImpl(TracingMuxerImpl*,
+                 TracingBackendId,
+                 uint32_t shmem_batch_commits_duration_ms,
+                 bool shmem_direct_patching_enabled);
+    ~ProducerImpl() override;
+
+    void Initialize(std::unique_ptr<ProducerEndpoint> endpoint);
+    void RegisterDataSource(const DataSourceDescriptor&,
+                            DataSourceFactory,
+                            DataSourceStaticState*);
+    void DisposeConnection();
+
+    // perfetto::Producer implementation.
+    void OnConnect() override;
+    void OnDisconnect() override;
+    void OnTracingSetup() override;
+    void OnStartupTracingSetup() override;
+    void SetupDataSource(DataSourceInstanceID,
+                         const DataSourceConfig&) override;
+    void StartDataSource(DataSourceInstanceID,
+                         const DataSourceConfig&) override;
+    void StopDataSource(DataSourceInstanceID) override;
+    void Flush(FlushRequestID,
+               const DataSourceInstanceID*,
+               size_t,
+               FlushFlags) override;
+    void ClearIncrementalState(const DataSourceInstanceID*, size_t) override;
+
+    bool SweepDeadServices();
+    void SendOnConnectTriggers();
+    void NotifyFlushForDataSourceDone(DataSourceInstanceID, FlushRequestID);
+
+    PERFETTO_THREAD_CHECKER(thread_checker_)
+    TracingMuxerImpl* muxer_;
+    TracingBackendId const backend_id_;
+    bool connected_ = false;
+    bool did_setup_tracing_ = false;
+    bool did_setup_startup_tracing_ = false;
+    std::atomic<uint32_t> connection_id_{0};
+    uint16_t last_startup_target_buffer_reservation_ = 0;
+    bool is_producer_provided_smb_ = false;
+    bool producer_provided_smb_failed_ = false;
+
+    const uint32_t shmem_batch_commits_duration_ms_ = 0;
+    const bool shmem_direct_patching_enabled_ = false;
+
+    // Set of data sources that have been actually registered on this producer.
+    // This can be a subset of the global |data_sources_|, because data sources
+    // can register before the producer is fully connected.
+    std::bitset<kMaxDataSources> registered_data_sources_{};
+
+    // A collection of disconnected service endpoints. Since trace writers on
+    // arbitrary threads might continue writing data to disconnected services,
+    // we keep the old services around and periodically try to clean up ones
+    // that no longer have any writers (see SweepDeadServices).
+    std::list<std::shared_ptr<ProducerEndpoint>> dead_services_;
+
+    // Triggers that should be sent when the service connects (trigger_name,
+    // expiration).
+    std::list<std::pair<std::string, base::TimeMillis>> on_connect_triggers_;
+
+    std::map<FlushRequestID, std::set<DataSourceInstanceID>> pending_flushes_;
+
+    // The currently active service endpoint is maintained as an atomic shared
+    // pointer so it won't get deleted from underneath threads that are creating
+    // trace writers. At any given time one endpoint can be shared (and thus
+    // kept alive) by the |service_| pointer, an entry in |dead_services_| and
+    // as a pointer on the stack in CreateTraceWriter() (on an arbitrary
+    // thread). The endpoint is never shared outside ProducerImpl itself.
+    //
+    // WARNING: Any *write* access to this variable or any *read* access from a
+    // non-muxer thread must be done through std::atomic_{load,store} to avoid
+    // data races.
+    std::shared_ptr<ProducerEndpoint> service_;  // Keep last.
+  };
+
+  // For each TracingSession created by the API client (Tracing::NewTrace() we
+  // create and register one ConsumerImpl instance.
+  // This talks to the consumer-side of the service, gets end-of-trace and
+  // on-trace-data callbacks and routes them to the API client callbacks.
+  // This class is needed to disambiguate callbacks coming from different
+  // tracing sessions.
+  class ConsumerImpl : public Consumer {
+   public:
+    ConsumerImpl(TracingMuxerImpl*, BackendType, TracingSessionGlobalID);
+    ~ConsumerImpl() override;
+
+    void Initialize(std::unique_ptr<ConsumerEndpoint> endpoint);
+
+    // perfetto::Consumer implementation.
+    void OnConnect() override;
+    void OnDisconnect() override;
+    void OnTracingDisabled(const std::string& error) override;
+    void OnTraceData(std::vector<TracePacket>, bool has_more) override;
+    void OnDetach(bool success) override;
+    void OnAttach(bool success, const TraceConfig&) override;
+    void OnTraceStats(bool success, const TraceStats&) override;
+    void OnObservableEvents(const ObservableEvents&) override;
+    void OnSessionCloned(const OnSessionClonedArgs&) override;
+
+    void NotifyStartComplete();
+    void NotifyError(const TracingError&);
+    void NotifyStopComplete();
+
+    // Will eventually inform the |muxer_| when it is safe to remove |this|.
+    void Disconnect();
+
+    TracingMuxerImpl* muxer_;
+    BackendType const backend_type_;
+    TracingSessionGlobalID const session_id_;
+    bool connected_ = false;
+
+    // This is to handle the case where the Setup call from the API client
+    // arrives before the consumer has connected. In this case we keep around
+    // the config and check if we have it after connection.
+    bool start_pending_ = false;
+
+    // Similarly if the session is stopped before the consumer was connected, we
+    // need to wait until the session has started before stopping it.
+    bool stop_pending_ = false;
+
+    // Similarly we need to buffer a call to get trace statistics if the
+    // consumer wasn't connected yet.
+    bool get_trace_stats_pending_ = false;
+
+    // Whether this session was already stopped. This will happen in response to
+    // Stop{,Blocking}, but also if the service stops the session for us
+    // automatically (e.g., when there are no data sources).
+    bool stopped_ = false;
+
+    // shared_ptr because it's posted across threads. This is to avoid copying
+    // it more than once.
+    std::shared_ptr<TraceConfig> trace_config_;
+    base::ScopedFile trace_fd_;
+
+    // If the API client passes a callback to start, we should invoke this when
+    // NotifyStartComplete() is invoked.
+    std::function<void()> start_complete_callback_;
+
+    // An internal callback used to implement StartBlocking().
+    std::function<void()> blocking_start_complete_callback_;
+
+    // If the API client passes a callback to get notification about the
+    // errors, we should invoke this when NotifyError() is invoked.
+    std::function<void(TracingError)> error_callback_;
+
+    // If the API client passes a callback to stop, we should invoke this when
+    // OnTracingDisabled() is invoked.
+    std::function<void()> stop_complete_callback_;
+
+    // An internal callback used to implement StopBlocking().
+    std::function<void()> blocking_stop_complete_callback_;
+
+    // Callback passed to ReadTrace().
+    std::function<void(TracingSession::ReadTraceCallbackArgs)>
+        read_trace_callback_;
+
+    // Callback passed to GetTraceStats().
+    TracingSession::GetTraceStatsCallback get_trace_stats_callback_;
+
+    // Callback for a pending call to QueryServiceState().
+    TracingSession::QueryServiceStateCallback query_service_state_callback_;
+
+    // The states of all data sources in this tracing session. |true| means the
+    // data source has started tracing.
+    using DataSourceHandle = std::pair<std::string, std::string>;
+    std::map<DataSourceHandle, bool> data_source_states_;
+
+    std::unique_ptr<ConsumerEndpoint> service_;  // Keep before last.
+    PERFETTO_THREAD_CHECKER(thread_checker_)     // Keep last.
+  };
+
+  // This object is returned to API clients when they call
+  // Tracing::CreateTracingSession().
+  class TracingSessionImpl : public TracingSession {
+   public:
+    TracingSessionImpl(TracingMuxerImpl*, TracingSessionGlobalID, BackendType);
+    ~TracingSessionImpl() override;
+    void Setup(const TraceConfig&, int fd) override;
+    void Start() override;
+    void StartBlocking() override;
+    void SetOnStartCallback(std::function<void()>) override;
+    void SetOnErrorCallback(std::function<void(TracingError)>) override;
+    void Stop() override;
+    void StopBlocking() override;
+    void Flush(std::function<void(bool)>, uint32_t timeout_ms) override;
+    void ReadTrace(ReadTraceCallback) override;
+    void SetOnStopCallback(std::function<void()>) override;
+    void GetTraceStats(GetTraceStatsCallback) override;
+    void QueryServiceState(QueryServiceStateCallback) override;
+    void ChangeTraceConfig(const TraceConfig&) override;
+
+   private:
+    TracingMuxerImpl* const muxer_;
+    TracingSessionGlobalID const session_id_;
+    BackendType const backend_type_;
+  };
+
+  // This object is returned to API clients when they call
+  // Tracing::SetupStartupTracing().
+  class StartupTracingSessionImpl : public StartupTracingSession {
+   public:
+    StartupTracingSessionImpl(TracingMuxerImpl*,
+                              TracingSessionGlobalID,
+                              BackendType);
+    ~StartupTracingSessionImpl() override;
+    void Abort() override;
+    void AbortBlocking() override;
+
+   private:
+    TracingMuxerImpl* const muxer_;
+    TracingSessionGlobalID const session_id_;
+    BackendType backend_type_;
+  };
+
+  struct RegisteredInterceptor {
+    protos::gen::InterceptorDescriptor descriptor;
+    InterceptorFactory factory{};
+    InterceptorBase::TLSFactory tls_factory{};
+    InterceptorBase::TracePacketCallback packet_callback{};
+  };
+
+  struct RegisteredStartupSession {
+    TracingSessionID session_id = 0;
+    int num_unbound_data_sources = 0;
+
+    bool is_aborting = false;
+    int num_aborting_data_sources = 0;
+
+    std::function<void()> on_aborted;
+    std::function<void()> on_adopted;
+  };
+
+  struct RegisteredProducerBackend {
+    // Backends are supposed to have static lifetime.
+    TracingProducerBackend* backend = nullptr;
+    TracingBackendId id = 0;
+    BackendType type{};
+
+    TracingBackend::ConnectProducerArgs producer_conn_args;
+    std::unique_ptr<ProducerImpl> producer;
+
+    std::vector<RegisteredStartupSession> startup_sessions;
+  };
+
+  struct RegisteredConsumerBackend {
+    // Backends are supposed to have static lifetime.
+    TracingConsumerBackend* backend = nullptr;
+    BackendType type{};
+    // The calling code can request more than one concurrently active tracing
+    // session for the same backend. We need to create one consumer per session.
+    std::vector<std::unique_ptr<ConsumerImpl>> consumers;
+  };
+
+  void UpdateDataSourceOnAllBackends(RegisteredDataSource& rds,
+                                     bool is_changed);
+  explicit TracingMuxerImpl(const TracingInitArgs&);
+  void Initialize(const TracingInitArgs& args);
+  void AddBackends(const TracingInitArgs& args);
+  void AddConsumerBackend(TracingConsumerBackend* backend, BackendType type);
+  void AddProducerBackend(TracingProducerBackend* backend,
+                          BackendType type,
+                          const TracingInitArgs& args);
+  ConsumerImpl* FindConsumer(TracingSessionGlobalID session_id);
+  std::pair<ConsumerImpl*, RegisteredConsumerBackend*> FindConsumerAndBackend(
+      TracingSessionGlobalID session_id);
+  RegisteredProducerBackend* FindProducerBackendById(TracingBackendId id);
+  RegisteredProducerBackend* FindProducerBackendByType(BackendType type);
+  RegisteredConsumerBackend* FindConsumerBackendByType(BackendType type);
+  void InitializeConsumer(TracingSessionGlobalID session_id);
+  void OnConsumerDisconnected(ConsumerImpl* consumer);
+  void OnProducerDisconnected(ProducerImpl* producer);
+  // Test only method.
+  void SweepDeadBackends();
+
+  struct FindDataSourceRes {
+    FindDataSourceRes() = default;
+    FindDataSourceRes(DataSourceStaticState* a,
+                      DataSourceState* b,
+                      uint32_t c,
+                      bool d)
+        : static_state(a),
+          internal_state(b),
+          instance_idx(c),
+          requires_callbacks_under_lock(d) {}
+    explicit operator bool() const { return !!internal_state; }
+
+    DataSourceStaticState* static_state = nullptr;
+    DataSourceState* internal_state = nullptr;
+    uint32_t instance_idx = 0;
+    bool requires_callbacks_under_lock = false;
+  };
+  FindDataSourceRes FindDataSource(TracingBackendId, DataSourceInstanceID);
+
+  FindDataSourceRes SetupDataSourceImpl(
+      const RegisteredDataSource&,
+      TracingBackendId,
+      uint32_t backend_connection_id,
+      DataSourceInstanceID,
+      const DataSourceConfig&,
+      TracingSessionGlobalID startup_session_id);
+  void StartDataSourceImpl(const FindDataSourceRes&);
+  void StopDataSource_AsyncBeginImpl(const FindDataSourceRes&);
+  void StopDataSource_AsyncEnd(TracingBackendId,
+                               uint32_t backend_connection_id,
+                               DataSourceInstanceID,
+                               const FindDataSourceRes&);
+  bool FlushDataSource_AsyncBegin(TracingBackendId,
+                                  DataSourceInstanceID,
+                                  FlushRequestID,
+                                  FlushFlags);
+  void FlushDataSource_AsyncEnd(TracingBackendId,
+                                uint32_t backend_connection_id,
+                                DataSourceInstanceID,
+                                const FindDataSourceRes&,
+                                FlushRequestID);
+  void AbortStartupTracingSession(TracingSessionGlobalID, BackendType);
+  // When ResetForTesting() is executed, `cb` will be called on the calling
+  // thread and on the muxer thread.
+  void AppendResetForTestingCallback(std::function<void()> cb);
+
+  // WARNING: If you add new state here, be sure to update ResetForTesting.
+  std::unique_ptr<base::TaskRunner> task_runner_;
+  std::vector<RegisteredDataSource> data_sources_;
+  // These lists can only have one backend per BackendType. The elements are
+  // sorted by BackendType priority (see BackendTypePriority). They always
+  // contain a fake low-priority kUnspecifiedBackend at the end.
+  std::list<RegisteredProducerBackend> producer_backends_;
+  std::list<RegisteredConsumerBackend> consumer_backends_;
+  std::vector<RegisteredInterceptor> interceptors_;
+  TracingPolicy* policy_ = nullptr;
+
+  // Learn more at TracingInitArgs::supports_multiple_data_source_instances
+  bool supports_multiple_data_source_instances_ = true;
+
+  std::atomic<TracingSessionGlobalID> next_tracing_session_id_{};
+  std::atomic<uint32_t> next_data_source_index_{};
+  uint32_t muxer_id_for_testing_{};
+
+  // Maximum number of times we will try to reconnect producer backend.
+  // Should only be modified for testing purposes.
+  std::atomic<uint32_t> max_producer_reconnections_{100u};
+
+  // Test only member.
+  // After ResetForTesting() is called, holds tracing backends which needs to be
+  // kept alive until all inbound references have gone away. See
+  // SweepDeadBackends().
+  std::list<RegisteredProducerBackend> dead_backends_;
+
+  // Test only member.
+  // Executes these cleanup functions on the calling thread and on the muxer
+  // thread when ResetForTesting() is called.
+  std::list<std::function<void()>> reset_callbacks_;
+
+  PERFETTO_THREAD_CHECKER(thread_checker_)
+};
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_INTERNAL_TRACING_MUXER_IMPL_H_
+// gen_amalgamated begin header: include/perfetto/ext/tracing/core/trace_stats.h
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_STATS_H_
+#define INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_STATS_H_
+
+// Creates the aliases in the ::perfetto namespace, doing things like:
+// using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
+// See comments in forward_decls.h for the historical reasons of this
+// indirection layer.
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/common/trace_stats.gen.h"
+
+#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_STATS_H_
+// gen_amalgamated begin header: include/perfetto/tracing/core/tracing_service_state.h
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_STATE_H_
+#define INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_STATE_H_
+
+// Creates the aliases in the ::perfetto namespace, doing things like:
+// using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
+// See comments in forward_decls.h for the historical reasons of this
+// indirection layer.
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_state.gen.h"
+
+#endif  // INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_STATE_H_
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/internal/tracing_muxer_impl.h"
+
+#include <algorithm>
+#include <atomic>
+#include <mutex>
+#include <optional>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/waitable_event.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_stats.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/buffer_exhausted_policy.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_config.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/tracing_service_state.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/data_source.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/data_source_internal.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/interceptor_trace_writer.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_backend_fake.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/tracing.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/tracing_backend.h"
+// gen_amalgamated expanded: #include "src/tracing/core/null_trace_writer.h"
+// gen_amalgamated expanded: #include "src/tracing/internal/tracing_muxer_fake.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <io.h>  // For dup()
+#else
+#include <unistd.h>  // For dup()
+#endif
+
+namespace perfetto {
+namespace internal {
+
+namespace {
+
+using RegisteredDataSource = TracingMuxerImpl::RegisteredDataSource;
+
+// A task runner which prevents calls to DataSource::Trace() while an operation
+// is in progress. Used to guard against unexpected re-entrancy where the
+// user-provided task runner implementation tries to enter a trace point under
+// the hood.
+class NonReentrantTaskRunner : public base::TaskRunner {
+ public:
+  NonReentrantTaskRunner(TracingMuxer* muxer,
+                         std::unique_ptr<base::TaskRunner> task_runner)
+      : muxer_(muxer), task_runner_(std::move(task_runner)) {}
+
+  // base::TaskRunner implementation.
+  void PostTask(std::function<void()> task) override {
+    CallWithGuard([&] { task_runner_->PostTask(std::move(task)); });
+  }
+
+  void PostDelayedTask(std::function<void()> task, uint32_t delay_ms) override {
+    CallWithGuard(
+        [&] { task_runner_->PostDelayedTask(std::move(task), delay_ms); });
+  }
+
+  void AddFileDescriptorWatch(base::PlatformHandle fd,
+                              std::function<void()> callback) override {
+    CallWithGuard(
+        [&] { task_runner_->AddFileDescriptorWatch(fd, std::move(callback)); });
+  }
+
+  void RemoveFileDescriptorWatch(base::PlatformHandle fd) override {
+    CallWithGuard([&] { task_runner_->RemoveFileDescriptorWatch(fd); });
+  }
+
+  bool RunsTasksOnCurrentThread() const override {
+    bool result;
+    CallWithGuard([&] { result = task_runner_->RunsTasksOnCurrentThread(); });
+    return result;
+  }
+
+ private:
+  template <typename T>
+  void CallWithGuard(T lambda) const {
+    auto* root_tls = muxer_->GetOrCreateTracingTLS();
+    if (PERFETTO_UNLIKELY(root_tls->is_in_trace_point)) {
+      lambda();
+      return;
+    }
+    ScopedReentrancyAnnotator scoped_annotator(*root_tls);
+    lambda();
+  }
+
+  TracingMuxer* const muxer_;
+  std::unique_ptr<base::TaskRunner> task_runner_;
+};
+
+class StopArgsImpl : public DataSourceBase::StopArgs {
+ public:
+  std::function<void()> HandleStopAsynchronously() const override {
+    auto closure = std::move(async_stop_closure);
+    async_stop_closure = std::function<void()>();
+    return closure;
+  }
+
+  mutable std::function<void()> async_stop_closure;
+};
+
+class FlushArgsImpl : public DataSourceBase::FlushArgs {
+ public:
+  std::function<void()> HandleFlushAsynchronously() const override {
+    auto closure = std::move(async_flush_closure);
+    async_flush_closure = std::function<void()>();
+    return closure;
+  }
+
+  mutable std::function<void()> async_flush_closure;
+};
+
+// Holds an earlier TracingMuxerImpl instance after ResetForTesting() is called.
+static TracingMuxerImpl* g_prev_instance{};
+
+template <typename RegisteredBackend>
+struct CompareBackendByType {
+  static int BackendTypePriority(BackendType type) {
+    switch (type) {
+      case kSystemBackend:
+        return 0;
+      case kInProcessBackend:
+        return 1;
+      case kCustomBackend:
+        return 2;
+      // The UnspecifiedBackend has the highest priority so that
+      // TracingBackendFake is the last one on the backend lists.
+      case kUnspecifiedBackend:
+        break;
+    }
+    return 3;
+  }
+  bool operator()(BackendType type, const RegisteredBackend& b) {
+    return BackendTypePriority(type) < BackendTypePriority(b.type);
+  }
+};
+
+}  // namespace
+
+// ----- Begin of TracingMuxerImpl::ProducerImpl
+TracingMuxerImpl::ProducerImpl::ProducerImpl(
+    TracingMuxerImpl* muxer,
+    TracingBackendId backend_id,
+    uint32_t shmem_batch_commits_duration_ms,
+    bool shmem_direct_patching_enabled)
+    : muxer_(muxer),
+      backend_id_(backend_id),
+      shmem_batch_commits_duration_ms_(shmem_batch_commits_duration_ms),
+      shmem_direct_patching_enabled_(shmem_direct_patching_enabled) {}
+
+TracingMuxerImpl::ProducerImpl::~ProducerImpl() {
+  muxer_ = nullptr;
+}
+
+void TracingMuxerImpl::ProducerImpl::Initialize(
+    std::unique_ptr<ProducerEndpoint> endpoint) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DCHECK(!connected_);
+  connection_id_.fetch_add(1, std::memory_order_relaxed);
+  is_producer_provided_smb_ = endpoint->shared_memory();
+  last_startup_target_buffer_reservation_ = 0;
+
+  // Adopt the endpoint into a shared pointer so that we can safely share it
+  // across threads that create trace writers. The custom deleter function
+  // ensures that the endpoint is always destroyed on the muxer's thread. (Note
+  // that |task_runner| is assumed to outlive tracing sessions on all threads.)
+  auto* task_runner = muxer_->task_runner_.get();
+  auto deleter = [task_runner](ProducerEndpoint* e) {
+    if (task_runner->RunsTasksOnCurrentThread()) {
+      delete e;
+      return;
+    }
+    task_runner->PostTask([e] { delete e; });
+  };
+  std::shared_ptr<ProducerEndpoint> service(endpoint.release(), deleter);
+  // This atomic store is needed because another thread might be concurrently
+  // creating a trace writer using the previous (disconnected) |service_|. See
+  // CreateTraceWriter().
+  std::atomic_store(&service_, std::move(service));
+  // Don't try to use the service here since it may not have connected yet. See
+  // OnConnect().
+}
+
+void TracingMuxerImpl::ProducerImpl::OnConnect() {
+  PERFETTO_DLOG("Producer connected");
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DCHECK(!connected_);
+  if (is_producer_provided_smb_ && !service_->IsShmemProvidedByProducer()) {
+    PERFETTO_ELOG(
+        "The service likely doesn't support producer-provided SMBs. Preventing "
+        "future attempts to use producer-provided SMB again with this "
+        "backend.");
+    producer_provided_smb_failed_ = true;
+    // Will call OnDisconnect() and cause a reconnect without producer-provided
+    // SMB.
+    service_->Disconnect();
+    return;
+  }
+  connected_ = true;
+  muxer_->UpdateDataSourcesOnAllBackends();
+  SendOnConnectTriggers();
+}
+
+void TracingMuxerImpl::ProducerImpl::OnDisconnect() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  // If we're being destroyed, bail out.
+  if (!muxer_)
+    return;
+  connected_ = false;
+  // Active data sources for this producer will be stopped by
+  // DestroyStoppedTraceWritersForCurrentThread() since the reconnected producer
+  // will have a different connection id (even before it has finished
+  // connecting).
+  registered_data_sources_.reset();
+  DisposeConnection();
+
+  // Try reconnecting the producer.
+  muxer_->OnProducerDisconnected(this);
+}
+
+void TracingMuxerImpl::ProducerImpl::DisposeConnection() {
+  // Keep the old service around as a dead connection in case it has active
+  // trace writers. If any tracing sessions were created, we can't clear
+  // |service_| here because other threads may be concurrently creating new
+  // trace writers. Any reconnection attempt will atomically swap the new
+  // service in place of the old one.
+  if (did_setup_tracing_ || did_setup_startup_tracing_) {
+    dead_services_.push_back(service_);
+  } else {
+    service_.reset();
+  }
+}
+
+void TracingMuxerImpl::ProducerImpl::OnTracingSetup() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  did_setup_tracing_ = true;
+  service_->MaybeSharedMemoryArbiter()->SetBatchCommitsDuration(
+      shmem_batch_commits_duration_ms_);
+  if (shmem_direct_patching_enabled_) {
+    service_->MaybeSharedMemoryArbiter()->EnableDirectSMBPatching();
+  }
+}
+
+void TracingMuxerImpl::ProducerImpl::OnStartupTracingSetup() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  did_setup_startup_tracing_ = true;
+}
+
+void TracingMuxerImpl::ProducerImpl::SetupDataSource(
+    DataSourceInstanceID id,
+    const DataSourceConfig& cfg) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!muxer_)
+    return;
+  muxer_->SetupDataSource(
+      backend_id_, connection_id_.load(std::memory_order_relaxed), id, cfg);
+}
+
+void TracingMuxerImpl::ProducerImpl::StartDataSource(DataSourceInstanceID id,
+                                                     const DataSourceConfig&) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!muxer_)
+    return;
+  muxer_->StartDataSource(backend_id_, id);
+  service_->NotifyDataSourceStarted(id);
+}
+
+void TracingMuxerImpl::ProducerImpl::StopDataSource(DataSourceInstanceID id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!muxer_)
+    return;
+  muxer_->StopDataSource_AsyncBegin(backend_id_, id);
+}
+
+void TracingMuxerImpl::ProducerImpl::Flush(
+    FlushRequestID flush_id,
+    const DataSourceInstanceID* instances,
+    size_t instance_count,
+    FlushFlags flush_flags) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  bool all_handled = true;
+  if (muxer_) {
+    for (size_t i = 0; i < instance_count; i++) {
+      DataSourceInstanceID ds_id = instances[i];
+      bool handled = muxer_->FlushDataSource_AsyncBegin(backend_id_, ds_id,
+                                                        flush_id, flush_flags);
+      if (!handled) {
+        pending_flushes_[flush_id].insert(ds_id);
+        all_handled = false;
+      }
+    }
+  }
+
+  if (all_handled) {
+    service_->NotifyFlushComplete(flush_id);
+  }
+}
+
+void TracingMuxerImpl::ProducerImpl::ClearIncrementalState(
+    const DataSourceInstanceID* instances,
+    size_t instance_count) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!muxer_)
+    return;
+  for (size_t inst_idx = 0; inst_idx < instance_count; inst_idx++) {
+    muxer_->ClearDataSourceIncrementalState(backend_id_, instances[inst_idx]);
+  }
+}
+
+bool TracingMuxerImpl::ProducerImpl::SweepDeadServices() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto is_unused = [](const std::shared_ptr<ProducerEndpoint>& endpoint) {
+    auto* arbiter = endpoint->MaybeSharedMemoryArbiter();
+    return !arbiter || arbiter->TryShutdown();
+  };
+  for (auto it = dead_services_.begin(); it != dead_services_.end();) {
+    auto next_it = it;
+    next_it++;
+    if (is_unused(*it)) {
+      dead_services_.erase(it);
+    }
+    it = next_it;
+  }
+  return dead_services_.empty();
+}
+
+void TracingMuxerImpl::ProducerImpl::SendOnConnectTriggers() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  base::TimeMillis now = base::GetWallTimeMs();
+  std::vector<std::string> triggers;
+  while (!on_connect_triggers_.empty()) {
+    // Skip if we passed TTL.
+    if (on_connect_triggers_.front().second > now) {
+      triggers.push_back(std::move(on_connect_triggers_.front().first));
+    }
+    on_connect_triggers_.pop_front();
+  }
+  if (!triggers.empty()) {
+    service_->ActivateTriggers(triggers);
+  }
+}
+
+void TracingMuxerImpl::ProducerImpl::NotifyFlushForDataSourceDone(
+    DataSourceInstanceID ds_id,
+    FlushRequestID flush_id) {
+  if (!connected_) {
+    return;
+  }
+
+  {
+    auto it = pending_flushes_.find(flush_id);
+    if (it == pending_flushes_.end()) {
+      return;
+    }
+    std::set<DataSourceInstanceID>& ds_ids = it->second;
+    ds_ids.erase(ds_id);
+  }
+
+  std::optional<DataSourceInstanceID> biggest_flush_id;
+  for (auto it = pending_flushes_.begin(); it != pending_flushes_.end();) {
+    if (it->second.empty()) {
+      biggest_flush_id = it->first;
+      it = pending_flushes_.erase(it);
+    } else {
+      break;
+    }
+  }
+
+  if (biggest_flush_id) {
+    service_->NotifyFlushComplete(*biggest_flush_id);
+  }
+}
+
+// ----- End of TracingMuxerImpl::ProducerImpl methods.
+
+// ----- Begin of TracingMuxerImpl::ConsumerImpl
+TracingMuxerImpl::ConsumerImpl::ConsumerImpl(TracingMuxerImpl* muxer,
+                                             BackendType backend_type,
+                                             TracingSessionGlobalID session_id)
+    : muxer_(muxer), backend_type_(backend_type), session_id_(session_id) {}
+
+TracingMuxerImpl::ConsumerImpl::~ConsumerImpl() {
+  muxer_ = nullptr;
+}
+
+void TracingMuxerImpl::ConsumerImpl::Initialize(
+    std::unique_ptr<ConsumerEndpoint> endpoint) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  service_ = std::move(endpoint);
+  // Don't try to use the service here since it may not have connected yet. See
+  // OnConnect().
+}
+
+void TracingMuxerImpl::ConsumerImpl::OnConnect() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DCHECK(!connected_);
+  connected_ = true;
+
+  // Observe data source instance events so we get notified when tracing starts.
+  service_->ObserveEvents(ObservableEvents::TYPE_DATA_SOURCES_INSTANCES |
+                          ObservableEvents::TYPE_ALL_DATA_SOURCES_STARTED);
+
+  // If the API client configured and started tracing before we connected,
+  // tell the backend about it now.
+  if (trace_config_)
+    muxer_->SetupTracingSession(session_id_, trace_config_);
+  if (start_pending_)
+    muxer_->StartTracingSession(session_id_);
+  if (get_trace_stats_pending_) {
+    auto callback = std::move(get_trace_stats_callback_);
+    get_trace_stats_callback_ = nullptr;
+    muxer_->GetTraceStats(session_id_, std::move(callback));
+  }
+  if (query_service_state_callback_) {
+    auto callback = std::move(query_service_state_callback_);
+    query_service_state_callback_ = nullptr;
+    muxer_->QueryServiceState(session_id_, std::move(callback));
+  }
+  if (stop_pending_)
+    muxer_->StopTracingSession(session_id_);
+}
+
+void TracingMuxerImpl::ConsumerImpl::OnDisconnect() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  // If we're being destroyed, bail out.
+  if (!muxer_)
+    return;
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  if (!connected_ && backend_type_ == kSystemBackend) {
+    PERFETTO_ELOG(
+        "Unable to connect to the system tracing service as a consumer. On "
+        "Android, use the \"perfetto\" command line tool instead to start "
+        "system-wide tracing sessions");
+  }
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+
+  // Notify the client about disconnection.
+  NotifyError(TracingError{TracingError::kDisconnected, "Peer disconnected"});
+
+  // Make sure the client doesn't hang in a blocking start/stop because of the
+  // disconnection.
+  NotifyStartComplete();
+  NotifyStopComplete();
+
+  // It shouldn't be necessary to call StopTracingSession. If we get this call
+  // it means that the service did shutdown before us, so there is no point
+  // trying it to ask it to stop the session. We should just remember to cleanup
+  // the consumer vector.
+  connected_ = false;
+
+  // Notify the muxer that it is safe to destroy |this|. This is needed because
+  // the ConsumerEndpoint stored in |service_| requires that |this| be safe to
+  // access until OnDisconnect() is called.
+  muxer_->OnConsumerDisconnected(this);
+}
+
+void TracingMuxerImpl::ConsumerImpl::Disconnect() {
+  // This is weird and deserves a comment.
+  //
+  // When we called the ConnectConsumer method on the service it returns
+  // us a ConsumerEndpoint which we stored in |service_|, however this
+  // ConsumerEndpoint holds a pointer to the ConsumerImpl pointed to by
+  // |this|. Part of the API contract to TracingService::ConnectConsumer is that
+  // the ConsumerImpl pointer has to be valid until the
+  // ConsumerImpl::OnDisconnect method is called. Therefore we reset the
+  // ConsumerEndpoint |service_|. Eventually this will call
+  // ConsumerImpl::OnDisconnect and we will inform the muxer it is safe to
+  // call the destructor of |this|.
+  service_.reset();
+}
+
+void TracingMuxerImpl::ConsumerImpl::OnTracingDisabled(
+    const std::string& error) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DCHECK(!stopped_);
+  stopped_ = true;
+
+  if (!error.empty())
+    NotifyError(TracingError{TracingError::kTracingFailed, error});
+
+  // If we're still waiting for the start event, fire it now. This may happen if
+  // there are no active data sources in the session.
+  NotifyStartComplete();
+  NotifyStopComplete();
+}
+
+void TracingMuxerImpl::ConsumerImpl::NotifyStartComplete() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (start_complete_callback_) {
+    muxer_->task_runner_->PostTask(std::move(start_complete_callback_));
+    start_complete_callback_ = nullptr;
+  }
+  if (blocking_start_complete_callback_) {
+    muxer_->task_runner_->PostTask(
+        std::move(blocking_start_complete_callback_));
+    blocking_start_complete_callback_ = nullptr;
+  }
+}
+
+void TracingMuxerImpl::ConsumerImpl::NotifyError(const TracingError& error) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (error_callback_) {
+    muxer_->task_runner_->PostTask(
+        std::bind(std::move(error_callback_), error));
+  }
+}
+
+void TracingMuxerImpl::ConsumerImpl::NotifyStopComplete() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (stop_complete_callback_) {
+    muxer_->task_runner_->PostTask(std::move(stop_complete_callback_));
+    stop_complete_callback_ = nullptr;
+  }
+  if (blocking_stop_complete_callback_) {
+    muxer_->task_runner_->PostTask(std::move(blocking_stop_complete_callback_));
+    blocking_stop_complete_callback_ = nullptr;
+  }
+}
+
+void TracingMuxerImpl::ConsumerImpl::OnTraceData(
+    std::vector<TracePacket> packets,
+    bool has_more) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!read_trace_callback_)
+    return;
+
+  size_t capacity = 0;
+  for (const auto& packet : packets) {
+    // 16 is an over-estimation of the proto preamble size
+    capacity += packet.size() + 16;
+  }
+
+  // The shared_ptr is to avoid making a copy of the buffer when PostTask-ing.
+  std::shared_ptr<std::vector<char>> buf(new std::vector<char>());
+  buf->reserve(capacity);
+  for (auto& packet : packets) {
+    char* start;
+    size_t size;
+    std::tie(start, size) = packet.GetProtoPreamble();
+    buf->insert(buf->end(), start, start + size);
+    for (auto& slice : packet.slices()) {
+      const auto* slice_data = reinterpret_cast<const char*>(slice.start);
+      buf->insert(buf->end(), slice_data, slice_data + slice.size);
+    }
+  }
+
+  auto callback = read_trace_callback_;
+  muxer_->task_runner_->PostTask([callback, buf, has_more] {
+    TracingSession::ReadTraceCallbackArgs callback_arg{};
+    callback_arg.data = buf->empty() ? nullptr : &(*buf)[0];
+    callback_arg.size = buf->size();
+    callback_arg.has_more = has_more;
+    callback(callback_arg);
+  });
+
+  if (!has_more)
+    read_trace_callback_ = nullptr;
+}
+
+void TracingMuxerImpl::ConsumerImpl::OnObservableEvents(
+    const ObservableEvents& events) {
+  if (events.instance_state_changes_size()) {
+    for (const auto& state_change : events.instance_state_changes()) {
+      DataSourceHandle handle{state_change.producer_name(),
+                              state_change.data_source_name()};
+      data_source_states_[handle] =
+          state_change.state() ==
+          ObservableEvents::DATA_SOURCE_INSTANCE_STATE_STARTED;
+    }
+  }
+
+  if (events.instance_state_changes_size() ||
+      events.all_data_sources_started()) {
+    // Data sources are first reported as being stopped before starting, so once
+    // all the data sources we know about have started we can declare tracing
+    // begun. In the case where there are no matching data sources for the
+    // session, the service will report the all_data_sources_started() event
+    // without adding any instances (only since Android S / Perfetto v10.0).
+    if (start_complete_callback_ || blocking_start_complete_callback_) {
+      bool all_data_sources_started = std::all_of(
+          data_source_states_.cbegin(), data_source_states_.cend(),
+          [](std::pair<DataSourceHandle, bool> state) { return state.second; });
+      if (all_data_sources_started)
+        NotifyStartComplete();
+    }
+  }
+}
+
+void TracingMuxerImpl::ConsumerImpl::OnSessionCloned(
+    const OnSessionClonedArgs&) {
+  // CloneSession is not exposed in the SDK. This should never happen.
+  PERFETTO_DCHECK(false);
+}
+
+void TracingMuxerImpl::ConsumerImpl::OnTraceStats(
+    bool success,
+    const TraceStats& trace_stats) {
+  if (!get_trace_stats_callback_)
+    return;
+  TracingSession::GetTraceStatsCallbackArgs callback_arg{};
+  callback_arg.success = success;
+  callback_arg.trace_stats_data = trace_stats.SerializeAsArray();
+  muxer_->task_runner_->PostTask(
+      std::bind(std::move(get_trace_stats_callback_), std::move(callback_arg)));
+  get_trace_stats_callback_ = nullptr;
+}
+
+// The callbacks below are not used.
+void TracingMuxerImpl::ConsumerImpl::OnDetach(bool) {}
+void TracingMuxerImpl::ConsumerImpl::OnAttach(bool, const TraceConfig&) {}
+// ----- End of TracingMuxerImpl::ConsumerImpl
+
+// ----- Begin of TracingMuxerImpl::TracingSessionImpl
+
+// TracingSessionImpl is the RAII object returned to API clients when they
+// invoke Tracing::CreateTracingSession. They use it for starting/stopping
+// tracing.
+
+TracingMuxerImpl::TracingSessionImpl::TracingSessionImpl(
+    TracingMuxerImpl* muxer,
+    TracingSessionGlobalID session_id,
+    BackendType backend_type)
+    : muxer_(muxer), session_id_(session_id), backend_type_(backend_type) {}
+
+// Can be destroyed from any thread.
+TracingMuxerImpl::TracingSessionImpl::~TracingSessionImpl() {
+  auto* muxer = muxer_;
+  auto session_id = session_id_;
+  muxer->task_runner_->PostTask(
+      [muxer, session_id] { muxer->DestroyTracingSession(session_id); });
+}
+
+// Can be called from any thread.
+void TracingMuxerImpl::TracingSessionImpl::Setup(const TraceConfig& cfg,
+                                                 int fd) {
+  auto* muxer = muxer_;
+  auto session_id = session_id_;
+  std::shared_ptr<TraceConfig> trace_config(new TraceConfig(cfg));
+  if (fd >= 0) {
+    base::ignore_result(backend_type_);  // For -Wunused in the amalgamation.
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    if (backend_type_ != kInProcessBackend) {
+      PERFETTO_FATAL(
+          "Passing a file descriptor to TracingSession::Setup() is only "
+          "supported with the kInProcessBackend on Windows. Use "
+          "TracingSession::ReadTrace() instead");
+    }
+#endif
+    trace_config->set_write_into_file(true);
+    fd = dup(fd);
+  }
+  muxer->task_runner_->PostTask([muxer, session_id, trace_config, fd] {
+    muxer->SetupTracingSession(session_id, trace_config, base::ScopedFile(fd));
+  });
+}
+
+// Can be called from any thread.
+void TracingMuxerImpl::TracingSessionImpl::Start() {
+  auto* muxer = muxer_;
+  auto session_id = session_id_;
+  muxer->task_runner_->PostTask(
+      [muxer, session_id] { muxer->StartTracingSession(session_id); });
+}
+
+// Can be called from any thread.
+void TracingMuxerImpl::TracingSessionImpl::ChangeTraceConfig(
+    const TraceConfig& cfg) {
+  auto* muxer = muxer_;
+  auto session_id = session_id_;
+  muxer->task_runner_->PostTask([muxer, session_id, cfg] {
+    muxer->ChangeTracingSessionConfig(session_id, cfg);
+  });
+}
+
+// Can be called from any thread except the service thread.
+void TracingMuxerImpl::TracingSessionImpl::StartBlocking() {
+  PERFETTO_DCHECK(!muxer_->task_runner_->RunsTasksOnCurrentThread());
+  auto* muxer = muxer_;
+  auto session_id = session_id_;
+  base::WaitableEvent tracing_started;
+  muxer->task_runner_->PostTask([muxer, session_id, &tracing_started] {
+    auto* consumer = muxer->FindConsumer(session_id);
+    if (!consumer) {
+      // TODO(skyostil): Signal an error to the user.
+      tracing_started.Notify();
+      return;
+    }
+    PERFETTO_DCHECK(!consumer->blocking_start_complete_callback_);
+    consumer->blocking_start_complete_callback_ = [&] {
+      tracing_started.Notify();
+    };
+    muxer->StartTracingSession(session_id);
+  });
+  tracing_started.Wait();
+}
+
+// Can be called from any thread.
+void TracingMuxerImpl::TracingSessionImpl::Flush(
+    std::function<void(bool)> user_callback,
+    uint32_t timeout_ms) {
+  auto* muxer = muxer_;
+  auto session_id = session_id_;
+  muxer->task_runner_->PostTask([muxer, session_id, timeout_ms, user_callback] {
+    auto* consumer = muxer->FindConsumer(session_id);
+    if (!consumer) {
+      std::move(user_callback)(false);
+      return;
+    }
+    muxer->FlushTracingSession(session_id, timeout_ms,
+                               std::move(user_callback));
+  });
+}
+
+// Can be called from any thread.
+void TracingMuxerImpl::TracingSessionImpl::Stop() {
+  auto* muxer = muxer_;
+  auto session_id = session_id_;
+  muxer->task_runner_->PostTask(
+      [muxer, session_id] { muxer->StopTracingSession(session_id); });
+}
+
+// Can be called from any thread except the service thread.
+void TracingMuxerImpl::TracingSessionImpl::StopBlocking() {
+  PERFETTO_DCHECK(!muxer_->task_runner_->RunsTasksOnCurrentThread());
+  auto* muxer = muxer_;
+  auto session_id = session_id_;
+  base::WaitableEvent tracing_stopped;
+  muxer->task_runner_->PostTask([muxer, session_id, &tracing_stopped] {
+    auto* consumer = muxer->FindConsumer(session_id);
+    if (!consumer) {
+      // TODO(skyostil): Signal an error to the user.
+      tracing_stopped.Notify();
+      return;
+    }
+    PERFETTO_DCHECK(!consumer->blocking_stop_complete_callback_);
+    consumer->blocking_stop_complete_callback_ = [&] {
+      tracing_stopped.Notify();
+    };
+    muxer->StopTracingSession(session_id);
+  });
+  tracing_stopped.Wait();
+}
+
+// Can be called from any thread.
+void TracingMuxerImpl::TracingSessionImpl::ReadTrace(ReadTraceCallback cb) {
+  auto* muxer = muxer_;
+  auto session_id = session_id_;
+  muxer->task_runner_->PostTask([muxer, session_id, cb] {
+    muxer->ReadTracingSessionData(session_id, std::move(cb));
+  });
+}
+
+// Can be called from any thread.
+void TracingMuxerImpl::TracingSessionImpl::SetOnStartCallback(
+    std::function<void()> cb) {
+  auto* muxer = muxer_;
+  auto session_id = session_id_;
+  muxer->task_runner_->PostTask([muxer, session_id, cb] {
+    auto* consumer = muxer->FindConsumer(session_id);
+    if (!consumer)
+      return;
+    consumer->start_complete_callback_ = cb;
+  });
+}
+
+// Can be called from any thread
+void TracingMuxerImpl::TracingSessionImpl::SetOnErrorCallback(
+    std::function<void(TracingError)> cb) {
+  auto* muxer = muxer_;
+  auto session_id = session_id_;
+  muxer->task_runner_->PostTask([muxer, session_id, cb] {
+    auto* consumer = muxer->FindConsumer(session_id);
+    if (!consumer) {
+      // Notify the client about concurrent disconnection of the session.
+      if (cb)
+        cb(TracingError{TracingError::kDisconnected, "Peer disconnected"});
+      return;
+    }
+    consumer->error_callback_ = cb;
+  });
+}
+
+// Can be called from any thread.
+void TracingMuxerImpl::TracingSessionImpl::SetOnStopCallback(
+    std::function<void()> cb) {
+  auto* muxer = muxer_;
+  auto session_id = session_id_;
+  muxer->task_runner_->PostTask([muxer, session_id, cb] {
+    auto* consumer = muxer->FindConsumer(session_id);
+    if (!consumer)
+      return;
+    consumer->stop_complete_callback_ = cb;
+  });
+}
+
+// Can be called from any thread.
+void TracingMuxerImpl::TracingSessionImpl::GetTraceStats(
+    GetTraceStatsCallback cb) {
+  auto* muxer = muxer_;
+  auto session_id = session_id_;
+  muxer->task_runner_->PostTask([muxer, session_id, cb] {
+    muxer->GetTraceStats(session_id, std::move(cb));
+  });
+}
+
+// Can be called from any thread.
+void TracingMuxerImpl::TracingSessionImpl::QueryServiceState(
+    QueryServiceStateCallback cb) {
+  auto* muxer = muxer_;
+  auto session_id = session_id_;
+  muxer->task_runner_->PostTask([muxer, session_id, cb] {
+    muxer->QueryServiceState(session_id, std::move(cb));
+  });
+}
+
+// ----- End of TracingMuxerImpl::TracingSessionImpl
+
+// ----- Begin of TracingMuxerImpl::StartupTracingSessionImpl
+
+TracingMuxerImpl::StartupTracingSessionImpl::StartupTracingSessionImpl(
+    TracingMuxerImpl* muxer,
+    TracingSessionGlobalID session_id,
+    BackendType backend_type)
+    : muxer_(muxer), session_id_(session_id), backend_type_(backend_type) {}
+
+// Can be destroyed from any thread.
+TracingMuxerImpl::StartupTracingSessionImpl::~StartupTracingSessionImpl() =
+    default;
+
+void TracingMuxerImpl::StartupTracingSessionImpl::Abort() {
+  auto* muxer = muxer_;
+  auto session_id = session_id_;
+  auto backend_type = backend_type_;
+  muxer->task_runner_->PostTask([muxer, session_id, backend_type] {
+    muxer->AbortStartupTracingSession(session_id, backend_type);
+  });
+}
+
+// Must not be called from the SDK's internal thread.
+void TracingMuxerImpl::StartupTracingSessionImpl::AbortBlocking() {
+  auto* muxer = muxer_;
+  auto session_id = session_id_;
+  auto backend_type = backend_type_;
+  PERFETTO_CHECK(!muxer->task_runner_->RunsTasksOnCurrentThread());
+  base::WaitableEvent event;
+  muxer->task_runner_->PostTask([muxer, session_id, backend_type, &event] {
+    muxer->AbortStartupTracingSession(session_id, backend_type);
+    event.Notify();
+  });
+  event.Wait();
+}
+
+// ----- End of TracingMuxerImpl::StartupTracingSessionImpl
+
+// static
+TracingMuxer* TracingMuxer::instance_ = TracingMuxerFake::Get();
+
+// This is called by perfetto::Tracing::Initialize().
+// Can be called on any thread. Typically, but not necessarily, that will be
+// the embedder's main thread.
+TracingMuxerImpl::TracingMuxerImpl(const TracingInitArgs& args)
+    : TracingMuxer(args.platform ? args.platform
+                                 : Platform::GetDefaultPlatform()) {
+  PERFETTO_DETACH_FROM_THREAD(thread_checker_);
+  instance_ = this;
+
+  // Create the thread where muxer, producers and service will live.
+  Platform::CreateTaskRunnerArgs tr_args{/*name_for_debugging=*/"TracingMuxer"};
+  task_runner_.reset(new NonReentrantTaskRunner(
+      this, platform_->CreateTaskRunner(std::move(tr_args))));
+
+  // Run the initializer on that thread.
+  task_runner_->PostTask([this, args] {
+    Initialize(args);
+    AddBackends(args);
+  });
+}
+
+void TracingMuxerImpl::Initialize(const TracingInitArgs& args) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);  // Rebind the thread checker.
+
+  policy_ = args.tracing_policy;
+  supports_multiple_data_source_instances_ =
+      args.supports_multiple_data_source_instances;
+
+  // Fallback backend for producer creation for an unsupported backend type.
+  PERFETTO_CHECK(producer_backends_.empty());
+  AddProducerBackend(internal::TracingBackendFake::GetInstance(),
+                     BackendType::kUnspecifiedBackend, args);
+  // Fallback backend for consumer creation for an unsupported backend type.
+  // This backend simply fails any attempt to start a tracing session.
+  PERFETTO_CHECK(consumer_backends_.empty());
+  AddConsumerBackend(internal::TracingBackendFake::GetInstance(),
+                     BackendType::kUnspecifiedBackend);
+}
+
+void TracingMuxerImpl::AddConsumerBackend(TracingConsumerBackend* backend,
+                                          BackendType type) {
+  if (!backend) {
+    // We skip the log in release builds because the *_backend_fake.cc code
+    // has already an ELOG before returning a nullptr.
+    PERFETTO_DLOG("Consumer backend creation failed, type %d",
+                  static_cast<int>(type));
+    return;
+  }
+  // Keep the backends sorted by type.
+  auto it =
+      std::upper_bound(consumer_backends_.begin(), consumer_backends_.end(),
+                       type, CompareBackendByType<RegisteredConsumerBackend>());
+  it = consumer_backends_.emplace(it);
+
+  RegisteredConsumerBackend& rb = *it;
+  rb.backend = backend;
+  rb.type = type;
+}
+
+void TracingMuxerImpl::AddProducerBackend(TracingProducerBackend* backend,
+                                          BackendType type,
+                                          const TracingInitArgs& args) {
+  if (!backend) {
+    // We skip the log in release builds because the *_backend_fake.cc code
+    // has already an ELOG before returning a nullptr.
+    PERFETTO_DLOG("Producer backend creation failed, type %d",
+                  static_cast<int>(type));
+    return;
+  }
+  TracingBackendId backend_id = producer_backends_.size();
+  // Keep the backends sorted by type.
+  auto it =
+      std::upper_bound(producer_backends_.begin(), producer_backends_.end(),
+                       type, CompareBackendByType<RegisteredProducerBackend>());
+  it = producer_backends_.emplace(it);
+
+  RegisteredProducerBackend& rb = *it;
+  rb.backend = backend;
+  rb.id = backend_id;
+  rb.type = type;
+  rb.producer.reset(new ProducerImpl(this, backend_id,
+                                     args.shmem_batch_commits_duration_ms,
+                                     args.shmem_direct_patching_enabled));
+  rb.producer_conn_args.producer = rb.producer.get();
+  rb.producer_conn_args.producer_name = platform_->GetCurrentProcessName();
+  rb.producer_conn_args.task_runner = task_runner_.get();
+  rb.producer_conn_args.shmem_size_hint_bytes = args.shmem_size_hint_kb * 1024;
+  rb.producer_conn_args.shmem_page_size_hint_bytes =
+      args.shmem_page_size_hint_kb * 1024;
+  rb.producer_conn_args.create_socket_async = args.create_socket_async;
+  rb.producer->Initialize(rb.backend->ConnectProducer(rb.producer_conn_args));
+}
+
+TracingMuxerImpl::RegisteredProducerBackend*
+TracingMuxerImpl::FindProducerBackendById(TracingBackendId id) {
+  for (RegisteredProducerBackend& b : producer_backends_) {
+    if (b.id == id) {
+      return &b;
+    }
+  }
+  return nullptr;
+}
+
+TracingMuxerImpl::RegisteredProducerBackend*
+TracingMuxerImpl::FindProducerBackendByType(BackendType type) {
+  for (RegisteredProducerBackend& b : producer_backends_) {
+    if (b.type == type) {
+      return &b;
+    }
+  }
+  return nullptr;
+}
+
+TracingMuxerImpl::RegisteredConsumerBackend*
+TracingMuxerImpl::FindConsumerBackendByType(BackendType type) {
+  for (RegisteredConsumerBackend& b : consumer_backends_) {
+    if (b.type == type) {
+      return &b;
+    }
+  }
+  return nullptr;
+}
+
+void TracingMuxerImpl::AddBackends(const TracingInitArgs& args) {
+  if (args.backends & kSystemBackend) {
+    PERFETTO_CHECK(args.system_producer_backend_factory_);
+    if (FindProducerBackendByType(kSystemBackend) == nullptr) {
+      AddProducerBackend(args.system_producer_backend_factory_(),
+                         kSystemBackend, args);
+    }
+    if (args.enable_system_consumer) {
+      PERFETTO_CHECK(args.system_consumer_backend_factory_);
+      if (FindConsumerBackendByType(kSystemBackend) == nullptr) {
+        AddConsumerBackend(args.system_consumer_backend_factory_(),
+                           kSystemBackend);
+      }
+    }
+  }
+
+  if (args.backends & kInProcessBackend) {
+    TracingBackend* b = nullptr;
+    if (FindProducerBackendByType(kInProcessBackend) == nullptr) {
+      if (!b) {
+        PERFETTO_CHECK(args.in_process_backend_factory_);
+        b = args.in_process_backend_factory_();
+      }
+      AddProducerBackend(b, kInProcessBackend, args);
+    }
+    if (FindConsumerBackendByType(kInProcessBackend) == nullptr) {
+      if (!b) {
+        PERFETTO_CHECK(args.in_process_backend_factory_);
+        b = args.in_process_backend_factory_();
+      }
+      AddConsumerBackend(b, kInProcessBackend);
+    }
+  }
+
+  if (args.backends & kCustomBackend) {
+    PERFETTO_CHECK(args.custom_backend);
+    if (FindProducerBackendByType(kCustomBackend) == nullptr) {
+      AddProducerBackend(args.custom_backend, kCustomBackend, args);
+    }
+    if (FindConsumerBackendByType(kCustomBackend) == nullptr) {
+      AddConsumerBackend(args.custom_backend, kCustomBackend);
+    }
+  }
+
+  if (args.backends & ~(kSystemBackend | kInProcessBackend | kCustomBackend)) {
+    PERFETTO_FATAL("Unsupported tracing backend type");
+  }
+}
+
+// Can be called from any thread (but not concurrently).
+bool TracingMuxerImpl::RegisterDataSource(
+    const DataSourceDescriptor& descriptor,
+    DataSourceFactory factory,
+    DataSourceParams params,
+    bool no_flush,
+    DataSourceStaticState* static_state) {
+  // Ignore repeated registrations.
+  if (static_state->index != kMaxDataSources)
+    return true;
+
+  uint32_t new_index = next_data_source_index_++;
+  if (new_index >= kMaxDataSources) {
+    PERFETTO_DLOG(
+        "RegisterDataSource failed: too many data sources already registered");
+    return false;
+  }
+
+  // Initialize the static state.
+  static_assert(sizeof(static_state->instances[0]) >= sizeof(DataSourceState),
+                "instances[] size mismatch");
+  for (size_t i = 0; i < static_state->instances.size(); i++)
+    new (&static_state->instances[i]) DataSourceState{};
+
+  static_state->index = new_index;
+
+  // Generate a semi-unique id for this data source.
+  base::Hasher hash;
+  hash.Update(reinterpret_cast<intptr_t>(static_state));
+  hash.Update(base::GetWallTimeNs().count());
+  static_state->id = hash.digest() ? hash.digest() : 1;
+
+  task_runner_->PostTask([this, descriptor, factory, static_state, params,
+                          no_flush] {
+    data_sources_.emplace_back();
+    RegisteredDataSource& rds = data_sources_.back();
+    rds.descriptor = descriptor;
+    rds.factory = factory;
+    rds.supports_multiple_instances =
+        supports_multiple_data_source_instances_ &&
+        params.supports_multiple_instances;
+    rds.requires_callbacks_under_lock = params.requires_callbacks_under_lock;
+    rds.static_state = static_state;
+    rds.no_flush = no_flush;
+
+    UpdateDataSourceOnAllBackends(rds, /*is_changed=*/false);
+  });
+  return true;
+}
+
+// Can be called from any thread (but not concurrently).
+void TracingMuxerImpl::UpdateDataSourceDescriptor(
+    const DataSourceDescriptor& descriptor,
+    const DataSourceStaticState* static_state) {
+  task_runner_->PostTask([this, descriptor, static_state] {
+    for (auto& rds : data_sources_) {
+      if (rds.static_state == static_state) {
+        PERFETTO_CHECK(rds.descriptor.name() == descriptor.name());
+        rds.descriptor = descriptor;
+        rds.descriptor.set_id(static_state->id);
+        UpdateDataSourceOnAllBackends(rds, /*is_changed=*/true);
+        return;
+      }
+    }
+  });
+}
+
+// Can be called from any thread (but not concurrently).
+void TracingMuxerImpl::RegisterInterceptor(
+    const InterceptorDescriptor& descriptor,
+    InterceptorFactory factory,
+    InterceptorBase::TLSFactory tls_factory,
+    InterceptorBase::TracePacketCallback packet_callback) {
+  task_runner_->PostTask([this, descriptor, factory, tls_factory,
+                          packet_callback] {
+    // Ignore repeated registrations.
+    for (const auto& interceptor : interceptors_) {
+      if (interceptor.descriptor.name() == descriptor.name()) {
+        PERFETTO_DCHECK(interceptor.tls_factory == tls_factory);
+        PERFETTO_DCHECK(interceptor.packet_callback == packet_callback);
+        return;
+      }
+    }
+    // Only allow certain interceptors for now.
+    if (descriptor.name() != "test_interceptor" &&
+        descriptor.name() != "console" && descriptor.name() != "etwexport") {
+      PERFETTO_ELOG(
+          "Interceptors are experimental. If you want to use them, please "
+          "get in touch with the project maintainers "
+          "(https://perfetto.dev/docs/contributing/"
+          "getting-started#community).");
+      return;
+    }
+    interceptors_.emplace_back();
+    RegisteredInterceptor& interceptor = interceptors_.back();
+    interceptor.descriptor = descriptor;
+    interceptor.factory = factory;
+    interceptor.tls_factory = tls_factory;
+    interceptor.packet_callback = packet_callback;
+  });
+}
+
+void TracingMuxerImpl::ActivateTriggers(
+    const std::vector<std::string>& triggers,
+    uint32_t ttl_ms) {
+  base::TimeMillis expire_time =
+      base::GetWallTimeMs() + base::TimeMillis(ttl_ms);
+  task_runner_->PostTask([this, triggers, expire_time] {
+    for (RegisteredProducerBackend& backend : producer_backends_) {
+      if (backend.producer->connected_) {
+        backend.producer->service_->ActivateTriggers(triggers);
+      } else {
+        for (const std::string& trigger : triggers) {
+          backend.producer->on_connect_triggers_.emplace_back(trigger,
+                                                              expire_time);
+        }
+      }
+    }
+  });
+}
+
+// Checks if there is any matching startup tracing data source instance for a
+// new SetupDataSource call. If so, moves the data source to this tracing
+// session (and its target buffer) and returns true, otherwise returns false.
+static bool MaybeAdoptStartupTracingInDataSource(
+    TracingBackendId backend_id,
+    uint32_t backend_connection_id,
+    DataSourceInstanceID instance_id,
+    const DataSourceConfig& cfg,
+    const std::vector<RegisteredDataSource>& data_sources) {
+  for (const auto& rds : data_sources) {
+    DataSourceStaticState* static_state = rds.static_state;
+    for (uint32_t i = 0; i < kMaxDataSourceInstances; i++) {
+      auto* internal_state = static_state->TryGet(i);
+
+      if (internal_state &&
+          internal_state->startup_target_buffer_reservation.load(
+              std::memory_order_relaxed) &&
+          internal_state->data_source_instance_id == 0 &&
+          internal_state->backend_id == backend_id &&
+          internal_state->backend_connection_id == backend_connection_id &&
+          internal_state->config &&
+          internal_state->data_source->CanAdoptStartupSession(
+              *internal_state->config, cfg)) {
+        PERFETTO_DLOG("Setting up data source %" PRIu64
+                      " %s by adopting it from a startup tracing session",
+                      instance_id, cfg.name().c_str());
+
+        std::lock_guard<std::recursive_mutex> lock(internal_state->lock);
+        // Set the associations. The actual takeover happens in
+        // StartDataSource().
+        internal_state->data_source_instance_id = instance_id;
+        internal_state->buffer_id =
+            static_cast<internal::BufferId>(cfg.target_buffer());
+        internal_state->config.reset(new DataSourceConfig(cfg));
+
+        // TODO(eseckler): Should the data souce config provided by the service
+        // be allowed to specify additional interceptors / additional data
+        // source params?
+
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+// Called by the service of one of the backends.
+void TracingMuxerImpl::SetupDataSource(TracingBackendId backend_id,
+                                       uint32_t backend_connection_id,
+                                       DataSourceInstanceID instance_id,
+                                       const DataSourceConfig& cfg) {
+  PERFETTO_DLOG("Setting up data source %" PRIu64 " %s", instance_id,
+                cfg.name().c_str());
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  // First check if there is any matching startup tracing data source instance.
+  if (MaybeAdoptStartupTracingInDataSource(backend_id, backend_connection_id,
+                                           instance_id, cfg, data_sources_)) {
+    return;
+  }
+
+  for (const auto& rds : data_sources_) {
+    if (rds.descriptor.name() != cfg.name())
+      continue;
+    DataSourceStaticState& static_state = *rds.static_state;
+
+    // If this data source is already active for this exact config, don't start
+    // another instance. This happens when we have several data sources with the
+    // same name, in which case the service sends one SetupDataSource event for
+    // each one. Since we can't map which event maps to which data source, we
+    // ensure each event only starts one data source instance.
+    // TODO(skyostil): Register a unique id with each data source to the service
+    // to disambiguate.
+    bool active_for_config = false;
+    for (uint32_t i = 0; i < kMaxDataSourceInstances; i++) {
+      if (!static_state.TryGet(i))
+        continue;
+      auto* internal_state =
+          reinterpret_cast<DataSourceState*>(&static_state.instances[i]);
+      if (internal_state->backend_id == backend_id &&
+          internal_state->backend_connection_id == backend_connection_id &&
+          internal_state->config && *internal_state->config == cfg) {
+        active_for_config = true;
+        break;
+      }
+    }
+    if (active_for_config) {
+      PERFETTO_DLOG(
+          "Data source %s is already active with this config, skipping",
+          cfg.name().c_str());
+      continue;
+    }
+
+    SetupDataSourceImpl(rds, backend_id, backend_connection_id, instance_id,
+                        cfg, /*startup_session_id=*/0);
+    return;
+  }
+}
+
+TracingMuxerImpl::FindDataSourceRes TracingMuxerImpl::SetupDataSourceImpl(
+    const RegisteredDataSource& rds,
+    TracingBackendId backend_id,
+    uint32_t backend_connection_id,
+    DataSourceInstanceID instance_id,
+    const DataSourceConfig& cfg,
+    TracingSessionGlobalID startup_session_id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  DataSourceStaticState& static_state = *rds.static_state;
+
+  // If any bit is set in `static_state.valid_instances` then at least one
+  // other instance of data source is running.
+  if (!rds.supports_multiple_instances &&
+      static_state.valid_instances.load(std::memory_order_acquire) != 0) {
+    PERFETTO_ELOG(
+        "Failed to setup data source because some another instance of this "
+        "data source is already active");
+    return FindDataSourceRes();
+  }
+
+  for (uint32_t i = 0; i < kMaxDataSourceInstances; i++) {
+    // Find a free slot.
+    if (static_state.TryGet(i))
+      continue;
+
+    auto* internal_state =
+        reinterpret_cast<DataSourceState*>(&static_state.instances[i]);
+    std::unique_lock<std::recursive_mutex> lock(internal_state->lock);
+    static_assert(
+        std::is_same<decltype(internal_state->data_source_instance_id),
+                     DataSourceInstanceID>::value,
+        "data_source_instance_id type mismatch");
+    internal_state->muxer_id_for_testing = muxer_id_for_testing_;
+    RegisteredProducerBackend& backend = *FindProducerBackendById(backend_id);
+
+    if (startup_session_id) {
+      uint16_t& last_reservation =
+          backend.producer->last_startup_target_buffer_reservation_;
+      if (last_reservation == std::numeric_limits<uint16_t>::max()) {
+        PERFETTO_ELOG(
+            "Startup buffer reservations exhausted, dropping data source");
+        return FindDataSourceRes();
+      }
+      internal_state->startup_target_buffer_reservation.store(
+          ++last_reservation, std::memory_order_relaxed);
+    } else {
+      internal_state->startup_target_buffer_reservation.store(
+          0, std::memory_order_relaxed);
+    }
+
+    internal_state->backend_id = backend_id;
+    internal_state->backend_connection_id = backend_connection_id;
+    internal_state->data_source_instance_id = instance_id;
+    internal_state->buffer_id =
+        static_cast<internal::BufferId>(cfg.target_buffer());
+    internal_state->config.reset(new DataSourceConfig(cfg));
+    internal_state->startup_session_id = startup_session_id;
+    internal_state->data_source = rds.factory();
+    internal_state->interceptor = nullptr;
+    internal_state->interceptor_id = 0;
+
+    if (cfg.has_interceptor_config()) {
+      for (size_t j = 0; j < interceptors_.size(); j++) {
+        if (cfg.interceptor_config().name() ==
+            interceptors_[j].descriptor.name()) {
+          PERFETTO_DLOG("Intercepting data source %" PRIu64
+                        " \"%s\" into \"%s\"",
+                        instance_id, cfg.name().c_str(),
+                        cfg.interceptor_config().name().c_str());
+          internal_state->interceptor_id = static_cast<uint32_t>(j + 1);
+          internal_state->interceptor = interceptors_[j].factory();
+          internal_state->interceptor->OnSetup({cfg});
+          break;
+        }
+      }
+      if (!internal_state->interceptor_id) {
+        PERFETTO_ELOG("Unknown interceptor configured for data source: %s",
+                      cfg.interceptor_config().name().c_str());
+      }
+    }
+
+    // This must be made at the end. See matching acquire-load in
+    // DataSource::Trace().
+    static_state.valid_instances.fetch_or(1 << i, std::memory_order_release);
+
+    DataSourceBase::SetupArgs setup_args;
+    setup_args.config = &cfg;
+    setup_args.backend_type = backend.type;
+    setup_args.internal_instance_index = i;
+
+    if (!rds.requires_callbacks_under_lock)
+      lock.unlock();
+    internal_state->data_source->OnSetup(setup_args);
+
+    return FindDataSourceRes(&static_state, internal_state, i,
+                             rds.requires_callbacks_under_lock);
+  }
+  PERFETTO_ELOG(
+      "Maximum number of data source instances exhausted. "
+      "Dropping data source %" PRIu64,
+      instance_id);
+  return FindDataSourceRes();
+}
+
+// Called by the service of one of the backends.
+void TracingMuxerImpl::StartDataSource(TracingBackendId backend_id,
+                                       DataSourceInstanceID instance_id) {
+  PERFETTO_DLOG("Starting data source %" PRIu64, instance_id);
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  auto ds = FindDataSource(backend_id, instance_id);
+  if (!ds) {
+    PERFETTO_ELOG("Could not find data source to start");
+    return;
+  }
+
+  // Check if the data source was already started for startup tracing.
+  uint16_t startup_reservation =
+      ds.internal_state->startup_target_buffer_reservation.load(
+          std::memory_order_relaxed);
+  if (startup_reservation) {
+    RegisteredProducerBackend& backend = *FindProducerBackendById(backend_id);
+    TracingSessionGlobalID session_id = ds.internal_state->startup_session_id;
+    auto session_it = std::find_if(
+        backend.startup_sessions.begin(), backend.startup_sessions.end(),
+        [session_id](const RegisteredStartupSession& session) {
+          return session.session_id == session_id;
+        });
+    PERFETTO_DCHECK(session_it != backend.startup_sessions.end());
+
+    if (session_it->is_aborting) {
+      PERFETTO_DLOG("Data source %" PRIu64
+                    " was already aborted for startup tracing, not starting it",
+                    instance_id);
+      return;
+    }
+
+    PERFETTO_DLOG(
+        "Data source %" PRIu64
+        " was already started for startup tracing, binding its target buffer",
+        instance_id);
+
+    backend.producer->service_->MaybeSharedMemoryArbiter()
+        ->BindStartupTargetBuffer(startup_reservation,
+                                  ds.internal_state->buffer_id);
+
+    // The reservation ID can be used even after binding it, so there's no need
+    // for any barriers here - we just need atomicity.
+    ds.internal_state->startup_target_buffer_reservation.store(
+        0, std::memory_order_relaxed);
+
+    // TODO(eseckler): Should we reset incremental state at this point, or
+    // notify the data source some other way?
+
+    // The session should not have been fully bound yet (or aborted).
+    PERFETTO_DCHECK(session_it->num_unbound_data_sources > 0);
+
+    session_it->num_unbound_data_sources--;
+    if (session_it->num_unbound_data_sources == 0) {
+      if (session_it->on_adopted)
+        task_runner_->PostTask(session_it->on_adopted);
+      backend.startup_sessions.erase(session_it);
+    }
+    return;
+  }
+
+  StartDataSourceImpl(ds);
+}
+
+void TracingMuxerImpl::StartDataSourceImpl(const FindDataSourceRes& ds) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  DataSourceBase::StartArgs start_args{};
+  start_args.internal_instance_index = ds.instance_idx;
+
+  std::unique_lock<std::recursive_mutex> lock(ds.internal_state->lock);
+  if (ds.internal_state->interceptor)
+    ds.internal_state->interceptor->OnStart({});
+  ds.internal_state->trace_lambda_enabled.store(true,
+                                                std::memory_order_relaxed);
+  PERFETTO_DCHECK(ds.internal_state->data_source != nullptr);
+
+  if (!ds.requires_callbacks_under_lock)
+    lock.unlock();
+  ds.internal_state->data_source->OnStart(start_args);
+}
+
+// Called by the service of one of the backends.
+void TracingMuxerImpl::StopDataSource_AsyncBegin(
+    TracingBackendId backend_id,
+    DataSourceInstanceID instance_id) {
+  PERFETTO_DLOG("Stopping data source %" PRIu64, instance_id);
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  auto ds = FindDataSource(backend_id, instance_id);
+  if (!ds) {
+    PERFETTO_ELOG("Could not find data source to stop");
+    return;
+  }
+
+  StopDataSource_AsyncBeginImpl(ds);
+}
+
+void TracingMuxerImpl::StopDataSource_AsyncBeginImpl(
+    const FindDataSourceRes& ds) {
+  TracingBackendId backend_id = ds.internal_state->backend_id;
+  uint32_t backend_connection_id = ds.internal_state->backend_connection_id;
+  DataSourceInstanceID instance_id = ds.internal_state->data_source_instance_id;
+
+  StopArgsImpl stop_args{};
+  stop_args.internal_instance_index = ds.instance_idx;
+  stop_args.async_stop_closure = [this, backend_id, backend_connection_id,
+                                  instance_id, ds] {
+    // TracingMuxerImpl is long lived, capturing |this| is okay.
+    // The notification closure can be moved out of the StopArgs by the
+    // embedder to handle stop asynchronously. The embedder might then
+    // call the closure on a different thread than the current one, hence
+    // this nested PostTask().
+    task_runner_->PostTask(
+        [this, backend_id, backend_connection_id, instance_id, ds] {
+          StopDataSource_AsyncEnd(backend_id, backend_connection_id,
+                                  instance_id, ds);
+        });
+  };
+
+  {
+    std::unique_lock<std::recursive_mutex> lock(ds.internal_state->lock);
+
+    // Don't call OnStop again if the datasource is already stopping.
+    if (ds.internal_state->async_stop_in_progress)
+      return;
+    ds.internal_state->async_stop_in_progress = true;
+
+    if (ds.internal_state->interceptor)
+      ds.internal_state->interceptor->OnStop({});
+
+    if (!ds.requires_callbacks_under_lock)
+      lock.unlock();
+    ds.internal_state->data_source->OnStop(stop_args);
+  }
+
+  // If the embedder hasn't called StopArgs.HandleStopAsynchronously() run the
+  // async closure here. In theory we could avoid the PostTask and call
+  // straight into CompleteDataSourceAsyncStop(). We keep that to reduce
+  // divergencies between the deferred-stop vs non-deferred-stop code paths.
+  if (stop_args.async_stop_closure)
+    std::move(stop_args.async_stop_closure)();
+}
+
+void TracingMuxerImpl::StopDataSource_AsyncEnd(TracingBackendId backend_id,
+                                               uint32_t backend_connection_id,
+                                               DataSourceInstanceID instance_id,
+                                               const FindDataSourceRes& ds) {
+  PERFETTO_DLOG("Ending async stop of data source %" PRIu64, instance_id);
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  // Check that the data source instance is still active and was not modified
+  // while it was being stopped.
+  if (!ds.static_state->TryGet(ds.instance_idx) ||
+      ds.internal_state->backend_id != backend_id ||
+      ds.internal_state->backend_connection_id != backend_connection_id ||
+      ds.internal_state->data_source_instance_id != instance_id) {
+    PERFETTO_ELOG(
+        "Async stop of data source %" PRIu64
+        " failed. This might be due to calling the async_stop_closure twice.",
+        instance_id);
+    return;
+  }
+
+  const uint32_t mask = ~(1 << ds.instance_idx);
+  ds.static_state->valid_instances.fetch_and(mask, std::memory_order_acq_rel);
+
+  // Take the mutex to prevent that the data source is in the middle of
+  // a Trace() execution where it called GetDataSourceLocked() while we
+  // destroy it.
+  uint16_t startup_buffer_reservation;
+  TracingSessionGlobalID startup_session_id;
+  {
+    std::lock_guard<std::recursive_mutex> guard(ds.internal_state->lock);
+    ds.internal_state->trace_lambda_enabled.store(false,
+                                                  std::memory_order_relaxed);
+    ds.internal_state->data_source.reset();
+    ds.internal_state->interceptor.reset();
+    ds.internal_state->config.reset();
+    ds.internal_state->async_stop_in_progress = false;
+    startup_buffer_reservation =
+        ds.internal_state->startup_target_buffer_reservation.load(
+            std::memory_order_relaxed);
+    startup_session_id = ds.internal_state->startup_session_id;
+  }
+
+  // The other fields of internal_state are deliberately *not* cleared.
+  // See races-related comments of DataSource::Trace().
+
+  TracingMuxer::generation_++;
+
+  // |producer_backends_| is append-only, Backend instances are always valid.
+  PERFETTO_CHECK(backend_id < producer_backends_.size());
+  RegisteredProducerBackend& backend = *FindProducerBackendById(backend_id);
+  ProducerImpl* producer = backend.producer.get();
+  if (!producer)
+    return;
+
+  // If the data source instance still has a startup buffer reservation, it was
+  // only active for startup tracing and never started by the service. Discard
+  // the startup buffer reservation.
+  if (startup_buffer_reservation) {
+    PERFETTO_DCHECK(startup_session_id);
+
+    if (producer->service_ && producer->service_->MaybeSharedMemoryArbiter()) {
+      producer->service_->MaybeSharedMemoryArbiter()
+          ->AbortStartupTracingForReservation(startup_buffer_reservation);
+    }
+
+    auto session_it = std::find_if(
+        backend.startup_sessions.begin(), backend.startup_sessions.end(),
+        [startup_session_id](const RegisteredStartupSession& session) {
+          return session.session_id == startup_session_id;
+        });
+
+    // Session should not be removed until abortion of all data source instances
+    // is complete.
+    PERFETTO_DCHECK(session_it != backend.startup_sessions.end());
+
+    session_it->num_aborting_data_sources--;
+    if (session_it->num_aborting_data_sources == 0) {
+      if (session_it->on_aborted)
+        task_runner_->PostTask(session_it->on_aborted);
+
+      backend.startup_sessions.erase(session_it);
+    }
+  }
+
+  if (producer->connected_ &&
+      backend.producer->connection_id_.load(std::memory_order_relaxed) ==
+          backend_connection_id) {
+    // Flush any commits that might have been batched by SharedMemoryArbiter.
+    producer->service_->MaybeSharedMemoryArbiter()
+        ->FlushPendingCommitDataRequests();
+    if (instance_id)
+      producer->service_->NotifyDataSourceStopped(instance_id);
+  }
+  producer->SweepDeadServices();
+}
+
+void TracingMuxerImpl::ClearDataSourceIncrementalState(
+    TracingBackendId backend_id,
+    DataSourceInstanceID instance_id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DLOG("Clearing incremental state for data source %" PRIu64,
+                instance_id);
+  auto ds = FindDataSource(backend_id, instance_id);
+  if (!ds) {
+    PERFETTO_ELOG("Could not find data source to clear incremental state for");
+    return;
+  }
+
+  DataSourceBase::ClearIncrementalStateArgs clear_incremental_state_args;
+  clear_incremental_state_args.internal_instance_index = ds.instance_idx;
+  {
+    std::unique_lock<std::recursive_mutex> lock;
+    if (ds.requires_callbacks_under_lock)
+      lock = std::unique_lock<std::recursive_mutex>(ds.internal_state->lock);
+    ds.internal_state->data_source->WillClearIncrementalState(
+        clear_incremental_state_args);
+  }
+
+  // Make DataSource::TraceContext::GetIncrementalState() eventually notice that
+  // the incremental state should be cleared.
+  ds.static_state->incremental_state_generation.fetch_add(
+      1, std::memory_order_relaxed);
+}
+
+bool TracingMuxerImpl::FlushDataSource_AsyncBegin(
+    TracingBackendId backend_id,
+    DataSourceInstanceID instance_id,
+    FlushRequestID flush_id,
+    FlushFlags flush_flags) {
+  PERFETTO_DLOG("Flushing data source %" PRIu64, instance_id);
+  auto ds = FindDataSource(backend_id, instance_id);
+  if (!ds) {
+    PERFETTO_ELOG("Could not find data source to flush");
+    return true;
+  }
+
+  uint32_t backend_connection_id = ds.internal_state->backend_connection_id;
+
+  FlushArgsImpl flush_args;
+  flush_args.flush_flags = flush_flags;
+  flush_args.internal_instance_index = ds.instance_idx;
+  flush_args.async_flush_closure = [this, backend_id, backend_connection_id,
+                                    instance_id, ds, flush_id] {
+    // TracingMuxerImpl is long lived, capturing |this| is okay.
+    // The notification closure can be moved out of the StopArgs by the
+    // embedder to handle stop asynchronously. The embedder might then
+    // call the closure on a different thread than the current one, hence
+    // this nested PostTask().
+    task_runner_->PostTask(
+        [this, backend_id, backend_connection_id, instance_id, ds, flush_id] {
+          FlushDataSource_AsyncEnd(backend_id, backend_connection_id,
+                                   instance_id, ds, flush_id);
+        });
+  };
+  {
+    std::unique_lock<std::recursive_mutex> lock;
+    if (ds.requires_callbacks_under_lock)
+      lock = std::unique_lock<std::recursive_mutex>(ds.internal_state->lock);
+    ds.internal_state->data_source->OnFlush(flush_args);
+  }
+
+  // |async_flush_closure| is moved out of |flush_args| if the producer
+  // requested to handle the flush asynchronously.
+  bool handled = static_cast<bool>(flush_args.async_flush_closure);
+  return handled;
+}
+
+void TracingMuxerImpl::FlushDataSource_AsyncEnd(
+    TracingBackendId backend_id,
+    uint32_t backend_connection_id,
+    DataSourceInstanceID instance_id,
+    const FindDataSourceRes& ds,
+    FlushRequestID flush_id) {
+  PERFETTO_DLOG("Ending async flush of data source %" PRIu64, instance_id);
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  // Check that the data source instance is still active and was not modified
+  // while it was being flushed.
+  if (!ds.static_state->TryGet(ds.instance_idx) ||
+      ds.internal_state->backend_id != backend_id ||
+      ds.internal_state->backend_connection_id != backend_connection_id ||
+      ds.internal_state->data_source_instance_id != instance_id) {
+    PERFETTO_ELOG("Async flush of data source %" PRIu64
+                  " failed. This might be due to the data source being stopped "
+                  "in the meantime",
+                  instance_id);
+    return;
+  }
+
+  // |producer_backends_| is append-only, Backend instances are always valid.
+  PERFETTO_CHECK(backend_id < producer_backends_.size());
+  RegisteredProducerBackend& backend = *FindProducerBackendById(backend_id);
+
+  ProducerImpl* producer = backend.producer.get();
+  if (!producer)
+    return;
+
+  // If the tracing service disconnects and reconnects while a data source is
+  // handling a flush request, there's no point is sending the flush reply to
+  // the newly reconnected producer.
+  if (producer->connected_ &&
+      backend.producer->connection_id_.load(std::memory_order_relaxed) ==
+          backend_connection_id) {
+    producer->NotifyFlushForDataSourceDone(instance_id, flush_id);
+  }
+}
+
+void TracingMuxerImpl::SyncProducersForTesting() {
+  std::mutex mutex;
+  std::condition_variable cv;
+
+  // IPC-based producers don't report connection errors explicitly for each
+  // command, but instead with an asynchronous callback
+  // (ProducerImpl::OnDisconnected). This means that the sync command below
+  // may have completed but failed to reach the service because of a
+  // disconnection, but we can't tell until the disconnection message comes
+  // through. To guard against this, we run two whole rounds of sync round-trips
+  // before returning; the first one will detect any disconnected producers and
+  // the second one will ensure any reconnections have completed and all data
+  // sources are registered in the service again.
+  for (size_t i = 0; i < 2; i++) {
+    size_t countdown = std::numeric_limits<size_t>::max();
+    task_runner_->PostTask([this, &mutex, &cv, &countdown] {
+      {
+        std::unique_lock<std::mutex> countdown_lock(mutex);
+        countdown = producer_backends_.size();
+      }
+      for (auto& backend : producer_backends_) {
+        auto* producer = backend.producer.get();
+        producer->service_->Sync([&mutex, &cv, &countdown] {
+          std::unique_lock<std::mutex> countdown_lock(mutex);
+          countdown--;
+          cv.notify_one();
+        });
+      }
+    });
+
+    {
+      std::unique_lock<std::mutex> countdown_lock(mutex);
+      cv.wait(countdown_lock, [&countdown] { return !countdown; });
+    }
+  }
+
+  // Check that all producers are indeed connected.
+  bool done = false;
+  bool all_producers_connected = true;
+  task_runner_->PostTask([this, &mutex, &cv, &done, &all_producers_connected] {
+    for (auto& backend : producer_backends_)
+      all_producers_connected &= backend.producer->connected_;
+    std::unique_lock<std::mutex> lock(mutex);
+    done = true;
+    cv.notify_one();
+  });
+
+  {
+    std::unique_lock<std::mutex> lock(mutex);
+    cv.wait(lock, [&done] { return done; });
+  }
+  PERFETTO_DCHECK(all_producers_connected);
+}
+
+void TracingMuxerImpl::DestroyStoppedTraceWritersForCurrentThread() {
+  // Iterate across all possible data source types.
+  auto cur_generation = generation_.load(std::memory_order_acquire);
+  auto* root_tls = GetOrCreateTracingTLS();
+
+  auto destroy_stopped_instances = [](DataSourceThreadLocalState& tls) {
+    // |tls| has a vector of per-data-source-instance thread-local state.
+    DataSourceStaticState* static_state = tls.static_state;
+    if (!static_state)
+      return;  // Slot not used.
+
+    // Iterate across all possible instances for this data source.
+    for (uint32_t inst = 0; inst < kMaxDataSourceInstances; inst++) {
+      DataSourceInstanceThreadLocalState& ds_tls = tls.per_instance[inst];
+      if (!ds_tls.trace_writer)
+        continue;
+
+      DataSourceState* ds_state = static_state->TryGet(inst);
+      if (ds_state &&
+          ds_state->muxer_id_for_testing == ds_tls.muxer_id_for_testing &&
+          ds_state->backend_id == ds_tls.backend_id &&
+          ds_state->backend_connection_id == ds_tls.backend_connection_id &&
+          ds_state->startup_target_buffer_reservation.load(
+              std::memory_order_relaxed) ==
+              ds_tls.startup_target_buffer_reservation &&
+          ds_state->buffer_id == ds_tls.buffer_id &&
+          ds_state->data_source_instance_id == ds_tls.data_source_instance_id) {
+        continue;
+      }
+
+      // The DataSource instance has been destroyed or recycled.
+      ds_tls.Reset();  // Will also destroy the |ds_tls.trace_writer|.
+    }
+  };
+
+  for (size_t ds_idx = 0; ds_idx < kMaxDataSources; ds_idx++) {
+    // |tls| has a vector of per-data-source-instance thread-local state.
+    DataSourceThreadLocalState& tls = root_tls->data_sources_tls[ds_idx];
+    destroy_stopped_instances(tls);
+  }
+  destroy_stopped_instances(root_tls->track_event_tls);
+  root_tls->generation = cur_generation;
+}
+
+// Called both when a new data source is registered or when a new backend
+// connects. In both cases we want to be sure we reflected the data source
+// registrations on the backends.
+void TracingMuxerImpl::UpdateDataSourcesOnAllBackends() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  for (RegisteredDataSource& rds : data_sources_) {
+    UpdateDataSourceOnAllBackends(rds, /*is_changed=*/false);
+  }
+}
+
+void TracingMuxerImpl::UpdateDataSourceOnAllBackends(RegisteredDataSource& rds,
+                                                     bool is_changed) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  for (RegisteredProducerBackend& backend : producer_backends_) {
+    // We cannot call RegisterDataSource on the backend before it connects.
+    if (!backend.producer->connected_)
+      continue;
+
+    PERFETTO_DCHECK(rds.static_state->index < kMaxDataSources);
+    bool is_registered = backend.producer->registered_data_sources_.test(
+        rds.static_state->index);
+    if (is_registered && !is_changed)
+      continue;
+
+    if (!rds.descriptor.no_flush()) {
+      rds.descriptor.set_no_flush(rds.no_flush);
+    }
+    rds.descriptor.set_will_notify_on_start(true);
+    rds.descriptor.set_will_notify_on_stop(true);
+    rds.descriptor.set_handles_incremental_state_clear(true);
+    rds.descriptor.set_id(rds.static_state->id);
+    if (is_registered) {
+      backend.producer->service_->UpdateDataSource(rds.descriptor);
+    } else {
+      backend.producer->service_->RegisterDataSource(rds.descriptor);
+    }
+    backend.producer->registered_data_sources_.set(rds.static_state->index);
+  }
+}
+
+void TracingMuxerImpl::SetupTracingSession(
+    TracingSessionGlobalID session_id,
+    const std::shared_ptr<TraceConfig>& trace_config,
+    base::ScopedFile trace_fd) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_CHECK(!trace_fd || trace_config->write_into_file());
+
+  auto* consumer = FindConsumer(session_id);
+  if (!consumer)
+    return;
+
+  consumer->trace_config_ = trace_config;
+  if (trace_fd)
+    consumer->trace_fd_ = std::move(trace_fd);
+
+  if (!consumer->connected_)
+    return;
+
+  // Only used in the deferred start mode.
+  if (trace_config->deferred_start()) {
+    consumer->service_->EnableTracing(*trace_config,
+                                      std::move(consumer->trace_fd_));
+  }
+}
+
+void TracingMuxerImpl::StartTracingSession(TracingSessionGlobalID session_id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  auto* consumer = FindConsumer(session_id);
+
+  if (!consumer)
+    return;
+
+  if (!consumer->trace_config_) {
+    PERFETTO_ELOG("Must call Setup(config) first");
+    return;
+  }
+
+  if (!consumer->connected_) {
+    consumer->start_pending_ = true;
+    return;
+  }
+
+  consumer->start_pending_ = false;
+  if (consumer->trace_config_->deferred_start()) {
+    consumer->service_->StartTracing();
+  } else {
+    consumer->service_->EnableTracing(*consumer->trace_config_,
+                                      std::move(consumer->trace_fd_));
+  }
+
+  // TODO implement support for the deferred-start + fast-triggering case.
+}
+
+void TracingMuxerImpl::ChangeTracingSessionConfig(
+    TracingSessionGlobalID session_id,
+    const TraceConfig& trace_config) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  auto* consumer = FindConsumer(session_id);
+
+  if (!consumer)
+    return;
+
+  if (!consumer->trace_config_) {
+    // Changing the config is only supported for started sessions.
+    PERFETTO_ELOG("Must call Setup(config) and Start() first");
+    return;
+  }
+
+  consumer->trace_config_ = std::make_shared<TraceConfig>(trace_config);
+  if (consumer->connected_)
+    consumer->service_->ChangeTraceConfig(trace_config);
+}
+
+void TracingMuxerImpl::FlushTracingSession(TracingSessionGlobalID session_id,
+                                           uint32_t timeout_ms,
+                                           std::function<void(bool)> callback) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto* consumer = FindConsumer(session_id);
+  if (!consumer || consumer->start_pending_ || consumer->stop_pending_ ||
+      !consumer->trace_config_) {
+    PERFETTO_ELOG("Flush() can be called only after Start() and before Stop()");
+    std::move(callback)(false);
+    return;
+  }
+
+  // For now we don't want to expose the flush reason to the consumer-side SDK
+  // users to avoid misuses until there is a strong need.
+  consumer->service_->Flush(timeout_ms, std::move(callback),
+                            FlushFlags(FlushFlags::Initiator::kConsumerSdk,
+                                       FlushFlags::Reason::kExplicit));
+}
+
+void TracingMuxerImpl::StopTracingSession(TracingSessionGlobalID session_id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto* consumer = FindConsumer(session_id);
+  if (!consumer)
+    return;
+
+  if (consumer->start_pending_) {
+    // If the session hasn't started yet, wait until it does before stopping.
+    consumer->stop_pending_ = true;
+    return;
+  }
+
+  consumer->stop_pending_ = false;
+  if (consumer->stopped_) {
+    // If the session was already stopped (e.g., it failed to start), don't try
+    // stopping again.
+    consumer->NotifyStopComplete();
+  } else if (!consumer->trace_config_) {
+    PERFETTO_ELOG("Must call Setup(config) and Start() first");
+    return;
+  } else {
+    consumer->service_->DisableTracing();
+  }
+
+  consumer->trace_config_.reset();
+}
+
+void TracingMuxerImpl::DestroyTracingSession(
+    TracingSessionGlobalID session_id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  for (RegisteredConsumerBackend& backend : consumer_backends_) {
+    // We need to find the consumer (if any) and call Disconnect as we destroy
+    // the tracing session. We can't call Disconnect() inside this for loop
+    // because in the in-process case this will end up to a synchronous call to
+    // OnConsumerDisconnect which will invalidate all the iterators to
+    // |backend.consumers|.
+    ConsumerImpl* consumer = nullptr;
+    for (auto& con : backend.consumers) {
+      if (con->session_id_ == session_id) {
+        consumer = con.get();
+        break;
+      }
+    }
+    if (consumer) {
+      // We broke out of the loop above on the assumption that each backend will
+      // only have a single consumer per session. This DCHECK ensures that
+      // this is the case.
+      PERFETTO_DCHECK(
+          std::count_if(backend.consumers.begin(), backend.consumers.end(),
+                        [session_id](const std::unique_ptr<ConsumerImpl>& con) {
+                          return con->session_id_ == session_id;
+                        }) == 1u);
+      consumer->Disconnect();
+    }
+  }
+}
+
+void TracingMuxerImpl::ReadTracingSessionData(
+    TracingSessionGlobalID session_id,
+    std::function<void(TracingSession::ReadTraceCallbackArgs)> callback) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto* consumer = FindConsumer(session_id);
+  if (!consumer) {
+    // TODO(skyostil): Signal an error to the user.
+    TracingSession::ReadTraceCallbackArgs callback_arg{};
+    callback(callback_arg);
+    return;
+  }
+  PERFETTO_DCHECK(!consumer->read_trace_callback_);
+  consumer->read_trace_callback_ = std::move(callback);
+  consumer->service_->ReadBuffers();
+}
+
+void TracingMuxerImpl::GetTraceStats(
+    TracingSessionGlobalID session_id,
+    TracingSession::GetTraceStatsCallback callback) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto* consumer = FindConsumer(session_id);
+  if (!consumer) {
+    TracingSession::GetTraceStatsCallbackArgs callback_arg{};
+    callback_arg.success = false;
+    callback(std::move(callback_arg));
+    return;
+  }
+  PERFETTO_DCHECK(!consumer->get_trace_stats_callback_);
+  consumer->get_trace_stats_callback_ = std::move(callback);
+  if (!consumer->connected_) {
+    consumer->get_trace_stats_pending_ = true;
+    return;
+  }
+  consumer->get_trace_stats_pending_ = false;
+  consumer->service_->GetTraceStats();
+}
+
+void TracingMuxerImpl::QueryServiceState(
+    TracingSessionGlobalID session_id,
+    TracingSession::QueryServiceStateCallback callback) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto* consumer = FindConsumer(session_id);
+  if (!consumer) {
+    TracingSession::QueryServiceStateCallbackArgs callback_arg{};
+    callback_arg.success = false;
+    callback(std::move(callback_arg));
+    return;
+  }
+  PERFETTO_DCHECK(!consumer->query_service_state_callback_);
+  if (!consumer->connected_) {
+    consumer->query_service_state_callback_ = std::move(callback);
+    return;
+  }
+  auto callback_wrapper = [callback](bool success,
+                                     protos::gen::TracingServiceState state) {
+    TracingSession::QueryServiceStateCallbackArgs callback_arg{};
+    callback_arg.success = success;
+    callback_arg.service_state_data = state.SerializeAsArray();
+    callback(std::move(callback_arg));
+  };
+  consumer->service_->QueryServiceState({}, std::move(callback_wrapper));
+}
+
+void TracingMuxerImpl::SetBatchCommitsDurationForTesting(
+    uint32_t batch_commits_duration_ms,
+    BackendType backend_type) {
+  for (RegisteredProducerBackend& backend : producer_backends_) {
+    if (backend.producer && backend.producer->connected_ &&
+        backend.type == backend_type) {
+      backend.producer->service_->MaybeSharedMemoryArbiter()
+          ->SetBatchCommitsDuration(batch_commits_duration_ms);
+    }
+  }
+}
+
+bool TracingMuxerImpl::EnableDirectSMBPatchingForTesting(
+    BackendType backend_type) {
+  for (RegisteredProducerBackend& backend : producer_backends_) {
+    if (backend.producer && backend.producer->connected_ &&
+        backend.type == backend_type &&
+        !backend.producer->service_->MaybeSharedMemoryArbiter()
+             ->EnableDirectSMBPatching()) {
+      return false;
+    }
+  }
+  return true;
+}
+
+TracingMuxerImpl::ConsumerImpl* TracingMuxerImpl::FindConsumer(
+    TracingSessionGlobalID session_id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  return FindConsumerAndBackend(session_id).first;
+}
+
+std::pair<TracingMuxerImpl::ConsumerImpl*,
+          TracingMuxerImpl::RegisteredConsumerBackend*>
+TracingMuxerImpl::FindConsumerAndBackend(TracingSessionGlobalID session_id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  for (RegisteredConsumerBackend& backend : consumer_backends_) {
+    for (auto& consumer : backend.consumers) {
+      if (consumer->session_id_ == session_id) {
+        return {consumer.get(), &backend};
+      }
+    }
+  }
+  return {nullptr, nullptr};
+}
+
+void TracingMuxerImpl::InitializeConsumer(TracingSessionGlobalID session_id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  auto res = FindConsumerAndBackend(session_id);
+  if (!res.first || !res.second)
+    return;
+  TracingMuxerImpl::ConsumerImpl* consumer = res.first;
+  RegisteredConsumerBackend& backend = *res.second;
+
+  TracingBackend::ConnectConsumerArgs conn_args;
+  conn_args.consumer = consumer;
+  conn_args.task_runner = task_runner_.get();
+  consumer->Initialize(backend.backend->ConnectConsumer(conn_args));
+}
+
+void TracingMuxerImpl::OnConsumerDisconnected(ConsumerImpl* consumer) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  for (RegisteredConsumerBackend& backend : consumer_backends_) {
+    auto pred = [consumer](const std::unique_ptr<ConsumerImpl>& con) {
+      return con.get() == consumer;
+    };
+    backend.consumers.erase(std::remove_if(backend.consumers.begin(),
+                                           backend.consumers.end(), pred),
+                            backend.consumers.end());
+  }
+}
+
+void TracingMuxerImpl::SetMaxProducerReconnectionsForTesting(uint32_t count) {
+  max_producer_reconnections_.store(count);
+}
+
+void TracingMuxerImpl::OnProducerDisconnected(ProducerImpl* producer) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  for (RegisteredProducerBackend& backend : producer_backends_) {
+    if (backend.producer.get() != producer)
+      continue;
+
+    // The tracing service is disconnected. It does not make sense to keep
+    // tracing (we wouldn't be able to commit). On reconnection, the tracing
+    // service will restart the data sources.
+    for (const auto& rds : data_sources_) {
+      DataSourceStaticState* static_state = rds.static_state;
+      for (uint32_t i = 0; i < kMaxDataSourceInstances; i++) {
+        auto* internal_state = static_state->TryGet(i);
+        if (internal_state && internal_state->backend_id == backend.id &&
+            internal_state->backend_connection_id ==
+                backend.producer->connection_id_.load(
+                    std::memory_order_relaxed)) {
+          StopDataSource_AsyncBeginImpl(
+              FindDataSourceRes(static_state, internal_state, i,
+                                rds.requires_callbacks_under_lock));
+        }
+      }
+    }
+
+    // Try reconnecting the disconnected producer. If the connection succeeds,
+    // all the data sources will be automatically re-registered.
+    if (producer->connection_id_.load(std::memory_order_relaxed) >
+        max_producer_reconnections_.load()) {
+      // Avoid reconnecting a failing producer too many times. Instead we just
+      // leak the producer instead of trying to avoid further complicating
+      // cross-thread trace writer creation.
+      PERFETTO_ELOG("Producer disconnected too many times; not reconnecting");
+      continue;
+    }
+
+    backend.producer->Initialize(
+        backend.backend->ConnectProducer(backend.producer_conn_args));
+    // Don't use producer-provided SMBs for the next connection unless startup
+    // tracing requires it again.
+    backend.producer_conn_args.use_producer_provided_smb = false;
+  }
+}
+
+void TracingMuxerImpl::SweepDeadBackends() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  for (auto it = dead_backends_.begin(); it != dead_backends_.end();) {
+    auto next_it = it;
+    next_it++;
+    if (it->producer->SweepDeadServices())
+      dead_backends_.erase(it);
+    it = next_it;
+  }
+}
+
+TracingMuxerImpl::FindDataSourceRes TracingMuxerImpl::FindDataSource(
+    TracingBackendId backend_id,
+    DataSourceInstanceID instance_id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  RegisteredProducerBackend& backend = *FindProducerBackendById(backend_id);
+  for (const auto& rds : data_sources_) {
+    DataSourceStaticState* static_state = rds.static_state;
+    for (uint32_t i = 0; i < kMaxDataSourceInstances; i++) {
+      auto* internal_state = static_state->TryGet(i);
+      if (internal_state && internal_state->backend_id == backend_id &&
+          internal_state->backend_connection_id ==
+              backend.producer->connection_id_.load(
+                  std::memory_order_relaxed) &&
+          internal_state->data_source_instance_id == instance_id) {
+        return FindDataSourceRes(static_state, internal_state, i,
+                                 rds.requires_callbacks_under_lock);
+      }
+    }
+  }
+  return FindDataSourceRes();
+}
+
+// Can be called from any thread.
+std::unique_ptr<TraceWriterBase> TracingMuxerImpl::CreateTraceWriter(
+    DataSourceStaticState* static_state,
+    uint32_t data_source_instance_index,
+    DataSourceState* data_source,
+    BufferExhaustedPolicy buffer_exhausted_policy) {
+  if (PERFETTO_UNLIKELY(data_source->interceptor_id)) {
+    // If the session is being intercepted, return a heap-backed trace writer
+    // instead. This is safe because all the data given to the interceptor is
+    // either thread-local (|instance_index|), statically allocated
+    // (|static_state|) or constant after initialization (|interceptor|). Access
+    // to the interceptor instance itself through |data_source| is protected by
+    // a statically allocated lock (similarly to the data source instance).
+    auto& interceptor = interceptors_[data_source->interceptor_id - 1];
+    return std::unique_ptr<TraceWriterBase>(new InterceptorTraceWriter(
+        interceptor.tls_factory(static_state, data_source_instance_index),
+        interceptor.packet_callback, static_state, data_source_instance_index));
+  }
+  ProducerImpl* producer =
+      FindProducerBackendById(data_source->backend_id)->producer.get();
+  // Atomically load the current service endpoint. We keep the pointer as a
+  // shared pointer on the stack to guard against it from being concurrently
+  // modified on the thread by ProducerImpl::Initialize() swapping in a
+  // reconnected service on the muxer task runner thread.
+  //
+  // The endpoint may also be concurrently modified by SweepDeadServices()
+  // clearing out old disconnected services. We guard against that by
+  // SharedMemoryArbiter keeping track of any outstanding trace writers. After
+  // shutdown has started, the trace writer created below will be a null one
+  // which will drop any written data. See SharedMemoryArbiter::TryShutdown().
+  //
+  // We use an atomic pointer instead of holding a lock because
+  // CreateTraceWriter posts tasks under the hood.
+  std::shared_ptr<ProducerEndpoint> service =
+      std::atomic_load(&producer->service_);
+
+  // The service may have been disconnected and reconnected concurrently after
+  // the data source was enabled, in which case we may not have an arbiter, or
+  // would be creating a TraceWriter for the wrong (a newer) connection / SMB.
+  // Instead, early-out now. A relaxed load is fine here because the atomic_load
+  // above ensures that the |service| isn't newer.
+  if (producer->connection_id_.load(std::memory_order_relaxed) !=
+      data_source->backend_connection_id) {
+    return std::unique_ptr<TraceWriter>(new NullTraceWriter());
+  }
+
+  // We just need a relaxed atomic read here: We can use the reservation ID even
+  // after the buffer was bound, we just need to be sure to read it atomically.
+  uint16_t startup_buffer_reservation =
+      data_source->startup_target_buffer_reservation.load(
+          std::memory_order_relaxed);
+  if (startup_buffer_reservation) {
+    return service->MaybeSharedMemoryArbiter()->CreateStartupTraceWriter(
+        startup_buffer_reservation);
+  }
+  return service->CreateTraceWriter(data_source->buffer_id,
+                                    buffer_exhausted_policy);
+}
+
+// This is called via the public API Tracing::NewTrace().
+// Can be called from any thread.
+std::unique_ptr<TracingSession> TracingMuxerImpl::CreateTracingSession(
+    BackendType requested_backend_type,
+    TracingConsumerBackend* (*system_backend_factory)()) {
+  TracingSessionGlobalID session_id = ++next_tracing_session_id_;
+
+  // |backend_type| can only specify one backend, not an OR-ed mask.
+  PERFETTO_CHECK((requested_backend_type & (requested_backend_type - 1)) == 0);
+
+  // Capturing |this| is fine because the TracingMuxer is a leaky singleton.
+  task_runner_->PostTask([this, requested_backend_type, session_id,
+                          system_backend_factory] {
+    if (requested_backend_type == kSystemBackend && system_backend_factory &&
+        !FindConsumerBackendByType(kSystemBackend)) {
+      AddConsumerBackend(system_backend_factory(), kSystemBackend);
+    }
+    for (RegisteredConsumerBackend& backend : consumer_backends_) {
+      if (requested_backend_type && backend.type &&
+          backend.type != requested_backend_type) {
+        continue;
+      }
+
+      // Create the consumer now, even if we have to ask the embedder below, so
+      // that any other tasks executing after this one can find the consumer and
+      // change its pending attributes.
+      backend.consumers.emplace_back(
+          new ConsumerImpl(this, backend.type, session_id));
+
+      // The last registered backend in |consumer_backends_| is the unsupported
+      // backend without a valid type.
+      if (!backend.type) {
+        PERFETTO_ELOG(
+            "No tracing backend ready for type=%d, consumer will disconnect",
+            requested_backend_type);
+        InitializeConsumer(session_id);
+        return;
+      }
+
+      // Check if the embedder wants to be asked for permission before
+      // connecting the consumer.
+      if (!policy_) {
+        InitializeConsumer(session_id);
+        return;
+      }
+
+      BackendType type = backend.type;
+      TracingPolicy::ShouldAllowConsumerSessionArgs args;
+      args.backend_type = backend.type;
+      args.result_callback = [this, type, session_id](bool allow) {
+        task_runner_->PostTask([this, type, session_id, allow] {
+          if (allow) {
+            InitializeConsumer(session_id);
+            return;
+          }
+
+          PERFETTO_ELOG(
+              "Consumer session for backend type type=%d forbidden, "
+              "consumer will disconnect",
+              type);
+
+          auto* consumer = FindConsumer(session_id);
+          if (!consumer)
+            return;
+
+          consumer->OnDisconnect();
+        });
+      };
+      policy_->ShouldAllowConsumerSession(args);
+      return;
+    }
+    PERFETTO_DFATAL("Not reached");
+  });
+
+  return std::unique_ptr<TracingSession>(
+      new TracingSessionImpl(this, session_id, requested_backend_type));
+}
+
+// static
+// This is called via the public API Tracing::SetupStartupTracing().
+// Can be called from any thread.
+std::unique_ptr<StartupTracingSession>
+TracingMuxerImpl::CreateStartupTracingSession(
+    const TraceConfig& config,
+    Tracing::SetupStartupTracingOpts opts) {
+  BackendType backend_type = opts.backend;
+  // |backend_type| can only specify one backend, not an OR-ed mask.
+  PERFETTO_CHECK((backend_type & (backend_type - 1)) == 0);
+  // The in-process backend doesn't support startup tracing.
+  PERFETTO_CHECK(backend_type != BackendType::kInProcessBackend);
+
+  TracingSessionGlobalID session_id = ++next_tracing_session_id_;
+
+  // Capturing |this| is fine because the TracingMuxer is a leaky singleton.
+  task_runner_->PostTask([this, config, opts, backend_type, session_id] {
+    for (RegisteredProducerBackend& backend : producer_backends_) {
+      if (backend_type && backend.type && backend.type != backend_type) {
+        continue;
+      }
+
+      TracingBackendId backend_id = backend.id;
+
+      // The last registered backend in |producer_backends_| is the unsupported
+      // backend without a valid type.
+      if (!backend.type) {
+        PERFETTO_ELOG(
+            "No tracing backend initialized for type=%d, startup tracing "
+            "failed",
+            backend_type);
+        if (opts.on_setup)
+          opts.on_setup(Tracing::OnStartupTracingSetupCallbackArgs{
+              0 /* num_data_sources_started */});
+        return;
+      }
+
+      if (!backend.producer->service_ ||
+          !backend.producer->service_->shared_memory()) {
+        // If we unsuccessfully attempted to use a producer-provided SMB in the
+        // past, don't try again.
+        if (backend.producer->producer_provided_smb_failed_) {
+          PERFETTO_ELOG(
+              "Backend %zu doesn't seem to support producer-provided "
+              "SMBs, startup tracing failed",
+              backend_id);
+          if (opts.on_setup)
+            opts.on_setup(Tracing::OnStartupTracingSetupCallbackArgs{
+                0 /* num_data_sources_started */});
+          return;
+        }
+
+        PERFETTO_DLOG("Reconnecting backend %zu for startup tracing",
+                      backend_id);
+        backend.producer_conn_args.use_producer_provided_smb = true;
+        backend.producer->service_->Disconnect();  // Causes a reconnect.
+        PERFETTO_DCHECK(backend.producer->service_ &&
+                        backend.producer->service_->MaybeSharedMemoryArbiter());
+      }
+
+      RegisteredStartupSession session;
+      session.session_id = session_id;
+      session.on_aborted = opts.on_aborted;
+      session.on_adopted = opts.on_adopted;
+
+      for (const TraceConfig::DataSource& ds_cfg : config.data_sources()) {
+        // Find all matching data sources and start one instance of each.
+        for (const auto& rds : data_sources_) {
+          if (rds.descriptor.name() != ds_cfg.config().name())
+            continue;
+
+          PERFETTO_DLOG(
+              "Setting up data source %s for startup tracing with target "
+              "buffer reservation %" PRIi32,
+              rds.descriptor.name().c_str(),
+              backend.producer->last_startup_target_buffer_reservation_ + 1u);
+          auto ds = SetupDataSourceImpl(
+              rds, backend_id,
+              backend.producer->connection_id_.load(std::memory_order_relaxed),
+              /*instance_id=*/0, ds_cfg.config(),
+              /*startup_session_id=*/session_id);
+          if (ds) {
+            StartDataSourceImpl(ds);
+            session.num_unbound_data_sources++;
+          }
+        }
+      }
+
+      int num_ds = session.num_unbound_data_sources;
+      auto on_setup = opts.on_setup;
+      if (on_setup) {
+        backend.producer->OnStartupTracingSetup();
+        task_runner_->PostTask([on_setup, num_ds] {
+          on_setup(Tracing::OnStartupTracingSetupCallbackArgs{num_ds});
+        });
+      }
+
+      if (num_ds > 0) {
+        backend.startup_sessions.push_back(std::move(session));
+
+        if (opts.timeout_ms > 0) {
+          task_runner_->PostDelayedTask(
+              [this, session_id, backend_type] {
+                AbortStartupTracingSession(session_id, backend_type);
+              },
+              opts.timeout_ms);
+        }
+      }
+      return;
+    }
+    PERFETTO_DFATAL("Invalid startup tracing session backend");
+  });
+
+  return std::unique_ptr<StartupTracingSession>(
+      new StartupTracingSessionImpl(this, session_id, backend_type));
+}
+
+// Must not be called from the SDK's internal thread.
+std::unique_ptr<StartupTracingSession>
+TracingMuxerImpl::CreateStartupTracingSessionBlocking(
+    const TraceConfig& config,
+    Tracing::SetupStartupTracingOpts opts) {
+  auto previous_on_setup = std::move(opts.on_setup);
+  PERFETTO_CHECK(!task_runner_->RunsTasksOnCurrentThread());
+  base::WaitableEvent event;
+  // It is safe to capture by reference because once on_setup is called only
+  // once before this method returns.
+  opts.on_setup = [&](Tracing::OnStartupTracingSetupCallbackArgs args) {
+    if (previous_on_setup) {
+      previous_on_setup(std::move(args));
+    }
+    event.Notify();
+  };
+  auto session = CreateStartupTracingSession(config, std::move(opts));
+  event.Wait();
+  return session;
+}
+
+void TracingMuxerImpl::AbortStartupTracingSession(
+    TracingSessionGlobalID session_id,
+    BackendType backend_type) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  for (RegisteredProducerBackend& backend : producer_backends_) {
+    if (backend_type != backend.type)
+      continue;
+
+    auto session_it = std::find_if(
+        backend.startup_sessions.begin(), backend.startup_sessions.end(),
+        [session_id](const RegisteredStartupSession& session) {
+          return session.session_id == session_id;
+        });
+
+    // The startup session may have already been aborted or fully adopted.
+    if (session_it == backend.startup_sessions.end())
+      return;
+    if (session_it->is_aborting)
+      return;
+
+    session_it->is_aborting = true;
+
+    // Iterate all data sources and abort them if they weren't adopted yet.
+    for (const auto& rds : data_sources_) {
+      DataSourceStaticState* static_state = rds.static_state;
+      for (uint32_t i = 0; i < kMaxDataSourceInstances; i++) {
+        auto* internal_state = static_state->TryGet(i);
+        if (internal_state &&
+            internal_state->startup_target_buffer_reservation.load(
+                std::memory_order_relaxed) &&
+            internal_state->data_source_instance_id == 0 &&
+            internal_state->startup_session_id == session_id) {
+          PERFETTO_DLOG(
+              "Aborting startup tracing for data source %s (target buffer "
+              "reservation %" PRIu16 ")",
+              rds.descriptor.name().c_str(),
+              internal_state->startup_target_buffer_reservation.load(
+                  std::memory_order_relaxed));
+
+          // Abort the instance asynchronously by stopping it. From this point
+          // onwards, the service will not be able to adopt it via
+          // StartDataSource().
+          session_it->num_aborting_data_sources++;
+          StopDataSource_AsyncBeginImpl(
+              FindDataSourceRes(static_state, internal_state, i,
+                                rds.requires_callbacks_under_lock));
+        }
+      }
+    }
+
+    // If we did everything right, we should have aborted all still-unbound data
+    // source instances.
+    PERFETTO_DCHECK(session_it->num_unbound_data_sources ==
+                    session_it->num_aborting_data_sources);
+
+    if (session_it->num_aborting_data_sources == 0) {
+      if (session_it->on_aborted)
+        task_runner_->PostTask(session_it->on_aborted);
+
+      backend.startup_sessions.erase(session_it);
+    }
+    return;
+  }
+  // We might reach here in tests because when we start a trace, we post the
+  // Task(AbortStartupTrace, delay=timeout). When we do
+  // perfetto::ResetForTesting, we sweep dead backends, and we are not able to
+  // kill those delayed tasks because TaskRunner doesn't have support for
+  // deleting scheduled future tasks and TaskRunner doesn't have any API for us
+  // to wait for the completion of all the scheduled tasks (apart from
+  // deleting the TaskRunner) and we want to avoid doing that because we need
+  // a long running TaskRunner in muxer.
+  PERFETTO_DLOG("Invalid startup tracing session backend");
+}
+
+void TracingMuxerImpl::InitializeInstance(const TracingInitArgs& args) {
+  if (instance_ != TracingMuxerFake::Get()) {
+    // The tracing muxer was already initialized. We might need to initialize
+    // additional backends that were not configured earlier.
+    auto* muxer = static_cast<TracingMuxerImpl*>(instance_);
+    muxer->task_runner_->PostTask([muxer, args] { muxer->AddBackends(args); });
+    return;
+  }
+  // If we previously had a TracingMuxerImpl instance which was reset,
+  // reinitialize and reuse it instead of trying to create a new one. See
+  // ResetForTesting().
+  if (g_prev_instance) {
+    auto* muxer = g_prev_instance;
+    g_prev_instance = nullptr;
+    instance_ = muxer;
+    muxer->task_runner_->PostTask([muxer, args] {
+      muxer->Initialize(args);
+      muxer->AddBackends(args);
+    });
+  } else {
+    new TracingMuxerImpl(args);
+  }
+}
+
+// static
+void TracingMuxerImpl::ResetForTesting() {
+  // Ideally we'd tear down the entire TracingMuxerImpl, but the lifetimes of
+  // various objects make that a non-starter. In particular:
+  //
+  // 1) Any thread that has entered a trace event has a TraceWriter, which holds
+  //    a reference back to ProducerImpl::service_.
+  //
+  // 2) ProducerImpl::service_ has a reference back to the ProducerImpl.
+  //
+  // 3) ProducerImpl holds reference to TracingMuxerImpl::task_runner_, which in
+  //    turn depends on TracingMuxerImpl itself.
+  //
+  // Because of this, it's not safe to deallocate TracingMuxerImpl until all
+  // threads have dropped their TraceWriters. Since we can't really ask the
+  // caller to guarantee this, we'll instead reset enough of the muxer's state
+  // so that it can be reinitialized later and ensure all necessary objects from
+  // the old state remain alive until all references have gone away.
+  auto* muxer = reinterpret_cast<TracingMuxerImpl*>(instance_);
+
+  base::WaitableEvent reset_done;
+  auto do_reset = [muxer, &reset_done] {
+    muxer->DestroyStoppedTraceWritersForCurrentThread();
+    // Unregister all data sources so they don't interfere with any future
+    // tracing sessions.
+    for (RegisteredDataSource& rds : muxer->data_sources_) {
+      for (RegisteredProducerBackend& backend : muxer->producer_backends_) {
+        if (!backend.producer->service_ || !backend.producer->connected_)
+          continue;
+        backend.producer->service_->UnregisterDataSource(rds.descriptor.name());
+      }
+    }
+    for (auto& backend : muxer->consumer_backends_) {
+      // Check that no consumer session is currently active on any backend.
+      for (auto& consumer : backend.consumers)
+        PERFETTO_CHECK(!consumer->service_);
+    }
+    for (auto& backend : muxer->producer_backends_) {
+      backend.producer->muxer_ = nullptr;
+      backend.producer->DisposeConnection();
+      muxer->dead_backends_.push_back(std::move(backend));
+    }
+    muxer->consumer_backends_.clear();
+    muxer->producer_backends_.clear();
+    muxer->interceptors_.clear();
+
+    for (auto& ds : muxer->data_sources_) {
+      ds.static_state->ResetForTesting();
+    }
+
+    muxer->data_sources_.clear();
+    muxer->next_data_source_index_ = 0;
+
+    // Free all backends without active trace writers or other inbound
+    // references. Note that even if all the backends get swept, the muxer still
+    // needs to stay around since |task_runner_| is assumed to be long-lived.
+    muxer->SweepDeadBackends();
+
+    // Make sure we eventually discard any per-thread trace writers from the
+    // previous instance.
+    muxer->muxer_id_for_testing_++;
+
+    g_prev_instance = muxer;
+    instance_ = TracingMuxerFake::Get();
+
+    // Call the user provided cleanups on the muxer thread.
+    for (auto& cb : muxer->reset_callbacks_) {
+      cb();
+    }
+
+    reset_done.Notify();
+  };
+
+  // Some tests run the muxer and the test on the same thread. In these cases,
+  // we can reset synchronously.
+  if (muxer->task_runner_->RunsTasksOnCurrentThread()) {
+    do_reset();
+  } else {
+    muxer->DestroyStoppedTraceWritersForCurrentThread();
+    muxer->task_runner_->PostTask(std::move(do_reset));
+    reset_done.Wait();
+    // Call the user provided cleanups also on this thread.
+    for (auto& cb : muxer->reset_callbacks_) {
+      cb();
+    }
+  }
+  muxer->reset_callbacks_.clear();
+}
+
+// static
+void TracingMuxerImpl::Shutdown() {
+  auto* muxer = reinterpret_cast<TracingMuxerImpl*>(instance_);
+
+  // Shutting down on the muxer thread would lead to a deadlock.
+  PERFETTO_CHECK(!muxer->task_runner_->RunsTasksOnCurrentThread());
+  muxer->DestroyStoppedTraceWritersForCurrentThread();
+
+  std::unique_ptr<base::TaskRunner> owned_task_runner(
+      muxer->task_runner_.get());
+  base::WaitableEvent shutdown_done;
+  owned_task_runner->PostTask([muxer, &shutdown_done] {
+    // Check that no consumer session is currently active on any backend.
+    // Producers will be automatically disconnected as a part of deleting the
+    // muxer below.
+    for (auto& backend : muxer->consumer_backends_) {
+      for (auto& consumer : backend.consumers) {
+        PERFETTO_CHECK(!consumer->service_);
+      }
+    }
+    // Make sure no trace writers are lingering around on the muxer thread. Note
+    // that we can't do this for any arbitrary thread in the process; it is the
+    // caller's responsibility to clean them up before shutting down Perfetto.
+    muxer->DestroyStoppedTraceWritersForCurrentThread();
+    // The task runner must be deleted outside the muxer thread. This is done by
+    // `owned_task_runner` above.
+    muxer->task_runner_.release();
+    auto* platform = muxer->platform_;
+    delete muxer;
+    instance_ = TracingMuxerFake::Get();
+    platform->Shutdown();
+    shutdown_done.Notify();
+  });
+  shutdown_done.Wait();
+}
+
+void TracingMuxerImpl::AppendResetForTestingCallback(std::function<void()> cb) {
+  reset_callbacks_.push_back(std::move(cb));
+}
+
+TracingMuxer::~TracingMuxer() = default;
+
+static_assert(std::is_same<internal::BufferId, BufferID>::value,
+              "public's BufferId and tracing/core's BufferID diverged");
+
+}  // namespace internal
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/internal/track_event_internal.cc
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_internal.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/proc_utils.h"
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_config.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_interned_fields.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track_event.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track_event_category_registry.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track_event_interned_data_index.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/track_event_descriptor.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/clock_snapshot.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet_defaults.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_descriptor.pbzero.h"
+
+using perfetto::protos::pbzero::ClockSnapshot;
+
+namespace perfetto {
+
+TrackEventSessionObserver::~TrackEventSessionObserver() = default;
+void TrackEventSessionObserver::OnSetup(const DataSourceBase::SetupArgs&) {}
+void TrackEventSessionObserver::OnStart(const DataSourceBase::StartArgs&) {}
+void TrackEventSessionObserver::OnStop(const DataSourceBase::StopArgs&) {}
+void TrackEventSessionObserver::WillClearIncrementalState(
+    const DataSourceBase::ClearIncrementalStateArgs&) {}
+
+TrackEventTlsStateUserData::~TrackEventTlsStateUserData() = default;
+
+namespace internal {
+
+BaseTrackEventInternedDataIndex::~BaseTrackEventInternedDataIndex() = default;
+
+namespace {
+
+static constexpr const char kLegacySlowPrefix[] = "disabled-by-default-";
+static constexpr const char kSlowTag[] = "slow";
+static constexpr const char kDebugTag[] = "debug";
+static constexpr const char kFilteredEventName[] = "FILTERED";
+
+constexpr auto kClockIdIncremental =
+    TrackEventIncrementalState::kClockIdIncremental;
+
+constexpr auto kClockIdAbsolute = TrackEventIncrementalState::kClockIdAbsolute;
+
+class TrackEventSessionObserverRegistry {
+ public:
+  static TrackEventSessionObserverRegistry* GetInstance() {
+    static TrackEventSessionObserverRegistry* instance =
+        new TrackEventSessionObserverRegistry();  // leaked
+    return instance;
+  }
+
+  void AddObserverForRegistry(const TrackEventCategoryRegistry& registry,
+                              TrackEventSessionObserver* observer) {
+    std::unique_lock<std::recursive_mutex> lock(mutex_);
+    observers_.emplace_back(&registry, observer);
+  }
+
+  void RemoveObserverForRegistry(const TrackEventCategoryRegistry& registry,
+                                 TrackEventSessionObserver* observer) {
+    std::unique_lock<std::recursive_mutex> lock(mutex_);
+    observers_.erase(std::remove(observers_.begin(), observers_.end(),
+                                 RegisteredObserver(&registry, observer)),
+                     observers_.end());
+  }
+
+  void ForEachObserverForRegistry(
+      const TrackEventCategoryRegistry& registry,
+      std::function<void(TrackEventSessionObserver*)> callback) {
+    std::unique_lock<std::recursive_mutex> lock(mutex_);
+    for (auto& registered_observer : observers_) {
+      if (&registry == registered_observer.registry) {
+        callback(registered_observer.observer);
+      }
+    }
+  }
+
+ private:
+  struct RegisteredObserver {
+    RegisteredObserver(const TrackEventCategoryRegistry* r,
+                       TrackEventSessionObserver* o)
+        : registry(r), observer(o) {}
+    bool operator==(const RegisteredObserver& other) {
+      return registry == other.registry && observer == other.observer;
+    }
+    const TrackEventCategoryRegistry* registry;
+    TrackEventSessionObserver* observer;
+  };
+
+  std::recursive_mutex mutex_;
+  std::vector<RegisteredObserver> observers_;
+};
+
+enum class MatchType { kExact, kPattern };
+
+bool NameMatchesPattern(const std::string& pattern,
+                        const std::string& name,
+                        MatchType match_type) {
+  // To avoid pulling in all of std::regex, for now we only support a single "*"
+  // wildcard at the end of the pattern.
+  size_t i = pattern.find('*');
+  if (i != std::string::npos) {
+    PERFETTO_DCHECK(i == pattern.size() - 1);
+    if (match_type != MatchType::kPattern)
+      return false;
+    return name.substr(0, i) == pattern.substr(0, i);
+  }
+  return name == pattern;
+}
+
+bool NameMatchesPatternList(const std::vector<std::string>& patterns,
+                            const std::string& name,
+                            MatchType match_type) {
+  for (const auto& pattern : patterns) {
+    if (NameMatchesPattern(pattern, name, match_type))
+      return true;
+  }
+  return false;
+}
+
+}  // namespace
+
+// static
+const Track TrackEventInternal::kDefaultTrack{};
+
+// static
+std::atomic<int> TrackEventInternal::session_count_{};
+
+// static
+bool TrackEventInternal::Initialize(
+    const TrackEventCategoryRegistry& registry,
+    bool (*register_data_source)(const DataSourceDescriptor&)) {
+  DataSourceDescriptor dsd;
+  dsd.set_name("track_event");
+
+  protozero::HeapBuffered<protos::pbzero::TrackEventDescriptor> ted;
+  for (size_t i = 0; i < registry.category_count(); i++) {
+    auto category = registry.GetCategory(i);
+    // Don't register group categories.
+    if (category->IsGroup())
+      continue;
+    auto cat = ted->add_available_categories();
+    cat->set_name(category->name);
+    if (category->description)
+      cat->set_description(category->description);
+    for (const auto& tag : category->tags) {
+      if (tag)
+        cat->add_tags(tag);
+    }
+    // Disabled-by-default categories get a "slow" tag.
+    if (!strncmp(category->name, kLegacySlowPrefix, strlen(kLegacySlowPrefix)))
+      cat->add_tags(kSlowTag);
+  }
+  dsd.set_track_event_descriptor_raw(ted.SerializeAsString());
+
+  return register_data_source(dsd);
+}
+
+// static
+bool TrackEventInternal::AddSessionObserver(
+    const TrackEventCategoryRegistry& registry,
+    TrackEventSessionObserver* observer) {
+  TrackEventSessionObserverRegistry::GetInstance()->AddObserverForRegistry(
+      registry, observer);
+  return true;
+}
+
+// static
+void TrackEventInternal::RemoveSessionObserver(
+    const TrackEventCategoryRegistry& registry,
+    TrackEventSessionObserver* observer) {
+  TrackEventSessionObserverRegistry::GetInstance()->RemoveObserverForRegistry(
+      registry, observer);
+}
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) && \
+    !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+static constexpr protos::pbzero::BuiltinClock kDefaultTraceClock =
+    protos::pbzero::BUILTIN_CLOCK_BOOTTIME;
+#else
+static constexpr protos::pbzero::BuiltinClock kDefaultTraceClock =
+    protos::pbzero::BUILTIN_CLOCK_MONOTONIC;
+#endif
+
+// static
+protos::pbzero::BuiltinClock TrackEventInternal::clock_ = kDefaultTraceClock;
+
+// static
+bool TrackEventInternal::disallow_merging_with_system_tracks_ = false;
+
+// static
+void TrackEventInternal::EnableTracing(
+    const TrackEventCategoryRegistry& registry,
+    const protos::gen::TrackEventConfig& config,
+    const DataSourceBase::SetupArgs& args) {
+  for (size_t i = 0; i < registry.category_count(); i++) {
+    if (IsCategoryEnabled(registry, config, *registry.GetCategory(i)))
+      registry.EnableCategoryForInstance(i, args.internal_instance_index);
+  }
+  TrackEventSessionObserverRegistry::GetInstance()->ForEachObserverForRegistry(
+      registry, [&](TrackEventSessionObserver* o) { o->OnSetup(args); });
+}
+
+// static
+void TrackEventInternal::OnStart(const TrackEventCategoryRegistry& registry,
+                                 const DataSourceBase::StartArgs& args) {
+  session_count_.fetch_add(1);
+  TrackEventSessionObserverRegistry::GetInstance()->ForEachObserverForRegistry(
+      registry, [&](TrackEventSessionObserver* o) { o->OnStart(args); });
+}
+
+// static
+void TrackEventInternal::OnStop(const TrackEventCategoryRegistry& registry,
+                                const DataSourceBase::StopArgs& args) {
+  TrackEventSessionObserverRegistry::GetInstance()->ForEachObserverForRegistry(
+      registry, [&](TrackEventSessionObserver* o) { o->OnStop(args); });
+}
+
+// static
+void TrackEventInternal::DisableTracing(
+    const TrackEventCategoryRegistry& registry,
+    uint32_t internal_instance_index) {
+  for (size_t i = 0; i < registry.category_count(); i++)
+    registry.DisableCategoryForInstance(i, internal_instance_index);
+}
+
+// static
+void TrackEventInternal::WillClearIncrementalState(
+    const TrackEventCategoryRegistry& registry,
+    const DataSourceBase::ClearIncrementalStateArgs& args) {
+  TrackEventSessionObserverRegistry::GetInstance()->ForEachObserverForRegistry(
+      registry, [&](TrackEventSessionObserver* o) {
+        o->WillClearIncrementalState(args);
+      });
+}
+
+// static
+bool TrackEventInternal::IsCategoryEnabled(
+    const TrackEventCategoryRegistry& registry,
+    const protos::gen::TrackEventConfig& config,
+    const Category& category) {
+  // If this is a group category, check if any of its constituent categories are
+  // enabled. If so, then this one is enabled too.
+  if (category.IsGroup()) {
+    bool result = false;
+    category.ForEachGroupMember([&](const char* member_name, size_t name_size) {
+      for (size_t i = 0; i < registry.category_count(); i++) {
+        const auto ref_category = registry.GetCategory(i);
+        // Groups can't refer to other groups.
+        if (ref_category->IsGroup())
+          continue;
+        // Require an exact match.
+        if (ref_category->name_size() != name_size ||
+            strncmp(ref_category->name, member_name, name_size)) {
+          continue;
+        }
+        if (IsCategoryEnabled(registry, config, *ref_category)) {
+          result = true;
+          // Break ForEachGroupMember() loop.
+          return false;
+        }
+        break;
+      }
+      // No match? Must be a dynamic category.
+      DynamicCategory dyn_category(std::string(member_name, name_size));
+      Category ref_category{Category::FromDynamicCategory(dyn_category)};
+      if (IsCategoryEnabled(registry, config, ref_category)) {
+        result = true;
+        // Break ForEachGroupMember() loop.
+        return false;
+      }
+      // No match found => keep iterating.
+      return true;
+    });
+    return result;
+  }
+
+  auto has_matching_tag = [&](std::function<bool(const char*)> matcher) {
+    for (const auto& tag : category.tags) {
+      if (!tag)
+        break;
+      if (matcher(tag))
+        return true;
+    }
+    // Legacy "disabled-by-default" categories automatically get the "slow" tag.
+    if (!strncmp(category.name, kLegacySlowPrefix, strlen(kLegacySlowPrefix)) &&
+        matcher(kSlowTag)) {
+      return true;
+    }
+    return false;
+  };
+
+  // First try exact matches, then pattern matches.
+  const std::array<MatchType, 2> match_types = {
+      {MatchType::kExact, MatchType::kPattern}};
+  for (auto match_type : match_types) {
+    // 1. Enabled categories.
+    if (NameMatchesPatternList(config.enabled_categories(), category.name,
+                               match_type)) {
+      return true;
+    }
+
+    // 2. Enabled tags.
+    if (has_matching_tag([&](const char* tag) {
+          return NameMatchesPatternList(config.enabled_tags(), tag, match_type);
+        })) {
+      return true;
+    }
+
+    // 2.5. A special case for Chrome's legacy disabled-by-default categories.
+    // We treat them as having a "slow" tag with one exception: they can be
+    // enabled by a pattern if the pattern starts with "disabled-by-default-"
+    // itself.
+    if (match_type == MatchType::kExact &&
+        !strncmp(category.name, kLegacySlowPrefix, strlen(kLegacySlowPrefix))) {
+      for (const auto& pattern : config.enabled_categories()) {
+        if (!strncmp(pattern.c_str(), kLegacySlowPrefix,
+                     strlen(kLegacySlowPrefix)) &&
+            NameMatchesPattern(pattern, category.name, MatchType::kPattern)) {
+          return true;
+        }
+      }
+    }
+
+    // 3. Disabled categories.
+    if (NameMatchesPatternList(config.disabled_categories(), category.name,
+                               match_type)) {
+      return false;
+    }
+
+    // 4. Disabled tags.
+    if (has_matching_tag([&](const char* tag) {
+          if (config.disabled_tags_size()) {
+            return NameMatchesPatternList(config.disabled_tags(), tag,
+                                          match_type);
+          } else {
+            // The "slow" and "debug" tags are disabled by default.
+            return NameMatchesPattern(kSlowTag, tag, match_type) ||
+                   NameMatchesPattern(kDebugTag, tag, match_type);
+          }
+        })) {
+      return false;
+    }
+  }
+
+  // If nothing matched, enable the category by default.
+  return true;
+}
+
+// static
+uint64_t TrackEventInternal::GetTimeNs() {
+  if (GetClockId() == protos::pbzero::BUILTIN_CLOCK_BOOTTIME)
+    return static_cast<uint64_t>(perfetto::base::GetBootTimeNs().count());
+  else if (GetClockId() == protos::pbzero::BUILTIN_CLOCK_MONOTONIC)
+    return static_cast<uint64_t>(perfetto::base::GetWallTimeNs().count());
+  PERFETTO_DCHECK(GetClockId() == protos::pbzero::BUILTIN_CLOCK_MONOTONIC_RAW);
+  return static_cast<uint64_t>(perfetto::base::GetWallTimeRawNs().count());
+}
+
+// static
+TraceTimestamp TrackEventInternal::GetTraceTime() {
+  return {kClockIdIncremental, GetTimeNs()};
+}
+
+// static
+int TrackEventInternal::GetSessionCount() {
+  return session_count_.load();
+}
+
+// static
+void TrackEventInternal::ResetIncrementalState(
+    TraceWriterBase* trace_writer,
+    TrackEventIncrementalState* incr_state,
+    const TrackEventTlsState& tls_state,
+    const TraceTimestamp& timestamp) {
+  auto sequence_timestamp = timestamp;
+  if (timestamp.clock_id != kClockIdIncremental) {
+    sequence_timestamp = TrackEventInternal::GetTraceTime();
+  }
+
+  incr_state->last_timestamp_ns = sequence_timestamp.value;
+  auto default_track = ThreadTrack::Current();
+  auto ts_unit_multiplier = tls_state.timestamp_unit_multiplier;
+  auto thread_time_counter_track =
+      CounterTrack("thread_time", default_track)
+          .set_is_incremental(true)
+          .set_unit_multiplier(static_cast<int64_t>(ts_unit_multiplier))
+          .set_type(protos::gen::CounterDescriptor::COUNTER_THREAD_TIME_NS);
+  {
+    // Mark any incremental state before this point invalid. Also set up
+    // defaults so that we don't need to repeat constant data for each packet.
+    auto packet = NewTracePacket(
+        trace_writer, incr_state, tls_state, timestamp,
+        protos::pbzero::TracePacket::SEQ_INCREMENTAL_STATE_CLEARED);
+    auto defaults = packet->set_trace_packet_defaults();
+    defaults->set_timestamp_clock_id(tls_state.default_clock);
+    // Establish the default track for this event sequence.
+    auto track_defaults = defaults->set_track_event_defaults();
+    track_defaults->set_track_uuid(default_track.uuid);
+    if (tls_state.enable_thread_time_sampling) {
+      track_defaults->add_extra_counter_track_uuids(
+          thread_time_counter_track.uuid);
+    }
+
+    if (tls_state.default_clock != static_cast<uint32_t>(GetClockId())) {
+      ClockSnapshot* clocks = packet->set_clock_snapshot();
+      // Trace clock.
+      ClockSnapshot::Clock* trace_clock = clocks->add_clocks();
+      trace_clock->set_clock_id(static_cast<uint32_t>(GetClockId()));
+      trace_clock->set_timestamp(sequence_timestamp.value);
+
+      if (PERFETTO_LIKELY(tls_state.default_clock == kClockIdIncremental)) {
+        // Delta-encoded incremental clock in nanoseconds by default but
+        // configurable by |tls_state.timestamp_unit_multiplier|.
+        ClockSnapshot::Clock* clock_incremental = clocks->add_clocks();
+        clock_incremental->set_clock_id(kClockIdIncremental);
+        clock_incremental->set_timestamp(sequence_timestamp.value /
+                                         ts_unit_multiplier);
+        clock_incremental->set_is_incremental(true);
+        clock_incremental->set_unit_multiplier_ns(ts_unit_multiplier);
+      }
+      if (ts_unit_multiplier > 1) {
+        // absolute clock with custom timestamp_unit_multiplier.
+        ClockSnapshot::Clock* absolute_clock = clocks->add_clocks();
+        absolute_clock->set_clock_id(kClockIdAbsolute);
+        absolute_clock->set_timestamp(sequence_timestamp.value /
+                                      ts_unit_multiplier);
+        absolute_clock->set_is_incremental(false);
+        absolute_clock->set_unit_multiplier_ns(ts_unit_multiplier);
+      }
+    }
+  }
+
+  // Every thread should write a descriptor for its default track, because most
+  // trace points won't explicitly reference it. We also write the process
+  // descriptor from every thread that writes trace events to ensure it gets
+  // emitted at least once.
+  WriteTrackDescriptor(default_track, trace_writer, incr_state, tls_state,
+                       sequence_timestamp);
+
+  WriteTrackDescriptor(ProcessTrack::Current(), trace_writer, incr_state,
+                       tls_state, sequence_timestamp);
+
+  if (tls_state.enable_thread_time_sampling) {
+    WriteTrackDescriptor(thread_time_counter_track, trace_writer, incr_state,
+                         tls_state, sequence_timestamp);
+  }
+}
+
+// static
+protozero::MessageHandle<protos::pbzero::TracePacket>
+TrackEventInternal::NewTracePacket(TraceWriterBase* trace_writer,
+                                   TrackEventIncrementalState* incr_state,
+                                   const TrackEventTlsState& tls_state,
+                                   TraceTimestamp timestamp,
+                                   uint32_t seq_flags) {
+  if (PERFETTO_UNLIKELY(tls_state.default_clock != kClockIdIncremental &&
+                        timestamp.clock_id == kClockIdIncremental)) {
+    timestamp.clock_id = tls_state.default_clock;
+  }
+  auto packet = trace_writer->NewTracePacket();
+  auto ts_unit_multiplier = tls_state.timestamp_unit_multiplier;
+  if (PERFETTO_LIKELY(timestamp.clock_id == kClockIdIncremental)) {
+    if (PERFETTO_LIKELY(incr_state->last_timestamp_ns <= timestamp.value)) {
+      // No need to set the clock id here, since kClockIdIncremental is the
+      // clock id assumed by default.
+      auto time_diff_ns = timestamp.value - incr_state->last_timestamp_ns;
+      auto time_diff_units = time_diff_ns / ts_unit_multiplier;
+      packet->set_timestamp(time_diff_units);
+      incr_state->last_timestamp_ns += time_diff_units * ts_unit_multiplier;
+    } else {
+      packet->set_timestamp(timestamp.value / ts_unit_multiplier);
+      packet->set_timestamp_clock_id(ts_unit_multiplier == 1
+                                         ? static_cast<uint32_t>(GetClockId())
+                                         : kClockIdAbsolute);
+    }
+  } else if (PERFETTO_LIKELY(timestamp.clock_id == tls_state.default_clock)) {
+    packet->set_timestamp(timestamp.value / ts_unit_multiplier);
+  } else {
+    packet->set_timestamp(timestamp.value);
+    packet->set_timestamp_clock_id(timestamp.clock_id);
+  }
+  packet->set_sequence_flags(seq_flags);
+  return packet;
+}
+
+// static
+void TrackEventInternal::WriteEventName(StaticString event_name,
+                                        perfetto::EventContext& event_ctx,
+                                        const TrackEventTlsState&) {
+  if (PERFETTO_LIKELY(event_name.value != nullptr)) {
+    size_t name_iid = InternedEventName::Get(&event_ctx, event_name.value);
+    event_ctx.event()->set_name_iid(name_iid);
+  }
+}
+
+// static
+void TrackEventInternal::WriteEventName(perfetto::DynamicString event_name,
+                                        perfetto::EventContext& event_ctx,
+                                        const TrackEventTlsState& tls_state) {
+  if (PERFETTO_UNLIKELY(tls_state.filter_dynamic_event_names)) {
+    event_ctx.event()->set_name(kFilteredEventName,
+                                sizeof(kFilteredEventName) - 1);
+  } else {
+    event_ctx.event()->set_name(event_name.value, event_name.length);
+  }
+}
+
+// static
+EventContext TrackEventInternal::WriteEvent(
+    TraceWriterBase* trace_writer,
+    TrackEventIncrementalState* incr_state,
+    TrackEventTlsState& tls_state,
+    const Category* category,
+    perfetto::protos::pbzero::TrackEvent::Type type,
+    const TraceTimestamp& timestamp,
+    bool on_current_thread_track) {
+  PERFETTO_DCHECK(!incr_state->was_cleared);
+  auto packet = NewTracePacket(trace_writer, incr_state, tls_state, timestamp);
+  EventContext ctx(trace_writer, std::move(packet), incr_state, &tls_state);
+
+  auto track_event = ctx.event();
+  if (type != protos::pbzero::TrackEvent::TYPE_UNSPECIFIED)
+    track_event->set_type(type);
+
+  if (tls_state.enable_thread_time_sampling && on_current_thread_track) {
+    int64_t thread_time_ns = base::GetThreadCPUTimeNs().count();
+    auto thread_time_delta_ns =
+        thread_time_ns - incr_state->last_thread_time_ns;
+    incr_state->last_thread_time_ns = thread_time_ns;
+    track_event->add_extra_counter_values(
+        thread_time_delta_ns /
+        static_cast<int64_t>(tls_state.timestamp_unit_multiplier));
+  }
+
+  // We assume that |category| points to the string with static lifetime.
+  // This means we can use their addresses as interning keys.
+  // TODO(skyostil): Intern categories at compile time.
+  if (category && type != protos::pbzero::TrackEvent::TYPE_SLICE_END &&
+      type != protos::pbzero::TrackEvent::TYPE_COUNTER) {
+    category->ForEachGroupMember(
+        [&](const char* member_name, size_t name_size) {
+          size_t category_iid =
+              InternedEventCategory::Get(&ctx, member_name, name_size);
+          track_event->add_category_iids(category_iid);
+          return true;
+        });
+  }
+  return ctx;
+}
+
+// static
+protos::pbzero::DebugAnnotation* TrackEventInternal::AddDebugAnnotation(
+    perfetto::EventContext* event_ctx,
+    const char* name) {
+  auto annotation = event_ctx->event()->add_debug_annotations();
+  annotation->set_name_iid(InternedDebugAnnotationName::Get(event_ctx, name));
+  return annotation;
+}
+
+// static
+protos::pbzero::DebugAnnotation* TrackEventInternal::AddDebugAnnotation(
+    perfetto::EventContext* event_ctx,
+    perfetto::DynamicString name) {
+  auto annotation = event_ctx->event()->add_debug_annotations();
+  annotation->set_name(name.value);
+  return annotation;
+}
+
+}  // namespace internal
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/internal/track_event_interned_fields.cc
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_interned_fields.h"
+
+namespace perfetto {
+namespace internal {
+
+InternedEventCategory::~InternedEventCategory() = default;
+
+// static
+void InternedEventCategory::Add(protos::pbzero::InternedData* interned_data,
+                                size_t iid,
+                                const char* value,
+                                size_t length) {
+  auto category = interned_data->add_event_categories();
+  category->set_iid(iid);
+  category->set_name(value, length);
+}
+
+InternedEventName::~InternedEventName() = default;
+
+// static
+void InternedEventName::Add(protos::pbzero::InternedData* interned_data,
+                            size_t iid,
+                            const char* value) {
+  auto name = interned_data->add_event_names();
+  name->set_iid(iid);
+  name->set_name(value);
+}
+
+InternedDebugAnnotationName::~InternedDebugAnnotationName() = default;
+
+// static
+void InternedDebugAnnotationName::Add(
+    protos::pbzero::InternedData* interned_data,
+    size_t iid,
+    const char* value) {
+  auto name = interned_data->add_debug_annotation_names();
+  name->set_iid(iid);
+  name->set_name(value);
+}
+
+InternedDebugAnnotationValueTypeName::~InternedDebugAnnotationValueTypeName() =
+    default;
+
+// static
+void InternedDebugAnnotationValueTypeName::Add(
+    protos::pbzero::InternedData* interned_data,
+    size_t iid,
+    const char* value) {
+  auto name = interned_data->add_debug_annotation_value_type_names();
+  name->set_iid(iid);
+  name->set_name(value);
+}
+
+}  // namespace internal
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/platform.cc
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/platform.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_tls.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
+
+namespace perfetto {
+
+PlatformThreadLocalObject::~PlatformThreadLocalObject() = default;
+Platform::~Platform() = default;
+
+void Platform::Shutdown() {}
+
+base::PlatformThreadId Platform::GetCurrentThreadId() {
+  return base::GetThreadId();
+}
+
+// static
+std::unique_ptr<PlatformThreadLocalObject>
+PlatformThreadLocalObject::CreateInstance() {
+  return std::unique_ptr<PlatformThreadLocalObject>(new internal::TracingTLS());
+}
+
+// static
+base::PlatformProcessId Platform::process_id_ = 0;
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/traced_value.cc
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/traced_value.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/debug_annotation.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_interned_fields.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
+
+namespace perfetto {
+
+namespace internal {
+
+TracedValue CreateTracedValueFromProto(
+    protos::pbzero::DebugAnnotation* annotation,
+    EventContext* event_context) {
+  return TracedValue::CreateFromProto(annotation, event_context);
+}
+
+}  // namespace internal
+
+// static
+TracedValue TracedValue::CreateFromProto(
+    protos::pbzero::DebugAnnotation* annotation,
+    EventContext* event_context) {
+  return TracedValue(annotation, event_context, nullptr);
+}
+
+TracedValue::TracedValue(TracedValue&&) = default;
+TracedValue::~TracedValue() = default;
+
+void TracedValue::WriteInt64(int64_t value) && {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  annotation_->set_int_value(value);
+}
+
+void TracedValue::WriteUInt64(uint64_t value) && {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  annotation_->set_uint_value(value);
+}
+
+void TracedValue::WriteDouble(double value) && {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  annotation_->set_double_value(value);
+}
+
+void TracedValue::WriteBoolean(bool value) && {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  annotation_->set_bool_value(value);
+}
+
+void TracedValue::WriteString(const char* value) && {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  annotation_->set_string_value(value);
+}
+
+void TracedValue::WriteString(const char* value, size_t len) && {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  annotation_->set_string_value(value, len);
+}
+
+void TracedValue::WriteString(const std::string& value) && {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  annotation_->set_string_value(value);
+}
+
+void TracedValue::WriteString(std::string_view value) && {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  annotation_->set_string_value(value.data(), value.size());
+}
+
+void TracedValue::WritePointer(const void* value) && {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  annotation_->set_pointer_value(reinterpret_cast<uint64_t>(value));
+}
+
+TracedDictionary TracedValue::WriteDictionary() && {
+  // Note: this passes |checked_scope_.is_active_| bit to the parent to be
+  // picked up later by the new TracedDictionary.
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  checked_scope_.Reset();
+
+  PERFETTO_DCHECK(!annotation_->is_finalized());
+  return TracedDictionary(annotation_,
+                          protos::pbzero::DebugAnnotation::kDictEntries,
+                          event_context_, checked_scope_.parent_scope());
+}
+
+TracedArray TracedValue::WriteArray() && {
+  // Note: this passes |checked_scope_.is_active_| bit to the parent to be
+  // picked up later by the new TracedDictionary.
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  checked_scope_.Reset();
+
+  PERFETTO_DCHECK(!annotation_->is_finalized());
+  return TracedArray(annotation_, event_context_,
+                     checked_scope_.parent_scope());
+}
+
+protozero::Message* TracedValue::WriteProtoInternal(const char* name) {
+  if (event_context_) {
+    annotation_->set_proto_type_name_iid(
+        internal::InternedDebugAnnotationValueTypeName::Get(event_context_,
+                                                            name));
+  } else {
+    annotation_->set_proto_type_name(name);
+  }
+  return annotation_->template BeginNestedMessage<protozero::Message>(
+      protos::pbzero::DebugAnnotation::kProtoValueFieldNumber);
+}
+
+TracedArray::TracedArray(TracedValue annotation)
+    : TracedArray(std::move(annotation).WriteArray()) {}
+
+TracedValue TracedArray::AppendItem() {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  return TracedValue(annotation_->add_array_values(), event_context_,
+                     &checked_scope_);
+}
+
+TracedDictionary TracedArray::AppendDictionary() {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  return AppendItem().WriteDictionary();
+}
+
+TracedArray TracedArray::AppendArray() {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  return AppendItem().WriteArray();
+}
+
+TracedDictionary::TracedDictionary(TracedValue annotation)
+    : TracedDictionary(std::move(annotation).WriteDictionary()) {}
+
+TracedValue TracedDictionary::AddItem(StaticString key) {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  protos::pbzero::DebugAnnotation* item =
+      message_->BeginNestedMessage<protos::pbzero::DebugAnnotation>(field_id_);
+  item->set_name(key.value);
+  return TracedValue(item, event_context_, &checked_scope_);
+}
+
+TracedValue TracedDictionary::AddItem(DynamicString key) {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  protos::pbzero::DebugAnnotation* item =
+      message_->BeginNestedMessage<protos::pbzero::DebugAnnotation>(field_id_);
+  item->set_name(key.value);
+  return TracedValue(item, event_context_, &checked_scope_);
+}
+
+TracedDictionary TracedDictionary::AddDictionary(StaticString key) {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  return AddItem(key).WriteDictionary();
+}
+
+TracedDictionary TracedDictionary::AddDictionary(DynamicString key) {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  return AddItem(key).WriteDictionary();
+}
+
+TracedArray TracedDictionary::AddArray(StaticString key) {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  return AddItem(key).WriteArray();
+}
+
+TracedArray TracedDictionary::AddArray(DynamicString key) {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  return AddItem(key).WriteArray();
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/tracing.cc
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/tracing.h"
+
+#include <atomic>
+#include <condition_variable>
+#include <mutex>
+
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/no_destructor.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/waitable_event.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_internal.h"
+// gen_amalgamated expanded: #include "src/tracing/internal/tracing_muxer_impl.h"
+
+namespace perfetto {
+namespace {
+bool g_was_initialized = false;
+
+// Wrapped in a function to avoid global constructor
+std::mutex& InitializedMutex() {
+  static base::NoDestructor<std::mutex> initialized_mutex;
+  return initialized_mutex.ref();
+}
+}  // namespace
+
+// static
+void Tracing::InitializeInternal(const TracingInitArgs& args) {
+  base::InitializeTime();
+  std::unique_lock<std::mutex> lock(InitializedMutex());
+  // If it's the first time Initialize is called, set some global params.
+  if (!g_was_initialized) {
+    // Make sure the headers and implementation files agree on the build config.
+    PERFETTO_CHECK(args.dcheck_is_on_ == PERFETTO_DCHECK_IS_ON());
+    if (args.log_message_callback) {
+      base::SetLogMessageCallback(args.log_message_callback);
+    }
+
+    if (args.use_monotonic_clock) {
+      PERFETTO_CHECK(!args.use_monotonic_raw_clock);
+      internal::TrackEventInternal::SetClockId(
+          protos::pbzero::BUILTIN_CLOCK_MONOTONIC);
+    } else if (args.use_monotonic_raw_clock) {
+      internal::TrackEventInternal::SetClockId(
+          protos::pbzero::BUILTIN_CLOCK_MONOTONIC_RAW);
+    }
+
+    if (args.disallow_merging_with_system_tracks) {
+      internal::TrackEventInternal::SetDisallowMergingWithSystemTracks(true);
+    }
+  }
+
+  internal::TracingMuxerImpl::InitializeInstance(args);
+  internal::TrackRegistry::InitializeInstance();
+  g_was_initialized = true;
+}
+
+// static
+bool Tracing::IsInitialized() {
+  std::unique_lock<std::mutex> lock(InitializedMutex());
+  return g_was_initialized;
+}
+
+// static
+void Tracing::Shutdown() {
+  std::unique_lock<std::mutex> lock(InitializedMutex());
+  if (!g_was_initialized)
+    return;
+  internal::TracingMuxerImpl::Shutdown();
+  g_was_initialized = false;
+}
+
+// static
+void Tracing::ResetForTesting() {
+  std::unique_lock<std::mutex> lock(InitializedMutex());
+  if (!g_was_initialized)
+    return;
+  base::SetLogMessageCallback(nullptr);
+  internal::TracingMuxerImpl::ResetForTesting();
+  internal::TrackRegistry::ResetForTesting();
+  g_was_initialized = false;
+}
+
+//  static
+std::unique_ptr<TracingSession> Tracing::NewTraceInternal(
+    BackendType backend,
+    TracingConsumerBackend* (*system_backend_factory)()) {
+  return static_cast<internal::TracingMuxerImpl*>(internal::TracingMuxer::Get())
+      ->CreateTracingSession(backend, system_backend_factory);
+}
+
+//  static
+std::unique_ptr<StartupTracingSession> Tracing::SetupStartupTracing(
+    const TraceConfig& config,
+    Tracing::SetupStartupTracingOpts opts) {
+  return static_cast<internal::TracingMuxerImpl*>(internal::TracingMuxer::Get())
+      ->CreateStartupTracingSession(config, std::move(opts));
+}
+
+//  static
+std::unique_ptr<StartupTracingSession> Tracing::SetupStartupTracingBlocking(
+    const TraceConfig& config,
+    Tracing::SetupStartupTracingOpts opts) {
+  return static_cast<internal::TracingMuxerImpl*>(internal::TracingMuxer::Get())
+      ->CreateStartupTracingSessionBlocking(config, std::move(opts));
+}
+
+//  static
+void Tracing::ActivateTriggers(const std::vector<std::string>& triggers,
+                               uint32_t ttl_ms) {
+  internal::TracingMuxer::Get()->ActivateTriggers(triggers, ttl_ms);
+}
+
+TracingSession::~TracingSession() = default;
+
+// Can be called from any thread.
+bool TracingSession::FlushBlocking(uint32_t timeout_ms) {
+  std::atomic<bool> flush_result;
+  base::WaitableEvent flush_ack;
+
+  // The non blocking Flush() can be called on any thread. It does the PostTask
+  // internally.
+  Flush(
+      [&flush_ack, &flush_result](bool res) {
+        flush_result = res;
+        flush_ack.Notify();
+      },
+      timeout_ms);
+  flush_ack.Wait();
+  return flush_result;
+}
+
+std::vector<char> TracingSession::ReadTraceBlocking() {
+  std::vector<char> raw_trace;
+  std::mutex mutex;
+  std::condition_variable cv;
+
+  bool all_read = false;
+
+  ReadTrace([&mutex, &raw_trace, &all_read, &cv](ReadTraceCallbackArgs cb) {
+    raw_trace.insert(raw_trace.end(), cb.data, cb.data + cb.size);
+    std::unique_lock<std::mutex> lock(mutex);
+    all_read = !cb.has_more;
+    if (all_read)
+      cv.notify_one();
+  });
+
+  {
+    std::unique_lock<std::mutex> lock(mutex);
+    cv.wait(lock, [&all_read] { return all_read; });
+  }
+  return raw_trace;
+}
+
+TracingSession::GetTraceStatsCallbackArgs
+TracingSession::GetTraceStatsBlocking() {
+  std::mutex mutex;
+  std::condition_variable cv;
+  GetTraceStatsCallbackArgs result;
+  bool stats_read = false;
+
+  GetTraceStats(
+      [&mutex, &result, &stats_read, &cv](GetTraceStatsCallbackArgs args) {
+        result = std::move(args);
+        std::unique_lock<std::mutex> lock(mutex);
+        stats_read = true;
+        cv.notify_one();
+      });
+
+  {
+    std::unique_lock<std::mutex> lock(mutex);
+    cv.wait(lock, [&stats_read] { return stats_read; });
+  }
+  return result;
+}
+
+TracingSession::QueryServiceStateCallbackArgs
+TracingSession::QueryServiceStateBlocking() {
+  std::mutex mutex;
+  std::condition_variable cv;
+  QueryServiceStateCallbackArgs result;
+  bool status_read = false;
+
+  QueryServiceState(
+      [&mutex, &result, &status_read, &cv](QueryServiceStateCallbackArgs args) {
+        result = std::move(args);
+        std::unique_lock<std::mutex> lock(mutex);
+        status_read = true;
+        cv.notify_one();
+      });
+
+  {
+    std::unique_lock<std::mutex> lock(mutex);
+    cv.wait(lock, [&status_read] { return status_read; });
+  }
+  return result;
+}
+
+StartupTracingSession::~StartupTracingSession() = default;
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/tracing_policy.cc
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/tracing_policy.h"
+
+namespace perfetto {
+
+TracingPolicy::~TracingPolicy() = default;
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/track.cc
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/track.h"
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_splitter.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/uuid.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_data_source.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_internal.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/counter_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/process_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/process_descriptor.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/thread_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/thread_descriptor.pbzero.h"
+
+namespace perfetto {
+
+// static
+uint64_t Track::process_uuid;
+
+protos::gen::TrackDescriptor Track::Serialize() const {
+  protos::gen::TrackDescriptor desc;
+  desc.set_uuid(uuid);
+  if (parent_uuid)
+    desc.set_parent_uuid(parent_uuid);
+  return desc;
+}
+
+void Track::Serialize(protos::pbzero::TrackDescriptor* desc) const {
+  auto bytes = Serialize().SerializeAsString();
+  desc->AppendRawProtoBytes(bytes.data(), bytes.size());
+}
+
+protos::gen::TrackDescriptor ProcessTrack::Serialize() const {
+  auto desc = Track::Serialize();
+  auto pd = desc.mutable_process();
+  pd->set_pid(static_cast<int32_t>(pid));
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  std::string cmdline;
+  if (base::ReadFile("/proc/self/cmdline", &cmdline)) {
+    // Since cmdline is a zero-terminated list of arguments, this ends up
+    // writing just the first element, i.e., the process name, into the process
+    // name field.
+    pd->set_process_name(cmdline.c_str());
+    base::StringSplitter splitter(std::move(cmdline), '\0');
+    while (splitter.Next()) {
+      pd->add_cmdline(
+          std::string(splitter.cur_token(), splitter.cur_token_size()));
+    }
+  }
+  // TODO(skyostil): Record command line on Windows and Mac.
+#endif
+  return desc;
+}
+
+void ProcessTrack::Serialize(protos::pbzero::TrackDescriptor* desc) const {
+  auto bytes = Serialize().SerializeAsString();
+  desc->AppendRawProtoBytes(bytes.data(), bytes.size());
+}
+
+protos::gen::TrackDescriptor ThreadTrack::Serialize() const {
+  auto desc = Track::Serialize();
+  auto td = desc.mutable_thread();
+  td->set_pid(static_cast<int32_t>(pid));
+  td->set_tid(static_cast<int32_t>(tid));
+  if (disallow_merging_with_system_tracks) {
+    desc.set_disallow_merging_with_system_tracks(true);
+  }
+  std::string thread_name;
+  if (base::GetThreadName(thread_name))
+    td->set_thread_name(thread_name);
+  return desc;
+}
+
+// static
+ThreadTrack ThreadTrack::Current() {
+  return ThreadTrack(
+      internal::TracingMuxer::Get()->GetCurrentThreadId(),
+      internal::TrackEventInternal::GetDisallowMergingWithSystemTracks());
+}
+
+// static
+ThreadTrack ThreadTrack::ForThread(base::PlatformThreadId tid_) {
+  return ThreadTrack(
+      tid_, internal::TrackEventInternal::GetDisallowMergingWithSystemTracks());
+}
+
+void ThreadTrack::Serialize(protos::pbzero::TrackDescriptor* desc) const {
+  auto bytes = Serialize().SerializeAsString();
+  desc->AppendRawProtoBytes(bytes.data(), bytes.size());
+}
+
+protos::gen::TrackDescriptor CounterTrack::Serialize() const {
+  auto desc = Track::Serialize();
+  desc.set_name(name_);
+  auto* counter = desc.mutable_counter();
+  if (category_)
+    counter->add_categories(category_);
+  if (unit_ != perfetto::protos::pbzero::CounterDescriptor::UNIT_UNSPECIFIED)
+    counter->set_unit(static_cast<protos::gen::CounterDescriptor_Unit>(unit_));
+  {
+    // if |type| is set, we don't want to emit |unit_name|. Trace processor
+    // infers the track name from the type in that case.
+    if (type_ !=
+        perfetto::protos::gen::CounterDescriptor::COUNTER_UNSPECIFIED) {
+      counter->set_type(type_);
+    } else if (unit_name_) {
+      counter->set_unit_name(unit_name_);
+    }
+  }
+  if (unit_multiplier_ != 1)
+    counter->set_unit_multiplier(unit_multiplier_);
+  if (is_incremental_)
+    counter->set_is_incremental(is_incremental_);
+  return desc;
+}
+
+void CounterTrack::Serialize(protos::pbzero::TrackDescriptor* desc) const {
+  auto bytes = Serialize().SerializeAsString();
+  desc->AppendRawProtoBytes(bytes.data(), bytes.size());
+}
+
+namespace internal {
+namespace {
+
+uint64_t GetProcessStartTime() {
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  std::string stat;
+  if (!base::ReadFile("/proc/self/stat", &stat))
+    return 0u;
+  // The stat file is a single line split into space-separated fields as "pid
+  // (comm) state ppid ...". However because the command name can contain any
+  // characters (including parentheses and spaces), we need to skip past it
+  // before parsing the rest of the fields. To do that, we look for the last
+  // instance of ") " (parentheses followed by space) and parse forward from
+  // that point.
+  size_t comm_end = stat.rfind(") ");
+  if (comm_end == std::string::npos)
+    return 0u;
+  stat = stat.substr(comm_end + strlen(") "));
+  base::StringSplitter splitter(stat, ' ');
+  for (size_t skip = 0; skip < 20; skip++) {
+    if (!splitter.Next())
+      return 0u;
+  }
+  return base::CStringToUInt64(splitter.cur_token()).value_or(0u);
+#else
+  return 0;
+#endif  // !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+}
+
+}  // namespace
+
+// static
+TrackRegistry* TrackRegistry::instance_;
+
+TrackRegistry::TrackRegistry() = default;
+TrackRegistry::~TrackRegistry() = default;
+
+// static
+void TrackRegistry::InitializeInstance() {
+  if (instance_)
+    return;
+  instance_ = new TrackRegistry();
+  Track::process_uuid = ComputeProcessUuid();
+}
+
+// static
+uint64_t TrackRegistry::ComputeProcessUuid() {
+  // Use the process start time + pid as the unique identifier for this process.
+  // This ensures that if there are two independent copies of the Perfetto SDK
+  // in the same process (e.g., one in the app and another in a system
+  // framework), events emitted by each will be consistently interleaved on
+  // common thread and process tracks.
+  if (uint64_t start_time = GetProcessStartTime()) {
+    base::Hasher hash;
+    hash.Update(start_time);
+    hash.Update(Platform::GetCurrentProcessId());
+    return hash.digest();
+  }
+  // Fall back to a randomly generated identifier.
+  static uint64_t random_once = static_cast<uint64_t>(base::Uuidv4().lsb());
+  return random_once;
+}
+
+void TrackRegistry::ResetForTesting() {
+  instance_->tracks_.clear();
+}
+
+void TrackRegistry::UpdateTrack(Track track,
+                                const std::string& serialized_desc) {
+  std::lock_guard<std::mutex> lock(mutex_);
+  tracks_[track.uuid] = std::move(serialized_desc);
+}
+
+void TrackRegistry::UpdateTrackImpl(
+    Track track,
+    std::function<void(protos::pbzero::TrackDescriptor*)> fill_function) {
+  constexpr size_t kInitialSliceSize = 32;
+  constexpr size_t kMaximumSliceSize = 4096;
+  protozero::HeapBuffered<protos::pbzero::TrackDescriptor> new_descriptor(
+      kInitialSliceSize, kMaximumSliceSize);
+  fill_function(new_descriptor.get());
+  auto serialized_desc = new_descriptor.SerializeAsString();
+  UpdateTrack(track, serialized_desc);
+}
+
+void TrackRegistry::EraseTrack(Track track) {
+  std::lock_guard<std::mutex> lock(mutex_);
+  tracks_.erase(track.uuid);
+}
+
+// static
+void TrackRegistry::WriteTrackDescriptor(
+    const SerializedTrackDescriptor& desc,
+    protozero::MessageHandle<protos::pbzero::TracePacket> packet) {
+  packet->AppendString(
+      perfetto::protos::pbzero::TracePacket::kTrackDescriptorFieldNumber, desc);
+}
+
+}  // namespace internal
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/track_event_category_registry.cc
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/track_event_category_registry.h"
+
+namespace perfetto {
+
+// static
+Category Category::FromDynamicCategory(const char* name) {
+  if (GetNthNameSize(1, name, name)) {
+    Category group(Group(name));
+    PERFETTO_DCHECK(group.name);
+    return group;
+  }
+  Category category(name);
+  PERFETTO_DCHECK(category.name);
+  return category;
+}
+
+Category Category::FromDynamicCategory(
+    const DynamicCategory& dynamic_category) {
+  return FromDynamicCategory(dynamic_category.name.c_str());
+}
+
+namespace internal {
+
+perfetto::DynamicCategory NullCategory(const perfetto::DynamicCategory&) {
+  return perfetto::DynamicCategory{};
+}
+
+void TrackEventCategoryRegistry::EnableCategoryForInstance(
+    size_t category_index,
+    uint32_t instance_index) const {
+  PERFETTO_DCHECK(instance_index < kMaxDataSourceInstances);
+  PERFETTO_DCHECK(category_index < category_count_);
+  // Matches the acquire_load in DataSource::Trace().
+  state_storage_[category_index].fetch_or(
+      static_cast<uint8_t>(1u << instance_index), std::memory_order_release);
+}
+
+void TrackEventCategoryRegistry::DisableCategoryForInstance(
+    size_t category_index,
+    uint32_t instance_index) const {
+  PERFETTO_DCHECK(instance_index < kMaxDataSourceInstances);
+  PERFETTO_DCHECK(category_index < category_count_);
+  // Matches the acquire_load in DataSource::Trace().
+  state_storage_[category_index].fetch_and(
+      static_cast<uint8_t>(~(1u << instance_index)), std::memory_order_release);
+}
+
+}  // namespace internal
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/track_event_legacy.cc
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/track_event_legacy.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
+
+// gen_amalgamated expanded: #include "perfetto/tracing/track.h"
+
+namespace perfetto {
+namespace legacy {
+
+template <>
+ThreadTrack ConvertThreadId(const PerfettoLegacyCurrentThreadId&) {
+  // Because of the short-circuit in PERFETTO_INTERNAL_LEGACY_EVENT, we should
+  // never get here.
+  PERFETTO_DCHECK(false);
+  return ThreadTrack::Current();
+}
+
+}  // namespace legacy
+
+namespace internal {
+
+void LegacyTraceId::Write(protos::pbzero::TrackEvent::LegacyEvent* event,
+                          uint32_t event_flags) const {
+  // Legacy flow events always use bind_id.
+  if (event_flags &
+      (legacy::kTraceEventFlagFlowOut | legacy::kTraceEventFlagFlowIn)) {
+    // Flow bind_ids don't have scopes, so we need to mangle in-process ones to
+    // avoid collisions.
+    if (id_flags_ & legacy::kTraceEventFlagHasLocalId) {
+      event->set_bind_id(raw_id_ ^ ProcessTrack::Current().uuid);
+    } else {
+      event->set_bind_id(raw_id_);
+    }
+    return;
+  }
+
+  uint32_t scope_flags = id_flags_ & (legacy::kTraceEventFlagHasId |
+                                      legacy::kTraceEventFlagHasLocalId |
+                                      legacy::kTraceEventFlagHasGlobalId);
+  uint64_t id = raw_id_;
+  if (scope_ && scope_flags != legacy::kTraceEventFlagHasGlobalId) {
+    id = base::Hasher::Combine(id, scope_);
+  }
+
+  switch (scope_flags) {
+    case legacy::kTraceEventFlagHasId:
+      event->set_unscoped_id(id);
+      break;
+    case legacy::kTraceEventFlagHasLocalId:
+      event->set_local_id(id);
+      break;
+    case legacy::kTraceEventFlagHasGlobalId:
+      event->set_global_id(id);
+      break;
+  }
+  if (scope_)
+    event->set_id_scope(scope_);
+}
+
+}  // namespace internal
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/track_event_state_tracker.cc
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/track_event_state_tracker.h"
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_internal.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/common/interceptor_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/clock_snapshot.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet_defaults.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/process_descriptor.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/thread_descriptor.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_descriptor.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_event.pbzero.h"
+
+namespace perfetto {
+
+using internal::TrackEventIncrementalState;
+
+TrackEventStateTracker::~TrackEventStateTracker() = default;
+TrackEventStateTracker::Delegate::~Delegate() = default;
+
+// static
+void TrackEventStateTracker::ProcessTracePacket(
+    Delegate& delegate,
+    SequenceState& sequence_state,
+    const protos::pbzero::TracePacket_Decoder& packet) {
+  UpdateIncrementalState(delegate, sequence_state, packet);
+
+  if (!packet.has_track_event())
+    return;
+  perfetto::protos::pbzero::TrackEvent::Decoder track_event(
+      packet.track_event());
+
+  auto clock_id = packet.timestamp_clock_id();
+  if (!packet.has_timestamp_clock_id())
+    clock_id = sequence_state.default_clock_id;
+  uint64_t timestamp = packet.timestamp();
+  // TODO(mohitms): Incorporate unit multiplier as well.
+  if (clock_id == internal::TrackEventIncrementalState::kClockIdIncremental) {
+    timestamp += sequence_state.most_recent_absolute_time_ns;
+    sequence_state.most_recent_absolute_time_ns = timestamp;
+  }
+
+  Track* track = &sequence_state.track;
+  if (track_event.has_track_uuid()) {
+    auto* session_state = delegate.GetSessionState();
+    if (!session_state)
+      return;  // Tracing must have ended.
+    track = &session_state->tracks[track_event.track_uuid()];
+  }
+
+  // We only log the first category of each event.
+  protozero::ConstChars category{};
+  uint64_t category_iid = 0;
+  if (auto iid_it = track_event.category_iids()) {
+    category_iid = *iid_it;
+    category.data = sequence_state.event_categories[category_iid].data();
+    category.size = sequence_state.event_categories[category_iid].size();
+  } else if (auto cat_it = track_event.categories()) {
+    category.data = reinterpret_cast<const char*>(cat_it->data());
+    category.size = cat_it->size();
+  }
+
+  protozero::ConstChars name{};
+  uint64_t name_iid = track_event.name_iid();
+  uint64_t name_hash = 0;
+  uint64_t duration = 0;
+  if (name_iid) {
+    name.data = sequence_state.event_names[name_iid].data();
+    name.size = sequence_state.event_names[name_iid].size();
+  } else if (track_event.has_name()) {
+    name.data = track_event.name().data;
+    name.size = track_event.name().size;
+  }
+
+  if (name.data) {
+    base::Hasher hash;
+    hash.Update(name.data, name.size);
+    name_hash = hash.digest();
+  }
+
+  size_t depth = track->stack.size();
+  switch (track_event.type()) {
+    case protos::pbzero::TrackEvent::TYPE_SLICE_BEGIN: {
+      StackFrame frame;
+      frame.timestamp = timestamp;
+      frame.name_hash = name_hash;
+      if (track_event.has_track_uuid()) {
+        frame.name = name.ToStdString();
+        frame.category = category.ToStdString();
+      } else {
+        frame.name_iid = name_iid;
+        frame.category_iid = category_iid;
+      }
+      track->stack.push_back(std::move(frame));
+      break;
+    }
+    case protos::pbzero::TrackEvent::TYPE_SLICE_END:
+      if (!track->stack.empty()) {
+        const auto& prev_frame = track->stack.back();
+        if (prev_frame.name_iid) {
+          name.data = sequence_state.event_names[prev_frame.name_iid].data();
+          name.size = sequence_state.event_names[prev_frame.name_iid].size();
+        } else {
+          name.data = prev_frame.name.data();
+          name.size = prev_frame.name.size();
+        }
+        name_hash = prev_frame.name_hash;
+        if (prev_frame.category_iid) {
+          category.data =
+              sequence_state.event_categories[prev_frame.category_iid].data();
+          category.size =
+              sequence_state.event_categories[prev_frame.category_iid].size();
+        } else {
+          category.data = prev_frame.category.data();
+          category.size = prev_frame.category.size();
+        }
+        duration = timestamp - prev_frame.timestamp;
+        depth--;
+      }
+      break;
+    case protos::pbzero::TrackEvent::TYPE_INSTANT:
+      break;
+    case protos::pbzero::TrackEvent::TYPE_COUNTER:
+    case protos::pbzero::TrackEvent::TYPE_UNSPECIFIED:
+      // TODO(skyostil): Support counters.
+      return;
+  }
+
+  ParsedTrackEvent parsed_event{track_event};
+  parsed_event.timestamp_ns = timestamp;
+  parsed_event.duration_ns = duration;
+  parsed_event.stack_depth = depth;
+  parsed_event.category = category;
+  parsed_event.name = name;
+  parsed_event.name_hash = name_hash;
+  delegate.OnTrackEvent(*track, parsed_event);
+
+  if (track_event.type() == protos::pbzero::TrackEvent::TYPE_SLICE_END &&
+      !track->stack.empty()) {
+    track->stack.pop_back();
+  }
+}
+
+// static
+void TrackEventStateTracker::UpdateIncrementalState(
+    Delegate& delegate,
+    SequenceState& sequence_state,
+    const protos::pbzero::TracePacket_Decoder& packet) {
+#if PERFETTO_DCHECK_IS_ON()
+  if (!sequence_state.sequence_id) {
+    sequence_state.sequence_id = packet.trusted_packet_sequence_id();
+  } else {
+    PERFETTO_DCHECK(sequence_state.sequence_id ==
+                    packet.trusted_packet_sequence_id());
+  }
+#endif
+
+  perfetto::protos::pbzero::ClockSnapshot::Decoder snapshot(
+      packet.clock_snapshot());
+  for (auto it = snapshot.clocks(); it; ++it) {
+    perfetto::protos::pbzero::ClockSnapshot::Clock::Decoder clock(*it);
+    // TODO(mohitms) : Handle the incremental clock other than default one.
+    if (clock.is_incremental() &&
+        clock.clock_id() ==
+            internal::TrackEventIncrementalState::kClockIdIncremental) {
+      sequence_state.most_recent_absolute_time_ns =
+          clock.timestamp() * clock.unit_multiplier_ns();
+      break;
+    }
+  }
+
+  if (packet.sequence_flags() &
+      perfetto::protos::pbzero::TracePacket::SEQ_INCREMENTAL_STATE_CLEARED) {
+    // Convert any existing event names and categories on the stack to
+    // non-interned strings so we can look up their names even after the
+    // incremental state is gone.
+    for (auto& frame : sequence_state.track.stack) {
+      if (frame.name_iid) {
+        frame.name = sequence_state.event_names[frame.name_iid];
+        frame.name_iid = 0u;
+      }
+      if (frame.category_iid) {
+        frame.category = sequence_state.event_categories[frame.category_iid];
+        frame.category_iid = 0u;
+      }
+    }
+    sequence_state.event_names.clear();
+    sequence_state.event_categories.clear();
+    sequence_state.debug_annotation_names.clear();
+    sequence_state.track.uuid = 0u;
+    sequence_state.track.index = 0u;
+  }
+  if (packet.has_interned_data()) {
+    perfetto::protos::pbzero::InternedData::Decoder interned_data(
+        packet.interned_data());
+    for (auto it = interned_data.event_names(); it; it++) {
+      perfetto::protos::pbzero::EventName::Decoder entry(*it);
+      sequence_state.event_names[entry.iid()] = entry.name().ToStdString();
+    }
+    for (auto it = interned_data.event_categories(); it; it++) {
+      perfetto::protos::pbzero::EventCategory::Decoder entry(*it);
+      sequence_state.event_categories[entry.iid()] = entry.name().ToStdString();
+    }
+    for (auto it = interned_data.debug_annotation_names(); it; it++) {
+      perfetto::protos::pbzero::DebugAnnotationName::Decoder entry(*it);
+      sequence_state.debug_annotation_names[entry.iid()] =
+          entry.name().ToStdString();
+    }
+  }
+  if (packet.has_trace_packet_defaults()) {
+    perfetto::protos::pbzero::TracePacketDefaults::Decoder defaults(
+        packet.trace_packet_defaults());
+    if (defaults.has_track_event_defaults()) {
+      perfetto::protos::pbzero::TrackEventDefaults::Decoder
+          track_event_defaults(defaults.track_event_defaults());
+      sequence_state.track.uuid = track_event_defaults.track_uuid();
+      if (defaults.has_timestamp_clock_id())
+        sequence_state.default_clock_id = defaults.timestamp_clock_id();
+    }
+  }
+  if (packet.has_track_descriptor()) {
+    perfetto::protos::pbzero::TrackDescriptor::Decoder track_descriptor(
+        packet.track_descriptor());
+    auto* session_state = delegate.GetSessionState();
+    auto& track = session_state->tracks[track_descriptor.uuid()];
+    if (!track.index)
+      track.index = static_cast<uint32_t>(session_state->tracks.size() + 1);
+    track.uuid = track_descriptor.uuid();
+
+    track.name = track_descriptor.name().ToStdString();
+    track.pid = 0;
+    track.tid = 0;
+    if (track_descriptor.has_process()) {
+      perfetto::protos::pbzero::ProcessDescriptor::Decoder process(
+          track_descriptor.process());
+      track.pid = process.pid();
+      if (track.name.empty())
+        track.name = process.process_name().ToStdString();
+    } else if (track_descriptor.has_thread()) {
+      perfetto::protos::pbzero::ThreadDescriptor::Decoder thread(
+          track_descriptor.thread());
+      track.pid = thread.pid();
+      track.tid = thread.tid();
+      if (track.name.empty())
+        track.name = thread.thread_name().ToStdString();
+    }
+    delegate.OnTrackUpdated(track);
+
+    // Mirror properties to the default track of the sequence. Note that
+    // this does not catch updates to the default track written through other
+    // sequences.
+    if (track.uuid == sequence_state.track.uuid) {
+      sequence_state.track.index = track.index;
+      sequence_state.track.name = track.name;
+      sequence_state.track.pid = track.pid;
+      sequence_state.track.tid = track.tid;
+      sequence_state.track.user_data = track.user_data;
+    }
+  }
+}
+
+TrackEventStateTracker::ParsedTrackEvent::ParsedTrackEvent(
+    const perfetto::protos::pbzero::TrackEvent::Decoder& track_event_)
+    : track_event(track_event_) {}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/virtual_destructors.cc
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_tls.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/tracing.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/tracing_backend.h"
+
+// This translation unit contains the definitions for the destructor of pure
+// virtual interfaces for the src/public:public target. The alternative would be
+// introducing a one-liner .cc file for each pure virtual interface, which is
+// overkill. This is for compliance with -Wweak-vtables.
+
+namespace perfetto {
+namespace internal {
+
+TracingTLS::~TracingTLS() {
+  // Avoid entering trace points while the thread is being torn down.
+  // This is the problem: when a thread exits, the at-thread-exit destroys the
+  // TracingTLS. As part of that the various TraceWriter for the active data
+  // sources are destroyd. A TraceWriter dtor will issue a PostTask on the IPC
+  // thread to issue a final flush and unregister its ID with the service.
+  // The PostTask, in chromium, might have a trace event that will try to
+  // re-enter the tracing system.
+  // We fix this by resetting the TLS key to the TracingTLS object that is
+  // being destroyed in the platform impl (platform_posix.cc,
+  // platform_windows.cc, chromium's platform.cc). We carefully rely on the fact
+  // that all the tracing path that will be invoked during thread exit will
+  // early out if |is_in_trace_point| == true and will not depend on the other
+  // TLS state that has been destroyed.
+  is_in_trace_point = true;
+}
+
+}  // namespace internal
+
+TracingProducerBackend::~TracingProducerBackend() = default;
+TracingConsumerBackend::~TracingConsumerBackend() = default;
+TracingBackend::~TracingBackend() = default;
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/android_stats/statsd_logging_helper.cc
+// gen_amalgamated begin header: src/android_stats/statsd_logging_helper.h
+// gen_amalgamated begin header: src/android_stats/perfetto_atoms.h
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_ANDROID_STATS_PERFETTO_ATOMS_H_
+#define SRC_ANDROID_STATS_PERFETTO_ATOMS_H_
+
+namespace perfetto {
+
+// This must match the values of the PerfettoUploadEvent enum in:
+// frameworks/proto_logging/stats/atoms.proto
+enum class PerfettoStatsdAtom {
+  kUndefined = 0,
+
+  // Checkpoints inside perfetto_cmd before tracing is finished.
+  kTraceBegin = 1,
+  kBackgroundTraceBegin = 2,
+  kOnConnect = 3,
+
+  // Guardrails inside perfetto_cmd before tracing is finished.
+  kOnTimeout = 16,
+  kCmdUserBuildTracingNotAllowed = 43,
+
+  // Checkpoints inside traced.
+  kTracedEnableTracing = 37,
+  kTracedStartTracing = 38,
+  kTracedDisableTracing = 39,
+  kTracedNotifyTracingDisabled = 40,
+
+  // Trigger checkpoints inside traced.
+  // These atoms are special because, along with the UUID,
+  // they log the trigger name.
+  kTracedTriggerStartTracing = 41,
+  kTracedTriggerStopTracing = 42,
+  kTracedTriggerCloneSnapshot = 53,
+
+  // Guardrails inside traced.
+  kTracedEnableTracingExistingTraceSession = 18,
+  kTracedEnableTracingTooLongTrace = 19,
+  kTracedEnableTracingInvalidTriggerTimeout = 20,
+  kTracedEnableTracingDurationWithTrigger = 21,
+  kTracedEnableTracingStopTracingWriteIntoFile = 22,
+  kTracedEnableTracingDuplicateTriggerName = 23,
+  kTracedEnableTracingInvalidDeferredStart = 24,
+  kTracedEnableTracingInvalidBufferSize = 25,
+  kTracedEnableTracingBufferSizeTooLarge = 26,
+  kTracedEnableTracingTooManyBuffers = 27,
+  kTracedEnableTracingDuplicateSessionName = 28,
+  kTracedEnableTracingSessionNameTooRecent = 29,
+  kTracedEnableTracingTooManySessionsForUid = 30,
+  kTracedEnableTracingTooManyConcurrentSessions = 31,
+  kTracedEnableTracingInvalidFdOutputFile = 32,
+  kTracedEnableTracingFailedToCreateFile = 33,
+  kTracedEnableTracingOom = 34,
+  kTracedEnableTracingUnknown = 35,
+  kTracedStartTracingInvalidSessionState = 36,
+  kTracedEnableTracingInvalidFilter = 47,
+  kTracedEnableTracingOobTargetBuffer = 48,
+  kTracedEnableTracingInvalidTriggerMode = 52,
+  kTracedEnableTracingInvalidBrFilename = 54,
+
+  // Checkpoints inside perfetto_cmd after tracing has finished.
+  kOnTracingDisabled = 4,
+  kFinalizeTraceAndExit = 11,
+  kCmdFwReportBegin = 49,
+  // Will be removed once incidentd is no longer used.
+  kUploadIncidentBegin = 8,
+  kNotUploadingEmptyTrace = 17,
+
+  // Guardrails inside perfetto_cmd after tracing has finished.
+  kCmdFwReportEmptyTrace = 50,
+  // Will be removed once incidentd is no longer used.
+  kUploadIncidentFailure = 10,
+
+  // "Successful" terminal states inside perfetto_cmd.
+  kCmdFwReportHandoff = 51,
+
+  // Deprecated as "success" is misleading; it simply means we were
+  // able to communicate with incidentd. Will be removed once
+  // incidentd is no longer used.
+  kUploadIncidentSuccess = 9,
+
+  // Contained trigger begin/success/failure. Replaced by
+  // |PerfettoTriggerAtom| to allow aggregation using a count metric
+  // and reduce spam.
+  // reserved 12, 13, 14;
+
+  // Contained that a guardrail in perfetto_cmd was hit. Replaced with
+  // kCmd* guardrails.
+  // reserved 15;
+
+  // Contained status of Dropbox uploads. Removed as Perfetto no
+  // longer supports uploading traces using Dropbox.
+  // reserved 5, 6, 7;
+
+  // Contained status of guardrail state initalization and upload limit in
+  // perfetto_cmd. Removed as perfetto no longer manages stateful guardrails
+  // reserved 44, 45, 46;
+};
+
+// This must match the values of the PerfettoTrigger::TriggerType enum in:
+// frameworks/proto_logging/stats/atoms.proto
+enum PerfettoTriggerAtom {
+  kUndefined = 0,
+
+  kCmdTrigger = 1,
+  kCmdTriggerFail = 2,
+
+  kTriggerPerfettoTrigger = 3,
+  kTriggerPerfettoTriggerFail = 4,
+
+  kTracedLimitProbability = 5,
+  kTracedLimitMaxPer24h = 6,
+
+  kProbesProducerTrigger = 7,
+  kProbesProducerTriggerFail = 8,
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_ANDROID_STATS_PERFETTO_ATOMS_H_
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_ANDROID_STATS_STATSD_LOGGING_HELPER_H_
+#define SRC_ANDROID_STATS_STATSD_LOGGING_HELPER_H_
+
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+// gen_amalgamated expanded: #include "src/android_stats/perfetto_atoms.h"
+
+namespace perfetto {
+namespace android_stats {
+
+// Functions in this file are only active on built in the Android
+// tree. On other platforms (including Android standalone and Chromium
+// on Android) these functions are a noop.
+
+// Logs the upload event to statsd if built in the Android tree.
+void MaybeLogUploadEvent(PerfettoStatsdAtom atom,
+                         int64_t uuid_lsb,
+                         int64_t uuid_msb,
+                         const std::string& trigger_name = "");
+
+// Logs the trigger events to statsd if built in the Android tree.
+void MaybeLogTriggerEvent(PerfettoTriggerAtom atom, const std::string& trigger);
+
+// Logs the trigger events to statsd if built in the Android tree.
+void MaybeLogTriggerEvents(PerfettoTriggerAtom atom,
+                           const std::vector<std::string>& triggers);
+
+}  // namespace android_stats
+}  // namespace perfetto
+
+#endif  // SRC_ANDROID_STATS_STATSD_LOGGING_HELPER_H_
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "src/android_stats/statsd_logging_helper.h"
+
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
+    PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
+// gen_amalgamated expanded: #include "src/android_internal/lazy_library_loader.h"  // nogncheck
+// gen_amalgamated expanded: #include "src/android_internal/statsd_logging.h"       // nogncheck
+#endif
+
+namespace perfetto {
+namespace android_stats {
+
+// Make sure we don't accidentally log on non-Android tree build. Note that even
+// removing this ifdef still doesn't make uploads work on OS_ANDROID.
+// PERFETTO_LAZY_LOAD will return a nullptr on non-Android and non-in-tree
+// builds as libperfetto_android_internal will not be available.
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
+    PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
+
+void MaybeLogUploadEvent(PerfettoStatsdAtom atom,
+                         int64_t uuid_lsb,
+                         int64_t uuid_msb,
+                         const std::string& trigger_name) {
+  PERFETTO_LAZY_LOAD(android_internal::StatsdLogUploadEvent, log_event_fn);
+  if (log_event_fn) {
+    log_event_fn(atom, uuid_lsb, uuid_msb, trigger_name.c_str());
+  }
+}
+
+void MaybeLogTriggerEvent(PerfettoTriggerAtom atom,
+                          const std::string& trigger_name) {
+  PERFETTO_LAZY_LOAD(android_internal::StatsdLogTriggerEvent, log_event_fn);
+  if (log_event_fn) {
+    log_event_fn(atom, trigger_name.c_str());
+  }
+}
+
+void MaybeLogTriggerEvents(PerfettoTriggerAtom atom,
+                           const std::vector<std::string>& triggers) {
+  PERFETTO_LAZY_LOAD(android_internal::StatsdLogTriggerEvent, log_event_fn);
+  if (log_event_fn) {
+    for (const std::string& trigger_name : triggers) {
+      log_event_fn(atom, trigger_name.c_str());
+    }
+  }
+}
+
+#else
+void MaybeLogUploadEvent(PerfettoStatsdAtom,
+                         int64_t,
+                         int64_t,
+                         const std::string&) {}
+void MaybeLogTriggerEvent(PerfettoTriggerAtom, const std::string&) {}
+void MaybeLogTriggerEvents(PerfettoTriggerAtom,
+                           const std::vector<std::string>&) {}
+#endif
+
+}  // namespace android_stats
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/version.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/version.h
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_VERSION_H_
+#define INCLUDE_PERFETTO_EXT_BASE_VERSION_H_
+
+namespace perfetto {
+namespace base {
+
+// The returned pointer is a static string and safe to pass around.
+// Returns a human readable string currently of the approximate form:
+// Perfetto v42.1-deadbeef0 (deadbeef03c641e4b4ea9cf38e9b5696670175a9)
+// However you should not depend on the format of this string.
+// It maybe not be possible to determine the version. In which case the
+// string will be of the approximate form:
+// Perfetto v0.0 (unknown)
+const char* GetVersionString();
+
+// The returned pointer is a static string and safe to pass around.
+// Returns the short code used to identity the version:
+// v42.1-deadbeef0
+// It maybe not be possible to determine the version. In which case
+// this returns nullptr.
+// This can be compared with equality to other
+// version codes to detect matched builds (for example to see if
+// trace_processor_shell and the UI were built at the same revision)
+// but you should not attempt to parse it as the format may change
+// without warning.
+const char* GetVersionCode();
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_VERSION_H_
+// gen_amalgamated begin header: gen/perfetto_version.gen.h
+// Generated by write_version_header.py
+
+#ifndef GEN_PERFETTO_VERSION_GEN_H_
+#define GEN_PERFETTO_VERSION_GEN_H_
+
+#define PERFETTO_VERSION_STRING() "v45.0-3252c170d"
+#define PERFETTO_VERSION_SCM_REVISION() "3252c170da369d935b34d93a9f5906e6ab890cdf"
+
+#endif  // GEN_PERFETTO_VERSION_GEN_H_
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/version.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+#include <stdio.h>
+
+#if PERFETTO_BUILDFLAG(PERFETTO_VERSION_GEN)
+// gen_amalgamated expanded: #include "perfetto_version.gen.h"
+#else
+#define PERFETTO_VERSION_STRING() nullptr
+#define PERFETTO_VERSION_SCM_REVISION() "unknown"
+#endif
+
+namespace perfetto {
+namespace base {
+
+const char* GetVersionCode() {
+  return PERFETTO_VERSION_STRING();
+}
+
+const char* GetVersionString() {
+  static const char* version_str = [] {
+    static constexpr size_t kMaxLen = 256;
+    const char* version_code = PERFETTO_VERSION_STRING();
+    if (version_code == nullptr) {
+      version_code = "v0.0";
+    }
+    char* version = new char[kMaxLen + 1];
+    snprintf(version, kMaxLen, "Perfetto %s (%s)", version_code,
+             PERFETTO_VERSION_SCM_REVISION());
+    return version;
+  }();
+  return version_str;
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/protozero/filtering/filter_bytecode_parser.cc
+// gen_amalgamated begin header: src/protozero/filtering/filter_bytecode_parser.h
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_PROTOZERO_FILTERING_FILTER_BYTECODE_PARSER_H_
+#define SRC_PROTOZERO_FILTERING_FILTER_BYTECODE_PARSER_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <optional>
+#include <vector>
+
+namespace protozero {
+
+// Loads the proto-encoded bytecode in memory and allows fast lookups for tuples
+// (msg_index, field_id) to tell if a given field should be allowed or not and,
+// in the case of nested fields, what is the next message index to recurse into.
+// This class does two things:
+// 1. Expands the array of varint from the proto into a vector<uint32_t>. This
+//    is to avoid performing varint decoding on every lookup, at the cost of
+//    some extra memory (2KB-4KB). Note that the expanded vector is not just a
+//    1:1 copy of the proto one (more below). This is to avoid O(Fields) linear
+//    lookup complexity.
+// 2. Creates an index of offsets to remember the start word for each message.
+//    This is so we can jump to O(1) to the N-th message when recursing into a
+//    nested fields, without having to scan and find the (N-1)-th END_OF_MESSAGE
+//    marker.
+// Overall lookups are O(1) for field ids < 128 (kDirectlyIndexLimit) and O(N),
+// with N being the number of allowed field ranges for other fields.
+// See comments around |word_| below for the structure of the word vector.
+class FilterBytecodeParser {
+ public:
+  // Result of a Query() operation
+  struct QueryResult {
+    bool allowed;  // Whether the field is allowed at all or no.
+
+    // If |allowed|==true && nested_msg_field() == true, this tells the message
+    // index of the nested field that should be used when recursing in the
+    // parser.
+    uint32_t nested_msg_index;
+
+    // If |allowed|==true, specifies if the field is of a simple type (varint,
+    // fixed32/64, string or byte).
+    bool simple_field() const { return nested_msg_index == kSimpleField; }
+
+    // If |allowed|==true, specifies if this field is a string field that needs
+    // to be filtered.
+    bool filter_string_field() const {
+      return nested_msg_index == kFilterStringField;
+    }
+
+    // If |allowed|==true, specifies if the field is a nested field that needs
+    // recursion. The caller is expected to use |nested_msg_index| for the next
+    // Query() calls.
+    bool nested_msg_field() const {
+      static_assert(kFilterStringField < kSimpleField,
+                    "kFilterStringField < kSimpleField");
+      return nested_msg_index < kFilterStringField;
+    }
+  };
+
+  // Loads a filter. The filter data consists of a sequence of varints which
+  // contains the filter opcodes and a final checksum.
+  bool Load(const void* filter_data, size_t len);
+
+  // Checks wheter a given field is allowed or not.
+  // msg_index = 0 is the index of the root message, where all queries should
+  // start from (typically perfetto.protos.Trace).
+  QueryResult Query(uint32_t msg_index, uint32_t field_id) const;
+
+  void Reset();
+  void set_suppress_logs_for_fuzzer(bool x) { suppress_logs_for_fuzzer_ = x; }
+
+ private:
+  static constexpr uint32_t kDirectlyIndexLimit = 128;
+  static constexpr uint32_t kAllowed = 1u << 31u;
+  static constexpr uint32_t kSimpleField = 0x7fffffff;
+  static constexpr uint32_t kFilterStringField = 0x7ffffffe;
+
+  bool LoadInternal(const uint8_t* filter_data, size_t len);
+
+  // The state of all fields for all messages is stored in one contiguous array.
+  // This is to avoid memory fragmentation and allocator overhead.
+  // We expect a high number of messages (hundreds), but each message is small.
+  // For each message we store two sets of uint32:
+  // 1. A set of "directly indexed" fields, for field ids < 128.
+  // 2. The remainder is a set of ranges.
+  // So each message descriptor consists of a sequence of words as follows:
+  //
+  // [0] -> how many directly indexed fields are stored next (up to 128)
+  //
+  // [1..N] -> One word per field id (See "field state" below).
+  //
+  // [N + 1] -> Start of field id range 1
+  // [N + 2] -> End of field id range 1 (exclusive, STL-style).
+  // [N + 3] -> Field state for fields in range 1 (below)
+  //
+  // [N + 4] -> Start of field id range 2
+  // [N + 5] -> End of field id range 2 (exclusive, STL-style).
+  // [N + 6] -> Field state for fields in range 2 (below)
+
+  // The "field state" word is as follows:
+  // Bit 31: 1 if the field is allowed, 0 if disallowed.
+  //         Only directly indexed fields can be 0 (it doesn't make sense to add
+  //         a range and then say "btw it's NOT allowed".. don't add it then.
+  //         0 is only used for filling gaps in the directly indexed bucket.
+  // Bits [30..0] (only when MSB == allowed):
+  //  0x7fffffff: The field is "simple" (varint, fixed32/64, string, bytes) and
+  //      can be directly passed through in output. No recursion is needed.
+  //  0x7ffffffe: The field is string field which needs to be filtered.
+  //  [0, 7ffffffd]: The field is a nested submessage. The value is the index
+  //     that must be passed as first argument to the next Query() calls.
+  //     Note that the message index is purely a monotonic counter in the
+  std::vector<uint32_t> words_;
+
+  // One entry for each message index stored in the filter plus a sentinel at
+  // the end. Maps each message index to the offset in |words_| where the
+  // Nth message start.
+  // message_offset_.size() - 2 == the max message id that can be parsed.
+  std::vector<uint32_t> message_offset_;
+
+  bool suppress_logs_for_fuzzer_ = false;
+};
+
+}  // namespace protozero
+
+#endif  // SRC_PROTOZERO_FILTERING_FILTER_BYTECODE_PARSER_H_
+// gen_amalgamated begin header: src/protozero/filtering/filter_bytecode_common.h
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_PROTOZERO_FILTERING_FILTER_BYTECODE_COMMON_H_
+#define SRC_PROTOZERO_FILTERING_FILTER_BYTECODE_COMMON_H_
+
+#include <stdint.h>
+
+namespace protozero {
+
+enum FilterOpcode : uint32_t {
+  // The immediate value is 0 in this case.
+  kFilterOpcode_EndOfMessage = 0,
+
+  // The immediate value is the id of the allowed field.
+  kFilterOpcode_SimpleField = 1,
+
+  // The immediate value is the start of the range. The next word (without
+  // any shifting) is the length of the range.
+  kFilterOpcode_SimpleFieldRange = 2,
+
+  // The immediate value is the id of the allowed field. The next word
+  // (without any shifting) is the index of the filter that should be used to
+  // recurse into the nested message.
+  kFilterOpcode_NestedField = 3,
+
+  // The imediate value is the id of the allowed field. The behaviour of this
+  // opcode is the same as kFilterOpcode_SimpleField, with the further semantic
+  // that the field is a string and needs to be processed using the string
+  // filtering fules.
+  kFilterOpcode_FilterString = 4,
+};
+
+}  // namespace protozero
+
+#endif  // SRC_PROTOZERO_FILTERING_FILTER_BYTECODE_COMMON_H_
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "src/protozero/filtering/filter_bytecode_parser.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+// gen_amalgamated expanded: #include "src/protozero/filtering/filter_bytecode_common.h"
+
+namespace protozero {
+
+void FilterBytecodeParser::Reset() {
+  bool suppress = suppress_logs_for_fuzzer_;
+  *this = FilterBytecodeParser();
+  suppress_logs_for_fuzzer_ = suppress;
+}
+
+bool FilterBytecodeParser::Load(const void* filter_data, size_t len) {
+  Reset();
+  bool res = LoadInternal(static_cast<const uint8_t*>(filter_data), len);
+  // If load fails, don't leave the parser in a half broken state.
+  if (!res)
+    Reset();
+  return res;
+}
+
+bool FilterBytecodeParser::LoadInternal(const uint8_t* bytecode_data,
+                                        size_t len) {
+  // First unpack the varints into a plain uint32 vector, so it's easy to
+  // iterate through them and look ahead.
+  std::vector<uint32_t> words;
+  bool packed_parse_err = false;
+  words.reserve(len);  // An overestimation, but avoids reallocations.
+  using BytecodeDecoder =
+      PackedRepeatedFieldIterator<proto_utils::ProtoWireType::kVarInt,
+                                  uint32_t>;
+  for (BytecodeDecoder it(bytecode_data, len, &packed_parse_err); it; ++it)
+    words.emplace_back(*it);
+
+  if (packed_parse_err || words.empty())
+    return false;
+
+  perfetto::base::Hasher hasher;
+  for (size_t i = 0; i < words.size() - 1; ++i)
+    hasher.Update(words[i]);
+
+  uint32_t expected_csum = static_cast<uint32_t>(hasher.digest());
+  if (expected_csum != words.back()) {
+    if (!suppress_logs_for_fuzzer_) {
+      PERFETTO_ELOG("Filter bytecode checksum failed. Expected: %x, actual: %x",
+                    expected_csum, words.back());
+    }
+    return false;
+  }
+
+  words.pop_back();  // Pop the checksum.
+
+  // Temporay storage for each message. Cleared on every END_OF_MESSAGE.
+  std::vector<uint32_t> direct_indexed_fields;
+  std::vector<uint32_t> ranges;
+  uint32_t max_msg_index = 0;
+
+  auto add_directly_indexed_field = [&](uint32_t field_id, uint32_t msg_id) {
+    PERFETTO_DCHECK(field_id > 0 && field_id < kDirectlyIndexLimit);
+    direct_indexed_fields.resize(std::max(direct_indexed_fields.size(),
+                                          static_cast<size_t>(field_id) + 1));
+    direct_indexed_fields[field_id] = kAllowed | msg_id;
+  };
+
+  auto add_range = [&](uint32_t id_start, uint32_t id_end, uint32_t msg_id) {
+    PERFETTO_DCHECK(id_end > id_start);
+    PERFETTO_DCHECK(id_start >= kDirectlyIndexLimit);
+    ranges.emplace_back(id_start);
+    ranges.emplace_back(id_end);
+    ranges.emplace_back(kAllowed | msg_id);
+  };
+
+  bool is_eom = true;
+  for (size_t i = 0; i < words.size(); ++i) {
+    const uint32_t word = words[i];
+    const bool has_next_word = i < words.size() - 1;
+    const uint32_t opcode = word & 0x7u;
+    const uint32_t field_id = word >> 3;
+
+    is_eom = opcode == kFilterOpcode_EndOfMessage;
+    if (field_id == 0 && opcode != kFilterOpcode_EndOfMessage) {
+      PERFETTO_DLOG("bytecode error @ word %zu, invalid field id (0)", i);
+      return false;
+    }
+
+    if (opcode == kFilterOpcode_SimpleField ||
+        opcode == kFilterOpcode_NestedField ||
+        opcode == kFilterOpcode_FilterString) {
+      // Field words are organized as follow:
+      // MSB: 1 if allowed, 0 if not allowed.
+      // Remaining bits:
+      //   Message index in the case of nested (non-simple) messages.
+      //   0x7f..e in the case of string fields which need filtering.
+      //   0x7f..f in the case of simple fields.
+      uint32_t msg_id;
+      if (opcode == kFilterOpcode_SimpleField) {
+        msg_id = kSimpleField;
+      } else if (opcode == kFilterOpcode_FilterString) {
+        msg_id = kFilterStringField;
+      } else {  // FILTER_OPCODE_NESTED_FIELD
+        // The next word in the bytecode contains the message index.
+        if (!has_next_word) {
+          PERFETTO_DLOG("bytecode error @ word %zu: unterminated nested field",
+                        i);
+          return false;
+        }
+        msg_id = words[++i];
+        max_msg_index = std::max(max_msg_index, msg_id);
+      }
+
+      if (field_id < kDirectlyIndexLimit) {
+        add_directly_indexed_field(field_id, msg_id);
+      } else {
+        // In the case of a large field id (rare) we waste an extra word and
+        // represent it as a range. Doesn't make sense to introduce extra
+        // complexity to deal with rare cases like this.
+        add_range(field_id, field_id + 1, msg_id);
+      }
+    } else if (opcode == kFilterOpcode_SimpleFieldRange) {
+      if (!has_next_word) {
+        PERFETTO_DLOG("bytecode error @ word %zu: unterminated range", i);
+        return false;
+      }
+      const uint32_t range_len = words[++i];
+      const uint32_t range_end = field_id + range_len;  // STL-style, excl.
+      uint32_t id = field_id;
+
+      // Here's the subtle complexity: at the bytecode level, we don't know
+      // anything about the kDirectlyIndexLimit. It is legit to define a range
+      // that spans across the direct-indexing threshold (e.g. 126-132). In that
+      // case we want to add all the elements < the indexing to the O(1) bucket
+      // and add only the remaining range as a non-indexed range.
+      for (; id < range_end && id < kDirectlyIndexLimit; ++id)
+        add_directly_indexed_field(id, kAllowed | kSimpleField);
+      PERFETTO_DCHECK(id >= kDirectlyIndexLimit || id == range_end);
+      if (id < range_end)
+        add_range(id, range_end, kSimpleField);
+    } else if (opcode == kFilterOpcode_EndOfMessage) {
+      // For each message append:
+      // 1. The "header" word telling how many directly indexed fields there
+      //    are.
+      // 2. The words for the directly indexed fields (id < 128).
+      // 3. The rest of the fields, encoded as ranges.
+      // Also update the |message_offset_| index to remember the word offset for
+      // the current message.
+      message_offset_.emplace_back(static_cast<uint32_t>(words_.size()));
+      words_.emplace_back(static_cast<uint32_t>(direct_indexed_fields.size()));
+      words_.insert(words_.end(), direct_indexed_fields.begin(),
+                    direct_indexed_fields.end());
+      words_.insert(words_.end(), ranges.begin(), ranges.end());
+      direct_indexed_fields.clear();
+      ranges.clear();
+    } else {
+      PERFETTO_DLOG("bytecode error @ word %zu: invalid opcode (%x)", i, word);
+      return false;
+    }
+  }  // (for word in bytecode).
+
+  if (!is_eom) {
+    PERFETTO_DLOG(
+        "bytecode error: end of message not the last word in the bytecode");
+    return false;
+  }
+
+  if (max_msg_index > 0 && max_msg_index >= message_offset_.size()) {
+    PERFETTO_DLOG(
+        "bytecode error: a message index (%u) is out of range "
+        "(num_messages=%zu)",
+        max_msg_index, message_offset_.size());
+    return false;
+  }
+
+  // Add a final entry to |message_offset_| so we can tell where the last
+  // message ends without an extra branch in the Query() hotpath.
+  message_offset_.emplace_back(static_cast<uint32_t>(words_.size()));
+
+  return true;
+}
+
+FilterBytecodeParser::QueryResult FilterBytecodeParser::Query(
+    uint32_t msg_index,
+    uint32_t field_id) const {
+  FilterBytecodeParser::QueryResult res{false, 0u};
+  if (static_cast<uint64_t>(msg_index) + 1 >=
+      static_cast<uint64_t>(message_offset_.size())) {
+    return res;
+  }
+  const uint32_t start_offset = message_offset_[msg_index];
+  // These are DCHECKs and not just CHECKS because the |words_| is populated
+  // by the LoadInternal call above. These cannot be violated with a malformed
+  // bytecode.
+  PERFETTO_DCHECK(start_offset < words_.size());
+  const uint32_t* word = &words_[start_offset];
+  const uint32_t end_off = message_offset_[msg_index + 1];
+  const uint32_t* const end = words_.data() + end_off;
+  PERFETTO_DCHECK(end > word && end <= words_.data() + words_.size());
+  const uint32_t num_directly_indexed = *(word++);
+  PERFETTO_DCHECK(num_directly_indexed <= kDirectlyIndexLimit);
+  PERFETTO_DCHECK(word + num_directly_indexed <= end);
+  uint32_t field_state = 0;
+  if (PERFETTO_LIKELY(field_id < num_directly_indexed)) {
+    PERFETTO_DCHECK(&word[field_id] < end);
+    field_state = word[field_id];
+  } else {
+    for (word = word + num_directly_indexed; word + 2 < end;) {
+      const uint32_t range_start = *(word++);
+      const uint32_t range_end = *(word++);
+      const uint32_t range_state = *(word++);
+      if (field_id >= range_start && field_id < range_end) {
+        field_state = range_state;
+        break;
+      }
+    }  // for (word in ranges)
+  }    // if (field_id >= num_directly_indexed)
+
+  res.allowed = (field_state & kAllowed) != 0;
+  res.nested_msg_index = field_state & ~kAllowed;
+  PERFETTO_DCHECK(!res.nested_msg_field() ||
+                  res.nested_msg_index < message_offset_.size() - 1);
+  return res;
+}
+
+}  // namespace protozero
+// gen_amalgamated begin source: src/protozero/filtering/string_filter.cc
+// gen_amalgamated begin header: src/protozero/filtering/string_filter.h
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_PROTOZERO_FILTERING_STRING_FILTER_H_
+#define SRC_PROTOZERO_FILTERING_STRING_FILTER_H_
+
+#include <regex>
+#include <string>
+#include <string_view>
+
+namespace protozero {
+
+// Performs filtering of strings in an "iptables" style. See the comments in
+// |TraceConfig.TraceFilter| for information on how this class works.
+class StringFilter {
+ public:
+  enum class Policy {
+    kMatchRedactGroups = 1,
+    kAtraceMatchRedactGroups = 2,
+    kMatchBreak = 3,
+    kAtraceMatchBreak = 4,
+    kAtraceRepeatedSearchRedactGroups = 5,
+  };
+
+  // Adds a new rule for filtering strings.
+  void AddRule(Policy policy,
+               std::string_view pattern,
+               std::string atrace_payload_starts_with);
+
+  // Tries to filter the given string. Returns true if the string was modified
+  // in any way, false otherwise.
+  bool MaybeFilter(char* ptr, size_t len) const {
+    if (len == 0 || rules_.empty()) {
+      return false;
+    }
+    return MaybeFilterInternal(ptr, len);
+  }
+
+ private:
+  struct Rule {
+    Policy policy;
+    std::regex pattern;
+    std::string atrace_payload_starts_with;
+  };
+
+  bool MaybeFilterInternal(char* ptr, size_t len) const;
+
+  std::vector<Rule> rules_;
+};
+
+}  // namespace protozero
+
+#endif  // SRC_PROTOZERO_FILTERING_STRING_FILTER_H_
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "src/protozero/filtering/string_filter.h"
+
+#include <cstring>
+#include <regex>
+#include <string_view>
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
+// gen_amalgamated expanded: #include "perfetto/public/compiler.h"
+
+namespace protozero {
+namespace {
+
+using Matches = std::match_results<char*>;
+
+static constexpr std::string_view kRedacted = "P60REDACTED";
+static constexpr char kRedactedDash = '-';
+
+// Returns a pointer to the first character after the tgid pipe character in
+// the atrace string given by [ptr, end). Returns null if no such character
+// exists.
+//
+// Examples:
+// E|1024 -> nullptr
+// foobarbaz -> nullptr
+// B|1024|x -> pointer to x
+const char* FindAtracePayloadPtr(const char* ptr, const char* end) {
+  // Don't even bother checking any strings which are so short that they could
+  // not contain a post-tgid section. This filters out strings like "E|" which
+  // emitted by Bionic.
+  //
+  // Also filter out any other strings starting with "E" as they never contain
+  // anything past the tgid: this removes >half of the strings for ~zero cost.
+  static constexpr size_t kEarliestSecondPipeIndex = 2;
+  const char* search_start = ptr + kEarliestSecondPipeIndex;
+  if (search_start >= end || *ptr == 'E') {
+    return nullptr;
+  }
+
+  // We skipped past the first '|' character by starting at the character at
+  // index 2. Just find the next pipe character (i.e. the one after tgid) using
+  // memchr.
+  const char* pipe = static_cast<const char*>(
+      memchr(search_start, '|', size_t(end - search_start)));
+  return pipe ? pipe + 1 : nullptr;
+}
+
+bool StartsWith(const char* ptr,
+                const char* end,
+                const std::string& starts_with) {
+  // Verify that the atrace string has enough characters to match against all
+  // the characters in the "starts with" string. If it does, memcmp to check if
+  // all the characters match and return true if they do.
+  return ptr + starts_with.size() <= end &&
+         memcmp(ptr, starts_with.data(), starts_with.size()) == 0;
+}
+
+void RedactMatches(const Matches& matches) {
+  // Go through every group in the matches.
+  for (size_t i = 1; i < matches.size(); ++i) {
+    const auto& match = matches[i];
+    PERFETTO_CHECK(match.second >= match.first);
+
+    // Overwrite the match with characters from |kRedacted|. If match is
+    // smaller, we will not use all of |kRedacted| but that's fine (i.e. we
+    // will overwrite with a truncated |kRedacted|).
+    size_t match_len = static_cast<size_t>(match.second - match.first);
+    size_t redacted_len = std::min(match_len, kRedacted.size());
+    memcpy(match.first, kRedacted.data(), redacted_len);
+
+    // Overwrite any characters after |kRedacted| with |kRedactedDash|.
+    memset(match.first + redacted_len, kRedactedDash, match_len - redacted_len);
+  }
+}
+
+}  // namespace
+
+void StringFilter::AddRule(Policy policy,
+                           std::string_view pattern_str,
+                           std::string atrace_payload_starts_with) {
+  rules_.emplace_back(StringFilter::Rule{
+      policy,
+      std::regex(pattern_str.begin(), pattern_str.end(),
+                 std::regex::ECMAScript | std::regex_constants::optimize),
+      std::move(atrace_payload_starts_with)});
+}
+
+bool StringFilter::MaybeFilterInternal(char* ptr, size_t len) const {
+  std::match_results<char*> matches;
+  bool atrace_find_tried = false;
+  const char* atrace_payload_ptr = nullptr;
+  for (const Rule& rule : rules_) {
+    switch (rule.policy) {
+      case Policy::kMatchRedactGroups:
+      case Policy::kMatchBreak:
+        if (std::regex_match(ptr, ptr + len, matches, rule.pattern)) {
+          if (rule.policy == Policy::kMatchBreak) {
+            return false;
+          }
+          RedactMatches(matches);
+          return true;
+        }
+        break;
+      case Policy::kAtraceMatchRedactGroups:
+      case Policy::kAtraceMatchBreak:
+        atrace_payload_ptr = atrace_find_tried
+                                 ? atrace_payload_ptr
+                                 : FindAtracePayloadPtr(ptr, ptr + len);
+        atrace_find_tried = true;
+        if (atrace_payload_ptr &&
+            StartsWith(atrace_payload_ptr, ptr + len,
+                       rule.atrace_payload_starts_with) &&
+            std::regex_match(ptr, ptr + len, matches, rule.pattern)) {
+          if (rule.policy == Policy::kAtraceMatchBreak) {
+            return false;
+          }
+          RedactMatches(matches);
+          return true;
+        }
+        break;
+      case Policy::kAtraceRepeatedSearchRedactGroups:
+        atrace_payload_ptr = atrace_find_tried
+                                 ? atrace_payload_ptr
+                                 : FindAtracePayloadPtr(ptr, ptr + len);
+        atrace_find_tried = true;
+        if (atrace_payload_ptr && StartsWith(atrace_payload_ptr, ptr + len,
+                                             rule.atrace_payload_starts_with)) {
+          auto beg = std::regex_iterator<char*>(ptr, ptr + len, rule.pattern);
+          auto end = std::regex_iterator<char*>();
+          bool has_any_matches = beg != end;
+          for (auto it = std::move(beg); it != end; ++it) {
+            RedactMatches(*it);
+          }
+          if (has_any_matches) {
+            return true;
+          }
+        }
+        break;
+    }
+  }
+  return false;
+}
+
+}  // namespace protozero
+// gen_amalgamated begin source: src/protozero/filtering/message_filter.cc
+// gen_amalgamated begin header: src/protozero/filtering/message_filter.h
+// gen_amalgamated begin header: src/protozero/filtering/message_tokenizer.h
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_PROTOZERO_FILTERING_MESSAGE_TOKENIZER_H_
+#define SRC_PROTOZERO_FILTERING_MESSAGE_TOKENIZER_H_
+
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace protozero {
+
+// A helper class for schema-less tokenizing of protobuf messages.
+// This class takes a stream of proto-encoded bytes, pushed one by one in input
+// via Push(octet), and returns a stream of tokens (each Push() call can return
+// 0 or 1 token).
+// A "token" contains metadata about a field, specifically: its ID, its wire
+// type and:
+//  - For varint and fixed32/64 fields: its payload.
+//  - For string and bytes fields: the length of its payload.
+//    In this case the caller is supposed to "eat" those N bytes before calling
+//    Push() again.
+// Note that this class cannot differentiate between a string/bytes field or
+// a submessage, because they are encoded in the same way. The caller is
+// supposed to know whether a field can be recursed into by just keep calling
+// Push() or is a string that should be skipped.
+// This is inline to allow the compiler to see through the Push method and
+// avoid a function call for each byte.
+class MessageTokenizer {
+ public:
+  struct Token {
+    uint32_t field_id;  // 0 == not valid.
+    proto_utils::ProtoWireType type;
+
+    // For kLengthDelimited, |value| represent the length of the payload.
+    uint64_t value;
+
+    inline bool valid() const { return field_id != 0; }
+    bool operator==(const Token& o) const {
+      return field_id == o.field_id && type == o.type && value == o.value;
+    }
+  };
+
+  // Pushes a byte in input and returns a token, only when getting to the last
+  // byte of each field. Specifically:
+  // - For varint and fixed32 fields, the Token is returned after the last byte
+  //   of the numeric payload is pushed.
+  // - For length-delimited fields, this returns after the last byte of the
+  //   length is pushed (i.e. right before the payload starts). The caller is
+  //   expected to either skip the next |value| bytes (in the case of a string
+  //   or bytes fields) or keep calling Push, in the case of a submessage.
+  inline Token Push(uint8_t octet) {
+    using protozero::proto_utils::ProtoWireType;
+
+    // Parsing a fixed32/64 field is the only case where we don't have to do
+    // any varint decoding. This is why this block is before the remaining
+    // switch statement below (all the rest is a varint).
+    if (PERFETTO_UNLIKELY(state_ == kFixedIntValue)) {
+      PERFETTO_DCHECK(fixed_int_bits_ == 32 || fixed_int_bits_ == 64);
+      fixed_int_value_ |= static_cast<uint64_t>(octet) << fixed_int_shift_;
+      fixed_int_shift_ += 8;
+      if (fixed_int_shift_ < fixed_int_bits_)
+        return Token{};  // Intermediate byte of a fixed32/64.
+      auto wire_type = fixed_int_bits_ == 32 ? ProtoWireType::kFixed32
+                                             : ProtoWireType::kFixed64;
+      uint64_t fixed_int_value = fixed_int_value_;
+      fixed_int_value_ = fixed_int_shift_ = fixed_int_bits_ = 0;
+      state_ = kFieldPreamble;
+      return Token{field_id_, wire_type, fixed_int_value};
+    }
+
+    // At this point either we are: (i) parsing a field preamble; (ii) parsing a
+    // varint field paylod; (iii) parsing the length of a length-delimited
+    // field. In all cases, we need to decode a varint before proceeding.
+    varint_ |= static_cast<uint64_t>(octet & 0x7F) << varint_shift_;
+    if (octet & 0x80) {
+      varint_shift_ += 7;
+      if (PERFETTO_UNLIKELY(varint_shift_ >= 64)) {
+        varint_shift_ = 0;
+        state_ = kInvalidVarInt;
+      }
+      return Token{};  // Still parsing a varint.
+    }
+
+    uint64_t varint = varint_;
+    varint_ = 0;
+    varint_shift_ = 0;
+
+    switch (state_) {
+      case kFieldPreamble: {
+        auto field_type = static_cast<uint32_t>(varint & 7u);  // 7 = 0..0111
+        field_id_ = static_cast<uint32_t>(varint >> 3);
+
+        // The field type is legit, now check it's well formed and within
+        // boundaries.
+        if (field_type == static_cast<uint32_t>(ProtoWireType::kVarInt)) {
+          state_ = kVarIntValue;
+        } else if (field_type ==
+                       static_cast<uint32_t>(ProtoWireType::kFixed32) ||
+                   field_type ==
+                       static_cast<uint32_t>(ProtoWireType::kFixed64)) {
+          state_ = kFixedIntValue;
+          fixed_int_shift_ = 0;
+          fixed_int_value_ = 0;
+          fixed_int_bits_ =
+              field_type == static_cast<uint32_t>(ProtoWireType::kFixed32) ? 32
+                                                                           : 64;
+        } else if (field_type ==
+                   static_cast<uint32_t>(ProtoWireType::kLengthDelimited)) {
+          state_ = kLenDelimited;
+        } else {
+          state_ = kInvalidFieldType;
+        }
+        return Token{};
+      }
+
+      case kVarIntValue: {
+        // Return the varint field payload and go back to the next field.
+        state_ = kFieldPreamble;
+        return Token{field_id_, ProtoWireType::kVarInt, varint};
+      }
+
+      case kLenDelimited: {
+        const auto payload_len = varint;
+        if (payload_len > protozero::proto_utils::kMaxMessageLength) {
+          state_ = kMessageTooBig;
+          return Token{};
+        }
+        state_ = kFieldPreamble;
+        // At this point the caller is expected to consume the next
+        // |payload_len| bytes.
+        return Token{field_id_, ProtoWireType::kLengthDelimited, payload_len};
+      }
+
+      case kFixedIntValue:
+        // Unreacheable because of the if before the switch.
+        PERFETTO_DCHECK(false);
+        break;
+
+      // Unrecoverable error states.
+      case kInvalidFieldType:
+      case kMessageTooBig:
+      case kInvalidVarInt:
+        break;
+    }  // switch(state_)
+
+    return Token{};  // Keep GCC happy.
+  }
+
+  // Returns true if the tokenizer FSM has reached quiescence (i.e. if we are
+  // NOT in the middle of parsing a field).
+  bool idle() const {
+    return state_ == kFieldPreamble && varint_shift_ == 0 &&
+           fixed_int_shift_ == 0;
+  }
+
+  // Only for reporting parser errors in the trace.
+  uint32_t state() const { return static_cast<uint32_t>(state_); }
+
+ private:
+  enum State {
+    kFieldPreamble = 0,  // Parsing the varint for the field preamble.
+    kVarIntValue = 1,    // Parsing the payload of a varint field.
+    kFixedIntValue = 2,  // Parsing the payload of a fixed32/64 field.
+    kLenDelimited = 3,   // Parsing the length of a length-delimited field.
+
+    // Unrecoverable error states:
+    kInvalidFieldType = 4,  // Encountered an invalid field type.
+    kMessageTooBig = 5,     // Size of the length delimited message was too big.
+    kInvalidVarInt = 6,     // Varint larger than 64 bits.
+  };
+
+  State state_ = kFieldPreamble;
+  uint32_t field_id_ = 0;
+  uint64_t varint_ = 0;
+  uint32_t varint_shift_ = 0;
+  uint32_t fixed_int_shift_ = 0;
+  uint32_t fixed_int_bits_ = 0;
+  uint64_t fixed_int_value_ = 0;
+};
+
+}  // namespace protozero
+
+#endif  // SRC_PROTOZERO_FILTERING_MESSAGE_TOKENIZER_H_
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_PROTOZERO_FILTERING_MESSAGE_FILTER_H_
+#define SRC_PROTOZERO_FILTERING_MESSAGE_FILTER_H_
+
+#include <stdint.h>
+
+#include <memory>
+#include <string>
+#include <unordered_map>
+
+// gen_amalgamated expanded: #include "src/protozero/filtering/filter_bytecode_parser.h"
+// gen_amalgamated expanded: #include "src/protozero/filtering/message_tokenizer.h"
+// gen_amalgamated expanded: #include "src/protozero/filtering/string_filter.h"
+
+namespace protozero {
+
+// A class to filter binary-encoded proto messages using an allow-list of field
+// ids, also known as "filter bytecode". The filter determines which fields are
+// allowed to be passed through in output and strips all the other fields.
+// See go/trace-filtering for full design.
+// This class takes in input:
+// 1) The filter bytecode, loaded once via the LoadFilterBytecode() method.
+// 2) A proto-encoded binary message. The message doesn't have to be contiguous,
+//    it can be passed as an array of arbitrarily chunked fragments.
+// The FilterMessage*() method returns in output a proto message, stripping out
+// all unknown fields. If the input is malformed (e.g., unknown proto field wire
+// types, lengths out of bound) the whole filtering failed and the |error| flag
+// of the FilteredMessage object is set to true.
+// The filtering operation is based on rewriting a copy of the message into a
+// self-allocated buffer, which is then returned in the output. The input buffer
+// is NOT altered.
+// Note also that the process of rewriting the protos gets rid of most redundant
+// varint encoding (if present). So even if all fields are allow-listed, the
+// output might NOT be bitwise identical to the input (but it will be
+// semantically equivalent).
+// Furthermore the enable_field_usage_tracking() method allows to keep track of
+// a histogram of allowed / denied fields. It slows down filtering and is
+// intended only on host tools.
+class MessageFilter {
+ public:
+  class Config {
+   public:
+    bool LoadFilterBytecode(const void* filter_data, size_t len);
+    bool SetFilterRoot(std::initializer_list<uint32_t> field_ids);
+
+    const FilterBytecodeParser& filter() const { return filter_; }
+    const StringFilter& string_filter() const { return string_filter_; }
+    StringFilter& string_filter() { return string_filter_; }
+    uint32_t root_msg_index() const { return root_msg_index_; }
+
+   private:
+    FilterBytecodeParser filter_;
+    StringFilter string_filter_;
+    uint32_t root_msg_index_ = 0;
+  };
+
+  MessageFilter();
+  explicit MessageFilter(Config);
+  ~MessageFilter();
+
+  struct InputSlice {
+    const void* data;
+    size_t len;
+  };
+
+  struct FilteredMessage {
+    FilteredMessage(std::unique_ptr<uint8_t[]> d, size_t s)
+        : data(std::move(d)), size(s) {}
+    std::unique_ptr<uint8_t[]> data;
+    size_t size;  // The used bytes in |data|. This is <= sizeof(data).
+    bool error = false;
+  };
+
+  // Loads the filter bytecode that will be used to filter any subsequent
+  // message. Must be called before the first call to FilterMessage*().
+  // |filter_data| must point to a byte buffer for a proto-encoded ProtoFilter
+  // message (see proto_filter.proto).
+  bool LoadFilterBytecode(const void* filter_data, size_t len) {
+    return config_.LoadFilterBytecode(filter_data, len);
+  }
+
+  // This affects the filter starting point of the subsequent FilterMessage*()
+  // calls. By default the filtering process starts from the message @ index 0,
+  // the root message passed to proto_filter when generating the bytecode
+  // (in typical tracing use-cases, this is perfetto.protos.Trace). However, the
+  // caller (TracingServiceImpl) might want to filter packets from the 2nd level
+  // (perfetto.protos.TracePacket) because the root level is pre-pended after
+  // the fact. This call allows to change the root message for the filter.
+  // The argument |field_ids| is an array of proto field ids and determines the
+  // path to the new root. For instance, in the case of [1,2,3] SetFilterRoot
+  // will identify the sub-message for the field "root.1.2.3" and use that.
+  // In order for this to succeed all the fields in the path must be allowed
+  // in the filter and must be a nested message type.
+  bool SetFilterRoot(std::initializer_list<uint32_t> field_ids) {
+    return config_.SetFilterRoot(field_ids);
+  }
+
+  // Takes an input message, fragmented in arbitrary slices, and returns a
+  // filtered message in output.
+  FilteredMessage FilterMessageFragments(const InputSlice*, size_t num_slices);
+
+  // Helper for tests, where the input is a contiguous buffer.
+  FilteredMessage FilterMessage(const void* data, size_t len) {
+    InputSlice slice{data, len};
+    return FilterMessageFragments(&slice, 1);
+  }
+
+  // When enabled returns a map of "field path" to "usage counter".
+  // The key (std::string) is a binary buffer (i.e. NOT an ASCII/UTF-8 string)
+  // which contains a varint for each field. Consider the following:
+  // message Root { Sub1 f1 = 1; };
+  // message Sub1 { Sub2 f2 = 7;}
+  // message Sub2 { string f3 = 5; }
+  // The field .f1.f2.f3 will be encoded as \x01\0x07\x05.
+  // The value is the number of times that field has been encountered. If the
+  // field is not allow-listed in the bytecode (the field is stripped in output)
+  // the count will be negative.
+  void enable_field_usage_tracking(bool x) { track_field_usage_ = x; }
+  const std::unordered_map<std::string, int32_t>& field_usage() const {
+    return field_usage_;
+  }
+
+  const Config& config() const { return config_; }
+
+  // Retuns the helper class used to perform string filtering.
+  StringFilter& string_filter() { return config_.string_filter(); }
+
+ private:
+  // This is called by FilterMessageFragments().
+  // Inlining allows the compiler turn the per-byte call/return into a for loop,
+  // while, at the same time, keeping the code easy to read and reason about.
+  // It gives a 20-25% speedup (265ms vs 215ms for a 25MB trace).
+  void FilterOneByte(uint8_t octet) PERFETTO_ALWAYS_INLINE;
+
+  // No-inline because this is a slowpath (only when usage tracking is enabled).
+  void IncrementCurrentFieldUsage(uint32_t field_id,
+                                  bool allowed) PERFETTO_NO_INLINE;
+
+  // Gets into an error state which swallows all the input and emits no output.
+  void SetUnrecoverableErrorState();
+
+  // We keep track of the nest of messages in a stack. Each StackState
+  // object corresponds to a level of nesting in the proto message structure.
+  // Every time a new field of type len-delimited that has a corresponding
+  // sub-message in the bytecode is encountered, a new StackState is pushed in
+  // |stack_|. stack_[0] is a sentinel to prevent over-popping without adding
+  // extra branches in the fastpath.
+  // |stack_|. stack_[1] is the state of the root message.
+  struct StackState {
+    uint32_t in_bytes = 0;  // Number of input bytes processed.
+
+    // When |in_bytes| reaches this value, the current state should be popped.
+    // This is set when recursing into nested submessages. This is 0 only for
+    // stack_[0] (we don't know the size of the root message upfront).
+    uint32_t in_bytes_limit = 0;
+
+    // This is set when a len-delimited message is encountered, either a string
+    // or a nested submessage that is NOT allow-listed in the bytecode.
+    // This causes input bytes to be consumed without being parsed from the
+    // input stream. If |passthrough_eaten_bytes| == true, they will be copied
+    // as-is in output (e.g. in the case of an allowed string/bytes field).
+    uint32_t eat_next_bytes = 0;
+
+    // Keeps tracks of the stream_writer output counter (out_.written()) then
+    // the StackState is pushed. This is used to work out, when popping, how
+    // many bytes have been written for the current submessage.
+    uint32_t out_bytes_written_at_start = 0;
+
+    uint32_t field_id = 0;   // The proto field id for the current message.
+    uint32_t msg_index = 0;  // The index of the message filter in the bytecode.
+
+    // This is a pointer to the proto preamble for the current submessage
+    // (it's nullptr for stack_[0] and non-null elsewhere). This will be filled
+    // with the actual size of the message (out_.written() -
+    // |out_bytes_written_at_start|) when finishing (popping) the message.
+    // This must be filled using WriteRedundantVarint(). Note that the
+    // |size_field_len| is variable and depends on the actual length of the
+    // input message. If the output message has roughly the same size of the
+    // input message, the length will not be redundant.
+    // In other words: the length of the field is reserved when the submessage
+    // starts. At that point we know the upper-bound for the output message
+    // (a filtered submessage can be <= the original one, but not >). So we
+    // reserve as many bytes it takes to write the input length in varint.
+    // Then, when the message is finalized and we know the actual output size
+    // we backfill the field.
+    // Consider the example of a submessage where the input size = 130 (>127,
+    // 2 varint bytes) and the output is 120 bytes. The length will be 2 bytes
+    // wide even though could have been encoded with just one byte.
+    uint8_t* size_field = nullptr;
+    uint32_t size_field_len = 0;
+
+    // The pointer to the start of the string to update the string if it is
+    // filtered.
+    uint8_t* filter_string_ptr = nullptr;
+
+    // How |eat_next_bytes| should be handled. It seems that keeping this field
+    // at the end rather than next to |eat_next_bytes| makes the filter a little
+    // (but measurably) faster. (likely something related with struct layout vs
+    // cache sizes).
+    enum FilterAction {
+      kDrop,
+      kPassthrough,
+      kFilterString,
+    };
+    FilterAction action = FilterAction::kDrop;
+  };
+
+  uint32_t out_written() { return static_cast<uint32_t>(out_ - &out_buf_[0]); }
+
+  Config config_;
+
+  std::unique_ptr<uint8_t[]> out_buf_;
+  uint8_t* out_ = nullptr;
+  uint8_t* out_end_ = nullptr;
+
+  MessageTokenizer tokenizer_;
+  std::vector<StackState> stack_;
+
+  bool error_ = false;
+  bool track_field_usage_ = false;
+  std::unordered_map<std::string, int32_t> field_usage_;
+};
+
+}  // namespace protozero
+
+#endif  // SRC_PROTOZERO_FILTERING_MESSAGE_FILTER_H_
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "src/protozero/filtering/message_filter.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+// gen_amalgamated expanded: #include "src/protozero/filtering/string_filter.h"
+
+namespace protozero {
+
+namespace {
+
+// Inline helpers to append proto fields in output. They are the equivalent of
+// the protozero::Message::AppendXXX() fields but don't require building and
+// maintaining a full protozero::Message object or dealing with scattered
+// output slices.
+// All these functions assume there is enough space in the output buffer, which
+// should be always the case assuming that we don't end up generating more
+// output than input.
+
+inline void AppendVarInt(uint32_t field_id, uint64_t value, uint8_t** out) {
+  *out = proto_utils::WriteVarInt(proto_utils::MakeTagVarInt(field_id), *out);
+  *out = proto_utils::WriteVarInt(value, *out);
+}
+
+// For fixed32 / fixed64.
+template <typename INT_T /* uint32_t | uint64_t*/>
+inline void AppendFixed(uint32_t field_id, INT_T value, uint8_t** out) {
+  *out = proto_utils::WriteVarInt(proto_utils::MakeTagFixed<INT_T>(field_id),
+                                  *out);
+  memcpy(*out, &value, sizeof(value));
+  *out += sizeof(value);
+}
+
+// For length-delimited (string, bytes) fields. Note: this function appends only
+// the proto preamble and the varint field that states the length of the payload
+// not the payload itself.
+// In the case of submessages, the caller needs to re-write the length at the
+// end in the in the returned memory area.
+// The problem here is that, because of filtering, the length of a submessage
+// might be < original length (the original length is still an upper-bound).
+// Returns a pair with: (1) the pointer where the final length should be written
+// into, (2) the length of the size field.
+// The caller must write a redundant varint to match the original size (i.e.
+// needs to use WriteRedundantVarInt()).
+inline std::pair<uint8_t*, uint32_t> AppendLenDelim(uint32_t field_id,
+                                                    uint32_t len,
+                                                    uint8_t** out) {
+  *out = proto_utils::WriteVarInt(proto_utils::MakeTagLengthDelimited(field_id),
+                                  *out);
+  uint8_t* size_field_start = *out;
+  *out = proto_utils::WriteVarInt(len, *out);
+  const size_t size_field_len = static_cast<size_t>(*out - size_field_start);
+  return std::make_pair(size_field_start, size_field_len);
+}
+}  // namespace
+
+MessageFilter::MessageFilter(Config config) : config_(std::move(config)) {
+  // Push a state on the stack for the implicit root message.
+  stack_.emplace_back();
+}
+
+MessageFilter::MessageFilter() : MessageFilter(Config()) {}
+
+MessageFilter::~MessageFilter() = default;
+
+bool MessageFilter::Config::LoadFilterBytecode(const void* filter_data,
+                                               size_t len) {
+  return filter_.Load(filter_data, len);
+}
+
+bool MessageFilter::Config::SetFilterRoot(
+    std::initializer_list<uint32_t> field_ids) {
+  uint32_t root_msg_idx = 0;
+  for (uint32_t field_id : field_ids) {
+    auto res = filter_.Query(root_msg_idx, field_id);
+    if (!res.allowed || !res.nested_msg_field())
+      return false;
+    root_msg_idx = res.nested_msg_index;
+  }
+  root_msg_index_ = root_msg_idx;
+  return true;
+}
+
+MessageFilter::FilteredMessage MessageFilter::FilterMessageFragments(
+    const InputSlice* slices,
+    size_t num_slices) {
+  // First compute the upper bound for the output. The filtered message cannot
+  // be > the original message.
+  uint32_t total_len = 0;
+  for (size_t i = 0; i < num_slices; ++i)
+    total_len += slices[i].len;
+  out_buf_.reset(new uint8_t[total_len]);
+  out_ = out_buf_.get();
+  out_end_ = out_ + total_len;
+
+  // Reset the parser state.
+  tokenizer_ = MessageTokenizer();
+  error_ = false;
+  stack_.clear();
+  stack_.resize(2);
+  // stack_[0] is a sentinel and should never be hit in nominal cases. If we
+  // end up there we will just keep consuming the input stream and detecting
+  // at the end, without hurting the fastpath.
+  stack_[0].in_bytes_limit = UINT32_MAX;
+  stack_[0].eat_next_bytes = UINT32_MAX;
+  // stack_[1] is the actual root message.
+  stack_[1].in_bytes_limit = total_len;
+  stack_[1].msg_index = config_.root_msg_index();
+
+  // Process the input data and write the output.
+  for (size_t slice_idx = 0; slice_idx < num_slices; ++slice_idx) {
+    const InputSlice& slice = slices[slice_idx];
+    const uint8_t* data = static_cast<const uint8_t*>(slice.data);
+    for (size_t i = 0; i < slice.len; ++i)
+      FilterOneByte(data[i]);
+  }
+
+  // Construct the output object.
+  PERFETTO_CHECK(out_ >= out_buf_.get() && out_ <= out_end_);
+  auto used_size = static_cast<size_t>(out_ - out_buf_.get());
+  FilteredMessage res{std::move(out_buf_), used_size};
+  res.error = error_;
+  if (stack_.size() != 1 || !tokenizer_.idle() ||
+      stack_[0].in_bytes != total_len) {
+    res.error = true;
+  }
+  return res;
+}
+
+void MessageFilter::FilterOneByte(uint8_t octet) {
+  PERFETTO_DCHECK(!stack_.empty());
+
+  auto* state = &stack_.back();
+  StackState next_state{};
+  bool push_next_state = false;
+
+  if (state->eat_next_bytes > 0) {
+    // This is the case where the previous tokenizer_.Push() call returned a
+    // length delimited message which is NOT a submessage (a string or a bytes
+    // field). We just want to consume it, and pass it through/filter strings
+    // if the field was allowed.
+    --state->eat_next_bytes;
+    if (state->action == StackState::kPassthrough) {
+      *(out_++) = octet;
+    } else if (state->action == StackState::kFilterString) {
+      *(out_++) = octet;
+      if (state->eat_next_bytes == 0) {
+        config_.string_filter().MaybeFilter(
+            reinterpret_cast<char*>(state->filter_string_ptr),
+            static_cast<size_t>(out_ - state->filter_string_ptr));
+      }
+    }
+  } else {
+    MessageTokenizer::Token token = tokenizer_.Push(octet);
+    // |token| will not be valid() in most cases and this is WAI. When pushing
+    // a varint field, only the last byte yields a token, all the other bytes
+    // return an invalid token, they just update the internal tokenizer state.
+    if (token.valid()) {
+      auto filter = config_.filter().Query(state->msg_index, token.field_id);
+      switch (token.type) {
+        case proto_utils::ProtoWireType::kVarInt:
+          if (filter.allowed && filter.simple_field())
+            AppendVarInt(token.field_id, token.value, &out_);
+          break;
+        case proto_utils::ProtoWireType::kFixed32:
+          if (filter.allowed && filter.simple_field())
+            AppendFixed(token.field_id, static_cast<uint32_t>(token.value),
+                        &out_);
+          break;
+        case proto_utils::ProtoWireType::kFixed64:
+          if (filter.allowed && filter.simple_field())
+            AppendFixed(token.field_id, static_cast<uint64_t>(token.value),
+                        &out_);
+          break;
+        case proto_utils::ProtoWireType::kLengthDelimited:
+          // Here we have two cases:
+          // A. A simple string/bytes field: we just want to consume the next
+          //    bytes (the string payload), optionally passing them through in
+          //    output if the field is allowed.
+          // B. This is a nested submessage. In this case we want to recurse and
+          //    push a new state on the stack.
+          // Note that we can't tell the difference between a
+          // "non-allowed string" and a "non-allowed submessage". But it doesn't
+          // matter because in both cases we just want to skip the next N bytes.
+          const auto submessage_len = static_cast<uint32_t>(token.value);
+          auto in_bytes_left = state->in_bytes_limit - state->in_bytes - 1;
+          if (PERFETTO_UNLIKELY(submessage_len > in_bytes_left)) {
+            // This is a malicious / malformed string/bytes/submessage that
+            // claims to be larger than the outer message that contains it.
+            return SetUnrecoverableErrorState();
+          }
+
+          if (filter.allowed && filter.nested_msg_field() &&
+              submessage_len > 0) {
+            // submessage_len == 0 is the edge case of a message with a 0-len
+            // (but present) submessage. In this case, if allowed, we don't want
+            // to push any further state (doing so would desync the FSM) but we
+            // still want to emit it.
+            // At this point |submessage_len| is only an upper bound. The
+            // final message written in output can be <= the one in input,
+            // only some of its fields might be allowed (also remember that
+            // this class implicitly removes redundancy varint encoding of
+            // len-delimited field lengths). The final length varint (the
+            // return value of AppendLenDelim()) will be filled when popping
+            // from |stack_|.
+            auto size_field =
+                AppendLenDelim(token.field_id, submessage_len, &out_);
+            push_next_state = true;
+            next_state.field_id = token.field_id;
+            next_state.msg_index = filter.nested_msg_index;
+            next_state.in_bytes_limit = submessage_len;
+            next_state.size_field = size_field.first;
+            next_state.size_field_len = size_field.second;
+            next_state.out_bytes_written_at_start = out_written();
+          } else {
+            // A string or bytes field, or a 0 length submessage.
+            state->eat_next_bytes = submessage_len;
+            if (filter.allowed && filter.filter_string_field()) {
+              state->action = StackState::kFilterString;
+              AppendLenDelim(token.field_id, submessage_len, &out_);
+              state->filter_string_ptr = out_;
+            } else if (filter.allowed) {
+              state->action = StackState::kPassthrough;
+              AppendLenDelim(token.field_id, submessage_len, &out_);
+            } else {
+              state->action = StackState::kDrop;
+            }
+          }
+          break;
+      }  // switch(type)
+
+      if (PERFETTO_UNLIKELY(track_field_usage_)) {
+        IncrementCurrentFieldUsage(token.field_id, filter.allowed);
+      }
+    }  // if (token.valid)
+  }    // if (eat_next_bytes == 0)
+
+  ++state->in_bytes;
+  while (state->in_bytes >= state->in_bytes_limit) {
+    PERFETTO_DCHECK(state->in_bytes == state->in_bytes_limit);
+    push_next_state = false;
+
+    // We can't possibly write more than we read.
+    const uint32_t msg_bytes_written = static_cast<uint32_t>(
+        out_written() - state->out_bytes_written_at_start);
+    PERFETTO_DCHECK(msg_bytes_written <= state->in_bytes_limit);
+
+    // Backfill the length field of the
+    proto_utils::WriteRedundantVarInt(msg_bytes_written, state->size_field,
+                                      state->size_field_len);
+
+    const uint32_t in_bytes_processes_for_last_msg = state->in_bytes;
+    stack_.pop_back();
+    PERFETTO_CHECK(!stack_.empty());
+    state = &stack_.back();
+    state->in_bytes += in_bytes_processes_for_last_msg;
+    if (PERFETTO_UNLIKELY(!tokenizer_.idle())) {
+      // If we hit this case, it means that we got to the end of a submessage
+      // while decoding a field. We can't recover from this and we don't want to
+      // propagate a broken sub-message.
+      return SetUnrecoverableErrorState();
+    }
+  }
+
+  if (push_next_state) {
+    PERFETTO_DCHECK(tokenizer_.idle());
+    stack_.emplace_back(std::move(next_state));
+    state = &stack_.back();
+  }
+}
+
+void MessageFilter::SetUnrecoverableErrorState() {
+  error_ = true;
+  stack_.clear();
+  stack_.resize(1);
+  auto& state = stack_[0];
+  state.eat_next_bytes = UINT32_MAX;
+  state.in_bytes_limit = UINT32_MAX;
+  state.action = StackState::kDrop;
+  out_ = out_buf_.get();  // Reset the write pointer.
+}
+
+void MessageFilter::IncrementCurrentFieldUsage(uint32_t field_id,
+                                               bool allowed) {
+  // Slowpath. Used mainly in offline tools and tests to workout used fields in
+  // a proto.
+  PERFETTO_DCHECK(track_field_usage_);
+
+  // Field path contains a concatenation of varints, one for each nesting level.
+  // e.g. y in message Root { Sub x = 2; }; message Sub { SubSub y = 7; }
+  // is encoded as [varint(2) + varint(7)].
+  // We use varint to take the most out of SSO (small string opt). In most cases
+  // the path will fit in the on-stack 22 bytes, requiring no heap.
+  std::string field_path;
+
+  auto append_field_id = [&field_path](uint32_t id) {
+    uint8_t buf[10];
+    uint8_t* end = proto_utils::WriteVarInt(id, buf);
+    field_path.append(reinterpret_cast<char*>(buf),
+                      static_cast<size_t>(end - buf));
+  };
+
+  // Append all the ancestors IDs from the state stack.
+  // The first entry of the stack has always ID 0 and we skip it (we don't know
+  // the ID of the root message itself).
+  PERFETTO_DCHECK(stack_.size() >= 2 && stack_[1].field_id == 0);
+  for (size_t i = 2; i < stack_.size(); ++i)
+    append_field_id(stack_[i].field_id);
+  // Append the id of the field in the current message.
+  append_field_id(field_id);
+  field_usage_[field_path] += allowed ? 1 : -1;
+}
+
+}  // namespace protozero
+// gen_amalgamated begin source: src/tracing/service/metatrace_writer.cc
+// gen_amalgamated begin header: src/tracing/service/metatrace_writer.h
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACING_SERVICE_METATRACE_WRITER_H_
+#define SRC_TRACING_SERVICE_METATRACE_WRITER_H_
+
+#include <functional>
+#include <memory>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/metatrace.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
+
+namespace perfetto {
+
+namespace base {
+class TaskRunner;
+}
+
+class TraceWriter;
+
+// Complements the base::metatrace infrastructure.
+// It hooks a callback to metatrace::Enable() and writes metatrace events into
+// a TraceWriter whenever the metatrace ring buffer is half full.
+// It is safe to create and attempt to start multiple instances of this class,
+// however only the first one will succeed because the metatrace framework
+// doesn't support multiple instances.
+// This class is defined here (instead of directly in src/probes/) so it can
+// be reused by other components (e.g. heapprofd).
+class MetatraceWriter {
+ public:
+  static constexpr char kDataSourceName[] = "perfetto.metatrace";
+
+  MetatraceWriter();
+  ~MetatraceWriter();
+
+  MetatraceWriter(const MetatraceWriter&) = delete;
+  MetatraceWriter& operator=(const MetatraceWriter&) = delete;
+  MetatraceWriter(MetatraceWriter&&) = delete;
+  MetatraceWriter& operator=(MetatraceWriter&&) = delete;
+
+  void Enable(base::TaskRunner*, std::unique_ptr<TraceWriter>, uint32_t tags);
+  void Disable();
+  void WriteAllAndFlushTraceWriter(std::function<void()> callback);
+
+ private:
+  void WriteAllAvailableEvents();
+
+  bool started_ = false;
+  base::TaskRunner* task_runner_ = nullptr;
+  std::unique_ptr<TraceWriter> trace_writer_;
+  PERFETTO_THREAD_CHECKER(thread_checker_)
+  base::WeakPtrFactory<MetatraceWriter> weak_ptr_factory_;  // Keep last.
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_SERVICE_METATRACE_WRITER_H_
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/service/metatrace_writer.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/trace/perfetto/perfetto_metatrace.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
+
+namespace perfetto {
+
+MetatraceWriter::MetatraceWriter() : weak_ptr_factory_(this) {}
+
+MetatraceWriter::~MetatraceWriter() {
+  Disable();
+}
+
+void MetatraceWriter::Enable(base::TaskRunner* task_runner,
+                             std::unique_ptr<TraceWriter> trace_writer,
+                             uint32_t tags) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (started_) {
+    PERFETTO_DFATAL_OR_ELOG("Metatrace already started from this instance");
+    return;
+  }
+  task_runner_ = task_runner;
+  trace_writer_ = std::move(trace_writer);
+  auto weak_ptr = weak_ptr_factory_.GetWeakPtr();
+  bool enabled = metatrace::Enable(
+      [weak_ptr] {
+        if (weak_ptr)
+          weak_ptr->WriteAllAvailableEvents();
+      },
+      task_runner, tags);
+  if (!enabled)
+    return;
+  started_ = true;
+}
+
+void MetatraceWriter::Disable() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!started_)
+    return;
+  metatrace::Disable();
+  started_ = false;
+  trace_writer_.reset();
+}
+
+void MetatraceWriter::WriteAllAvailableEvents() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!started_)
+    return;
+  for (auto it = metatrace::RingBuffer::GetReadIterator(); it; ++it) {
+    auto type_and_id = it->type_and_id.load(std::memory_order_acquire);
+    if (type_and_id == 0)
+      break;  // Stop at the first incomplete event.
+
+    auto packet = trace_writer_->NewTracePacket();
+    packet->set_timestamp(it->timestamp_ns());
+    auto* evt = packet->set_perfetto_metatrace();
+    uint16_t type = type_and_id & metatrace::Record::kTypeMask;
+    uint16_t id = type_and_id & ~metatrace::Record::kTypeMask;
+    if (type == metatrace::Record::kTypeCounter) {
+      evt->set_counter_id(id);
+      evt->set_counter_value(it->counter_value);
+    } else {
+      evt->set_event_id(id);
+      evt->set_event_duration_ns(it->duration_ns);
+    }
+
+    evt->set_thread_id(static_cast<uint32_t>(it->thread_id));
+
+    if (metatrace::RingBuffer::has_overruns())
+      evt->set_has_overruns(true);
+  }
+  // The |it| destructor will automatically update the read index position in
+  // the meta-trace ring buffer.
+}
+
+void MetatraceWriter::WriteAllAndFlushTraceWriter(
+    std::function<void()> callback) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!started_)
+    return;
+  WriteAllAvailableEvents();
+  trace_writer_->Flush(std::move(callback));
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/service/packet_stream_validator.cc
+// gen_amalgamated begin header: src/tracing/service/packet_stream_validator.h
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACING_SERVICE_PACKET_STREAM_VALIDATOR_H_
+#define SRC_TRACING_SERVICE_PACKET_STREAM_VALIDATOR_H_
+
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/slice.h"
+
+namespace perfetto {
+
+// Checks that the stream of trace packets sent by the producer is well formed.
+// This includes:
+//
+// - Checking that the packets are not truncated.
+// - There are no dangling bytes left over in the packets.
+// - Any trusted fields (e.g., uid) are not set.
+//
+// Note that we only validate top-level fields in the trace proto; sub-messages
+// are simply skipped.
+class PacketStreamValidator {
+ public:
+  PacketStreamValidator() = delete;
+
+  static bool Validate(const Slices&);
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_SERVICE_PACKET_STREAM_VALIDATOR_H_
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/service/packet_stream_validator.h"
+
+#include <stddef.h>
+
+#include <cinttypes>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
+
+namespace perfetto {
+
+namespace {
+
+using protozero::proto_utils::ProtoWireType;
+
+const uint32_t kReservedFieldIds[] = {
+    protos::pbzero::TracePacket::kTrustedUidFieldNumber,
+    protos::pbzero::TracePacket::kTrustedPacketSequenceIdFieldNumber,
+    protos::pbzero::TracePacket::kTraceConfigFieldNumber,
+    protos::pbzero::TracePacket::kTraceStatsFieldNumber,
+    protos::pbzero::TracePacket::kCompressedPacketsFieldNumber,
+    protos::pbzero::TracePacket::kSynchronizationMarkerFieldNumber,
+    protos::pbzero::TracePacket::kTrustedPidFieldNumber,
+    protos::pbzero::TracePacket::kMachineIdFieldNumber,
+};
+
+// This translation unit is quite subtle and perf-sensitive. Remember to check
+// BM_PacketStreamValidator in perfetto_benchmarks when making changes.
+
+// Checks that a packet, spread over several slices, is well-formed and doesn't
+// contain reserved top-level fields.
+// The checking logic is based on a state-machine that skips the fields' payload
+// and operates as follows:
+//              +-------------------------------+ <-------------------------+
+// +----------> | Read field preamble (varint)  | <----------------------+  |
+// |            +-------------------------------+                        |  |
+// |              |              |            |                          |  |
+// |       <Varint>        <Fixed 32/64>     <Length-delimited field>    |  |
+// |          V                  |                      V                |  |
+// |  +------------------+       |               +--------------+        |  |
+// |  | Read field value |       |               | Read length  |        |  |
+// |  | (another varint) |       |               |   (varint)   |        |  |
+// |  +------------------+       |               +--------------+        |  |
+// |           |                 V                      V                |  |
+// +-----------+        +----------------+     +-----------------+       |  |
+//                      | Skip 4/8 Bytes |     | Skip $len Bytes |-------+  |
+//                      +----------------+     +-----------------+          |
+//                               |                                          |
+//                               +------------------------------------------+
+class ProtoFieldParserFSM {
+ public:
+  // This method effectively continuously parses varints (either for the field
+  // preamble or the payload or the submessage length) and tells the caller
+  // (the Validate() method) how many bytes to skip until the next field.
+  size_t Push(uint8_t octet) {
+    varint_ |= static_cast<uint64_t>(octet & 0x7F) << varint_shift_;
+    if (octet & 0x80) {
+      varint_shift_ += 7;
+      if (varint_shift_ >= 64) {
+        // Do not invoke UB on next call.
+        varint_shift_ = 0;
+        state_ = kInvalidVarInt;
+      }
+      return 0;
+    }
+    uint64_t varint = varint_;
+    varint_ = 0;
+    varint_shift_ = 0;
+
+    switch (state_) {
+      case kFieldPreamble: {
+        uint64_t field_type = varint & 7;  // 7 = 0..0111
+        auto field_id = static_cast<uint32_t>(varint >> 3);
+        // Check if the field id is reserved, go into an error state if it is.
+        for (size_t i = 0; i < base::ArraySize(kReservedFieldIds); ++i) {
+          if (field_id == kReservedFieldIds[i]) {
+            state_ = kWroteReservedField;
+            return 0;
+          }
+        }
+        // The field type is legit, now check it's well formed and within
+        // boundaries.
+        if (field_type == static_cast<uint64_t>(ProtoWireType::kVarInt)) {
+          state_ = kVarIntValue;
+        } else if (field_type ==
+                   static_cast<uint64_t>(ProtoWireType::kFixed32)) {
+          return 4;
+        } else if (field_type ==
+                   static_cast<uint64_t>(ProtoWireType::kFixed64)) {
+          return 8;
+        } else if (field_type ==
+                   static_cast<uint64_t>(ProtoWireType::kLengthDelimited)) {
+          state_ = kLenDelimitedLen;
+        } else {
+          state_ = kUnknownFieldType;
+        }
+        return 0;
+      }
+
+      case kVarIntValue: {
+        // Consume the int field payload and go back to the next field.
+        state_ = kFieldPreamble;
+        return 0;
+      }
+
+      case kLenDelimitedLen: {
+        if (varint > protozero::proto_utils::kMaxMessageLength) {
+          state_ = kMessageTooBig;
+          return 0;
+        }
+        state_ = kFieldPreamble;
+        return static_cast<size_t>(varint);
+      }
+
+      case kWroteReservedField:
+      case kUnknownFieldType:
+      case kMessageTooBig:
+      case kInvalidVarInt:
+        // Persistent error states.
+        return 0;
+
+    }          // switch(state_)
+    return 0;  // To keep GCC happy.
+  }
+
+  // Queried at the end of the all payload. A message is well-formed only
+  // if the FSM is back to the state where it should parse the next field and
+  // hasn't started parsing any preamble.
+  bool valid() const { return state_ == kFieldPreamble && varint_shift_ == 0; }
+  int state() const { return static_cast<int>(state_); }
+
+ private:
+  enum State {
+    kFieldPreamble = 0,  // Parsing the varint for the field preamble.
+    kVarIntValue,        // Parsing the varint value for the field payload.
+    kLenDelimitedLen,    // Parsing the length of the length-delimited field.
+
+    // Error states:
+    kWroteReservedField,  // Tried to set a reserved field id.
+    kUnknownFieldType,    // Encountered an invalid field type.
+    kMessageTooBig,       // Size of the length delimited message was too big.
+    kInvalidVarInt,       // VarInt larger than 64 bits.
+  };
+
+  State state_ = kFieldPreamble;
+  uint64_t varint_ = 0;
+  uint32_t varint_shift_ = 0;
+};
+
+}  // namespace
+
+// static
+bool PacketStreamValidator::Validate(const Slices& slices) {
+  ProtoFieldParserFSM parser;
+  size_t skip_bytes = 0;
+  for (const Slice& slice : slices) {
+    for (size_t i = 0; i < slice.size;) {
+      const size_t skip_bytes_cur_slice = std::min(skip_bytes, slice.size - i);
+      if (skip_bytes_cur_slice > 0) {
+        i += skip_bytes_cur_slice;
+        skip_bytes -= skip_bytes_cur_slice;
+      } else {
+        uint8_t octet = *(reinterpret_cast<const uint8_t*>(slice.start) + i);
+        skip_bytes = parser.Push(octet);
+        i++;
+      }
+    }
+  }
+  if (skip_bytes == 0 && parser.valid())
+    return true;
+
+  PERFETTO_DLOG("Packet validation error (state %d, skip = %zu)",
+                parser.state(), skip_bytes);
+  return false;
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/service/trace_buffer.cc
+// gen_amalgamated begin header: src/tracing/service/trace_buffer.h
+// gen_amalgamated begin header: include/perfetto/ext/base/flat_hash_map.h
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_FLAT_HASH_MAP_H_
+#define INCLUDE_PERFETTO_EXT_BASE_FLAT_HASH_MAP_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+
+#include <algorithm>
+#include <limits>
+
+namespace perfetto {
+namespace base {
+
+// An open-addressing hashmap implementation.
+// Pointers are not stable, neither for keys nor values.
+// Has similar performances of a RobinHood hash (without the complications)
+// and 2x an unordered map.
+// Doc: http://go/perfetto-hashtables .
+//
+// When used to implement a string pool in TraceProcessor, the performance
+// characteristics obtained by replaying the set of strings seeen in a 4GB trace
+// (226M strings, 1M unique) are the following (see flat_hash_map_benchmark.cc):
+// This(Linear+AppendOnly)    879,383,676 ns    258.013M insertions/s
+// This(LinearProbe):         909,206,047 ns    249.546M insertions/s
+// This(QuadraticProbe):    1,083,844,388 ns    209.363M insertions/s
+// std::unordered_map:      6,203,351,870 ns    36.5811M insertions/s
+// tsl::robin_map:            931,403,397 ns    243.622M insertions/s
+// absl::flat_hash_map:       998,013,459 ns    227.379M insertions/s
+// FollyF14FastMap:         1,181,480,602 ns    192.074M insertions/s
+//
+// TODO(primiano): the table regresses for heavy insert+erase workloads since we
+// don't clean up tombstones outside of resizes. In the limit, the entire
+// table's capacity is made up of values/tombstones, so each search has to
+// exhaustively scan the full capacity.
+
+// The structs below define the probing algorithm used to probe slots upon a
+// collision. They are guaranteed to visit all slots as our table size is always
+// a power of two (see https://en.wikipedia.org/wiki/Quadratic_probing).
+
+// Linear probing can be faster if the hashing is well distributed and the load
+// is not high. For TraceProcessor's StringPool this is the fastest. It can
+// degenerate badly if the hashing doesn't spread (e.g., if using directly pids
+// as keys, with a no-op hashing function).
+struct LinearProbe {
+  static inline size_t Calc(size_t key_hash, size_t step, size_t capacity) {
+    return (key_hash + step) & (capacity - 1);  // Linear probe
+  }
+};
+
+// Generates the sequence: 0, 3, 10, 21, 36, 55, ...
+// Can be a bit (~5%) slower than LinearProbe because it's less cache hot, but
+// avoids degenerating badly if the hash function is bad and causes clusters.
+// A good default choice unless benchmarks prove otherwise.
+struct QuadraticProbe {
+  static inline size_t Calc(size_t key_hash, size_t step, size_t capacity) {
+    return (key_hash + 2 * step * step + step) & (capacity - 1);
+  }
+};
+
+// Tends to perform in the middle between linear and quadratic.
+// It's a bit more cache-effective than the QuadraticProbe but can create more
+// clustering if the hash function doesn't spread well.
+// Generates the sequence: 0, 1, 3, 6, 10, 15, 21, ...
+struct QuadraticHalfProbe {
+  static inline size_t Calc(size_t key_hash, size_t step, size_t capacity) {
+    return (key_hash + (step * step + step) / 2) & (capacity - 1);
+  }
+};
+
+template <typename Key,
+          typename Value,
+          typename Hasher = base::Hash<Key>,
+          typename Probe = QuadraticProbe,
+          bool AppendOnly = false>
+class FlatHashMap {
+ public:
+  class Iterator {
+   public:
+    explicit Iterator(const FlatHashMap* map) : map_(map) { FindNextNonFree(); }
+    ~Iterator() = default;
+    Iterator(const Iterator&) = default;
+    Iterator& operator=(const Iterator&) = default;
+    Iterator(Iterator&&) noexcept = default;
+    Iterator& operator=(Iterator&&) noexcept = default;
+
+    Key& key() { return map_->keys_[idx_]; }
+    Value& value() { return map_->values_[idx_]; }
+    const Key& key() const { return map_->keys_[idx_]; }
+    const Value& value() const { return map_->values_[idx_]; }
+
+    explicit operator bool() const { return idx_ != kEnd; }
+    Iterator& operator++() {
+      PERFETTO_DCHECK(idx_ < map_->capacity_);
+      ++idx_;
+      FindNextNonFree();
+      return *this;
+    }
+
+   private:
+    static constexpr size_t kEnd = std::numeric_limits<size_t>::max();
+
+    void FindNextNonFree() {
+      const auto& tags = map_->tags_;
+      for (; idx_ < map_->capacity_; idx_++) {
+        if (tags[idx_] != kFreeSlot && (AppendOnly || tags[idx_] != kTombstone))
+          return;
+      }
+      idx_ = kEnd;
+    }
+
+    const FlatHashMap* map_ = nullptr;
+    size_t idx_ = 0;
+  };  // Iterator
+
+  static constexpr int kDefaultLoadLimitPct = 75;
+  explicit FlatHashMap(size_t initial_capacity = 0,
+                       int load_limit_pct = kDefaultLoadLimitPct)
+      : load_limit_percent_(load_limit_pct) {
+    if (initial_capacity > 0)
+      Reset(initial_capacity);
+  }
+
+  // We are calling Clear() so that the destructors for the inserted entries are
+  // called (unless they are trivial, in which case it will be a no-op).
+  ~FlatHashMap() { Clear(); }
+
+  FlatHashMap(FlatHashMap&& other) noexcept {
+    tags_ = std::move(other.tags_);
+    keys_ = std::move(other.keys_);
+    values_ = std::move(other.values_);
+    capacity_ = other.capacity_;
+    size_ = other.size_;
+    max_probe_length_ = other.max_probe_length_;
+    load_limit_ = other.load_limit_;
+    load_limit_percent_ = other.load_limit_percent_;
+
+    new (&other) FlatHashMap();
+  }
+
+  FlatHashMap& operator=(FlatHashMap&& other) noexcept {
+    this->~FlatHashMap();
+    new (this) FlatHashMap(std::move(other));
+    return *this;
+  }
+
+  FlatHashMap(const FlatHashMap&) = delete;
+  FlatHashMap& operator=(const FlatHashMap&) = delete;
+
+  std::pair<Value*, bool> Insert(Key key, Value value) {
+    const size_t key_hash = Hasher{}(key);
+    const uint8_t tag = HashToTag(key_hash);
+    static constexpr size_t kSlotNotFound = std::numeric_limits<size_t>::max();
+
+    // This for loop does in reality at most two attempts:
+    // The first iteration either:
+    //  - Early-returns, because the key exists already,
+    //  - Finds an insertion slot and proceeds because the load is < limit.
+    // The second iteration is only hit in the unlikely case of this insertion
+    // bringing the table beyond the target |load_limit_| (or the edge case
+    // of the HT being full, if |load_limit_pct_| = 100).
+    // We cannot simply pre-grow the table before insertion, because we must
+    // guarantee that calling Insert() with a key that already exists doesn't
+    // invalidate iterators.
+    size_t insertion_slot;
+    size_t probe_len;
+    for (;;) {
+      PERFETTO_DCHECK((capacity_ & (capacity_ - 1)) == 0);  // Must be a pow2.
+      insertion_slot = kSlotNotFound;
+      // Start the iteration at the desired slot (key_hash % capacity_)
+      // searching either for a free slot or a tombstone. In the worst case we
+      // might end up scanning the whole array of slots. The Probe functions are
+      // guaranteed to visit all the slots within |capacity_| steps. If we find
+      // a free slot, we can stop the search immediately (a free slot acts as an
+      // "end of chain for entries having the same hash". If we find a
+      // tombstones (a deleted slot) we remember its position, but have to keep
+      // searching until a free slot to make sure we don't insert a duplicate
+      // key.
+      for (probe_len = 0; probe_len < capacity_;) {
+        const size_t idx = Probe::Calc(key_hash, probe_len, capacity_);
+        PERFETTO_DCHECK(idx < capacity_);
+        const uint8_t tag_idx = tags_[idx];
+        ++probe_len;
+        if (tag_idx == kFreeSlot) {
+          // Rationale for "insertion_slot == kSlotNotFound": if we encountered
+          // a tombstone while iterating we should reuse that rather than
+          // taking another slot.
+          if (AppendOnly || insertion_slot == kSlotNotFound)
+            insertion_slot = idx;
+          break;
+        }
+        // We should never encounter tombstones in AppendOnly mode.
+        PERFETTO_DCHECK(!(tag_idx == kTombstone && AppendOnly));
+        if (!AppendOnly && tag_idx == kTombstone) {
+          insertion_slot = idx;
+          continue;
+        }
+        if (tag_idx == tag && keys_[idx] == key) {
+          // The key is already in the map.
+          return std::make_pair(&values_[idx], false);
+        }
+      }  // for (idx)
+
+      // If we got to this point the key does not exist (otherwise we would have
+      // hit the return above) and we are going to insert a new entry.
+      // Before doing so, ensure we stay under the target load limit.
+      if (PERFETTO_UNLIKELY(size_ >= load_limit_)) {
+        MaybeGrowAndRehash(/*grow=*/true);
+        continue;
+      }
+      PERFETTO_DCHECK(insertion_slot != kSlotNotFound);
+      break;
+    }  // for (attempt)
+
+    PERFETTO_CHECK(insertion_slot < capacity_);
+
+    // We found a free slot (or a tombstone). Proceed with the insertion.
+    Value* value_idx = &values_[insertion_slot];
+    new (&keys_[insertion_slot]) Key(std::move(key));
+    new (value_idx) Value(std::move(value));
+    tags_[insertion_slot] = tag;
+    PERFETTO_DCHECK(probe_len > 0 && probe_len <= capacity_);
+    max_probe_length_ = std::max(max_probe_length_, probe_len);
+    size_++;
+
+    return std::make_pair(value_idx, true);
+  }
+
+  Value* Find(const Key& key) const {
+    const size_t idx = FindInternal(key);
+    if (idx == kNotFound)
+      return nullptr;
+    return &values_[idx];
+  }
+
+  bool Erase(const Key& key) {
+    if (AppendOnly)
+      PERFETTO_FATAL("Erase() not supported because AppendOnly=true");
+    size_t idx = FindInternal(key);
+    if (idx == kNotFound)
+      return false;
+    EraseInternal(idx);
+    return true;
+  }
+
+  void Clear() {
+    // Avoid trivial heap operations on zero-capacity std::move()-d objects.
+    if (PERFETTO_UNLIKELY(capacity_ == 0))
+      return;
+
+    for (size_t i = 0; i < capacity_; ++i) {
+      const uint8_t tag = tags_[i];
+      if (tag != kFreeSlot && tag != kTombstone)
+        EraseInternal(i);
+    }
+    // Clear all tombstones. We really need to do this for AppendOnly.
+    MaybeGrowAndRehash(/*grow=*/false);
+  }
+
+  Value& operator[](Key key) {
+    auto it_and_inserted = Insert(std::move(key), Value{});
+    return *it_and_inserted.first;
+  }
+
+  Iterator GetIterator() { return Iterator(this); }
+  const Iterator GetIterator() const { return Iterator(this); }
+
+  size_t size() const { return size_; }
+  size_t capacity() const { return capacity_; }
+
+  // "protected" here is only for the flat_hash_map_benchmark.cc. Everything
+  // below is by all means private.
+ protected:
+  enum ReservedTags : uint8_t { kFreeSlot = 0, kTombstone = 1 };
+  static constexpr size_t kNotFound = std::numeric_limits<size_t>::max();
+
+  size_t FindInternal(const Key& key) const {
+    const size_t key_hash = Hasher{}(key);
+    const uint8_t tag = HashToTag(key_hash);
+    PERFETTO_DCHECK((capacity_ & (capacity_ - 1)) == 0);  // Must be a pow2.
+    PERFETTO_DCHECK(max_probe_length_ <= capacity_);
+    for (size_t i = 0; i < max_probe_length_; ++i) {
+      const size_t idx = Probe::Calc(key_hash, i, capacity_);
+      const uint8_t tag_idx = tags_[idx];
+
+      if (tag_idx == kFreeSlot)
+        return kNotFound;
+      // HashToTag() never returns kTombstone, so the tag-check below cannot
+      // possibly match. Also we just want to skip tombstones.
+      if (tag_idx == tag && keys_[idx] == key) {
+        PERFETTO_DCHECK(tag_idx > kTombstone);
+        return idx;
+      }
+    }  // for (idx)
+    return kNotFound;
+  }
+
+  void EraseInternal(size_t idx) {
+    PERFETTO_DCHECK(tags_[idx] > kTombstone);
+    PERFETTO_DCHECK(size_ > 0);
+    tags_[idx] = kTombstone;
+    keys_[idx].~Key();
+    values_[idx].~Value();
+    size_--;
+  }
+
+  PERFETTO_NO_INLINE void MaybeGrowAndRehash(bool grow) {
+    PERFETTO_DCHECK(size_ <= capacity_);
+    const size_t old_capacity = capacity_;
+
+    // Grow quickly up to 1MB, then chill.
+    const size_t old_size_bytes = old_capacity * (sizeof(Key) + sizeof(Value));
+    const size_t grow_factor = old_size_bytes < (1024u * 1024u) ? 8 : 2;
+    const size_t new_capacity =
+        grow ? std::max(old_capacity * grow_factor, size_t(1024))
+             : old_capacity;
+
+    auto old_tags(std::move(tags_));
+    auto old_keys(std::move(keys_));
+    auto old_values(std::move(values_));
+    size_t old_size = size_;
+
+    // This must be a CHECK (i.e. not just a DCHECK) to prevent UAF attacks on
+    // 32-bit archs that try to double the size of the table until wrapping.
+    PERFETTO_CHECK(new_capacity >= old_capacity);
+    Reset(new_capacity);
+
+    size_t new_size = 0;  // Recompute the size.
+    for (size_t i = 0; i < old_capacity; ++i) {
+      const uint8_t old_tag = old_tags[i];
+      if (old_tag != kFreeSlot && old_tag != kTombstone) {
+        Insert(std::move(old_keys[i]), std::move(old_values[i]));
+        old_keys[i].~Key();  // Destroy the old objects.
+        old_values[i].~Value();
+        new_size++;
+      }
+    }
+    PERFETTO_DCHECK(new_size == old_size);
+    size_ = new_size;
+  }
+
+  // Doesn't call destructors. Use Clear() for that.
+  PERFETTO_NO_INLINE void Reset(size_t n) {
+    PERFETTO_DCHECK((n & (n - 1)) == 0);  // Must be a pow2.
+
+    capacity_ = n;
+    max_probe_length_ = 0;
+    size_ = 0;
+    load_limit_ = n * static_cast<size_t>(load_limit_percent_) / 100;
+    load_limit_ = std::min(load_limit_, n);
+
+    tags_.reset(new uint8_t[n]);
+    memset(&tags_[0], 0, n);                  // Clear all tags.
+    keys_ = AlignedAllocTyped<Key[]>(n);      // Deliberately not 0-initialized.
+    values_ = AlignedAllocTyped<Value[]>(n);  // Deliberately not 0-initialized.
+  }
+
+  static inline uint8_t HashToTag(size_t full_hash) {
+    uint8_t tag = full_hash >> (sizeof(full_hash) * 8 - 8);
+    // Ensure the hash is always >= 2. We use 0, 1 for kFreeSlot and kTombstone.
+    tag += (tag <= kTombstone) << 1;
+    PERFETTO_DCHECK(tag > kTombstone);
+    return tag;
+  }
+
+  size_t capacity_ = 0;
+  size_t size_ = 0;
+  size_t max_probe_length_ = 0;
+  size_t load_limit_ = 0;  // Updated every time |capacity_| changes.
+  int load_limit_percent_ =
+      kDefaultLoadLimitPct;  // Load factor limit in % of |capacity_|.
+
+  // These arrays have always the |capacity_| elements.
+  // Note: AlignedUniquePtr just allocates memory, doesn't invoke any ctor/dtor.
+  std::unique_ptr<uint8_t[]> tags_;
+  AlignedUniquePtr<Key[]> keys_;
+  AlignedUniquePtr<Value[]> values_;
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_FLAT_HASH_MAP_H_
+// gen_amalgamated begin header: include/perfetto/ext/tracing/core/client_identity.h
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_CLIENT_IDENTITY_H_
+#define INCLUDE_PERFETTO_EXT_TRACING_CORE_CLIENT_IDENTITY_H_
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/sys_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
+
+namespace perfetto {
+
+// This class groups data fields of a connected client that can get passed in
+// the tracing core to be emitted to trace packets.
+class ClientIdentity {
+ public:
+  ClientIdentity() = default;
+  ClientIdentity(uid_t uid, pid_t pid, MachineID machine_id = kDefaultMachineID)
+      : uid_(uid), pid_(pid), machine_id_(machine_id) {}
+
+  bool has_uid() const { return uid_ != base::kInvalidUid; }
+  uid_t uid() const { return uid_; }
+
+  bool has_pid() const { return pid_ != base::kInvalidPid; }
+  pid_t pid() const { return pid_; }
+
+  bool has_non_default_machine_id() const {
+    return machine_id_ != kDefaultMachineID;
+  }
+  base::MachineID machine_id() const { return machine_id_; }
+
+ private:
+  uid_t uid_ = base::kInvalidUid;
+  pid_t pid_ = base::kInvalidPid;
+  MachineID machine_id_ = kDefaultMachineID;
+};
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_CLIENT_IDENTITY_H_
+// gen_amalgamated begin header: src/tracing/service/histogram.h
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACING_SERVICE_HISTOGRAM_H_
+#define SRC_TRACING_SERVICE_HISTOGRAM_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <limits>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+
+namespace perfetto {
+
+using HistValue = int64_t;
+
+// Usage:
+// Histogram<10, 100, 1000> h;  // A histogram with 3 + 1 (overflow) bucket.
+// h.Add(value);
+// h.GetBucketSum(0);  // Returns SUM(x) for 0 < x <= 10
+// h.GetBucketSum(1);  // Returns SUM(x) for 10 < x <= 100
+// h.GetBucketSum(2);  // Returns SUM(x) for 100 < x <= 1000
+// h.GetBucketSum(3);  // Returns SUM(x) for x > 1000
+// Likewise h.GetBucketCount(x) returns the COUNT(x).
+template <HistValue... thresholds>
+class Histogram {
+ public:
+  // 1+ is for the overflow bucket (anything > the last threshold).
+  static constexpr size_t kNumBuckets = 1 + sizeof...(thresholds);
+
+  void Add(HistValue value) {
+    size_t bucket = BucketForValue(value);
+    bucket_sum_[bucket] += value;
+    ++bucket_count_[bucket];
+  }
+
+  static constexpr size_t num_buckets() { return kNumBuckets; }
+
+  HistValue GetBucketThres(size_t n) const {
+    PERFETTO_DCHECK(n < kNumBuckets);
+    return bucket_thres_[n];
+  }
+
+  uint64_t GetBucketCount(size_t n) const {
+    PERFETTO_DCHECK(n < kNumBuckets);
+    return bucket_count_[n];
+  }
+
+  HistValue GetBucketSum(size_t n) const {
+    PERFETTO_DCHECK(n < kNumBuckets);
+    return bucket_sum_[n];
+  }
+
+  void Merge(const Histogram& other) {
+    for (size_t i = 0; i < kNumBuckets; ++i) {
+      bucket_sum_[i] += other.bucket_sum_[i];
+      bucket_count_[i] += other.bucket_count_[i];
+    }
+  }
+
+ private:
+  static size_t BucketForValue(HistValue value) {
+    for (size_t i = 0; i < kNumBuckets - 1; i++) {
+      if (value <= bucket_thres_[i])
+        return i;
+    }
+    return kNumBuckets - 1;
+  }
+
+  static constexpr HistValue bucket_thres_[kNumBuckets]{
+      thresholds..., std::numeric_limits<HistValue>::max()};
+
+  HistValue bucket_sum_[kNumBuckets]{};
+  uint64_t bucket_count_[kNumBuckets]{};
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_SERVICE_HISTOGRAM_H_
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACING_SERVICE_TRACE_BUFFER_H_
+#define SRC_TRACING_SERVICE_TRACE_BUFFER_H_
+
+#include <stdint.h>
+#include <string.h>
+
+#include <array>
+#include <limits>
+#include <map>
+#include <tuple>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/flat_hash_map.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/paged_memory.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_annotations.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/client_identity.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/slice.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_stats.h"
+// gen_amalgamated expanded: #include "src/tracing/service/histogram.h"
+
+namespace perfetto {
+
+class TracePacket;
+
+// The main buffer, owned by the tracing service, where all the trace data is
+// ultimately stored into. The service will own several instances of this class,
+// at least one per active consumer (as defined in the |buffers| section of
+// trace_config.proto) and will copy chunks from the producer's shared memory
+// buffers into here when a CommitData IPC is received.
+//
+// Writing into the buffer
+// -----------------------
+// Data is copied from the SMB(s) using CopyChunkUntrusted(). The buffer will
+// hence contain data coming from different producers and different writer
+// sequences, more specifically:
+// - The service receives data by several producer(s), identified by their ID.
+// - Each producer writes several sequences identified by the same WriterID.
+//   (they correspond to TraceWriter instances in the producer).
+// - Each Writer writes, in order, several chunks.
+// - Each chunk contains zero, one, or more TracePacket(s), or even just
+//   fragments of packets (when they span across several chunks).
+//
+// So at any point in time, the buffer will contain a variable number of logical
+// sequences identified by the {ProducerID, WriterID} tuple. Any given chunk
+// will only contain packets (or fragments) belonging to the same sequence.
+//
+// The buffer operates by default as a ring buffer.
+// It has two overwrite policies:
+//  1. kOverwrite (default): if the write pointer reaches the read pointer, old
+//     unread chunks will be overwritten by new chunks.
+//  2. kDiscard: if the write pointer reaches the read pointer, unread chunks
+//     are preserved and the new chunks are discarded. Any future write becomes
+//     a no-op, even if the reader manages to fully catch up. This is because
+//     once a chunk is discarded, the sequence of packets is broken and trying
+//     to recover would be too hard (also due to the fact that, at the same
+//     time, we allow out-of-order commits and chunk re-writes).
+//
+// Chunks are (over)written in the same order of the CopyChunkUntrusted() calls.
+// When overwriting old content, entire chunks are overwritten or clobbered.
+// The buffer never leaves a partial chunk around. Chunks' payload is copied
+// as-is, but their header is not and is repacked in order to keep the
+// ProducerID around.
+//
+// Chunks are stored in the buffer next to each other. Each chunk is prefixed by
+// an inline header (ChunkRecord), which contains most of the fields of the
+// SharedMemoryABI ChunkHeader + the ProducerID + the size of the payload.
+// It's a conventional binary object stream essentially, where each ChunkRecord
+// tells where it ends and hence where to find the next one, like this:
+//
+//          .-------------------------. 16 byte boundary
+//          | ChunkRecord:   16 bytes |
+//          | - chunk id:     4 bytes |
+//          | - producer id:  2 bytes |
+//          | - writer id:    2 bytes |
+//          | - #fragments:   2 bytes |
+//    +-----+ - record size:  2 bytes |
+//    |     | - flags+pad:    4 bytes |
+//    |     +-------------------------+
+//    |     |                         |
+//    |     :     Chunk payload       :
+//    |     |                         |
+//    |     +-------------------------+
+//    |     |    Optional padding     |
+//    +---> +-------------------------+ 16 byte boundary
+//          |      ChunkRecord        |
+//          :                         :
+// Chunks stored in the buffer are always rounded up to 16 bytes (that is
+// sizeof(ChunkRecord)), in order to avoid further inner fragmentation.
+// Special "padding" chunks can be put in the buffer, e.g. in the case when we
+// try to write a chunk of size N while the write pointer is at the end of the
+// buffer, but the write pointer is < N bytes from the end (and hence needs to
+// wrap over).
+// Because of this, the buffer is self-describing: the contents of the buffer
+// can be reconstructed by just looking at the buffer content (this will be
+// quite useful in future to recover the buffer from crash reports).
+//
+// However, in order to keep some operations (patching and reading) fast, a
+// lookaside index is maintained (in |index_|), keeping each chunk in the buffer
+// indexed by their {ProducerID, WriterID, ChunkID} tuple.
+//
+// Patching data out-of-band
+// -------------------------
+// This buffer also supports patching chunks' payload out-of-band, after they
+// have been stored. This is to allow producers to backfill the "size" fields
+// of the protos that spawn across several chunks, when the previous chunks are
+// returned to the service. The MaybePatchChunkContents() deals with the fact
+// that a chunk might have been lost (because of wrapping) by the time the OOB
+// IPC comes.
+//
+// Reading from the buffer
+// -----------------------
+// This class supports one reader only (the consumer). Reads are NOT idempotent
+// as they move the read cursors around. Reading back the buffer is the most
+// conceptually complex part. The ReadNextTracePacket() method operates with
+// whole packet granularity. Packets are returned only when all their fragments
+// are available.
+// This class takes care of:
+// - Gluing packets within the same sequence, even if they are not stored
+//   adjacently in the buffer.
+// - Re-ordering chunks within a sequence (using the ChunkID, which wraps).
+// - Detecting holes in packet fragments (because of loss of chunks).
+// Reads guarantee that packets for the same sequence are read in FIFO order
+// (according to their ChunkID), but don't give any guarantee about the read
+// order of packets from different sequences, see comments in
+// ReadNextTracePacket() below.
+class TraceBuffer {
+ public:
+  static const size_t InlineChunkHeaderSize;  // For test/fake_packet.{cc,h}.
+
+  // See comment in the header above.
+  enum OverwritePolicy { kOverwrite, kDiscard };
+
+  // Argument for out-of-band patches applied through TryPatchChunkContents().
+  struct Patch {
+    // From SharedMemoryABI::kPacketHeaderSize.
+    static constexpr size_t kSize = 4;
+
+    size_t offset_untrusted;
+    std::array<uint8_t, kSize> data;
+  };
+
+  // Identifiers that are constant for a packet sequence.
+  struct PacketSequenceProperties {
+    ProducerID producer_id_trusted;
+    ClientIdentity client_identity_trusted;
+    WriterID writer_id;
+
+    uid_t producer_uid_trusted() const { return client_identity_trusted.uid(); }
+    pid_t producer_pid_trusted() const { return client_identity_trusted.pid(); }
+  };
+
+  // Holds the "used chunk" stats for each <Producer, Writer> tuple.
+  struct WriterStats {
+    Histogram<8, 32, 128, 512, 1024, 2048, 4096, 8192, 12288, 16384>
+        used_chunk_hist;
+  };
+
+  using WriterStatsMap = base::FlatHashMap<ProducerAndWriterID,
+                                           WriterStats,
+                                           std::hash<ProducerAndWriterID>,
+                                           base::QuadraticProbe,
+                                           /*AppendOnly=*/true>;
+
+  // Can return nullptr if the memory allocation fails.
+  static std::unique_ptr<TraceBuffer> Create(size_t size_in_bytes,
+                                             OverwritePolicy = kOverwrite);
+
+  ~TraceBuffer();
+
+  // Copies a Chunk from a producer Shared Memory Buffer into the trace buffer.
+  // |src| points to the first packet in the SharedMemoryABI's chunk shared with
+  // an untrusted producer. "untrusted" here means: the producer might be
+  // malicious and might change |src| concurrently while we read it (internally
+  // this method memcpy()-s first the chunk before processing it). None of the
+  // arguments should be trusted, unless otherwise stated. We can trust that
+  // |src| points to a valid memory area, but not its contents.
+  //
+  // This method may be called multiple times for the same chunk. In this case,
+  // the original chunk's payload will be overridden and its number of fragments
+  // and flags adjusted to match |num_fragments| and |chunk_flags|. The service
+  // may use this to insert partial chunks (|chunk_complete = false|) before the
+  // producer has committed them.
+  //
+  // If |chunk_complete| is |false|, the TraceBuffer will only consider the
+  // first |num_fragments - 1| packets to be complete, since the producer may
+  // not have finished writing the latest packet. Reading from a sequence will
+  // also not progress past any incomplete chunks until they were rewritten with
+  // |chunk_complete = true|, e.g. after a producer's commit.
+  //
+  // TODO(eseckler): Pass in a PacketStreamProperties instead of individual IDs.
+  void CopyChunkUntrusted(ProducerID producer_id_trusted,
+                          const ClientIdentity& client_identity_trusted,
+
+                          WriterID writer_id,
+                          ChunkID chunk_id,
+                          uint16_t num_fragments,
+                          uint8_t chunk_flags,
+                          bool chunk_complete,
+                          const uint8_t* src,
+                          size_t size);
+
+  // Applies a batch of |patches| to the given chunk, if the given chunk is
+  // still in the buffer. Does nothing if the given ChunkID is gone.
+  // Returns true if the chunk has been found and patched, false otherwise.
+  // |other_patches_pending| is used to determine whether this is the only
+  // batch of patches for the chunk or there is more.
+  // If |other_patches_pending| == false, the chunk is marked as ready to be
+  // consumed. If true, the state of the chunk is not altered.
+  //
+  // Note: If the producer is batching commits (see shared_memory_arbiter.h), it
+  // will also attempt to do patching locally. Namely, if nested messages are
+  // completed while the chunk on which they started is being batched (i.e.
+  // before it has been committed to the service), the producer will apply the
+  // respective patches to the batched chunk. These patches will not be sent to
+  // the service - i.e. only the patches that the producer did not manage to
+  // apply before committing the chunk will be applied here.
+  bool TryPatchChunkContents(ProducerID,
+                             WriterID,
+                             ChunkID,
+                             const Patch* patches,
+                             size_t patches_size,
+                             bool other_patches_pending);
+
+  // To read the contents of the buffer the caller needs to:
+  //   BeginRead()
+  //   while (ReadNextTracePacket(packet_fragments)) { ... }
+  // No other calls to any other method should be interleaved between
+  // BeginRead() and ReadNextTracePacket().
+  // Reads in the TraceBuffer are NOT idempotent.
+  void BeginRead();
+
+  // Returns the next packet in the buffer, if any, and the producer_id,
+  // producer_uid, and writer_id of the producer/writer that wrote it (as passed
+  // in the CopyChunkUntrusted() call). Returns false if no packets can be read
+  // at this point. If a packet was read successfully,
+  // |previous_packet_on_sequence_dropped| is set to |true| if the previous
+  // packet on the sequence was dropped from the buffer before it could be read
+  // (e.g. because its chunk was overridden due to the ring buffer wrapping or
+  // due to an ABI violation), and to |false| otherwise.
+  //
+  // This function returns only complete packets. Specifically:
+  // When there is at least one complete packet in the buffer, this function
+  // returns true and populates the TracePacket argument with the boundaries of
+  // each fragment for one packet.
+  // TracePacket will have at least one slice when this function returns true.
+  // When there are no whole packets eligible to read (e.g. we are still missing
+  // fragments) this function returns false.
+  // This function guarantees also that packets for a given
+  // {ProducerID, WriterID} are read in FIFO order.
+  // This function does not guarantee any ordering w.r.t. packets belonging to
+  // different WriterID(s). For instance, given the following packets copied
+  // into the buffer:
+  //   {ProducerID: 1, WriterID: 1}: P1 P2 P3
+  //   {ProducerID: 1, WriterID: 2}: P4 P5 P6
+  //   {ProducerID: 2, WriterID: 1}: P7 P8 P9
+  // The following read sequence is possible:
+  //   P1, P4, P7, P2, P3, P5, P8, P9, P6
+  // But the following is guaranteed to NOT happen:
+  //   P1, P5, P7, P4 (P4 cannot come after P5)
+  bool ReadNextTracePacket(TracePacket*,
+                           PacketSequenceProperties* sequence_properties,
+                           bool* previous_packet_on_sequence_dropped);
+
+  // Creates a read-only clone of the trace buffer. The read iterators of the
+  // new buffer will be reset, as if no Read() had been called. Calls to
+  // CopyChunkUntrusted() and TryPatchChunkContents() on the returned cloned
+  // TraceBuffer will CHECK().
+  std::unique_ptr<TraceBuffer> CloneReadOnly() const;
+
+  void set_read_only() { read_only_ = true; }
+  const WriterStatsMap& writer_stats() const { return writer_stats_; }
+  const TraceStats::BufferStats& stats() const { return stats_; }
+  size_t size() const { return size_; }
+  size_t used_size() const { return used_size_; }
+  OverwritePolicy overwrite_policy() const { return overwrite_policy_; }
+  bool has_data() const { return has_data_; }
+
+ private:
+  friend class TraceBufferTest;
+
+  // ChunkRecord is a Chunk header stored inline in the |data_| buffer, before
+  // the chunk payload (the packets' data). The |data_| buffer looks like this:
+  // +---------------+------------------++---------------+-----------------+
+  // | ChunkRecord 1 | Chunk payload 1  || ChunkRecord 2 | Chunk payload 2 | ...
+  // +---------------+------------------++---------------+-----------------+
+  // Most of the ChunkRecord fields are copied from SharedMemoryABI::ChunkHeader
+  // (the chunk header used in the shared memory buffers).
+  // A ChunkRecord can be a special "padding" record. In this case its payload
+  // should be ignored and the record should be just skipped.
+  //
+  // Full page move optimization:
+  // This struct has to be exactly (sizeof(PageHeader) + sizeof(ChunkHeader))
+  // (from shared_memory_abi.h) to allow full page move optimizations
+  // (TODO(primiano): not implemented yet). In the special case of moving a full
+  // 4k page that contains only one chunk, in fact, we can just ask the kernel
+  // to move the full SHM page (see SPLICE_F_{GIFT,MOVE}) and overlay the
+  // ChunkRecord on top of the moved SMB's header (page + chunk header).
+  // This special requirement is covered by static_assert(s) in the .cc file.
+  struct ChunkRecord {
+    explicit ChunkRecord(size_t sz) : flags{0}, is_padding{0} {
+      PERFETTO_DCHECK(sz >= sizeof(ChunkRecord) &&
+                      sz % sizeof(ChunkRecord) == 0 && sz <= kMaxSize);
+      size = static_cast<decltype(size)>(sz);
+    }
+
+    bool is_valid() const { return size != 0; }
+
+    // Keep this structure packed and exactly 16 bytes (128 bits) big.
+
+    // [32 bits] Monotonic counter within the same writer_id.
+    ChunkID chunk_id = 0;
+
+    // [16 bits] ID of the Producer from which the Chunk was copied from.
+    ProducerID producer_id = 0;
+
+    // [16 bits] Unique per Producer (but not within the service).
+    // If writer_id == kWriterIdPadding the record should just be skipped.
+    WriterID writer_id = 0;
+
+    // Number of fragments contained in the chunk.
+    uint16_t num_fragments = 0;
+
+    // Size in bytes, including sizeof(ChunkRecord) itself.
+    uint16_t size;
+
+    uint8_t flags : 6;  // See SharedMemoryABI::ChunkHeader::flags.
+    static constexpr size_t kFlagsBitMask = (1 << 6) - 1;
+
+    uint8_t is_padding : 1;
+    uint8_t unused_flag : 1;
+
+    // Not strictly needed, can be reused for more fields in the future. But
+    // right now helps to spot chunks in hex dumps.
+    char unused[3] = {'C', 'H', 'U'};
+
+    static constexpr size_t kMaxSize =
+        std::numeric_limits<decltype(size)>::max();
+  };
+
+  // Lookaside index entry. This serves two purposes:
+  // 1) Allow a fast lookup of ChunkRecord by their ID (the tuple
+  //   {ProducerID, WriterID, ChunkID}). This is used when applying out-of-band
+  //   patches to the contents of the chunks after they have been copied into
+  //   the TraceBuffer.
+  // 2) keep the chunks ordered by their ID. This is used when reading back.
+  // 3) Keep metadata about the status of the chunk, e.g. whether the contents
+  //    have been read already and should be skipped in a future read pass.
+  // This struct should not have any field that is essential for reconstructing
+  // the contents of the buffer from a crash dump.
+  struct ChunkMeta {
+    // Key used for sorting in the map.
+    struct Key {
+      Key(ProducerID p, WriterID w, ChunkID c)
+          : producer_id{p}, writer_id{w}, chunk_id{c} {}
+
+      Key(const Key&) noexcept = default;
+      Key& operator=(const Key&) = default;
+
+      explicit Key(const ChunkRecord& cr)
+          : Key(cr.producer_id, cr.writer_id, cr.chunk_id) {}
+
+      // Note that this sorting doesn't keep into account the fact that ChunkID
+      // will wrap over at some point. The extra logic in SequenceIterator deals
+      // with that.
+      bool operator<(const Key& other) const {
+        return std::tie(producer_id, writer_id, chunk_id) <
+               std::tie(other.producer_id, other.writer_id, other.chunk_id);
+      }
+
+      bool operator==(const Key& other) const {
+        return std::tie(producer_id, writer_id, chunk_id) ==
+               std::tie(other.producer_id, other.writer_id, other.chunk_id);
+      }
+
+      bool operator!=(const Key& other) const { return !(*this == other); }
+
+      // These fields should match at all times the corresponding fields in
+      // the |chunk_record|. They are copied here purely for efficiency to avoid
+      // dereferencing the buffer all the time.
+      ProducerID producer_id;
+      WriterID writer_id;
+      ChunkID chunk_id;
+    };
+
+    enum IndexFlags : uint8_t {
+      // If set, the chunk state was kChunkComplete at the time it was copied.
+      // If unset, the chunk was still kChunkBeingWritten while copied. When
+      // reading from the chunk's sequence, the sequence will not advance past
+      // this chunk until this flag is set.
+      kComplete = 1 << 0,
+
+      // If set, we skipped the last packet that we read from this chunk e.g.
+      // because we it was a continuation from a previous chunk that was dropped
+      // or due to an ABI violation.
+      kLastReadPacketSkipped = 1 << 1
+    };
+
+    ChunkMeta(uint32_t _record_off,
+              uint16_t _num_fragments,
+              bool complete,
+              uint8_t _flags,
+              const ClientIdentity& client_identity)
+        : record_off{_record_off},
+          client_identity_trusted(client_identity),
+          flags{_flags},
+          num_fragments{_num_fragments} {
+      if (complete)
+        index_flags = kComplete;
+    }
+
+    ChunkMeta(const ChunkMeta&) noexcept = default;
+
+    bool is_complete() const { return index_flags & kComplete; }
+
+    void set_complete(bool complete) {
+      if (complete) {
+        index_flags |= kComplete;
+      } else {
+        index_flags &= ~kComplete;
+      }
+    }
+
+    bool last_read_packet_skipped() const {
+      return index_flags & kLastReadPacketSkipped;
+    }
+
+    void set_last_read_packet_skipped(bool skipped) {
+      if (skipped) {
+        index_flags |= kLastReadPacketSkipped;
+      } else {
+        index_flags &= ~kLastReadPacketSkipped;
+      }
+    }
+
+    const uint32_t record_off;  // Offset of ChunkRecord within |data_|.
+    const ClientIdentity client_identity_trusted;
+    // Flags set by TraceBuffer to track the state of the chunk in the index.
+    uint8_t index_flags = 0;
+
+    // Correspond to |chunk_record->flags| and |chunk_record->num_fragments|.
+    // Copied here for performance reasons (avoids having to dereference
+    // |chunk_record| while iterating over ChunkMeta) and to aid debugging in
+    // case the buffer gets corrupted.
+    uint8_t flags = 0;           // See SharedMemoryABI::ChunkHeader::flags.
+    uint16_t num_fragments = 0;  // Total number of packet fragments.
+
+    uint16_t num_fragments_read = 0;  // Number of fragments already read.
+
+    // The start offset of the next fragment (the |num_fragments_read|-th) to be
+    // read. This is the offset in bytes from the beginning of the ChunkRecord's
+    // payload (the 1st fragment starts at |chunk_record| +
+    // sizeof(ChunkRecord)).
+    uint16_t cur_fragment_offset = 0;
+  };
+
+  using ChunkMap = std::map<ChunkMeta::Key, ChunkMeta>;
+
+  // Allows to iterate over a sub-sequence of |index_| for all keys belonging to
+  // the same {ProducerID,WriterID}. Furthermore takes into account the wrapping
+  // of ChunkID. Instances are valid only as long as the |index_| is not altered
+  // (can be used safely only between adjacent ReadNextTracePacket() calls).
+  // The order of the iteration will proceed in the following order:
+  // |wrapping_id| + 1 -> |seq_end|, |seq_begin| -> |wrapping_id|.
+  // Practical example:
+  // - Assume that kMaxChunkID == 7
+  // - Assume that we have all 8 chunks in the range (0..7).
+  // - Hence, |seq_begin| == c0, |seq_end| == c7
+  // - Assume |wrapping_id| = 4 (c4 is the last chunk copied over
+  //   through a CopyChunkUntrusted()).
+  // The resulting iteration order will be: c5, c6, c7, c0, c1, c2, c3, c4.
+  struct SequenceIterator {
+    // Points to the 1st key (the one with the numerically min ChunkID).
+    ChunkMap::iterator seq_begin;
+
+    // Points one past the last key (the one with the numerically max ChunkID).
+    ChunkMap::iterator seq_end;
+
+    // Current iterator, always >= seq_begin && <= seq_end.
+    ChunkMap::iterator cur;
+
+    // The latest ChunkID written. Determines the start/end of the sequence.
+    ChunkID wrapping_id;
+
+    bool is_valid() const { return cur != seq_end; }
+
+    ProducerID producer_id() const {
+      PERFETTO_DCHECK(is_valid());
+      return cur->first.producer_id;
+    }
+
+    WriterID writer_id() const {
+      PERFETTO_DCHECK(is_valid());
+      return cur->first.writer_id;
+    }
+
+    ChunkID chunk_id() const {
+      PERFETTO_DCHECK(is_valid());
+      return cur->first.chunk_id;
+    }
+
+    ChunkMeta& operator*() {
+      PERFETTO_DCHECK(is_valid());
+      return cur->second;
+    }
+
+    // Moves |cur| to the next chunk in the index.
+    // is_valid() will become false after calling this, if this was the last
+    // entry of the sequence.
+    void MoveNext();
+
+    void MoveToEnd() { cur = seq_end; }
+  };
+
+  enum class ReadAheadResult {
+    kSucceededReturnSlices,
+    kFailedMoveToNextSequence,
+    kFailedStayOnSameSequence,
+  };
+
+  enum class ReadPacketResult {
+    kSucceeded,
+    kFailedInvalidPacket,
+    kFailedEmptyPacket,
+  };
+
+  explicit TraceBuffer(OverwritePolicy);
+  TraceBuffer(const TraceBuffer&) = delete;
+  TraceBuffer& operator=(const TraceBuffer&) = delete;
+
+  // Not using the implicit copy ctor to avoid unintended copies.
+  // This tagged ctor should be used only for Clone().
+  struct CloneCtor {};
+  TraceBuffer(CloneCtor, const TraceBuffer&);
+
+  bool Initialize(size_t size);
+
+  // Returns an object that allows to iterate over chunks in the |index_| that
+  // have the same {ProducerID, WriterID} of
+  // |seq_begin.first.{producer,writer}_id|. |seq_begin| must be an iterator to
+  // the first entry in the |index_| that has a different {ProducerID, WriterID}
+  // from the previous one. It is valid for |seq_begin| to be == index_.end()
+  // (i.e. if the index is empty). The iteration takes care of ChunkID wrapping,
+  // by using |last_chunk_id_|.
+  SequenceIterator GetReadIterForSequence(ChunkMap::iterator seq_begin);
+
+  // Used as a last resort when a buffer corruption is detected.
+  void ClearContentsAndResetRWCursors();
+
+  // Adds a padding record of the given size (must be a multiple of
+  // sizeof(ChunkRecord)).
+  void AddPaddingRecord(size_t);
+
+  // Look for contiguous fragment of the same packet starting from |read_iter_|.
+  // If a contiguous packet is found, all the fragments are pushed into
+  // TracePacket and the function returns kSucceededReturnSlices. If not, the
+  // function returns either kFailedMoveToNextSequence or
+  // kFailedStayOnSameSequence, telling the caller to continue looking for
+  // packets.
+  ReadAheadResult ReadAhead(TracePacket*);
+
+  // Deletes (by marking the record invalid and removing form the index) all
+  // chunks from |wptr_| to |wptr_| + |bytes_to_clear|.
+  // Returns:
+  //   * The size of the gap left between the next valid Chunk and the end of
+  //     the deletion range.
+  //   * 0 if no next valid chunk exists (if the buffer is still zeroed).
+  //   * -1 if the buffer |overwrite_policy_| == kDiscard and the deletion would
+  //     cause unread chunks to be overwritten. In this case the buffer is left
+  //     untouched.
+  // Graphically, assume the initial situation is the following (|wptr_| = 10).
+  // |0        |10 (wptr_)       |30       |40                 |60
+  // +---------+-----------------+---------+-------------------+---------+
+  // | Chunk 1 | Chunk 2         | Chunk 3 | Chunk 4           | Chunk 5 |
+  // +---------+-----------------+---------+-------------------+---------+
+  //           |_________Deletion range_______|~~return value~~|
+  //
+  // A call to DeleteNextChunksFor(32) will remove chunks 2,3,4 and return 18
+  // (60 - 42), the distance between chunk 5 and the end of the deletion range.
+  ssize_t DeleteNextChunksFor(size_t bytes_to_clear);
+
+  // Decodes the boundaries of the next packet (or a fragment) pointed by
+  // ChunkMeta and pushes that into |TracePacket|. It also increments the
+  // |num_fragments_read| counter.
+  // TracePacket can be nullptr, in which case the read state is still advanced.
+  // When TracePacket is not nullptr, ProducerID must also be not null and will
+  // be updated with the ProducerID that originally wrote the chunk.
+  ReadPacketResult ReadNextPacketInChunk(ProducerAndWriterID,
+                                         ChunkMeta*,
+                                         TracePacket*);
+
+  void DcheckIsAlignedAndWithinBounds(const uint8_t* ptr) const {
+    PERFETTO_DCHECK(ptr >= begin() && ptr <= end() - sizeof(ChunkRecord));
+    PERFETTO_DCHECK(
+        (reinterpret_cast<uintptr_t>(ptr) & (alignof(ChunkRecord) - 1)) == 0);
+  }
+
+  ChunkRecord* GetChunkRecordAt(uint8_t* ptr) {
+    DcheckIsAlignedAndWithinBounds(ptr);
+    // We may be accessing a new (empty) record.
+    EnsureCommitted(static_cast<size_t>(ptr + sizeof(ChunkRecord) - begin()));
+    return reinterpret_cast<ChunkRecord*>(ptr);
+  }
+
+  void EnsureCommitted(size_t size) {
+    PERFETTO_DCHECK(size <= size_);
+    data_.EnsureCommitted(size);
+    used_size_ = std::max(used_size_, size);
+  }
+
+  void DiscardWrite();
+
+  // |src| can be nullptr (in which case |size| must be ==
+  // record.size - sizeof(ChunkRecord)), for the case of writing a padding
+  // record. |wptr_| is NOT advanced by this function, the caller must do that.
+  void WriteChunkRecord(uint8_t* wptr,
+                        const ChunkRecord& record,
+                        const uint8_t* src,
+                        size_t size) {
+    // Note: |record.size| will be slightly bigger than |size| because of the
+    // ChunkRecord header and rounding, to ensure that all ChunkRecord(s) are
+    // multiple of sizeof(ChunkRecord). The invariant is:
+    // record.size >= |size| + sizeof(ChunkRecord) (== if no rounding).
+    PERFETTO_DCHECK(size <= ChunkRecord::kMaxSize);
+    PERFETTO_DCHECK(record.size >= sizeof(record));
+    PERFETTO_DCHECK(record.size % sizeof(record) == 0);
+    PERFETTO_DCHECK(record.size >= size + sizeof(record));
+    DcheckIsAlignedAndWithinBounds(wptr);
+
+    // We may be writing to this area for the first time.
+    EnsureCommitted(static_cast<size_t>(wptr + record.size - begin()));
+
+    // Deliberately not a *D*CHECK.
+    PERFETTO_CHECK(wptr + sizeof(record) + size <= end());
+    memcpy(wptr, &record, sizeof(record));
+    if (PERFETTO_LIKELY(src)) {
+      // If the producer modifies the data in the shared memory buffer while we
+      // are copying it to the central buffer, TSAN will (rightfully) flag that
+      // as a race. However the entire purpose of copying the data into the
+      // central buffer is that we can validate it without worrying that the
+      // producer changes it from under our feet, so this race is benign. The
+      // alternative would be to try computing which part of the buffer is safe
+      // to read (assuming a well-behaving client), but the risk of introducing
+      // a bug that way outweighs the benefit.
+      PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(
+          src, size, "Benign race when copying chunk from shared memory.")
+      memcpy(wptr + sizeof(record), src, size);
+    } else {
+      PERFETTO_DCHECK(size == record.size - sizeof(record));
+    }
+    const size_t rounding_size = record.size - sizeof(record) - size;
+    memset(wptr + sizeof(record) + size, 0, rounding_size);
+  }
+
+  uint32_t GetOffset(const void* _addr) {
+    const uintptr_t addr = reinterpret_cast<uintptr_t>(_addr);
+    const uintptr_t buf_start = reinterpret_cast<uintptr_t>(begin());
+    PERFETTO_DCHECK(addr >= buf_start && addr < buf_start + size_);
+    return static_cast<uint32_t>(addr - buf_start);
+  }
+
+  uint8_t* begin() const { return reinterpret_cast<uint8_t*>(data_.Get()); }
+  uint8_t* end() const { return begin() + size_; }
+  size_t size_to_end() const { return static_cast<size_t>(end() - wptr_); }
+
+  base::PagedMemory data_;
+  size_t size_ = 0;            // Size in bytes of |data_|.
+
+  // High watermark. The number of bytes (<= |size_|) written into the buffer
+  // before the first wraparound. This increases as data is written into the
+  // buffer and then saturates at |size_|. Used for CloneReadOnly().
+  size_t used_size_ = 0;
+
+  size_t max_chunk_size_ = 0;  // Max size in bytes allowed for a chunk.
+  uint8_t* wptr_ = nullptr;    // Write pointer.
+
+  // An index that keeps track of the positions and metadata of each
+  // ChunkRecord.
+  ChunkMap index_;
+
+  // Read iterator used for ReadNext(). It is reset by calling BeginRead().
+  // It becomes invalid after any call to methods that alters the |index_|.
+  SequenceIterator read_iter_;
+
+  // See comments at the top of the file.
+  OverwritePolicy overwrite_policy_ = kOverwrite;
+
+  // This buffer is a read-only snapshot obtained via Clone(). If this is true
+  // calls to CopyChunkUntrusted() and TryPatchChunkContents() will CHECK().
+  bool read_only_ = false;
+
+  // Only used when |overwrite_policy_ == kDiscard|. This is set the first time
+  // a write fails because it would overwrite unread chunks.
+  bool discard_writes_ = false;
+
+  // Keeps track of the highest ChunkID written for a given sequence, taking
+  // into account a potential overflow of ChunkIDs. In the case of overflow,
+  // stores the highest ChunkID written since the overflow.
+  //
+  // TODO(primiano): should clean up keys from this map. Right now it grows
+  // without bounds (although realistically is not a problem unless we have too
+  // many producers/writers within the same trace session).
+  std::map<std::pair<ProducerID, WriterID>, ChunkID> last_chunk_id_written_;
+
+  // Statistics about buffer usage.
+  TraceStats::BufferStats stats_;
+
+  // Per-{Producer, Writer} statistics.
+  WriterStatsMap writer_stats_;
+
+  // Set to true upon the very first call to CopyChunkUntrusted() and never
+  // cleared. This is used to tell if the buffer has never been used since its
+  // creation (which in turn is used to optimize `clear_before_clone`).
+  bool has_data_ = false;
+
+#if PERFETTO_DCHECK_IS_ON()
+  bool changed_since_last_read_ = false;
+#endif
+
+  // When true disable some DCHECKs that have been put in place to detect
+  // bugs in the producers. This is for tests that feed malicious inputs and
+  // hence mimic a buggy producer.
+  bool suppress_client_dchecks_for_testing_ = false;
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_SERVICE_TRACE_BUFFER_H_
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/service/trace_buffer.h"
+
+#include <limits>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/client_identity.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+#define TRACE_BUFFER_VERBOSE_LOGGING() 0  // Set to 1 when debugging unittests.
+#if TRACE_BUFFER_VERBOSE_LOGGING()
+#define TRACE_BUFFER_DLOG PERFETTO_DLOG
+#else
+#define TRACE_BUFFER_DLOG(...) void()
+#endif
+
+namespace perfetto {
+
+namespace {
+constexpr uint8_t kFirstPacketContinuesFromPrevChunk =
+    SharedMemoryABI::ChunkHeader::kFirstPacketContinuesFromPrevChunk;
+constexpr uint8_t kLastPacketContinuesOnNextChunk =
+    SharedMemoryABI::ChunkHeader::kLastPacketContinuesOnNextChunk;
+constexpr uint8_t kChunkNeedsPatching =
+    SharedMemoryABI::ChunkHeader::kChunkNeedsPatching;
+}  // namespace.
+
+const size_t TraceBuffer::InlineChunkHeaderSize = sizeof(ChunkRecord);
+
+// static
+std::unique_ptr<TraceBuffer> TraceBuffer::Create(size_t size_in_bytes,
+                                                 OverwritePolicy pol) {
+  std::unique_ptr<TraceBuffer> trace_buffer(new TraceBuffer(pol));
+  if (!trace_buffer->Initialize(size_in_bytes))
+    return nullptr;
+  return trace_buffer;
+}
+
+TraceBuffer::TraceBuffer(OverwritePolicy pol) : overwrite_policy_(pol) {
+  // See comments in ChunkRecord for the rationale of this.
+  static_assert(sizeof(ChunkRecord) == sizeof(SharedMemoryABI::PageHeader) +
+                                           sizeof(SharedMemoryABI::ChunkHeader),
+                "ChunkRecord out of sync with the layout of SharedMemoryABI");
+}
+
+TraceBuffer::~TraceBuffer() = default;
+
+bool TraceBuffer::Initialize(size_t size) {
+  static_assert(
+      SharedMemoryABI::kMinPageSize % sizeof(ChunkRecord) == 0,
+      "sizeof(ChunkRecord) must be an integer divider of a page size");
+  auto max_size = std::numeric_limits<decltype(ChunkMeta::record_off)>::max();
+  PERFETTO_CHECK(size <= static_cast<size_t>(max_size));
+  data_ = base::PagedMemory::Allocate(
+      size, base::PagedMemory::kMayFail | base::PagedMemory::kDontCommit);
+  if (!data_.IsValid()) {
+    PERFETTO_ELOG("Trace buffer allocation failed (size: %zu)", size);
+    return false;
+  }
+  size_ = size;
+  used_size_ = 0;
+  stats_.set_buffer_size(size);
+  max_chunk_size_ = std::min(size, ChunkRecord::kMaxSize);
+  wptr_ = begin();
+  index_.clear();
+  last_chunk_id_written_.clear();
+  read_iter_ = GetReadIterForSequence(index_.end());
+  return true;
+}
+
+// Note: |src| points to a shmem region that is shared with the producer. Assume
+// that the producer is malicious and will change the content of |src|
+// while we execute here. Don't do any processing on it other than memcpy().
+void TraceBuffer::CopyChunkUntrusted(
+    ProducerID producer_id_trusted,
+    const ClientIdentity& client_identity_trusted,
+    WriterID writer_id,
+    ChunkID chunk_id,
+    uint16_t num_fragments,
+    uint8_t chunk_flags,
+    bool chunk_complete,
+    const uint8_t* src,
+    size_t size) {
+  PERFETTO_CHECK(!read_only_);
+
+  // |record_size| = |size| + sizeof(ChunkRecord), rounded up to avoid to end
+  // up in a fragmented state where size_to_end() < sizeof(ChunkRecord).
+  const size_t record_size =
+      base::AlignUp<sizeof(ChunkRecord)>(size + sizeof(ChunkRecord));
+  TRACE_BUFFER_DLOG("CopyChunk @ %" PRIdPTR ", size=%zu", wptr_ - begin(), record_size);
+  if (PERFETTO_UNLIKELY(record_size > max_chunk_size_)) {
+    stats_.set_abi_violations(stats_.abi_violations() + 1);
+    PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
+    return;
+  }
+
+  has_data_ = true;
+#if PERFETTO_DCHECK_IS_ON()
+  changed_since_last_read_ = true;
+#endif
+
+  // If the chunk hasn't been completed, we should only consider the first
+  // |num_fragments - 1| packets complete. For simplicity, we simply disregard
+  // the last one when we copy the chunk.
+  if (PERFETTO_UNLIKELY(!chunk_complete)) {
+    if (num_fragments > 0) {
+      num_fragments--;
+      // These flags should only affect the last packet in the chunk. We clear
+      // them, so that TraceBuffer is able to look at the remaining packets in
+      // this chunk.
+      chunk_flags &= ~kLastPacketContinuesOnNextChunk;
+      chunk_flags &= ~kChunkNeedsPatching;
+    }
+  }
+
+  ChunkRecord record(record_size);
+  record.producer_id = producer_id_trusted;
+  record.chunk_id = chunk_id;
+  record.writer_id = writer_id;
+  record.num_fragments = num_fragments;
+  record.flags = chunk_flags & ChunkRecord::kFlagsBitMask;
+  ChunkMeta::Key key(record);
+
+  // Check whether we have already copied the same chunk previously. This may
+  // happen if the service scrapes chunks in a potentially incomplete state
+  // before receiving commit requests for them from the producer. Note that the
+  // service may scrape and thus override chunks in arbitrary order since the
+  // chunks aren't ordered in the SMB.
+  const auto it = index_.find(key);
+  if (PERFETTO_UNLIKELY(it != index_.end())) {
+    ChunkMeta* record_meta = &it->second;
+    ChunkRecord* prev = GetChunkRecordAt(begin() + record_meta->record_off);
+
+    // Verify that the old chunk's metadata corresponds to the new one.
+    // Overridden chunks should never change size, since the page layout is
+    // fixed per writer. The number of fragments should also never decrease and
+    // flags should not be removed.
+    if (PERFETTO_UNLIKELY(ChunkMeta::Key(*prev) != key ||
+                          prev->size != record_size ||
+                          prev->num_fragments > num_fragments ||
+                          (prev->flags & chunk_flags) != prev->flags)) {
+      stats_.set_abi_violations(stats_.abi_violations() + 1);
+      PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
+      return;
+    }
+
+    // If this chunk was previously copied with the same number of fragments and
+    // the number didn't change, there's no need to copy it again. If the
+    // previous chunk was complete already, this should always be the case.
+    PERFETTO_DCHECK(suppress_client_dchecks_for_testing_ ||
+                    !record_meta->is_complete() ||
+                    (chunk_complete && prev->num_fragments == num_fragments));
+    if (prev->num_fragments == num_fragments) {
+      TRACE_BUFFER_DLOG("  skipping recommit of identical chunk");
+      return;
+    }
+
+    // If we've already started reading from chunk N+1 following this chunk N,
+    // don't override chunk N. Otherwise we may end up reading a packet from
+    // chunk N after having read from chunk N+1, thereby violating sequential
+    // read of packets. This shouldn't happen if the producer is well-behaved,
+    // because it shouldn't start chunk N+1 before completing chunk N.
+    ChunkMeta::Key subsequent_key = key;
+    static_assert(std::numeric_limits<ChunkID>::max() == kMaxChunkID,
+                  "ChunkID wraps");
+    subsequent_key.chunk_id++;
+    const auto subsequent_it = index_.find(subsequent_key);
+    if (subsequent_it != index_.end() &&
+        subsequent_it->second.num_fragments_read > 0) {
+      stats_.set_abi_violations(stats_.abi_violations() + 1);
+      PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
+      return;
+    }
+
+    // We should not have read past the last packet.
+    if (record_meta->num_fragments_read > prev->num_fragments) {
+      PERFETTO_ELOG(
+          "TraceBuffer read too many fragments from an incomplete chunk");
+      PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
+      return;
+    }
+
+    uint8_t* wptr = reinterpret_cast<uint8_t*>(prev);
+    TRACE_BUFFER_DLOG("  overriding chunk @ %" PRIdPTR ", size=%zu", wptr - begin(),
+                      record_size);
+
+    // Update chunk meta data stored in the index, as it may have changed.
+    record_meta->num_fragments = num_fragments;
+    record_meta->flags = chunk_flags;
+    record_meta->set_complete(chunk_complete);
+
+    // Override the ChunkRecord contents at the original |wptr|.
+    TRACE_BUFFER_DLOG("  copying @ [%" PRIdPTR " - %" PRIdPTR "] %zu", wptr - begin(),
+                      uintptr_t(wptr - begin()) + record_size, record_size);
+    WriteChunkRecord(wptr, record, src, size);
+    TRACE_BUFFER_DLOG("Chunk raw: %s",
+                      base::HexDump(wptr, record_size).c_str());
+    stats_.set_chunks_rewritten(stats_.chunks_rewritten() + 1);
+    return;
+  }
+
+  if (PERFETTO_UNLIKELY(discard_writes_))
+    return DiscardWrite();
+
+  // If there isn't enough room from the given write position. Write a padding
+  // record to clear the end of the buffer and wrap back.
+  const size_t cached_size_to_end = size_to_end();
+  if (PERFETTO_UNLIKELY(record_size > cached_size_to_end)) {
+    ssize_t res = DeleteNextChunksFor(cached_size_to_end);
+    if (res == -1)
+      return DiscardWrite();
+    PERFETTO_DCHECK(static_cast<size_t>(res) <= cached_size_to_end);
+    AddPaddingRecord(cached_size_to_end);
+    wptr_ = begin();
+    stats_.set_write_wrap_count(stats_.write_wrap_count() + 1);
+    PERFETTO_DCHECK(size_to_end() >= record_size);
+  }
+
+  // At this point either |wptr_| points to an untouched part of the buffer
+  // (i.e. *wptr_ == 0) or we are about to overwrite one or more ChunkRecord(s).
+  // In the latter case we need to first figure out where the next valid
+  // ChunkRecord is (if it exists) and add padding between the new record.
+  // Example ((w) == write cursor):
+  //
+  // Initial state (wtpr_ == 0):
+  // |0 (w)    |10               |30                  |50
+  // +---------+-----------------+--------------------+--------------------+
+  // | Chunk 1 | Chunk 2         | Chunk 3            | Chunk 4            |
+  // +---------+-----------------+--------------------+--------------------+
+  //
+  // Let's assume we now want now write a 5th Chunk of size == 35. The final
+  // state should look like this:
+  // |0                                |35 (w)         |50
+  // +---------------------------------+---------------+--------------------+
+  // | Chunk 5                         | Padding Chunk | Chunk 4            |
+  // +---------------------------------+---------------+--------------------+
+
+  // Deletes all chunks from |wptr_| to |wptr_| + |record_size|.
+  ssize_t del_res = DeleteNextChunksFor(record_size);
+  if (del_res == -1)
+    return DiscardWrite();
+  size_t padding_size = static_cast<size_t>(del_res);
+
+  // Now first insert the new chunk. At the end, if necessary, add the padding.
+  stats_.set_chunks_written(stats_.chunks_written() + 1);
+  stats_.set_bytes_written(stats_.bytes_written() + record_size);
+
+  uint32_t chunk_off = GetOffset(GetChunkRecordAt(wptr_));
+  auto it_and_inserted =
+      index_.emplace(key, ChunkMeta(chunk_off, num_fragments, chunk_complete,
+                                    chunk_flags, client_identity_trusted));
+  PERFETTO_DCHECK(it_and_inserted.second);
+  TRACE_BUFFER_DLOG("  copying @ [%" PRIdPTR " - %" PRIdPTR "] %zu", wptr_ - begin(),
+                    uintptr_t(wptr_ - begin()) + record_size, record_size);
+  WriteChunkRecord(wptr_, record, src, size);
+  TRACE_BUFFER_DLOG("Chunk raw: %s", base::HexDump(wptr_, record_size).c_str());
+  wptr_ += record_size;
+  if (wptr_ >= end()) {
+    PERFETTO_DCHECK(padding_size == 0);
+    wptr_ = begin();
+    stats_.set_write_wrap_count(stats_.write_wrap_count() + 1);
+  }
+  DcheckIsAlignedAndWithinBounds(wptr_);
+
+  // Chunks may be received out of order, so only update last_chunk_id if the
+  // new chunk_id is larger. But take into account overflows by only selecting
+  // the new ID if its distance to the latest ID is smaller than half the number
+  // space.
+  //
+  // This accounts for both the case where the new ID has just overflown and
+  // last_chunk_id be updated even though it's smaller (e.g. |chunk_id| = 1 and
+  // |last_chunk_id| = kMaxChunkId; chunk_id - last_chunk_id = 0) and the case
+  // where the new ID is an out-of-order ID right after an overflow and
+  // last_chunk_id shouldn't be updated even though it's larger (e.g. |chunk_id|
+  // = kMaxChunkId and |last_chunk_id| = 1; chunk_id - last_chunk_id =
+  // kMaxChunkId - 1).
+  auto producer_and_writer_id = std::make_pair(producer_id_trusted, writer_id);
+  ChunkID& last_chunk_id = last_chunk_id_written_[producer_and_writer_id];
+  static_assert(std::numeric_limits<ChunkID>::max() == kMaxChunkID,
+                "This code assumes that ChunkID wraps at kMaxChunkID");
+  if (chunk_id - last_chunk_id < kMaxChunkID / 2) {
+    last_chunk_id = chunk_id;
+  } else {
+    stats_.set_chunks_committed_out_of_order(
+        stats_.chunks_committed_out_of_order() + 1);
+  }
+
+  if (padding_size)
+    AddPaddingRecord(padding_size);
+}
+
+ssize_t TraceBuffer::DeleteNextChunksFor(size_t bytes_to_clear) {
+  PERFETTO_CHECK(!discard_writes_);
+
+  // Find the position of the first chunk which begins at or after
+  // (|wptr_| + |bytes|). Note that such a chunk might not exist and we might
+  // either reach the end of the buffer or a zeroed region of the buffer.
+  uint8_t* next_chunk_ptr = wptr_;
+  uint8_t* search_end = wptr_ + bytes_to_clear;
+  TRACE_BUFFER_DLOG("Delete [%zu %zu]", wptr_ - begin(), search_end - begin());
+  DcheckIsAlignedAndWithinBounds(wptr_);
+  PERFETTO_DCHECK(search_end <= end());
+  std::vector<ChunkMap::iterator> index_delete;
+  uint64_t chunks_overwritten = stats_.chunks_overwritten();
+  uint64_t bytes_overwritten = stats_.bytes_overwritten();
+  uint64_t padding_bytes_cleared = stats_.padding_bytes_cleared();
+  while (next_chunk_ptr < search_end) {
+    const ChunkRecord& next_chunk = *GetChunkRecordAt(next_chunk_ptr);
+    TRACE_BUFFER_DLOG(
+        "  scanning chunk [%zu %zu] (valid=%d)", next_chunk_ptr - begin(),
+        next_chunk_ptr - begin() + next_chunk.size, next_chunk.is_valid());
+
+    // We just reached the untouched part of the buffer, it's going to be all
+    // zeroes from here to end().
+    // Optimization: if during Initialize() we fill the buffer with padding
+    // records we could get rid of this branch.
+    if (PERFETTO_UNLIKELY(!next_chunk.is_valid())) {
+      // This should happen only at the first iteration. The zeroed area can
+      // only begin precisely at the |wptr_|, not after. Otherwise it means that
+      // we wrapped but screwed up the ChunkRecord chain.
+      PERFETTO_DCHECK(next_chunk_ptr == wptr_);
+      return 0;
+    }
+
+    // Remove |next_chunk| from the index, unless it's a padding record (padding
+    // records are not part of the index).
+    if (PERFETTO_LIKELY(!next_chunk.is_padding)) {
+      ChunkMeta::Key key(next_chunk);
+      auto it = index_.find(key);
+      bool will_remove = false;
+      if (PERFETTO_LIKELY(it != index_.end())) {
+        const ChunkMeta& meta = it->second;
+        if (PERFETTO_UNLIKELY(meta.num_fragments_read < meta.num_fragments)) {
+          if (overwrite_policy_ == kDiscard)
+            return -1;
+          chunks_overwritten++;
+          bytes_overwritten += next_chunk.size;
+        }
+        index_delete.push_back(it);
+        will_remove = true;
+      }
+      TRACE_BUFFER_DLOG(
+          "  del index {%" PRIu32 ",%" PRIu32 ",%u} @ [%" PRIdPTR " - %" PRIdPTR "] %d",
+          key.producer_id, key.writer_id, key.chunk_id,
+          next_chunk_ptr - begin(), next_chunk_ptr - begin() + next_chunk.size,
+          will_remove);
+      PERFETTO_DCHECK(will_remove);
+    } else {
+      padding_bytes_cleared += next_chunk.size;
+    }
+
+    next_chunk_ptr += next_chunk.size;
+
+    // We should never hit this, unless we managed to screw up while writing
+    // to the buffer and breaking the ChunkRecord(s) chain.
+    // TODO(primiano): Write more meaningful logging with the status of the
+    // buffer, to get more actionable bugs in case we hit this.
+    PERFETTO_CHECK(next_chunk_ptr <= end());
+  }
+
+  // Remove from the index.
+  for (auto it : index_delete) {
+    index_.erase(it);
+  }
+  stats_.set_chunks_overwritten(chunks_overwritten);
+  stats_.set_bytes_overwritten(bytes_overwritten);
+  stats_.set_padding_bytes_cleared(padding_bytes_cleared);
+
+  PERFETTO_DCHECK(next_chunk_ptr >= search_end && next_chunk_ptr <= end());
+  return static_cast<ssize_t>(next_chunk_ptr - search_end);
+}
+
+void TraceBuffer::AddPaddingRecord(size_t size) {
+  PERFETTO_DCHECK(size >= sizeof(ChunkRecord) && size <= ChunkRecord::kMaxSize);
+  ChunkRecord record(size);
+  record.is_padding = 1;
+  TRACE_BUFFER_DLOG("AddPaddingRecord @ [%" PRIdPTR " - %" PRIdPTR "] %zu", wptr_ - begin(),
+                    uintptr_t(wptr_ - begin()) + size, size);
+  WriteChunkRecord(wptr_, record, nullptr, size - sizeof(ChunkRecord));
+  stats_.set_padding_bytes_written(stats_.padding_bytes_written() + size);
+  // |wptr_| is deliberately not advanced when writing a padding record.
+}
+
+bool TraceBuffer::TryPatchChunkContents(ProducerID producer_id,
+                                        WriterID writer_id,
+                                        ChunkID chunk_id,
+                                        const Patch* patches,
+                                        size_t patches_size,
+                                        bool other_patches_pending) {
+  PERFETTO_CHECK(!read_only_);
+  ChunkMeta::Key key(producer_id, writer_id, chunk_id);
+  auto it = index_.find(key);
+  if (it == index_.end()) {
+    stats_.set_patches_failed(stats_.patches_failed() + 1);
+    return false;
+  }
+  ChunkMeta& chunk_meta = it->second;
+
+  // Check that the index is consistent with the actual ProducerID/WriterID
+  // stored in the ChunkRecord.
+
+  ChunkRecord* chunk_record = GetChunkRecordAt(begin() + chunk_meta.record_off);
+  PERFETTO_DCHECK(ChunkMeta::Key(*chunk_record) == key);
+  uint8_t* chunk_begin = reinterpret_cast<uint8_t*>(chunk_record);
+  PERFETTO_DCHECK(chunk_begin >= begin());
+  uint8_t* chunk_end = chunk_begin + chunk_record->size;
+  PERFETTO_DCHECK(chunk_end <= end());
+
+  static_assert(Patch::kSize == SharedMemoryABI::kPacketHeaderSize,
+                "Patch::kSize out of sync with SharedMemoryABI");
+
+  for (size_t i = 0; i < patches_size; i++) {
+    uint8_t* ptr =
+        chunk_begin + sizeof(ChunkRecord) + patches[i].offset_untrusted;
+    TRACE_BUFFER_DLOG("PatchChunk {%" PRIu32 ",%" PRIu32
+                      ",%u} size=%zu @ %zu with {%02x %02x %02x %02x} cur "
+                      "{%02x %02x %02x %02x}",
+                      producer_id, writer_id, chunk_id, chunk_end - chunk_begin,
+                      patches[i].offset_untrusted, patches[i].data[0],
+                      patches[i].data[1], patches[i].data[2],
+                      patches[i].data[3], ptr[0], ptr[1], ptr[2], ptr[3]);
+    if (ptr < chunk_begin + sizeof(ChunkRecord) ||
+        ptr > chunk_end - Patch::kSize) {
+      // Either the IPC was so slow and in the meantime the writer managed to
+      // wrap over |chunk_id| or the producer sent a malicious IPC.
+      stats_.set_patches_failed(stats_.patches_failed() + 1);
+      return false;
+    }
+
+    memcpy(ptr, &patches[i].data[0], Patch::kSize);
+  }
+  TRACE_BUFFER_DLOG("Chunk raw (after patch): %s",
+                    base::HexDump(chunk_begin, chunk_record->size).c_str());
+
+  stats_.set_patches_succeeded(stats_.patches_succeeded() + patches_size);
+  if (!other_patches_pending) {
+    chunk_meta.flags &= ~kChunkNeedsPatching;
+    chunk_record->flags = chunk_meta.flags & ChunkRecord::kFlagsBitMask;
+  }
+  return true;
+}
+
+void TraceBuffer::BeginRead() {
+  read_iter_ = GetReadIterForSequence(index_.begin());
+#if PERFETTO_DCHECK_IS_ON()
+  changed_since_last_read_ = false;
+#endif
+}
+
+TraceBuffer::SequenceIterator TraceBuffer::GetReadIterForSequence(
+    ChunkMap::iterator seq_begin) {
+  SequenceIterator iter;
+  iter.seq_begin = seq_begin;
+  if (seq_begin == index_.end()) {
+    iter.cur = iter.seq_end = index_.end();
+    return iter;
+  }
+
+#if PERFETTO_DCHECK_IS_ON()
+  // Either |seq_begin| is == index_.begin() or the item immediately before must
+  // belong to a different {ProducerID, WriterID} sequence.
+  if (seq_begin != index_.begin() && seq_begin != index_.end()) {
+    auto prev_it = seq_begin;
+    prev_it--;
+    PERFETTO_DCHECK(
+        seq_begin == index_.begin() ||
+        std::tie(prev_it->first.producer_id, prev_it->first.writer_id) <
+            std::tie(seq_begin->first.producer_id, seq_begin->first.writer_id));
+  }
+#endif
+
+  // Find the first entry that has a greater {ProducerID, WriterID} (or just
+  // index_.end() if we reached the end).
+  ChunkMeta::Key key = seq_begin->first;  // Deliberate copy.
+  key.chunk_id = kMaxChunkID;
+  iter.seq_end = index_.upper_bound(key);
+  PERFETTO_DCHECK(iter.seq_begin != iter.seq_end);
+
+  // Now find the first entry between [seq_begin, seq_end) that is
+  // > last_chunk_id_written_. This is where we the sequence will start (see
+  // notes about wrapping of IDs in the header).
+  auto producer_and_writer_id = std::make_pair(key.producer_id, key.writer_id);
+  PERFETTO_DCHECK(last_chunk_id_written_.count(producer_and_writer_id));
+  iter.wrapping_id = last_chunk_id_written_[producer_and_writer_id];
+  key.chunk_id = iter.wrapping_id;
+  iter.cur = index_.upper_bound(key);
+  if (iter.cur == iter.seq_end)
+    iter.cur = iter.seq_begin;
+  return iter;
+}
+
+void TraceBuffer::SequenceIterator::MoveNext() {
+  // Stop iterating when we reach the end of the sequence.
+  // Note: |seq_begin| might be == |seq_end|.
+  if (cur == seq_end || cur->first.chunk_id == wrapping_id) {
+    cur = seq_end;
+    return;
+  }
+
+  // If the current chunk wasn't completed yet, we shouldn't advance past it as
+  // it may be rewritten with additional packets.
+  if (!cur->second.is_complete()) {
+    cur = seq_end;
+    return;
+  }
+
+  ChunkID last_chunk_id = cur->first.chunk_id;
+  if (++cur == seq_end)
+    cur = seq_begin;
+
+  // There may be a missing chunk in the sequence of chunks, in which case the
+  // next chunk's ID won't follow the last one's. If so, skip the rest of the
+  // sequence. We'll return to it later once the hole is filled.
+  if (last_chunk_id + 1 != cur->first.chunk_id)
+    cur = seq_end;
+}
+
+bool TraceBuffer::ReadNextTracePacket(
+    TracePacket* packet,
+    PacketSequenceProperties* sequence_properties,
+    bool* previous_packet_on_sequence_dropped) {
+  // Note: MoveNext() moves only within the next chunk within the same
+  // {ProducerID, WriterID} sequence. Here we want to:
+  // - return the next patched+complete packet in the current sequence, if any.
+  // - return the first patched+complete packet in the next sequence, if any.
+  // - return false if none of the above is found.
+  TRACE_BUFFER_DLOG("ReadNextTracePacket()");
+
+  // Just in case we forget to initialize these below.
+  *sequence_properties = {0, ClientIdentity(), 0};
+  *previous_packet_on_sequence_dropped = false;
+
+  // At the start of each sequence iteration, we consider the last read packet
+  // dropped. While iterating over the chunks in the sequence, we update this
+  // flag based on our knowledge about the last packet that was read from each
+  // chunk (|last_read_packet_skipped| in ChunkMeta).
+  bool previous_packet_dropped = true;
+
+#if PERFETTO_DCHECK_IS_ON()
+  PERFETTO_DCHECK(!changed_since_last_read_);
+#endif
+  for (;; read_iter_.MoveNext()) {
+    if (PERFETTO_UNLIKELY(!read_iter_.is_valid())) {
+      // We ran out of chunks in the current {ProducerID, WriterID} sequence or
+      // we just reached the index_.end().
+
+      if (PERFETTO_UNLIKELY(read_iter_.seq_end == index_.end()))
+        return false;
+
+      // We reached the end of sequence, move to the next one.
+      // Note: ++read_iter_.seq_end might become index_.end(), but
+      // GetReadIterForSequence() knows how to deal with that.
+      read_iter_ = GetReadIterForSequence(read_iter_.seq_end);
+      PERFETTO_DCHECK(read_iter_.is_valid() && read_iter_.cur != index_.end());
+      previous_packet_dropped = true;
+    }
+
+    ChunkMeta* chunk_meta = &*read_iter_;
+
+    // If the chunk has holes that are awaiting to be patched out-of-band,
+    // skip the current sequence and move to the next one.
+    if (chunk_meta->flags & kChunkNeedsPatching) {
+      read_iter_.MoveToEnd();
+      continue;
+    }
+
+    const ProducerID trusted_producer_id = read_iter_.producer_id();
+    const WriterID writer_id = read_iter_.writer_id();
+    const ProducerAndWriterID producer_and_writer_id =
+        MkProducerAndWriterID(trusted_producer_id, writer_id);
+    const ClientIdentity& client_identity = chunk_meta->client_identity_trusted;
+
+    // At this point we have a chunk in |chunk_meta| that has not been fully
+    // read. We don't know yet whether we have enough data to read the full
+    // packet (in the case it's fragmented over several chunks) and we are about
+    // to find that out. Specifically:
+    // A) If the first fragment is unread and is a fragment continuing from a
+    //    previous chunk, it means we have missed the previous ChunkID. In
+    //    fact, if this wasn't the case, a previous call to ReadNext() shouldn't
+    //    have moved the cursor to this chunk.
+    // B) Any fragment > 0 && < last is always readable. By definition an inner
+    //    packet is never fragmented and hence doesn't require neither stitching
+    //    nor any out-of-band patching. The same applies to the last packet
+    //    iff it doesn't continue on the next chunk.
+    // C) If the last packet (which might be also the only packet in the chunk)
+    //    is a fragment and continues on the next chunk, we peek at the next
+    //    chunks and, if we have all of them, mark as read and move the cursor.
+    //
+    // +---------------+   +-------------------+  +---------------+
+    // | ChunkID: 1    |   | ChunkID: 2        |  | ChunkID: 3    |
+    // |---------------+   +-------------------+  +---------------+
+    // | Packet 1      |   |                   |  | ... Packet 3  |
+    // | Packet 2      |   | ... Packet 3  ... |  | Packet 4      |
+    // | Packet 3  ... |   |                   |  | Packet 5 ...  |
+    // +---------------+   +-------------------+  +---------------+
+
+    PERFETTO_DCHECK(chunk_meta->num_fragments_read <=
+                    chunk_meta->num_fragments);
+
+    // If we didn't read any packets from this chunk, the last packet was from
+    // the previous chunk we iterated over; so don't update
+    // |previous_packet_dropped| in this case.
+    if (chunk_meta->num_fragments_read > 0)
+      previous_packet_dropped = chunk_meta->last_read_packet_skipped();
+
+    while (chunk_meta->num_fragments_read < chunk_meta->num_fragments) {
+      enum { kSkip = 0, kReadOnePacket, kTryReadAhead } action;
+      if (chunk_meta->num_fragments_read == 0) {
+        if (chunk_meta->flags & kFirstPacketContinuesFromPrevChunk) {
+          action = kSkip;  // Case A.
+        } else if (chunk_meta->num_fragments == 1 &&
+                   (chunk_meta->flags & kLastPacketContinuesOnNextChunk)) {
+          action = kTryReadAhead;  // Case C.
+        } else {
+          action = kReadOnePacket;  // Case B.
+        }
+      } else if (chunk_meta->num_fragments_read <
+                     chunk_meta->num_fragments - 1 ||
+                 !(chunk_meta->flags & kLastPacketContinuesOnNextChunk)) {
+        action = kReadOnePacket;  // Case B.
+      } else {
+        action = kTryReadAhead;  // Case C.
+      }
+
+      TRACE_BUFFER_DLOG("  chunk %u, packet %hu of %hu, action=%d",
+                        read_iter_.chunk_id(), chunk_meta->num_fragments_read,
+                        chunk_meta->num_fragments, action);
+
+      if (action == kSkip) {
+        // This fragment will be skipped forever, not just in this ReadPacket()
+        // iteration. This happens by virtue of ReadNextPacketInChunk()
+        // incrementing the |num_fragments_read| and marking the fragment as
+        // read even if we didn't really.
+        ReadNextPacketInChunk(producer_and_writer_id, chunk_meta, nullptr);
+        chunk_meta->set_last_read_packet_skipped(true);
+        previous_packet_dropped = true;
+        continue;
+      }
+
+      if (action == kReadOnePacket) {
+        // The easy peasy case B.
+        ReadPacketResult result =
+            ReadNextPacketInChunk(producer_and_writer_id, chunk_meta, packet);
+
+        if (PERFETTO_LIKELY(result == ReadPacketResult::kSucceeded)) {
+          *sequence_properties = {trusted_producer_id, client_identity,
+                                  writer_id};
+          *previous_packet_on_sequence_dropped = previous_packet_dropped;
+          return true;
+        } else if (result == ReadPacketResult::kFailedEmptyPacket) {
+          // We can ignore and skip empty packets.
+          PERFETTO_DCHECK(packet->slices().empty());
+          continue;
+        }
+
+        // In extremely rare cases (producer bugged / malicious) the chunk might
+        // contain an invalid fragment. In such case we don't want to stall the
+        // sequence but just skip the chunk and move on. ReadNextPacketInChunk()
+        // marks the chunk as fully read, so we don't attempt to read from it
+        // again in a future call to ReadBuffers(). It also already records an
+        // abi violation for this.
+        PERFETTO_DCHECK(result == ReadPacketResult::kFailedInvalidPacket);
+        chunk_meta->set_last_read_packet_skipped(true);
+        previous_packet_dropped = true;
+        break;
+      }
+
+      PERFETTO_DCHECK(action == kTryReadAhead);
+      ReadAheadResult ra_res = ReadAhead(packet);
+      if (ra_res == ReadAheadResult::kSucceededReturnSlices) {
+        stats_.set_readaheads_succeeded(stats_.readaheads_succeeded() + 1);
+        *sequence_properties = {trusted_producer_id, client_identity,
+                                writer_id};
+        *previous_packet_on_sequence_dropped = previous_packet_dropped;
+        return true;
+      }
+
+      if (ra_res == ReadAheadResult::kFailedMoveToNextSequence) {
+        // readahead didn't find a contiguous packet sequence. We'll try again
+        // on the next ReadPacket() call.
+        stats_.set_readaheads_failed(stats_.readaheads_failed() + 1);
+
+        // TODO(primiano): optimization: this MoveToEnd() is the reason why
+        // MoveNext() (that is called in the outer for(;;MoveNext)) needs to
+        // deal gracefully with the case of |cur|==|seq_end|. Maybe we can do
+        // something to avoid that check by reshuffling the code here?
+        read_iter_.MoveToEnd();
+
+        // This break will go back to beginning of the for(;;MoveNext()). That
+        // will move to the next sequence because we set the read iterator to
+        // its end.
+        break;
+      }
+
+      PERFETTO_DCHECK(ra_res == ReadAheadResult::kFailedStayOnSameSequence);
+
+      // In this case ReadAhead() might advance |read_iter_|, so we need to
+      // re-cache the |chunk_meta| pointer to point to the current chunk.
+      chunk_meta = &*read_iter_;
+      chunk_meta->set_last_read_packet_skipped(true);
+      previous_packet_dropped = true;
+    }  // while(...)  [iterate over packet fragments for the current chunk].
+  }    // for(;;MoveNext()) [iterate over chunks].
+}
+
+TraceBuffer::ReadAheadResult TraceBuffer::ReadAhead(TracePacket* packet) {
+  static_assert(static_cast<ChunkID>(kMaxChunkID + 1) == 0,
+                "relying on kMaxChunkID to wrap naturally");
+  TRACE_BUFFER_DLOG(" readahead start @ chunk %u", read_iter_.chunk_id());
+  ChunkID next_chunk_id = read_iter_.chunk_id() + 1;
+  SequenceIterator it = read_iter_;
+  for (it.MoveNext(); it.is_valid(); it.MoveNext(), next_chunk_id++) {
+    // We should stay within the same sequence while iterating here.
+    PERFETTO_DCHECK(it.producer_id() == read_iter_.producer_id() &&
+                    it.writer_id() == read_iter_.writer_id());
+
+    TRACE_BUFFER_DLOG("   expected chunk ID: %u, actual ID: %u", next_chunk_id,
+                      it.chunk_id());
+
+    if (PERFETTO_UNLIKELY((*it).num_fragments == 0))
+      continue;
+
+    // If we miss the next chunk, stop looking in the current sequence and
+    // try another sequence. This chunk might come in the near future.
+    // The second condition is the edge case of a buggy/malicious
+    // producer. The ChunkID is contiguous but its flags don't make sense.
+    if (it.chunk_id() != next_chunk_id ||
+        PERFETTO_UNLIKELY(
+            !((*it).flags & kFirstPacketContinuesFromPrevChunk))) {
+      return ReadAheadResult::kFailedMoveToNextSequence;
+    }
+
+    // If the chunk is contiguous but has not been patched yet move to the next
+    // sequence and try coming back here on the next ReadNextTracePacket() call.
+    // TODO(primiano): add a test to cover this, it's a subtle case.
+    if ((*it).flags & kChunkNeedsPatching)
+      return ReadAheadResult::kFailedMoveToNextSequence;
+
+    // This is the case of an intermediate chunk which contains only one
+    // fragment which continues on the next chunk. This is the case for large
+    // packets, e.g.: [Packet0, Packet1(0)] [Packet1(1)] [Packet1(2), ...]
+    // (Packet1(X) := fragment X of Packet1).
+    if ((*it).num_fragments == 1 &&
+        ((*it).flags & kLastPacketContinuesOnNextChunk)) {
+      continue;
+    }
+
+    // We made it! We got all fragments for the packet without holes.
+    TRACE_BUFFER_DLOG("  readahead success @ chunk %u", it.chunk_id());
+    PERFETTO_DCHECK(((*it).num_fragments == 1 &&
+                     !((*it).flags & kLastPacketContinuesOnNextChunk)) ||
+                    (*it).num_fragments > 1);
+
+    // Now let's re-iterate over the [read_iter_, it] sequence and mark
+    // all the fragments as read.
+    bool packet_corruption = false;
+    for (;;) {
+      PERFETTO_DCHECK(read_iter_.is_valid());
+      TRACE_BUFFER_DLOG("    commit chunk %u", read_iter_.chunk_id());
+      if (PERFETTO_LIKELY((*read_iter_).num_fragments > 0)) {
+        // In the unlikely case of a corrupted packet (corrupted or empty
+        // fragment), invalidate the all stitching and move on to the next chunk
+        // in the same sequence, if any.
+        auto pw_id = MkProducerAndWriterID(it.producer_id(), it.writer_id());
+        packet_corruption |=
+            ReadNextPacketInChunk(pw_id, &*read_iter_, packet) ==
+            ReadPacketResult::kFailedInvalidPacket;
+      }
+      if (read_iter_.cur == it.cur)
+        break;
+      read_iter_.MoveNext();
+    }  // for(;;)
+    PERFETTO_DCHECK(read_iter_.cur == it.cur);
+
+    if (PERFETTO_UNLIKELY(packet_corruption)) {
+      // ReadNextPacketInChunk() already records an abi violation for this case.
+      *packet = TracePacket();  // clear.
+      return ReadAheadResult::kFailedStayOnSameSequence;
+    }
+
+    return ReadAheadResult::kSucceededReturnSlices;
+  }  // for(it...)  [readahead loop]
+  return ReadAheadResult::kFailedMoveToNextSequence;
+}
+
+TraceBuffer::ReadPacketResult TraceBuffer::ReadNextPacketInChunk(
+    ProducerAndWriterID producer_and_writer_id,
+    ChunkMeta* const chunk_meta,
+    TracePacket* packet) {
+  PERFETTO_DCHECK(chunk_meta->num_fragments_read < chunk_meta->num_fragments);
+  PERFETTO_DCHECK(!(chunk_meta->flags & kChunkNeedsPatching));
+
+  const uint8_t* record_begin = begin() + chunk_meta->record_off;
+  DcheckIsAlignedAndWithinBounds(record_begin);
+  auto* chunk_record = reinterpret_cast<const ChunkRecord*>(record_begin);
+  const uint8_t* record_end = record_begin + chunk_record->size;
+  const uint8_t* packets_begin = record_begin + sizeof(ChunkRecord);
+  const uint8_t* packet_begin = packets_begin + chunk_meta->cur_fragment_offset;
+
+  if (PERFETTO_UNLIKELY(packet_begin < packets_begin ||
+                        packet_begin >= record_end)) {
+    // The producer has a bug or is malicious and did declare that the chunk
+    // contains more packets beyond its boundaries.
+    stats_.set_abi_violations(stats_.abi_violations() + 1);
+    PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
+    chunk_meta->cur_fragment_offset = 0;
+    chunk_meta->num_fragments_read = chunk_meta->num_fragments;
+    if (PERFETTO_LIKELY(chunk_meta->is_complete())) {
+      stats_.set_chunks_read(stats_.chunks_read() + 1);
+      stats_.set_bytes_read(stats_.bytes_read() + chunk_record->size);
+    }
+    return ReadPacketResult::kFailedInvalidPacket;
+  }
+
+  // A packet (or a fragment) starts with a varint stating its size, followed
+  // by its content. The varint shouldn't be larger than 4 bytes (just in case
+  // the producer is using a redundant encoding)
+  uint64_t packet_size = 0;
+  const uint8_t* header_end =
+      std::min(packet_begin + protozero::proto_utils::kMessageLengthFieldSize,
+               record_end);
+  const uint8_t* packet_data = protozero::proto_utils::ParseVarInt(
+      packet_begin, header_end, &packet_size);
+
+  const uint8_t* next_packet = packet_data + packet_size;
+  if (PERFETTO_UNLIKELY(next_packet <= packet_begin ||
+                        next_packet > record_end)) {
+    // In BufferExhaustedPolicy::kDrop mode, TraceWriter may abort a fragmented
+    // packet by writing an invalid size in the last fragment's header. We
+    // should handle this case without recording an ABI violation (since Android
+    // R).
+    if (packet_size != SharedMemoryABI::kPacketSizeDropPacket) {
+      stats_.set_abi_violations(stats_.abi_violations() + 1);
+      PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
+    } else {
+      stats_.set_trace_writer_packet_loss(stats_.trace_writer_packet_loss() +
+                                          1);
+    }
+    chunk_meta->cur_fragment_offset = 0;
+    chunk_meta->num_fragments_read = chunk_meta->num_fragments;
+    if (PERFETTO_LIKELY(chunk_meta->is_complete())) {
+      stats_.set_chunks_read(stats_.chunks_read() + 1);
+      stats_.set_bytes_read(stats_.bytes_read() + chunk_record->size);
+    }
+    return ReadPacketResult::kFailedInvalidPacket;
+  }
+
+  chunk_meta->cur_fragment_offset =
+      static_cast<uint16_t>(next_packet - packets_begin);
+  chunk_meta->num_fragments_read++;
+
+  if (PERFETTO_UNLIKELY(chunk_meta->num_fragments_read ==
+                            chunk_meta->num_fragments &&
+                        chunk_meta->is_complete())) {
+    stats_.set_chunks_read(stats_.chunks_read() + 1);
+    stats_.set_bytes_read(stats_.bytes_read() + chunk_record->size);
+    auto* writer_stats = writer_stats_.Insert(producer_and_writer_id, {}).first;
+    writer_stats->used_chunk_hist.Add(chunk_meta->cur_fragment_offset);
+  } else {
+    // We have at least one more packet to parse. It should be within the chunk.
+    if (chunk_meta->cur_fragment_offset + sizeof(ChunkRecord) >=
+        chunk_record->size) {
+      PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
+    }
+  }
+
+  chunk_meta->set_last_read_packet_skipped(false);
+
+  if (PERFETTO_UNLIKELY(packet_size == 0))
+    return ReadPacketResult::kFailedEmptyPacket;
+
+  if (PERFETTO_LIKELY(packet))
+    packet->AddSlice(packet_data, static_cast<size_t>(packet_size));
+
+  return ReadPacketResult::kSucceeded;
+}
+
+void TraceBuffer::DiscardWrite() {
+  PERFETTO_DCHECK(overwrite_policy_ == kDiscard);
+  discard_writes_ = true;
+  stats_.set_chunks_discarded(stats_.chunks_discarded() + 1);
+  TRACE_BUFFER_DLOG("  discarding write");
+}
+
+std::unique_ptr<TraceBuffer> TraceBuffer::CloneReadOnly() const {
+  std::unique_ptr<TraceBuffer> buf(new TraceBuffer(CloneCtor(), *this));
+  if (!buf->data_.IsValid())
+    return nullptr;  // PagedMemory::Allocate() failed. We are out of memory.
+  return buf;
+}
+
+TraceBuffer::TraceBuffer(CloneCtor, const TraceBuffer& src)
+    : overwrite_policy_(src.overwrite_policy_),
+      read_only_(true),
+      discard_writes_(src.discard_writes_) {
+  if (!Initialize(src.data_.size()))
+    return;  // TraceBuffer::Clone() will check |data_| and return nullptr.
+
+  // The assignments below must be done after Initialize().
+
+  EnsureCommitted(src.used_size_);
+  memcpy(data_.Get(), src.data_.Get(), src.used_size_);
+  last_chunk_id_written_ = src.last_chunk_id_written_;
+
+  stats_ = src.stats_;
+  stats_.set_bytes_read(0);
+  stats_.set_chunks_read(0);
+  stats_.set_readaheads_failed(0);
+  stats_.set_readaheads_succeeded(0);
+
+  // Copy the index of chunk metadata and reset the read states.
+  index_ = ChunkMap(src.index_);
+  for (auto& kv : index_) {
+    ChunkMeta& chunk_meta = kv.second;
+    chunk_meta.num_fragments_read = 0;
+    chunk_meta.cur_fragment_offset = 0;
+    chunk_meta.set_last_read_packet_skipped(false);
+  }
+  read_iter_ = SequenceIterator();
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/service/tracing_service_impl.cc
+// gen_amalgamated begin header: src/tracing/service/tracing_service_impl.h
+// gen_amalgamated begin header: include/perfetto/ext/base/circular_queue.h
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_CIRCULAR_QUEUE_H_
+#define INCLUDE_PERFETTO_EXT_BASE_CIRCULAR_QUEUE_H_
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <cstddef>
+#include <iterator>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+
+namespace perfetto {
+namespace base {
+
+// CircularQueue is a push-back-only / pop-front-only queue with the following
+// characteristics:
+// - The storage is based on a flat circular buffer. Beginning and end wrap
+//   as necessary, to keep pushes and pops O(1) as long as capacity expansion is
+//   not required.
+// - Capacity is automatically expanded like in a std::vector. Expansion has a
+//   O(N) cost.
+// - It allows random access, allowing in-place std::sort.
+// - Iterators are not stable. Mutating the container invalidates all iterators.
+// - It doesn't bother with const-correctness.
+//
+// Implementation details:
+// Internally, |begin|, |end| and iterators use 64-bit monotonic indexes, which
+// are incremented as if the queue was backed by unlimited storage.
+// Even assuming that elements are inserted and removed every nanosecond, 64 bit
+// is enough for 584 years.
+// Wrapping happens only when addressing elements in the underlying circular
+// storage. This limits the complexity and avoiding dealing with modular
+// arithmetic all over the places.
+template <class T>
+class CircularQueue {
+ public:
+  class Iterator {
+   public:
+    using difference_type = ptrdiff_t;
+    using value_type = T;
+    using pointer = T*;
+    using reference = T&;
+    using iterator_category = std::random_access_iterator_tag;
+
+    Iterator(CircularQueue* queue, uint64_t pos, uint32_t generation)
+        : queue_(queue),
+          pos_(pos)
+#if PERFETTO_DCHECK_IS_ON()
+          ,
+          generation_(generation)
+#endif
+    {
+      ignore_result(generation);
+    }
+
+    Iterator(const Iterator&) noexcept = default;
+    Iterator& operator=(const Iterator&) noexcept = default;
+    Iterator(Iterator&&) noexcept = default;
+    Iterator& operator=(Iterator&&) noexcept = default;
+
+    T* operator->() const {
+#if PERFETTO_DCHECK_IS_ON()
+      PERFETTO_DCHECK(generation_ == queue_->generation());
+#endif
+      return queue_->Get(pos_);
+    }
+
+    T& operator*() const { return *(operator->()); }
+
+    value_type& operator[](difference_type i) { return *(*this + i); }
+
+    Iterator& operator++() {
+      Add(1);
+      return *this;
+    }
+
+    Iterator operator++(int) {
+      Iterator ret = *this;
+      Add(1);
+      return ret;
+    }
+
+    Iterator& operator--() {
+      Add(-1);
+      return *this;
+    }
+
+    Iterator operator--(int) {
+      Iterator ret = *this;
+      Add(-1);
+      return ret;
+    }
+
+    friend Iterator operator+(const Iterator& iter, difference_type offset) {
+      Iterator ret = iter;
+      ret.Add(offset);
+      return ret;
+    }
+
+    Iterator& operator+=(difference_type offset) {
+      Add(offset);
+      return *this;
+    }
+
+    friend Iterator operator-(const Iterator& iter, difference_type offset) {
+      Iterator ret = iter;
+      ret.Add(-offset);
+      return ret;
+    }
+
+    Iterator& operator-=(difference_type offset) {
+      Add(-offset);
+      return *this;
+    }
+
+    friend ptrdiff_t operator-(const Iterator& lhs, const Iterator& rhs) {
+      return static_cast<ptrdiff_t>(lhs.pos_) -
+             static_cast<ptrdiff_t>(rhs.pos_);
+    }
+
+    friend bool operator==(const Iterator& lhs, const Iterator& rhs) {
+      return lhs.pos_ == rhs.pos_;
+    }
+
+    friend bool operator!=(const Iterator& lhs, const Iterator& rhs) {
+      return lhs.pos_ != rhs.pos_;
+    }
+
+    friend bool operator<(const Iterator& lhs, const Iterator& rhs) {
+      return lhs.pos_ < rhs.pos_;
+    }
+
+    friend bool operator<=(const Iterator& lhs, const Iterator& rhs) {
+      return lhs.pos_ <= rhs.pos_;
+    }
+
+    friend bool operator>(const Iterator& lhs, const Iterator& rhs) {
+      return lhs.pos_ > rhs.pos_;
+    }
+
+    friend bool operator>=(const Iterator& lhs, const Iterator& rhs) {
+      return lhs.pos_ >= rhs.pos_;
+    }
+
+   private:
+    inline void Add(difference_type offset) {
+      pos_ = static_cast<uint64_t>(static_cast<difference_type>(pos_) + offset);
+      PERFETTO_DCHECK(pos_ <= queue_->end_);
+    }
+
+    CircularQueue* queue_;
+    uint64_t pos_;
+
+#if PERFETTO_DCHECK_IS_ON()
+    uint32_t generation_;
+#endif
+  };
+
+  explicit CircularQueue(size_t initial_capacity = 1024) {
+    Grow(initial_capacity);
+  }
+
+  CircularQueue(CircularQueue&& other) noexcept
+      : entries_(std::move(other.entries_)),
+        capacity_(other.capacity_),
+        begin_(other.begin_),
+        end_(other.end_) {
+    increment_generation();
+    new (&other) CircularQueue();  // Reset the old queue so it's still usable.
+  }
+
+  CircularQueue& operator=(CircularQueue&& other) noexcept {
+    this->~CircularQueue();                      // Destroy the current state.
+    new (this) CircularQueue(std::move(other));  // Use the move ctor above.
+    return *this;
+  }
+
+  explicit CircularQueue(const CircularQueue& other) noexcept {
+    Grow(other.capacity());
+    for (const auto& e : const_cast<CircularQueue&>(other))
+      emplace_back(e);
+    PERFETTO_DCHECK(size() == other.size());
+  }
+
+  CircularQueue& operator=(const CircularQueue& other) noexcept {
+    this->~CircularQueue();           // Destroy the current state.
+    new (this) CircularQueue(other);  // Use the copy ctor above.
+    return *this;
+  }
+
+  ~CircularQueue() {
+    if (!entries_) {
+      PERFETTO_DCHECK(empty());
+      return;
+    }
+    clear();  // Invoke destructors on all alive entries.
+    PERFETTO_DCHECK(empty());
+  }
+
+  template <typename... Args>
+  void emplace_back(Args&&... args) {
+    increment_generation();
+    if (PERFETTO_UNLIKELY(size() >= capacity_))
+      Grow();
+    T* slot = Get(end_++);
+    new (slot) T(std::forward<Args>(args)...);
+  }
+
+  void erase_front(size_t n) {
+    increment_generation();
+    for (; n && (begin_ < end_); --n) {
+      Get(begin_)->~T();
+      begin_++;  // This needs to be its own statement, Get() checks begin_.
+    }
+  }
+
+  void pop_front() { erase_front(1); }
+
+  void clear() { erase_front(size()); }
+
+  void shrink_to_fit() {
+    // We only bother shrinking if we can fit in quarter of the capacity we are
+    // currently using. Moreover, don't bother shrinking below 4096 elements as
+    // that will cause a lot of reallocations for little benefit.
+    if (size() > capacity() / 2 || capacity() <= 4096) {
+      return;
+    }
+    ChangeCapacity(capacity() / 2);
+  }
+
+  T& at(size_t idx) {
+    PERFETTO_DCHECK(idx < size());
+    return *Get(begin_ + idx);
+  }
+
+  Iterator begin() { return Iterator(this, begin_, generation()); }
+  Iterator end() { return Iterator(this, end_, generation()); }
+  T& front() { return *begin(); }
+  T& back() { return *(end() - 1); }
+
+  bool empty() const { return size() == 0; }
+
+  size_t size() const {
+    PERFETTO_DCHECK(end_ - begin_ <= capacity_);
+    return static_cast<size_t>(end_ - begin_);
+  }
+
+  size_t capacity() const { return capacity_; }
+
+#if PERFETTO_DCHECK_IS_ON()
+  uint32_t generation() const { return generation_; }
+  void increment_generation() { ++generation_; }
+#else
+  uint32_t generation() const { return 0; }
+  void increment_generation() {}
+#endif
+
+ private:
+  void Grow(size_t new_capacity = 0) {
+    // Capacity must be always a power of two. This allows Get() to use a simple
+    // bitwise-AND for handling the wrapping instead of a full division.
+    new_capacity = new_capacity ? new_capacity : capacity_ * 2;
+    PERFETTO_CHECK((new_capacity & (new_capacity - 1)) == 0);  // Must be pow2.
+
+    // On 32-bit systems this might hit the 4GB wall and overflow. We can't do
+    // anything other than crash in this case.
+    PERFETTO_CHECK(new_capacity > capacity_);
+
+    ChangeCapacity(new_capacity);
+  }
+
+  void ChangeCapacity(size_t new_capacity) {
+    // We should still have enough space to fit all the elements in the queue.
+    PERFETTO_CHECK(new_capacity >= size());
+
+    AlignedUniquePtr<T[]> new_vec = AlignedAllocTyped<T[]>(new_capacity);
+
+    // Move all elements in the expanded array.
+    size_t new_size = 0;
+    for (uint64_t i = begin_; i < end_; i++)
+      new (&new_vec[new_size++]) T(std::move(*Get(i)));  // Placement move ctor.
+
+    // Even if all the elements are std::move()-d and likely empty, we are still
+    // required to call the dtor for them.
+    for (uint64_t i = begin_; i < end_; i++)
+      Get(i)->~T();
+
+    begin_ = 0;
+    end_ = new_size;
+    capacity_ = new_capacity;
+    entries_ = std::move(new_vec);
+  }
+
+  inline T* Get(uint64_t pos) {
+    PERFETTO_DCHECK(pos >= begin_ && pos < end_);
+    PERFETTO_DCHECK((capacity_ & (capacity_ - 1)) == 0);  // Must be a pow2.
+    auto index = static_cast<size_t>(pos & (capacity_ - 1));
+    return &entries_[index];
+  }
+
+  // Underlying storage. It's raw malloc-ed rather than being a unique_ptr<T[]>
+  // to allow having uninitialized entries inside it.
+  AlignedUniquePtr<T[]> entries_;
+  size_t capacity_ = 0;  // Number of allocated slots (NOT bytes) in |entries_|.
+
+  // The |begin_| and |end_| indexes are monotonic and never wrap. Modular arith
+  // is used only when dereferencing entries in the vector.
+  uint64_t begin_ = 0;
+  uint64_t end_ = 0;
+
+// Generation is used in debug builds only for checking iterator validity.
+#if PERFETTO_DCHECK_IS_ON()
+  uint32_t generation_ = 0;
+#endif
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_CIRCULAR_QUEUE_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACING_SERVICE_TRACING_SERVICE_IMPL_H_
+#define SRC_TRACING_SERVICE_TRACING_SERVICE_IMPL_H_
+
+#include <algorithm>
+#include <functional>
+#include <map>
+#include <memory>
+#include <optional>
+#include <random>
+#include <set>
+#include <utility>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/status.h"
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/circular_queue.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/periodic_task.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/uuid.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/client_identity.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/commit_data_request.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/observable_events.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_stats.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_config.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/trace_config.h"
+// gen_amalgamated expanded: #include "src/android_stats/perfetto_atoms.h"
+// gen_amalgamated expanded: #include "src/tracing/core/id_allocator.h"
+
+namespace protozero {
+class MessageFilter;
+}
+
+namespace perfetto {
+
+namespace base {
+class TaskRunner;
+}  // namespace base
+
+namespace protos {
+namespace gen {
+enum TraceStats_FinalFlushOutcome : int;
+}
+}  // namespace protos
+
+class Consumer;
+class Producer;
+class SharedMemory;
+class SharedMemoryArbiterImpl;
+class TraceBuffer;
+class TracePacket;
+
+// The tracing service business logic.
+class TracingServiceImpl : public TracingService {
+ private:
+  struct DataSourceInstance;
+
+ public:
+  static constexpr size_t kMaxShmSize = 32 * 1024 * 1024ul;
+  static constexpr uint32_t kDataSourceStopTimeoutMs = 5000;
+  static constexpr uint8_t kSyncMarker[] = {0x82, 0x47, 0x7a, 0x76, 0xb2, 0x8d,
+                                            0x42, 0xba, 0x81, 0xdc, 0x33, 0x32,
+                                            0x6d, 0x57, 0xa0, 0x79};
+  static constexpr size_t kMaxTracePacketSliceSize =
+      128 * 1024 - 512;  // This is ipc::kIPCBufferSize - 512, see assertion in
+                         // tracing_integration_test.cc and b/195065199
+
+  // This is a rough threshold to determine how many bytes to read from the
+  // buffers on each iteration when writing into a file. Since filtering and
+  // compression allocate memory, this effectively limits the amount of memory
+  // allocated.
+  static constexpr size_t kWriteIntoFileChunkSize = 1024 * 1024ul;
+
+  // The implementation behind the service endpoint exposed to each producer.
+  class ProducerEndpointImpl : public TracingService::ProducerEndpoint {
+   public:
+    ProducerEndpointImpl(ProducerID,
+                         const ClientIdentity& client_identity,
+                         TracingServiceImpl*,
+                         base::TaskRunner*,
+                         Producer*,
+                         const std::string& producer_name,
+                         const std::string& sdk_version,
+                         bool in_process,
+                         bool smb_scraping_enabled);
+    ~ProducerEndpointImpl() override;
+
+    // TracingService::ProducerEndpoint implementation.
+    void Disconnect() override;
+    void RegisterDataSource(const DataSourceDescriptor&) override;
+    void UpdateDataSource(const DataSourceDescriptor&) override;
+    void UnregisterDataSource(const std::string& name) override;
+    void RegisterTraceWriter(uint32_t writer_id,
+                             uint32_t target_buffer) override;
+    void UnregisterTraceWriter(uint32_t writer_id) override;
+    void CommitData(const CommitDataRequest&, CommitDataCallback) override;
+    void SetupSharedMemory(std::unique_ptr<SharedMemory>,
+                           size_t page_size_bytes,
+                           bool provided_by_producer);
+    std::unique_ptr<TraceWriter> CreateTraceWriter(
+        BufferID,
+        BufferExhaustedPolicy) override;
+    SharedMemoryArbiter* MaybeSharedMemoryArbiter() override;
+    bool IsShmemProvidedByProducer() const override;
+    void NotifyFlushComplete(FlushRequestID) override;
+    void NotifyDataSourceStarted(DataSourceInstanceID) override;
+    void NotifyDataSourceStopped(DataSourceInstanceID) override;
+    SharedMemory* shared_memory() const override;
+    size_t shared_buffer_page_size_kb() const override;
+    void ActivateTriggers(const std::vector<std::string>&) override;
+    void Sync(std::function<void()> callback) override;
+
+    void OnTracingSetup();
+    void SetupDataSource(DataSourceInstanceID, const DataSourceConfig&);
+    void StartDataSource(DataSourceInstanceID, const DataSourceConfig&);
+    void StopDataSource(DataSourceInstanceID);
+    void Flush(FlushRequestID,
+               const std::vector<DataSourceInstanceID>&,
+               FlushFlags);
+    void OnFreeBuffers(const std::vector<BufferID>& target_buffers);
+    void ClearIncrementalState(const std::vector<DataSourceInstanceID>&);
+
+    bool is_allowed_target_buffer(BufferID buffer_id) const {
+      return allowed_target_buffers_.count(buffer_id);
+    }
+
+    std::optional<BufferID> buffer_id_for_writer(WriterID writer_id) const {
+      const auto it = writers_.find(writer_id);
+      if (it != writers_.end())
+        return it->second;
+      return std::nullopt;
+    }
+
+    uid_t uid() const { return client_identity_.uid(); }
+    pid_t pid() const { return client_identity_.pid(); }
+    const ClientIdentity& client_identity() const { return client_identity_; }
+
+   private:
+    friend class TracingServiceImpl;
+    friend class TracingServiceImplTest;
+    friend class TracingIntegrationTest;
+    ProducerEndpointImpl(const ProducerEndpointImpl&) = delete;
+    ProducerEndpointImpl& operator=(const ProducerEndpointImpl&) = delete;
+
+    ProducerID const id_;
+    ClientIdentity const client_identity_;
+    TracingServiceImpl* const service_;
+    base::TaskRunner* const task_runner_;
+    Producer* producer_;
+    std::unique_ptr<SharedMemory> shared_memory_;
+    size_t shared_buffer_page_size_kb_ = 0;
+    SharedMemoryABI shmem_abi_;
+    size_t shmem_size_hint_bytes_ = 0;
+    size_t shmem_page_size_hint_bytes_ = 0;
+    bool is_shmem_provided_by_producer_ = false;
+    const std::string name_;
+    std::string sdk_version_;
+    bool in_process_;
+    bool smb_scraping_enabled_;
+
+    // Set of the global target_buffer IDs that the producer is configured to
+    // write into in any active tracing session.
+    std::set<BufferID> allowed_target_buffers_;
+
+    // Maps registered TraceWriter IDs to their target buffers as registered by
+    // the producer. Note that producers aren't required to register their
+    // writers, so we may see commits of chunks with WriterIDs that aren't
+    // contained in this map. However, if a producer does register a writer, the
+    // service will prevent the writer from writing into any other buffer than
+    // the one associated with it here. The BufferIDs stored in this map are
+    // untrusted, so need to be verified against |allowed_target_buffers_|
+    // before use.
+    std::map<WriterID, BufferID> writers_;
+
+    // This is used only in in-process configurations.
+    // SharedMemoryArbiterImpl methods themselves are thread-safe.
+    std::unique_ptr<SharedMemoryArbiterImpl> inproc_shmem_arbiter_;
+
+    PERFETTO_THREAD_CHECKER(thread_checker_)
+    base::WeakPtrFactory<ProducerEndpointImpl> weak_ptr_factory_;  // Keep last.
+  };
+
+  // The implementation behind the service endpoint exposed to each consumer.
+  class ConsumerEndpointImpl : public TracingService::ConsumerEndpoint {
+   public:
+    ConsumerEndpointImpl(TracingServiceImpl*,
+                         base::TaskRunner*,
+                         Consumer*,
+                         uid_t uid);
+    ~ConsumerEndpointImpl() override;
+
+    void NotifyOnTracingDisabled(const std::string& error);
+    void NotifyCloneSnapshotTrigger();
+
+    // TracingService::ConsumerEndpoint implementation.
+    void EnableTracing(const TraceConfig&, base::ScopedFile) override;
+    void ChangeTraceConfig(const TraceConfig& cfg) override;
+    void StartTracing() override;
+    void DisableTracing() override;
+    void ReadBuffers() override;
+    void FreeBuffers() override;
+    void Flush(uint32_t timeout_ms, FlushCallback, FlushFlags) override;
+    void Detach(const std::string& key) override;
+    void Attach(const std::string& key) override;
+    void GetTraceStats() override;
+    void ObserveEvents(uint32_t enabled_event_types) override;
+    void QueryServiceState(QueryServiceStateArgs,
+                           QueryServiceStateCallback) override;
+    void QueryCapabilities(QueryCapabilitiesCallback) override;
+    void SaveTraceForBugreport(SaveTraceForBugreportCallback) override;
+    void CloneSession(TracingSessionID, CloneSessionArgs) override;
+
+    // Will queue a task to notify the consumer about the state change.
+    void OnDataSourceInstanceStateChange(const ProducerEndpointImpl&,
+                                         const DataSourceInstance&);
+    void OnAllDataSourcesStarted();
+
+    base::WeakPtr<ConsumerEndpointImpl> GetWeakPtr() {
+      return weak_ptr_factory_.GetWeakPtr();
+    }
+
+   private:
+    friend class TracingServiceImpl;
+    ConsumerEndpointImpl(const ConsumerEndpointImpl&) = delete;
+    ConsumerEndpointImpl& operator=(const ConsumerEndpointImpl&) = delete;
+
+    // Returns a pointer to an ObservableEvents object that the caller can fill
+    // and schedules a task to send the ObservableEvents to the consumer.
+    ObservableEvents* AddObservableEvents();
+
+    base::TaskRunner* const task_runner_;
+    TracingServiceImpl* const service_;
+    Consumer* const consumer_;
+    uid_t const uid_;
+    TracingSessionID tracing_session_id_ = 0;
+
+    // Whether the consumer is interested in DataSourceInstance state change
+    // events.
+    uint32_t observable_events_mask_ = 0;
+
+    // ObservableEvents that will be sent to the consumer. If set, a task to
+    // flush the events to the consumer has been queued.
+    std::unique_ptr<ObservableEvents> observable_events_;
+
+    PERFETTO_THREAD_CHECKER(thread_checker_)
+    base::WeakPtrFactory<ConsumerEndpointImpl> weak_ptr_factory_;  // Keep last.
+  };
+
+  class RelayEndpointImpl : public TracingService::RelayEndpoint {
+   public:
+    using SyncMode = RelayEndpoint::SyncMode;
+
+    struct SyncedClockSnapshots {
+      SyncedClockSnapshots(SyncMode _sync_mode,
+                           ClockSnapshotVector _client_clocks,
+                           ClockSnapshotVector _host_clocks)
+          : sync_mode(_sync_mode),
+            client_clocks(std::move(_client_clocks)),
+            host_clocks(std::move(_host_clocks)) {}
+      SyncMode sync_mode;
+      ClockSnapshotVector client_clocks;
+      ClockSnapshotVector host_clocks;
+    };
+
+    explicit RelayEndpointImpl(RelayClientID relay_client_id,
+                               TracingServiceImpl* service);
+    ~RelayEndpointImpl() override;
+    void SyncClocks(SyncMode sync_mode,
+                    ClockSnapshotVector client_clocks,
+                    ClockSnapshotVector host_clocks) override;
+    void Disconnect() override;
+
+    MachineID machine_id() const { return relay_client_id_.first; }
+
+    base::CircularQueue<SyncedClockSnapshots>& synced_clocks() {
+      return synced_clocks_;
+    }
+
+   private:
+    RelayEndpointImpl(const RelayEndpointImpl&) = delete;
+    RelayEndpointImpl& operator=(const RelayEndpointImpl&) = delete;
+
+    RelayClientID relay_client_id_;
+    TracingServiceImpl* const service_;
+    base::CircularQueue<SyncedClockSnapshots> synced_clocks_;
+
+    PERFETTO_THREAD_CHECKER(thread_checker_)
+  };
+
+  explicit TracingServiceImpl(std::unique_ptr<SharedMemory::Factory>,
+                              base::TaskRunner*,
+                              InitOpts = {});
+  ~TracingServiceImpl() override;
+
+  // Called by ProducerEndpointImpl.
+  void DisconnectProducer(ProducerID);
+  void RegisterDataSource(ProducerID, const DataSourceDescriptor&);
+  void UpdateDataSource(ProducerID, const DataSourceDescriptor&);
+  void UnregisterDataSource(ProducerID, const std::string& name);
+  void CopyProducerPageIntoLogBuffer(ProducerID,
+                                     const ClientIdentity&,
+                                     WriterID,
+                                     ChunkID,
+                                     BufferID,
+                                     uint16_t num_fragments,
+                                     uint8_t chunk_flags,
+                                     bool chunk_complete,
+                                     const uint8_t* src,
+                                     size_t size);
+  void ApplyChunkPatches(ProducerID,
+                         const std::vector<CommitDataRequest::ChunkToPatch>&);
+  void NotifyFlushDoneForProducer(ProducerID, FlushRequestID);
+  void NotifyDataSourceStarted(ProducerID, DataSourceInstanceID);
+  void NotifyDataSourceStopped(ProducerID, DataSourceInstanceID);
+  void ActivateTriggers(ProducerID, const std::vector<std::string>& triggers);
+
+  // Called by ConsumerEndpointImpl.
+  bool DetachConsumer(ConsumerEndpointImpl*, const std::string& key);
+  bool AttachConsumer(ConsumerEndpointImpl*, const std::string& key);
+  void DisconnectConsumer(ConsumerEndpointImpl*);
+  base::Status EnableTracing(ConsumerEndpointImpl*,
+                             const TraceConfig&,
+                             base::ScopedFile);
+  void ChangeTraceConfig(ConsumerEndpointImpl*, const TraceConfig&);
+
+  base::Status StartTracing(TracingSessionID);
+  void DisableTracing(TracingSessionID, bool disable_immediately = false);
+  void Flush(TracingSessionID tsid,
+             uint32_t timeout_ms,
+             ConsumerEndpoint::FlushCallback,
+             FlushFlags);
+  void FlushAndDisableTracing(TracingSessionID);
+  void FlushAndCloneSession(ConsumerEndpointImpl*,
+                            TracingSessionID,
+                            bool skip_filter,
+                            bool for_bugreport);
+
+  // Starts reading the internal tracing buffers from the tracing session `tsid`
+  // and sends them to `*consumer` (which must be != nullptr).
+  //
+  // Only reads a limited amount of data in one call. If there's more data,
+  // immediately schedules itself on a PostTask.
+  //
+  // Returns false in case of error.
+  bool ReadBuffersIntoConsumer(TracingSessionID tsid,
+                               ConsumerEndpointImpl* consumer);
+
+  // Reads all the tracing buffers from the tracing session `tsid` and writes
+  // them into the associated file.
+  //
+  // Reads all the data in the buffers (or until the file is full) before
+  // returning.
+  //
+  // If the tracing session write_period_ms is 0, the file is full or there has
+  // been an error, flushes the file and closes it. Otherwise, schedules itself
+  // to be executed after write_period_ms.
+  //
+  // Returns false in case of error.
+  bool ReadBuffersIntoFile(TracingSessionID);
+
+  void FreeBuffers(TracingSessionID);
+
+  // Service implementation.
+  std::unique_ptr<TracingService::ProducerEndpoint> ConnectProducer(
+      Producer*,
+      const ClientIdentity& client_identity,
+      const std::string& producer_name,
+      size_t shared_memory_size_hint_bytes = 0,
+      bool in_process = false,
+      ProducerSMBScrapingMode smb_scraping_mode =
+          ProducerSMBScrapingMode::kDefault,
+      size_t shared_memory_page_size_hint_bytes = 0,
+      std::unique_ptr<SharedMemory> shm = nullptr,
+      const std::string& sdk_version = {}) override;
+
+  std::unique_ptr<TracingService::ConsumerEndpoint> ConnectConsumer(
+      Consumer*,
+      uid_t) override;
+
+  std::unique_ptr<TracingService::RelayEndpoint> ConnectRelayClient(
+      RelayClientID) override;
+
+  void DisconnectRelayClient(RelayClientID);
+
+  // Set whether SMB scraping should be enabled by default or not. Producers can
+  // override this setting for their own SMBs.
+  void SetSMBScrapingEnabled(bool enabled) override {
+    smb_scraping_enabled_ = enabled;
+  }
+
+  // Exposed mainly for testing.
+  size_t num_producers() const { return producers_.size(); }
+  ProducerEndpointImpl* GetProducer(ProducerID) const;
+
+ private:
+  friend class TracingServiceImplTest;
+  friend class TracingIntegrationTest;
+
+  static constexpr int64_t kOneDayInNs = 24ll * 60 * 60 * 1000 * 1000 * 1000;
+
+  struct TriggerHistory {
+    int64_t timestamp_ns;
+    uint64_t name_hash;
+
+    bool operator<(const TriggerHistory& other) const {
+      return timestamp_ns < other.timestamp_ns;
+    }
+  };
+
+  struct RegisteredDataSource {
+    ProducerID producer_id;
+    DataSourceDescriptor descriptor;
+  };
+
+  // Represents an active data source for a tracing session.
+  struct DataSourceInstance {
+    DataSourceInstance(DataSourceInstanceID id,
+                       const DataSourceConfig& cfg,
+                       const std::string& ds_name,
+                       bool notify_on_start,
+                       bool notify_on_stop,
+                       bool handles_incremental_state_invalidation,
+                       bool no_flush_)
+        : instance_id(id),
+          config(cfg),
+          data_source_name(ds_name),
+          will_notify_on_start(notify_on_start),
+          will_notify_on_stop(notify_on_stop),
+          handles_incremental_state_clear(
+              handles_incremental_state_invalidation),
+          no_flush(no_flush_) {}
+    DataSourceInstance(const DataSourceInstance&) = delete;
+    DataSourceInstance& operator=(const DataSourceInstance&) = delete;
+
+    DataSourceInstanceID instance_id;
+    DataSourceConfig config;
+    std::string data_source_name;
+    bool will_notify_on_start;
+    bool will_notify_on_stop;
+    bool handles_incremental_state_clear;
+    bool no_flush;
+
+    enum DataSourceInstanceState {
+      CONFIGURED,
+      STARTING,
+      STARTED,
+      STOPPING,
+      STOPPED
+    };
+    DataSourceInstanceState state = CONFIGURED;
+  };
+
+  struct PendingFlush {
+    std::set<ProducerID> producers;
+    ConsumerEndpoint::FlushCallback callback;
+    explicit PendingFlush(decltype(callback) cb) : callback(std::move(cb)) {}
+  };
+
+  using PendingCloneID = uint64_t;
+
+  struct PendingClone {
+    size_t pending_flush_cnt = 0;
+    // This vector might not be populated all at once. Some buffers might be
+    // nullptr while flushing is not done.
+    std::vector<std::unique_ptr<TraceBuffer>> buffers;
+    bool flush_failed = false;
+    base::WeakPtr<ConsumerEndpointImpl> weak_consumer;
+    bool skip_trace_filter = false;
+  };
+
+  // Holds the state of a tracing session. A tracing session is uniquely bound
+  // a specific Consumer. Each Consumer can own one or more sessions.
+  struct TracingSession {
+    enum State {
+      DISABLED = 0,
+      CONFIGURED,
+      STARTED,
+      DISABLING_WAITING_STOP_ACKS,
+      CLONED_READ_ONLY,
+    };
+
+    TracingSession(TracingSessionID,
+                   ConsumerEndpointImpl*,
+                   const TraceConfig&,
+                   base::TaskRunner*);
+    TracingSession(TracingSession&&) = delete;
+    TracingSession& operator=(TracingSession&&) = delete;
+
+    size_t num_buffers() const { return buffers_index.size(); }
+
+    uint32_t delay_to_next_write_period_ms() const {
+      PERFETTO_DCHECK(write_period_ms > 0);
+      return write_period_ms -
+             static_cast<uint32_t>(base::GetWallTimeMs().count() %
+                                   write_period_ms);
+    }
+
+    uint32_t flush_timeout_ms() {
+      uint32_t timeout_ms = config.flush_timeout_ms();
+      return timeout_ms ? timeout_ms : kDefaultFlushTimeoutMs;
+    }
+
+    uint32_t data_source_stop_timeout_ms() {
+      uint32_t timeout_ms = config.data_source_stop_timeout_ms();
+      return timeout_ms ? timeout_ms : kDataSourceStopTimeoutMs;
+    }
+
+    PacketSequenceID GetPacketSequenceID(MachineID machine_id,
+                                         ProducerID producer_id,
+                                         WriterID writer_id) {
+      auto key = std::make_tuple(machine_id, producer_id, writer_id);
+      auto it = packet_sequence_ids.find(key);
+      if (it != packet_sequence_ids.end())
+        return it->second;
+      // We shouldn't run out of sequence IDs (producer ID is 16 bit, writer IDs
+      // are limited to 1024).
+      static_assert(kMaxPacketSequenceID > kMaxProducerID * kMaxWriterID,
+                    "PacketSequenceID value space doesn't cover service "
+                    "sequence ID and all producer/writer ID combinations!");
+      PERFETTO_DCHECK(last_packet_sequence_id < kMaxPacketSequenceID);
+      PacketSequenceID sequence_id = ++last_packet_sequence_id;
+      packet_sequence_ids[key] = sequence_id;
+      return sequence_id;
+    }
+
+    DataSourceInstance* GetDataSourceInstance(
+        ProducerID producer_id,
+        DataSourceInstanceID instance_id) {
+      for (auto& inst_kv : data_source_instances) {
+        if (inst_kv.first != producer_id ||
+            inst_kv.second.instance_id != instance_id) {
+          continue;
+        }
+        return &inst_kv.second;
+      }
+      return nullptr;
+    }
+
+    bool AllDataSourceInstancesStarted() {
+      return std::all_of(
+          data_source_instances.begin(), data_source_instances.end(),
+          [](decltype(data_source_instances)::const_reference x) {
+            return x.second.state == DataSourceInstance::STARTED;
+          });
+    }
+
+    bool AllDataSourceInstancesStopped() {
+      return std::all_of(
+          data_source_instances.begin(), data_source_instances.end(),
+          [](decltype(data_source_instances)::const_reference x) {
+            return x.second.state == DataSourceInstance::STOPPED;
+          });
+    }
+
+    // Checks whether |clone_uid| is allowed to clone the current tracing
+    // session.
+    bool IsCloneAllowed(uid_t clone_uid) const;
+
+    const TracingSessionID id;
+
+    // The consumer that started the session.
+    // Can be nullptr if the consumer detached from the session.
+    ConsumerEndpointImpl* consumer_maybe_null;
+
+    // Unix uid of the consumer. This is valid even after the consumer detaches
+    // and does not change for the entire duration of the session. It is used to
+    // prevent that a consumer re-attaches to a session from a different uid.
+    uid_t const consumer_uid;
+
+    // The list of triggers this session received while alive and the time they
+    // were received at. This is used to insert 'fake' packets back to the
+    // consumer so they can tell when some event happened. The order matches the
+    // order they were received.
+    struct TriggerInfo {
+      uint64_t boot_time_ns;
+      std::string trigger_name;
+      std::string producer_name;
+      uid_t producer_uid;
+    };
+    std::vector<TriggerInfo> received_triggers;
+
+    // The trace config provided by the Consumer when calling
+    // EnableTracing(), plus any updates performed by ChangeTraceConfig.
+    TraceConfig config;
+
+    // List of data source instances that have been enabled on the various
+    // producers for this tracing session.
+    std::multimap<ProducerID, DataSourceInstance> data_source_instances;
+
+    // For each Flush(N) request, keeps track of the set of producers for which
+    // we are still awaiting a NotifyFlushComplete(N) ack.
+    std::map<FlushRequestID, PendingFlush> pending_flushes;
+
+    // For each Clone request, keeps track of the flushes acknowledgement that
+    // we are still waiting for.
+    std::map<PendingCloneID, PendingClone> pending_clones;
+
+    PendingCloneID last_pending_clone_id_ = 0;
+
+    // Maps a per-trace-session buffer index into the corresponding global
+    // BufferID (shared namespace amongst all consumers). This vector has as
+    // many entries as |config.buffers_size()|.
+    std::vector<BufferID> buffers_index;
+
+    std::map<std::tuple<MachineID, ProducerID, WriterID>, PacketSequenceID>
+        packet_sequence_ids;
+    PacketSequenceID last_packet_sequence_id = kServicePacketSequenceID;
+
+    // Whether we should emit the trace stats next time we reach EOF while
+    // performing ReadBuffers.
+    bool should_emit_stats = false;
+
+    // Whether we should emit the sync marker the next time ReadBuffers() is
+    // called.
+    bool should_emit_sync_marker = false;
+
+    // Whether we put the initial packets (trace config, system info,
+    // etc.) into the trace output yet.
+    bool did_emit_initial_packets = false;
+
+    // Whether we emitted clock offsets for relay clients yet.
+    bool did_emit_remote_clock_sync_ = false;
+
+    // Whether we should compress TracePackets after reading them.
+    bool compress_deflate = false;
+
+    // The number of received triggers we've emitted into the trace output.
+    size_t num_triggers_emitted_into_trace = 0;
+
+    // Packets that failed validation of the TrustedPacket.
+    uint64_t invalid_packets = 0;
+
+    // Flush() stats. See comments in trace_stats.proto for more.
+    uint64_t flushes_requested = 0;
+    uint64_t flushes_succeeded = 0;
+    uint64_t flushes_failed = 0;
+
+    // Outcome of the final Flush() done by FlushAndDisableTracing().
+    protos::gen::TraceStats_FinalFlushOutcome final_flush_outcome{};
+
+    // Set to true on the first call to MaybeNotifyAllDataSourcesStarted().
+    bool did_notify_all_data_source_started = false;
+
+    // Stores all lifecycle events of a particular type (i.e. associated with a
+    // single field id in the TracingServiceEvent proto).
+    struct LifecycleEvent {
+      LifecycleEvent(uint32_t f_id, uint32_t m_size = 1)
+          : field_id(f_id), max_size(m_size), timestamps(m_size) {}
+
+      // The field id of the event in the TracingServiceEvent proto.
+      uint32_t field_id;
+
+      // Stores the max size of |timestamps|. Set to 1 by default (in
+      // the constructor) but can be overriden in TraceSession constructor
+      // if a larger size is required.
+      uint32_t max_size;
+
+      // Stores the timestamps emitted for each event type (in nanoseconds).
+      // Emitted into the trace and cleared when the consumer next calls
+      // ReadBuffers.
+      base::CircularQueue<int64_t> timestamps;
+    };
+    std::vector<LifecycleEvent> lifecycle_events;
+
+    using ClockSnapshotData = ClockSnapshotVector;
+
+    // Initial clock snapshot, captured at trace start time (when state goes to
+    // TracingSession::STARTED). Emitted into the trace when the consumer first
+    // calls ReadBuffers().
+    ClockSnapshotData initial_clock_snapshot;
+
+    // Stores clock snapshots to emit into the trace as a ring buffer. This
+    // buffer is populated both periodically and when lifecycle events happen
+    // but only when significant clock drift is detected. Emitted into the trace
+    // and cleared when the consumer next calls ReadBuffers().
+    base::CircularQueue<ClockSnapshotData> clock_snapshot_ring_buffer;
+
+    State state = DISABLED;
+
+    // If the consumer detached the session, this variable defines the key used
+    // for identifying the session later when reattaching.
+    std::string detach_key;
+
+    // This is set when the Consumer calls sets |write_into_file| == true in the
+    // TraceConfig. In this case this represents the file we should stream the
+    // trace packets into, rather than returning it to the consumer via
+    // OnTraceData().
+    base::ScopedFile write_into_file;
+    uint32_t write_period_ms = 0;
+    uint64_t max_file_size_bytes = 0;
+    uint64_t bytes_written_into_file = 0;
+
+    // Periodic task for snapshotting service events (e.g. clocks, sync markers
+    // etc)
+    base::PeriodicTask snapshot_periodic_task;
+
+    // Deferred task that stops the trace when |duration_ms| expires. This is
+    // to handle the case of |prefer_suspend_clock_for_duration| which cannot
+    // use PostDelayedTask.
+    base::PeriodicTask timed_stop_task;
+
+    // When non-NULL the packets should be post-processed using the filter.
+    std::unique_ptr<protozero::MessageFilter> trace_filter;
+    uint64_t filter_input_packets = 0;
+    uint64_t filter_input_bytes = 0;
+    uint64_t filter_output_bytes = 0;
+    uint64_t filter_errors = 0;
+    uint64_t filter_time_taken_ns = 0;
+    std::vector<uint64_t> filter_bytes_discarded_per_buffer;
+
+    // A randomly generated trace identifier. Note that this does NOT always
+    // match the requested TraceConfig.trace_uuid_msb/lsb. Spcifically, it does
+    // until a gap-less snapshot is requested. Each snapshot re-generates the
+    // uuid to avoid emitting two different traces with the same uuid.
+    base::Uuid trace_uuid;
+
+    // NOTE: when adding new fields here consider whether that state should be
+    // copied over in DoCloneSession() or not. Ask yourself: is this a
+    // "runtime state" (e.g. active data sources) or a "trace (meta)data state"?
+    // If the latter, it should be handled by DoCloneSession()).
+  };
+
+  TracingServiceImpl(const TracingServiceImpl&) = delete;
+  TracingServiceImpl& operator=(const TracingServiceImpl&) = delete;
+
+  bool IsInitiatorPrivileged(const TracingSession&);
+
+  DataSourceInstance* SetupDataSource(const TraceConfig::DataSource&,
+                                      const TraceConfig::ProducerConfig&,
+                                      const RegisteredDataSource&,
+                                      TracingSession*);
+
+  // Returns the next available ProducerID that is not in |producers_|.
+  ProducerID GetNextProducerID();
+
+  // Returns a pointer to the |tracing_sessions_| entry or nullptr if the
+  // session doesn't exists.
+  TracingSession* GetTracingSession(TracingSessionID);
+
+  // Returns a pointer to the tracing session that has the highest
+  // TraceConfig.bugreport_score, if any, or nullptr.
+  TracingSession* FindTracingSessionWithMaxBugreportScore();
+
+  // Returns a pointer to the |tracing_sessions_| entry, matching the given
+  // uid and detach key, or nullptr if no such session exists.
+  TracingSession* GetDetachedSession(uid_t, const std::string& key);
+
+  // Update the memory guard rail by using the latest information from the
+  // shared memory and trace buffers.
+  void UpdateMemoryGuardrail();
+
+  void StartDataSourceInstance(ProducerEndpointImpl*,
+                               TracingSession*,
+                               DataSourceInstance*);
+  void StopDataSourceInstance(ProducerEndpointImpl*,
+                              TracingSession*,
+                              DataSourceInstance*,
+                              bool disable_immediately);
+  void PeriodicSnapshotTask(TracingSessionID);
+  void MaybeSnapshotClocksIntoRingBuffer(TracingSession*);
+  bool SnapshotClocks(TracingSession::ClockSnapshotData*);
+  void SnapshotLifecyleEvent(TracingSession*,
+                             uint32_t field_id,
+                             bool snapshot_clocks);
+  void EmitClockSnapshot(TracingSession*,
+                         TracingSession::ClockSnapshotData,
+                         std::vector<TracePacket>*);
+  void EmitSyncMarker(std::vector<TracePacket>*);
+  void EmitStats(TracingSession*, std::vector<TracePacket>*);
+  TraceStats GetTraceStats(TracingSession*);
+  void EmitLifecycleEvents(TracingSession*, std::vector<TracePacket>*);
+  void EmitUuid(TracingSession*, std::vector<TracePacket>*);
+  void MaybeEmitTraceConfig(TracingSession*, std::vector<TracePacket>*);
+  void EmitSystemInfo(std::vector<TracePacket>*);
+  void MaybeEmitReceivedTriggers(TracingSession*, std::vector<TracePacket>*);
+  void MaybeEmitRemoteClockSync(TracingSession*, std::vector<TracePacket>*);
+  void MaybeNotifyAllDataSourcesStarted(TracingSession*);
+  void OnFlushTimeout(TracingSessionID, FlushRequestID);
+  void OnDisableTracingTimeout(TracingSessionID);
+  void DisableTracingNotifyConsumerAndFlushFile(TracingSession*);
+  void PeriodicFlushTask(TracingSessionID, bool post_next_only);
+  void CompleteFlush(TracingSessionID tsid,
+                     ConsumerEndpoint::FlushCallback callback,
+                     bool success);
+  void ScrapeSharedMemoryBuffers(TracingSession*, ProducerEndpointImpl*);
+  void PeriodicClearIncrementalStateTask(TracingSessionID, bool post_next_only);
+  TraceBuffer* GetBufferByID(BufferID);
+  void FlushDataSourceInstances(
+      TracingSession*,
+      uint32_t timeout_ms,
+      const std::map<ProducerID, std::vector<DataSourceInstanceID>>&,
+      ConsumerEndpoint::FlushCallback,
+      FlushFlags);
+  std::map<ProducerID, std::vector<DataSourceInstanceID>>
+  GetFlushableDataSourceInstancesForBuffers(TracingSession*,
+                                            const std::set<BufferID>&);
+  bool DoCloneBuffers(TracingSession*,
+                      const std::set<BufferID>&,
+                      std::vector<std::unique_ptr<TraceBuffer>>*);
+  base::Status FinishCloneSession(ConsumerEndpointImpl*,
+                                  TracingSessionID,
+                                  std::vector<std::unique_ptr<TraceBuffer>>,
+                                  bool skip_filter,
+                                  bool final_flush_outcome,
+                                  base::Uuid*);
+  void OnFlushDoneForClone(TracingSessionID src_tsid,
+                           PendingCloneID clone_id,
+                           const std::set<BufferID>& buf_ids,
+                           bool final_flush_outcome);
+
+  // Returns true if `*tracing_session` is waiting for a trigger that hasn't
+  // happened.
+  static bool IsWaitingForTrigger(TracingSession* tracing_session);
+
+  // Reads the buffers from `*tracing_session` and returns them (along with some
+  // metadata packets).
+  //
+  // The function stops when the cumulative size of the return packets exceeds
+  // `threshold` (so it's not a strict upper bound) and sets `*has_more` to
+  // true, or when there are no more packets (and sets `*has_more` to false).
+  std::vector<TracePacket> ReadBuffers(TracingSession* tracing_session,
+                                       size_t threshold,
+                                       bool* has_more);
+
+  // If `*tracing_session` has a filter, applies it to `*packets`. Doesn't
+  // change the number of `*packets`, only their content.
+  void MaybeFilterPackets(TracingSession* tracing_session,
+                          std::vector<TracePacket>* packets);
+
+  // If `*tracing_session` has compression enabled, compress `*packets`.
+  void MaybeCompressPackets(TracingSession* tracing_session,
+                            std::vector<TracePacket>* packets);
+
+  // If `*tracing_session` is configured to write into a file, writes `packets`
+  // into the file.
+  //
+  // Returns true if the file should be closed (because it's full or there has
+  // been an error), false otherwise.
+  bool WriteIntoFile(TracingSession* tracing_session,
+                     std::vector<TracePacket> packets);
+  void OnStartTriggersTimeout(TracingSessionID tsid);
+  void MaybeLogUploadEvent(const TraceConfig&,
+                           const base::Uuid&,
+                           PerfettoStatsdAtom atom,
+                           const std::string& trigger_name = "");
+  void MaybeLogTriggerEvent(const TraceConfig&,
+                            PerfettoTriggerAtom atom,
+                            const std::string& trigger_name);
+  size_t PurgeExpiredAndCountTriggerInWindow(int64_t now_ns,
+                                             uint64_t trigger_name_hash);
+  static void StopOnDurationMsExpiry(base::WeakPtr<TracingServiceImpl>,
+                                     TracingSessionID);
+
+  base::TaskRunner* const task_runner_;
+  const InitOpts init_opts_;
+  std::unique_ptr<SharedMemory::Factory> shm_factory_;
+  ProducerID last_producer_id_ = 0;
+  DataSourceInstanceID last_data_source_instance_id_ = 0;
+  TracingSessionID last_tracing_session_id_ = 0;
+  FlushRequestID last_flush_request_id_ = 0;
+  uid_t uid_ = 0;
+
+  // Buffer IDs are global across all consumers (because a Producer can produce
+  // data for more than one trace session, hence more than one consumer).
+  IdAllocator<BufferID> buffer_ids_;
+
+  std::multimap<std::string /*name*/, RegisteredDataSource> data_sources_;
+  std::map<ProducerID, ProducerEndpointImpl*> producers_;
+  std::set<ConsumerEndpointImpl*> consumers_;
+  std::map<RelayClientID, RelayEndpointImpl*> relay_clients_;
+  std::map<TracingSessionID, TracingSession> tracing_sessions_;
+  std::map<BufferID, std::unique_ptr<TraceBuffer>> buffers_;
+  std::map<std::string, int64_t> session_to_last_trace_s_;
+
+  // Contains timestamps of triggers.
+  // The queue is sorted by timestamp and invocations older than
+  // |trigger_window_ns_| are purged when a trigger happens.
+  base::CircularQueue<TriggerHistory> trigger_history_;
+
+  bool smb_scraping_enabled_ = false;
+  bool lockdown_mode_ = false;
+  uint32_t min_write_period_ms_ = 100;       // Overridable for testing.
+  int64_t trigger_window_ns_ = kOneDayInNs;  // Overridable for testing.
+
+  std::minstd_rand trigger_probability_rand_;
+  std::uniform_real_distribution<> trigger_probability_dist_;
+  double trigger_rnd_override_for_testing_ = 0;  // Overridable for testing.
+
+  uint8_t sync_marker_packet_[32];  // Lazily initialized.
+  size_t sync_marker_packet_size_ = 0;
+
+  // Stats.
+  uint64_t chunks_discarded_ = 0;
+  uint64_t patches_discarded_ = 0;
+
+  PERFETTO_THREAD_CHECKER(thread_checker_)
+
+  base::WeakPtrFactory<TracingServiceImpl>
+      weak_ptr_factory_;  // Keep at the end.
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_SERVICE_TRACING_SERVICE_IMPL_H_
+// gen_amalgamated begin header: include/perfetto/tracing/core/tracing_service_capabilities.h
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_CAPABILITIES_H_
+#define INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_CAPABILITIES_H_
+
+// Creates the aliases in the ::perfetto namespace, doing things like:
+// using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
+// See comments in forward_decls.h for the historical reasons of this
+// indirection layer.
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_capabilities.gen.h"
+
+#endif  // INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_CAPABILITIES_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/service/tracing_service_impl.h"
+
+#include <limits.h>
+#include <string.h>
+
+#include <cinttypes>
+#include <cstdint>
+#include <limits>
+#include <optional>
+#include <regex>
+#include <unordered_set>
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/client_identity.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/clock_snapshots.h"
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
+    !PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
+#include <sys/uio.h>
+#include <sys/utsname.h>
+#include <unistd.h>
+#endif
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
+    PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
+// gen_amalgamated expanded: #include "src/android_internal/lazy_library_loader.h"    // nogncheck
+// gen_amalgamated expanded: #include "src/android_internal/tracing_service_proxy.h"  // nogncheck
+#endif
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+#define PERFETTO_HAS_CHMOD
+#include <sys/stat.h>
+#endif
+
+#include <algorithm>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/status.h"
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/android_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/metatrace.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/sys_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/uuid.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/version.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/watchdog.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/consumer.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/observable_events.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/producer.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/static_buffer.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/tracing_service_capabilities.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/tracing_service_state.h"
+// gen_amalgamated expanded: #include "src/android_stats/statsd_logging_helper.h"
+// gen_amalgamated expanded: #include "src/protozero/filtering/message_filter.h"
+// gen_amalgamated expanded: #include "src/protozero/filtering/string_filter.h"
+// gen_amalgamated expanded: #include "src/tracing/core/shared_memory_arbiter_impl.h"
+// gen_amalgamated expanded: #include "src/tracing/service/packet_stream_validator.h"
+// gen_amalgamated expanded: #include "src/tracing/service/trace_buffer.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/trace_stats.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/trace_config.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/clock_snapshot.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/perfetto/tracing_service_event.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/remote_clock_sync.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/system_info.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_uuid.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/trigger.pbzero.h"
+
+// General note: this class must assume that Producers are malicious and will
+// try to crash / exploit this class. We can trust pointers because they come
+// from the IPC layer, but we should never assume that that the producer calls
+// come in the right order or their arguments are sane / within bounds.
+
+// This is a macro because we want the call-site line number for the ELOG.
+#define PERFETTO_SVC_ERR(...) \
+  (PERFETTO_ELOG(__VA_ARGS__), ::perfetto::base::ErrStatus(__VA_ARGS__))
+
+namespace perfetto {
+
+namespace {
+constexpr int kMaxBuffersPerConsumer = 128;
+constexpr uint32_t kDefaultSnapshotsIntervalMs = 10 * 1000;
+constexpr int kDefaultWriteIntoFilePeriodMs = 5000;
+constexpr int kMaxConcurrentTracingSessions = 15;
+constexpr int kMaxConcurrentTracingSessionsPerUid = 5;
+constexpr int kMaxConcurrentTracingSessionsForStatsdUid = 10;
+constexpr int64_t kMinSecondsBetweenTracesGuardrail = 5 * 60;
+
+constexpr uint32_t kMillisPerHour = 3600000;
+constexpr uint32_t kMillisPerDay = kMillisPerHour * 24;
+constexpr uint32_t kMaxTracingDurationMillis = 7 * 24 * kMillisPerHour;
+
+// These apply only if enable_extra_guardrails is true.
+constexpr uint32_t kGuardrailsMaxTracingBufferSizeKb = 128 * 1024;
+constexpr uint32_t kGuardrailsMaxTracingDurationMillis = 24 * kMillisPerHour;
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) || PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
+struct iovec {
+  void* iov_base;  // Address
+  size_t iov_len;  // Block size
+};
+
+// Simple implementation of writev. Note that this does not give the atomicity
+// guarantees of a real writev, but we don't depend on these (we aren't writing
+// to the same file from another thread).
+ssize_t writev(int fd, const struct iovec* iov, int iovcnt) {
+  ssize_t total_size = 0;
+  for (int i = 0; i < iovcnt; ++i) {
+    ssize_t current_size = base::WriteAll(fd, iov[i].iov_base, iov[i].iov_len);
+    if (current_size != static_cast<ssize_t>(iov[i].iov_len))
+      return -1;
+    total_size += current_size;
+  }
+  return total_size;
+}
+
+#define IOV_MAX 1024  // Linux compatible limit.
+
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) ||
+        // PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
+
+// Partially encodes a CommitDataRequest in an int32 for the purposes of
+// metatracing. Note that it encodes only the bottom 10 bits of the producer id
+// (which is technically 16 bits wide).
+//
+// Format (by bit range):
+// [   31 ][         30 ][             29:20 ][            19:10 ][        9:0]
+// [unused][has flush id][num chunks to patch][num chunks to move][producer id]
+int32_t EncodeCommitDataRequest(ProducerID producer_id,
+                                const CommitDataRequest& req_untrusted) {
+  uint32_t cmov = static_cast<uint32_t>(req_untrusted.chunks_to_move_size());
+  uint32_t cpatch = static_cast<uint32_t>(req_untrusted.chunks_to_patch_size());
+  uint32_t has_flush_id = req_untrusted.flush_request_id() != 0;
+
+  uint32_t mask = (1 << 10) - 1;
+  uint32_t acc = 0;
+  acc |= has_flush_id << 30;
+  acc |= (cpatch & mask) << 20;
+  acc |= (cmov & mask) << 10;
+  acc |= (producer_id & mask);
+  return static_cast<int32_t>(acc);
+}
+
+void SerializeAndAppendPacket(std::vector<TracePacket>* packets,
+                              std::vector<uint8_t> packet) {
+  Slice slice = Slice::Allocate(packet.size());
+  memcpy(slice.own_data(), packet.data(), packet.size());
+  packets->emplace_back();
+  packets->back().AddSlice(std::move(slice));
+}
+
+std::tuple<size_t /*shm_size*/, size_t /*page_size*/> EnsureValidShmSizes(
+    size_t shm_size,
+    size_t page_size) {
+  // Theoretically the max page size supported by the ABI is 64KB.
+  // However, the current implementation of TraceBuffer (the non-shared
+  // userspace buffer where the service copies data) supports at most
+  // 32K. Setting 64K "works" from the producer<>consumer viewpoint
+  // but then causes the data to be discarded when copying it into
+  // TraceBuffer.
+  constexpr size_t kMaxPageSize = 32 * 1024;
+  static_assert(kMaxPageSize <= SharedMemoryABI::kMaxPageSize, "");
+
+  if (page_size == 0)
+    page_size = TracingServiceImpl::kDefaultShmPageSize;
+  if (shm_size == 0)
+    shm_size = TracingServiceImpl::kDefaultShmSize;
+
+  page_size = std::min<size_t>(page_size, kMaxPageSize);
+  shm_size = std::min<size_t>(shm_size, TracingServiceImpl::kMaxShmSize);
+
+  // The tracing page size has to be multiple of 4K. On some systems (e.g. Mac
+  // on Arm64) the system page size can be larger (e.g., 16K). That doesn't
+  // matter here, because the tracing page size is just a logical partitioning
+  // and does not have any dependencies on kernel mm syscalls (read: it's fine
+  // to have trace page sizes of 4K on a system where the kernel page size is
+  // 16K).
+  bool page_size_is_valid = page_size >= SharedMemoryABI::kMinPageSize;
+  page_size_is_valid &= page_size % SharedMemoryABI::kMinPageSize == 0;
+
+  // Only allow power of two numbers of pages, i.e. 1, 2, 4, 8 pages.
+  size_t num_pages = page_size / SharedMemoryABI::kMinPageSize;
+  page_size_is_valid &= (num_pages & (num_pages - 1)) == 0;
+
+  if (!page_size_is_valid || shm_size < page_size ||
+      shm_size % page_size != 0) {
+    return std::make_tuple(TracingServiceImpl::kDefaultShmSize,
+                           TracingServiceImpl::kDefaultShmPageSize);
+  }
+  return std::make_tuple(shm_size, page_size);
+}
+
+bool NameMatchesFilter(const std::string& name,
+                       const std::vector<std::string>& name_filter,
+                       const std::vector<std::string>& name_regex_filter) {
+  bool filter_is_set = !name_filter.empty() || !name_regex_filter.empty();
+  if (!filter_is_set)
+    return true;
+  bool filter_matches = std::find(name_filter.begin(), name_filter.end(),
+                                  name) != name_filter.end();
+  bool filter_regex_matches =
+      std::find_if(name_regex_filter.begin(), name_regex_filter.end(),
+                   [&](const std::string& regex) {
+                     return std::regex_match(
+                         name, std::regex(regex, std::regex::extended));
+                   }) != name_regex_filter.end();
+  return filter_matches || filter_regex_matches;
+}
+
+// Used when TraceConfig.write_into_file == true and output_path is not empty.
+base::ScopedFile CreateTraceFile(const std::string& path, bool overwrite) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
+    PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
+  // This is NOT trying to preserve any security property, SELinux does that.
+  // It just improves the actionability of the error when people try to save the
+  // trace in a location that is not SELinux-allowed (a generic "permission
+  // denied" vs "don't put it here, put it there").
+  // These are the only SELinux approved dir for trace files that are created
+  // directly by traced.
+  static const char* kTraceDirBasePath = "/data/misc/perfetto-traces/";
+  if (!base::StartsWith(path, kTraceDirBasePath)) {
+    PERFETTO_ELOG("Invalid output_path %s. On Android it must be within %s.",
+                  path.c_str(), kTraceDirBasePath);
+    return base::ScopedFile();
+  }
+#endif
+  // O_CREAT | O_EXCL will fail if the file exists already.
+  const int flags = O_RDWR | O_CREAT | (overwrite ? O_TRUNC : O_EXCL);
+  auto fd = base::OpenFile(path, flags, 0600);
+  if (fd) {
+#if defined(PERFETTO_HAS_CHMOD)
+    // Passing 0644 directly above won't work because of umask.
+    PERFETTO_CHECK(fchmod(*fd, 0644) == 0);
+#endif
+  } else {
+    PERFETTO_PLOG("Failed to create %s", path.c_str());
+  }
+  return fd;
+}
+
+bool ShouldLogEvent(const TraceConfig& cfg) {
+  switch (cfg.statsd_logging()) {
+    case TraceConfig::STATSD_LOGGING_ENABLED:
+      return true;
+    case TraceConfig::STATSD_LOGGING_DISABLED:
+      return false;
+    case TraceConfig::STATSD_LOGGING_UNSPECIFIED:
+      break;
+  }
+  // For backward compatibility with older versions of perfetto_cmd.
+  return cfg.enable_extra_guardrails();
+}
+
+// Appends `data` (which has `size` bytes), to `*packet`. Splits the data in
+// slices no larger than `max_slice_size`.
+void AppendOwnedSlicesToPacket(std::unique_ptr<uint8_t[]> data,
+                               size_t size,
+                               size_t max_slice_size,
+                               perfetto::TracePacket* packet) {
+  if (size <= max_slice_size) {
+    packet->AddSlice(Slice::TakeOwnership(std::move(data), size));
+    return;
+  }
+  uint8_t* src_ptr = data.get();
+  for (size_t size_left = size; size_left > 0;) {
+    const size_t slice_size = std::min(size_left, max_slice_size);
+
+    Slice slice = Slice::Allocate(slice_size);
+    memcpy(slice.own_data(), src_ptr, slice_size);
+    packet->AddSlice(std::move(slice));
+
+    src_ptr += slice_size;
+    size_left -= slice_size;
+  }
+}
+
+using TraceFilter = protos::gen::TraceConfig::TraceFilter;
+std::optional<protozero::StringFilter::Policy> ConvertPolicy(
+    TraceFilter::StringFilterPolicy policy) {
+  switch (policy) {
+    case TraceFilter::SFP_UNSPECIFIED:
+      return std::nullopt;
+    case TraceFilter::SFP_MATCH_REDACT_GROUPS:
+      return protozero::StringFilter::Policy::kMatchRedactGroups;
+    case TraceFilter::SFP_ATRACE_MATCH_REDACT_GROUPS:
+      return protozero::StringFilter::Policy::kAtraceMatchRedactGroups;
+    case TraceFilter::SFP_MATCH_BREAK:
+      return protozero::StringFilter::Policy::kMatchBreak;
+    case TraceFilter::SFP_ATRACE_MATCH_BREAK:
+      return protozero::StringFilter::Policy::kAtraceMatchBreak;
+    case TraceFilter::SFP_ATRACE_REPEATED_SEARCH_REDACT_GROUPS:
+      return protozero::StringFilter::Policy::kAtraceRepeatedSearchRedactGroups;
+  }
+  return std::nullopt;
+}
+
+}  // namespace
+
+// static
+std::unique_ptr<TracingService> TracingService::CreateInstance(
+    std::unique_ptr<SharedMemory::Factory> shm_factory,
+    base::TaskRunner* task_runner,
+    InitOpts init_opts) {
+  return std::unique_ptr<TracingService>(
+      new TracingServiceImpl(std::move(shm_factory), task_runner, init_opts));
+}
+
+TracingServiceImpl::TracingServiceImpl(
+    std::unique_ptr<SharedMemory::Factory> shm_factory,
+    base::TaskRunner* task_runner,
+    InitOpts init_opts)
+    : task_runner_(task_runner),
+      init_opts_(init_opts),
+      shm_factory_(std::move(shm_factory)),
+      uid_(base::GetCurrentUserId()),
+      buffer_ids_(kMaxTraceBufferID),
+      trigger_probability_rand_(
+          static_cast<uint32_t>(base::GetWallTimeNs().count())),
+      weak_ptr_factory_(this) {
+  PERFETTO_DCHECK(task_runner_);
+}
+
+TracingServiceImpl::~TracingServiceImpl() {
+  // TODO(fmayer): handle teardown of all Producer.
+}
+
+std::unique_ptr<TracingService::ProducerEndpoint>
+TracingServiceImpl::ConnectProducer(Producer* producer,
+                                    const ClientIdentity& client_identity,
+                                    const std::string& producer_name,
+                                    size_t shared_memory_size_hint_bytes,
+                                    bool in_process,
+                                    ProducerSMBScrapingMode smb_scraping_mode,
+                                    size_t shared_memory_page_size_hint_bytes,
+                                    std::unique_ptr<SharedMemory> shm,
+                                    const std::string& sdk_version) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  auto uid = client_identity.uid();
+  if (lockdown_mode_ && uid != base::GetCurrentUserId()) {
+    PERFETTO_DLOG("Lockdown mode. Rejecting producer with UID %ld",
+                  static_cast<unsigned long>(uid));
+    return nullptr;
+  }
+
+  if (producers_.size() >= kMaxProducerID) {
+    PERFETTO_DFATAL("Too many producers.");
+    return nullptr;
+  }
+  const ProducerID id = GetNextProducerID();
+  PERFETTO_DLOG("Producer %" PRIu16 " connected, uid=%d", id,
+                static_cast<int>(uid));
+  bool smb_scraping_enabled = smb_scraping_enabled_;
+  switch (smb_scraping_mode) {
+    case ProducerSMBScrapingMode::kDefault:
+      break;
+    case ProducerSMBScrapingMode::kEnabled:
+      smb_scraping_enabled = true;
+      break;
+    case ProducerSMBScrapingMode::kDisabled:
+      smb_scraping_enabled = false;
+      break;
+  }
+
+  std::unique_ptr<ProducerEndpointImpl> endpoint(new ProducerEndpointImpl(
+      id, client_identity, this, task_runner_, producer, producer_name,
+      sdk_version, in_process, smb_scraping_enabled));
+  auto it_and_inserted = producers_.emplace(id, endpoint.get());
+  PERFETTO_DCHECK(it_and_inserted.second);
+  endpoint->shmem_size_hint_bytes_ = shared_memory_size_hint_bytes;
+  endpoint->shmem_page_size_hint_bytes_ = shared_memory_page_size_hint_bytes;
+
+  // Producer::OnConnect() should run before Producer::OnTracingSetup(). The
+  // latter may be posted by SetupSharedMemory() below, so post OnConnect() now.
+  auto weak_ptr = endpoint->weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostTask([weak_ptr] {
+    if (weak_ptr)
+      weak_ptr->producer_->OnConnect();
+  });
+
+  if (shm) {
+    // The producer supplied an SMB. This is used only by Chrome; in the most
+    // common cases the SMB is created by the service and passed via
+    // OnTracingSetup(). Verify that it is correctly sized before we attempt to
+    // use it. The transport layer has to verify the integrity of the SMB (e.g.
+    // ensure that the producer can't resize if after the fact).
+    size_t shm_size, page_size;
+    std::tie(shm_size, page_size) =
+        EnsureValidShmSizes(shm->size(), endpoint->shmem_page_size_hint_bytes_);
+    if (shm_size == shm->size() &&
+        page_size == endpoint->shmem_page_size_hint_bytes_) {
+      PERFETTO_DLOG(
+          "Adopting producer-provided SMB of %zu kB for producer \"%s\"",
+          shm_size / 1024, endpoint->name_.c_str());
+      endpoint->SetupSharedMemory(std::move(shm), page_size,
+                                  /*provided_by_producer=*/true);
+    } else {
+      PERFETTO_LOG(
+          "Discarding incorrectly sized producer-provided SMB for producer "
+          "\"%s\", falling back to service-provided SMB. Requested sizes: %zu "
+          "B total, %zu B page size; suggested corrected sizes: %zu B total, "
+          "%zu B page size",
+          endpoint->name_.c_str(), shm->size(),
+          endpoint->shmem_page_size_hint_bytes_, shm_size, page_size);
+      shm.reset();
+    }
+  }
+
+  return std::unique_ptr<ProducerEndpoint>(std::move(endpoint));
+}
+
+void TracingServiceImpl::DisconnectProducer(ProducerID id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DLOG("Producer %" PRIu16 " disconnected", id);
+  PERFETTO_DCHECK(producers_.count(id));
+
+  // Scrape remaining chunks for this producer to ensure we don't lose data.
+  if (auto* producer = GetProducer(id)) {
+    for (auto& session_id_and_session : tracing_sessions_)
+      ScrapeSharedMemoryBuffers(&session_id_and_session.second, producer);
+  }
+
+  for (auto it = data_sources_.begin(); it != data_sources_.end();) {
+    auto next = it;
+    next++;
+    if (it->second.producer_id == id)
+      UnregisterDataSource(id, it->second.descriptor.name());
+    it = next;
+  }
+
+  producers_.erase(id);
+  UpdateMemoryGuardrail();
+}
+
+TracingServiceImpl::ProducerEndpointImpl* TracingServiceImpl::GetProducer(
+    ProducerID id) const {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto it = producers_.find(id);
+  if (it == producers_.end())
+    return nullptr;
+  return it->second;
+}
+
+std::unique_ptr<TracingService::ConsumerEndpoint>
+TracingServiceImpl::ConnectConsumer(Consumer* consumer, uid_t uid) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DLOG("Consumer %p connected from UID %" PRIu64,
+                reinterpret_cast<void*>(consumer), static_cast<uint64_t>(uid));
+  std::unique_ptr<ConsumerEndpointImpl> endpoint(
+      new ConsumerEndpointImpl(this, task_runner_, consumer, uid));
+  auto it_and_inserted = consumers_.emplace(endpoint.get());
+  PERFETTO_DCHECK(it_and_inserted.second);
+  // Consumer might go away before we're able to send the connect notification,
+  // if that is the case just bail out.
+  auto weak_ptr = endpoint->weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostTask([weak_ptr] {
+    if (weak_ptr)
+      weak_ptr->consumer_->OnConnect();
+  });
+  return std::unique_ptr<ConsumerEndpoint>(std::move(endpoint));
+}
+
+void TracingServiceImpl::DisconnectConsumer(ConsumerEndpointImpl* consumer) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DLOG("Consumer %p disconnected", reinterpret_cast<void*>(consumer));
+  PERFETTO_DCHECK(consumers_.count(consumer));
+
+  // TODO(primiano) : Check that this is safe (what happens if there are
+  // ReadBuffers() calls posted in the meantime? They need to become noop).
+  if (consumer->tracing_session_id_)
+    FreeBuffers(consumer->tracing_session_id_);  // Will also DisableTracing().
+  consumers_.erase(consumer);
+
+  // At this point no more pointers to |consumer| should be around.
+  PERFETTO_DCHECK(!std::any_of(
+      tracing_sessions_.begin(), tracing_sessions_.end(),
+      [consumer](const std::pair<const TracingSessionID, TracingSession>& kv) {
+        return kv.second.consumer_maybe_null == consumer;
+      }));
+}
+
+bool TracingServiceImpl::DetachConsumer(ConsumerEndpointImpl* consumer,
+                                        const std::string& key) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DLOG("Consumer %p detached", reinterpret_cast<void*>(consumer));
+  PERFETTO_DCHECK(consumers_.count(consumer));
+
+  TracingSessionID tsid = consumer->tracing_session_id_;
+  TracingSession* tracing_session;
+  if (!tsid || !(tracing_session = GetTracingSession(tsid)))
+    return false;
+
+  if (GetDetachedSession(consumer->uid_, key)) {
+    PERFETTO_ELOG("Another session has been detached with the same key \"%s\"",
+                  key.c_str());
+    return false;
+  }
+
+  PERFETTO_DCHECK(tracing_session->consumer_maybe_null == consumer);
+  tracing_session->consumer_maybe_null = nullptr;
+  tracing_session->detach_key = key;
+  consumer->tracing_session_id_ = 0;
+  return true;
+}
+
+std::unique_ptr<TracingService::RelayEndpoint>
+TracingServiceImpl::ConnectRelayClient(RelayClientID relay_client_id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  auto endpoint = std::make_unique<RelayEndpointImpl>(relay_client_id, this);
+  relay_clients_[relay_client_id] = endpoint.get();
+
+  return std::move(endpoint);
+}
+
+void TracingServiceImpl::DisconnectRelayClient(RelayClientID relay_client_id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  if (relay_clients_.find(relay_client_id) == relay_clients_.end())
+    return;
+  relay_clients_.erase(relay_client_id);
+}
+
+bool TracingServiceImpl::AttachConsumer(ConsumerEndpointImpl* consumer,
+                                        const std::string& key) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DLOG("Consumer %p attaching to session %s",
+                reinterpret_cast<void*>(consumer), key.c_str());
+  PERFETTO_DCHECK(consumers_.count(consumer));
+
+  if (consumer->tracing_session_id_) {
+    PERFETTO_ELOG(
+        "Cannot reattach consumer to session %s"
+        " while it already attached tracing session ID %" PRIu64,
+        key.c_str(), consumer->tracing_session_id_);
+    return false;
+  }
+
+  auto* tracing_session = GetDetachedSession(consumer->uid_, key);
+  if (!tracing_session) {
+    PERFETTO_ELOG(
+        "Failed to attach consumer, session '%s' not found for uid %d",
+        key.c_str(), static_cast<int>(consumer->uid_));
+    return false;
+  }
+
+  consumer->tracing_session_id_ = tracing_session->id;
+  tracing_session->consumer_maybe_null = consumer;
+  tracing_session->detach_key.clear();
+  return true;
+}
+
+base::Status TracingServiceImpl::EnableTracing(ConsumerEndpointImpl* consumer,
+                                               const TraceConfig& cfg,
+                                               base::ScopedFile fd) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  // If the producer is specifying a UUID, respect that (at least for the first
+  // snapshot). Otherwise generate a new UUID.
+  base::Uuid uuid(cfg.trace_uuid_lsb(), cfg.trace_uuid_msb());
+  if (!uuid)
+    uuid = base::Uuidv4();
+
+  PERFETTO_DLOG("Enabling tracing for consumer %p, UUID: %s",
+                reinterpret_cast<void*>(consumer),
+                uuid.ToPrettyString().c_str());
+  MaybeLogUploadEvent(cfg, uuid, PerfettoStatsdAtom::kTracedEnableTracing);
+  if (cfg.lockdown_mode() == TraceConfig::LOCKDOWN_SET)
+    lockdown_mode_ = true;
+  if (cfg.lockdown_mode() == TraceConfig::LOCKDOWN_CLEAR)
+    lockdown_mode_ = false;
+
+  // Scope |tracing_session| to this block to prevent accidental use of a null
+  // pointer later in this function.
+  {
+    TracingSession* tracing_session =
+        GetTracingSession(consumer->tracing_session_id_);
+    if (tracing_session) {
+      MaybeLogUploadEvent(
+          cfg, uuid,
+          PerfettoStatsdAtom::kTracedEnableTracingExistingTraceSession);
+      return PERFETTO_SVC_ERR(
+          "A Consumer is trying to EnableTracing() but another tracing "
+          "session is already active (forgot a call to FreeBuffers() ?)");
+    }
+  }
+
+  const uint32_t max_duration_ms = cfg.enable_extra_guardrails()
+                                       ? kGuardrailsMaxTracingDurationMillis
+                                       : kMaxTracingDurationMillis;
+  if (cfg.duration_ms() > max_duration_ms) {
+    MaybeLogUploadEvent(cfg, uuid,
+                        PerfettoStatsdAtom::kTracedEnableTracingTooLongTrace);
+    return PERFETTO_SVC_ERR("Requested too long trace (%" PRIu32
+                            "ms  > %" PRIu32 " ms)",
+                            cfg.duration_ms(), max_duration_ms);
+  }
+
+  const bool has_trigger_config =
+      GetTriggerMode(cfg) != TraceConfig::TriggerConfig::UNSPECIFIED;
+  if (has_trigger_config &&
+      (cfg.trigger_config().trigger_timeout_ms() == 0 ||
+       cfg.trigger_config().trigger_timeout_ms() > max_duration_ms)) {
+    MaybeLogUploadEvent(
+        cfg, uuid,
+        PerfettoStatsdAtom::kTracedEnableTracingInvalidTriggerTimeout);
+    return PERFETTO_SVC_ERR(
+        "Traces with START_TRACING triggers must provide a positive "
+        "trigger_timeout_ms < 7 days (received %" PRIu32 "ms)",
+        cfg.trigger_config().trigger_timeout_ms());
+  }
+
+  // This check has been introduced in May 2023 after finding b/274931668.
+  if (static_cast<int>(cfg.trigger_config().trigger_mode()) >
+      TraceConfig::TriggerConfig::TriggerMode_MAX) {
+    MaybeLogUploadEvent(
+        cfg, uuid, PerfettoStatsdAtom::kTracedEnableTracingInvalidTriggerMode);
+    return PERFETTO_SVC_ERR(
+        "The trace config specified an invalid trigger_mode");
+  }
+
+  if (cfg.trigger_config().use_clone_snapshot_if_available() &&
+      cfg.trigger_config().trigger_mode() !=
+          TraceConfig::TriggerConfig::STOP_TRACING) {
+    MaybeLogUploadEvent(
+        cfg, uuid, PerfettoStatsdAtom::kTracedEnableTracingInvalidTriggerMode);
+    return PERFETTO_SVC_ERR(
+        "trigger_mode must be STOP_TRACING when "
+        "use_clone_snapshot_if_available=true");
+  }
+
+  if (has_trigger_config && cfg.duration_ms() != 0) {
+    MaybeLogUploadEvent(
+        cfg, uuid, PerfettoStatsdAtom::kTracedEnableTracingDurationWithTrigger);
+    return PERFETTO_SVC_ERR(
+        "duration_ms was set, this must not be set for traces with triggers.");
+  }
+
+  for (char c : cfg.bugreport_filename()) {
+    if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
+          (c >= '0' && c <= '9') || c == '-' || c == '_' || c == '.')) {
+      MaybeLogUploadEvent(
+          cfg, uuid, PerfettoStatsdAtom::kTracedEnableTracingInvalidBrFilename);
+      return PERFETTO_SVC_ERR(
+          "bugreport_filename contains invalid chars. Use [a-zA-Z0-9-_.]+");
+    }
+  }
+
+  if ((GetTriggerMode(cfg) == TraceConfig::TriggerConfig::STOP_TRACING ||
+       GetTriggerMode(cfg) == TraceConfig::TriggerConfig::CLONE_SNAPSHOT) &&
+      cfg.write_into_file()) {
+    // We don't support this usecase because there are subtle assumptions which
+    // break around TracingServiceEvents and windowed sorting (i.e. if we don't
+    // drain the events in ReadBuffersIntoFile because we are waiting for
+    // STOP_TRACING, we can end up queueing up a lot of TracingServiceEvents and
+    // emitting them wildy out of order breaking windowed sorting in trace
+    // processor).
+    MaybeLogUploadEvent(
+        cfg, uuid,
+        PerfettoStatsdAtom::kTracedEnableTracingStopTracingWriteIntoFile);
+    return PERFETTO_SVC_ERR(
+        "Specifying trigger mode STOP_TRACING/CLONE_SNAPSHOT and "
+        "write_into_file together is unsupported");
+  }
+
+  std::unordered_set<std::string> triggers;
+  for (const auto& trigger : cfg.trigger_config().triggers()) {
+    if (!triggers.insert(trigger.name()).second) {
+      MaybeLogUploadEvent(
+          cfg, uuid,
+          PerfettoStatsdAtom::kTracedEnableTracingDuplicateTriggerName);
+      return PERFETTO_SVC_ERR("Duplicate trigger name: %s",
+                              trigger.name().c_str());
+    }
+  }
+
+  if (cfg.enable_extra_guardrails()) {
+    if (cfg.deferred_start()) {
+      MaybeLogUploadEvent(
+          cfg, uuid,
+          PerfettoStatsdAtom::kTracedEnableTracingInvalidDeferredStart);
+      return PERFETTO_SVC_ERR(
+          "deferred_start=true is not supported in unsupervised traces");
+    }
+    uint64_t buf_size_sum = 0;
+    for (const auto& buf : cfg.buffers()) {
+      if (buf.size_kb() % 4 != 0) {
+        MaybeLogUploadEvent(
+            cfg, uuid,
+            PerfettoStatsdAtom::kTracedEnableTracingInvalidBufferSize);
+        return PERFETTO_SVC_ERR(
+            "buffers.size_kb must be a multiple of 4, got %" PRIu32,
+            buf.size_kb());
+      }
+      buf_size_sum += buf.size_kb();
+    }
+
+    uint32_t max_tracing_buffer_size_kb =
+        std::max(kGuardrailsMaxTracingBufferSizeKb,
+                 cfg.guardrail_overrides().max_tracing_buffer_size_kb());
+    if (buf_size_sum > max_tracing_buffer_size_kb) {
+      MaybeLogUploadEvent(
+          cfg, uuid,
+          PerfettoStatsdAtom::kTracedEnableTracingBufferSizeTooLarge);
+      return PERFETTO_SVC_ERR("Requested too large trace buffer (%" PRIu64
+                              "kB  > %" PRIu32 " kB)",
+                              buf_size_sum, max_tracing_buffer_size_kb);
+    }
+  }
+
+  if (cfg.buffers_size() > kMaxBuffersPerConsumer) {
+    MaybeLogUploadEvent(cfg, uuid,
+                        PerfettoStatsdAtom::kTracedEnableTracingTooManyBuffers);
+    return PERFETTO_SVC_ERR("Too many buffers configured (%d)",
+                            cfg.buffers_size());
+  }
+  // Check that the config specifies all buffers for its data sources. This
+  // is also checked in SetupDataSource, but it is simpler to return a proper
+  // error to the consumer from here (and there will be less state to undo).
+  for (const TraceConfig::DataSource& cfg_data_source : cfg.data_sources()) {
+    size_t num_buffers = static_cast<size_t>(cfg.buffers_size());
+    size_t target_buffer = cfg_data_source.config().target_buffer();
+    if (target_buffer >= num_buffers) {
+      MaybeLogUploadEvent(
+          cfg, uuid, PerfettoStatsdAtom::kTracedEnableTracingOobTargetBuffer);
+      return PERFETTO_SVC_ERR(
+          "Data source \"%s\" specified an out of bounds target_buffer (%zu >= "
+          "%zu)",
+          cfg_data_source.config().name().c_str(), target_buffer, num_buffers);
+    }
+  }
+
+  if (!cfg.unique_session_name().empty()) {
+    const std::string& name = cfg.unique_session_name();
+    for (auto& kv : tracing_sessions_) {
+      if (kv.second.state == TracingSession::CLONED_READ_ONLY)
+        continue;  // Don't consider cloned sessions in uniqueness checks.
+      if (kv.second.config.unique_session_name() == name) {
+        MaybeLogUploadEvent(
+            cfg, uuid,
+            PerfettoStatsdAtom::kTracedEnableTracingDuplicateSessionName);
+        static const char fmt[] =
+            "A trace with this unique session name (%s) already exists";
+        // This happens frequently, don't make it an "E"LOG.
+        PERFETTO_LOG(fmt, name.c_str());
+        return base::ErrStatus(fmt, name.c_str());
+      }
+    }
+  }
+
+  if (cfg.enable_extra_guardrails()) {
+    // unique_session_name can be empty
+    const std::string& name = cfg.unique_session_name();
+    int64_t now_s = base::GetBootTimeS().count();
+
+    // Remove any entries where the time limit has passed so this map doesn't
+    // grow indefinitely:
+    std::map<std::string, int64_t>& sessions = session_to_last_trace_s_;
+    for (auto it = sessions.cbegin(); it != sessions.cend();) {
+      if (now_s - it->second > kMinSecondsBetweenTracesGuardrail) {
+        it = sessions.erase(it);
+      } else {
+        ++it;
+      }
+    }
+
+    int64_t& previous_s = session_to_last_trace_s_[name];
+    if (previous_s == 0) {
+      previous_s = now_s;
+    } else {
+      MaybeLogUploadEvent(
+          cfg, uuid,
+          PerfettoStatsdAtom::kTracedEnableTracingSessionNameTooRecent);
+      return PERFETTO_SVC_ERR(
+          "A trace with unique session name \"%s\" began less than %" PRId64
+          "s ago (%" PRId64 "s)",
+          name.c_str(), kMinSecondsBetweenTracesGuardrail, now_s - previous_s);
+    }
+  }
+
+  const int sessions_for_uid = static_cast<int>(std::count_if(
+      tracing_sessions_.begin(), tracing_sessions_.end(),
+      [consumer](const decltype(tracing_sessions_)::value_type& s) {
+        return s.second.consumer_uid == consumer->uid_;
+      }));
+
+  int per_uid_limit = kMaxConcurrentTracingSessionsPerUid;
+  if (consumer->uid_ == 1066 /* AID_STATSD*/) {
+    per_uid_limit = kMaxConcurrentTracingSessionsForStatsdUid;
+  }
+  if (sessions_for_uid >= per_uid_limit) {
+    MaybeLogUploadEvent(
+        cfg, uuid,
+        PerfettoStatsdAtom::kTracedEnableTracingTooManySessionsForUid);
+    return PERFETTO_SVC_ERR(
+        "Too many concurrent tracing sesions (%d) for uid %d limit is %d",
+        sessions_for_uid, static_cast<int>(consumer->uid_), per_uid_limit);
+  }
+
+  // TODO(primiano): This is a workaround to prevent that a producer gets stuck
+  // in a state where it stalls by design by having more TraceWriterImpl
+  // instances than free pages in the buffer. This is really a bug in
+  // trace_probes and the way it handles stalls in the shmem buffer.
+  if (tracing_sessions_.size() >= kMaxConcurrentTracingSessions) {
+    MaybeLogUploadEvent(
+        cfg, uuid,
+        PerfettoStatsdAtom::kTracedEnableTracingTooManyConcurrentSessions);
+    return PERFETTO_SVC_ERR("Too many concurrent tracing sesions (%zu)",
+                            tracing_sessions_.size());
+  }
+
+  // If the trace config provides a filter bytecode, setup the filter now.
+  // If the filter loading fails, abort the tracing session rather than running
+  // unfiltered.
+  std::unique_ptr<protozero::MessageFilter> trace_filter;
+  if (cfg.has_trace_filter()) {
+    const auto& filt = cfg.trace_filter();
+    trace_filter.reset(new protozero::MessageFilter());
+
+    protozero::StringFilter& string_filter = trace_filter->string_filter();
+    for (const auto& rule : filt.string_filter_chain().rules()) {
+      auto opt_policy = ConvertPolicy(rule.policy());
+      if (!opt_policy.has_value()) {
+        MaybeLogUploadEvent(
+            cfg, uuid, PerfettoStatsdAtom::kTracedEnableTracingInvalidFilter);
+        return PERFETTO_SVC_ERR(
+            "Trace filter has invalid string filtering rules, aborting");
+      }
+      string_filter.AddRule(*opt_policy, rule.regex_pattern(),
+                            rule.atrace_payload_starts_with());
+    }
+
+    const std::string& bytecode_v1 = filt.bytecode();
+    const std::string& bytecode_v2 = filt.bytecode_v2();
+    const std::string& bytecode =
+        bytecode_v2.empty() ? bytecode_v1 : bytecode_v2;
+    if (!trace_filter->LoadFilterBytecode(bytecode.data(), bytecode.size())) {
+      MaybeLogUploadEvent(
+          cfg, uuid, PerfettoStatsdAtom::kTracedEnableTracingInvalidFilter);
+      return PERFETTO_SVC_ERR("Trace filter bytecode invalid, aborting");
+    }
+
+    // The filter is created using perfetto.protos.Trace as root message
+    // (because that makes it possible to play around with the `proto_filter`
+    // tool on actual traces). Here in the service, however, we deal with
+    // perfetto.protos.TracePacket(s), which are one level down (Trace.packet).
+    // The IPC client (or the write_into_filte logic in here) are responsible
+    // for pre-pending the packet preamble (See GetProtoPreamble() calls), but
+    // the preamble is not there at ReadBuffer time. Hence we change the root of
+    // the filtering to start at the Trace.packet level.
+    if (!trace_filter->SetFilterRoot({TracePacket::kPacketFieldNumber})) {
+      MaybeLogUploadEvent(
+          cfg, uuid, PerfettoStatsdAtom::kTracedEnableTracingInvalidFilter);
+      return PERFETTO_SVC_ERR("Failed to set filter root.");
+    }
+  }
+
+  const TracingSessionID tsid = ++last_tracing_session_id_;
+  TracingSession* tracing_session =
+      &tracing_sessions_
+           .emplace(std::piecewise_construct, std::forward_as_tuple(tsid),
+                    std::forward_as_tuple(tsid, consumer, cfg, task_runner_))
+           .first->second;
+
+  tracing_session->trace_uuid = uuid;
+
+  if (trace_filter)
+    tracing_session->trace_filter = std::move(trace_filter);
+
+  if (cfg.write_into_file()) {
+    if (!fd ^ !cfg.output_path().empty()) {
+      MaybeLogUploadEvent(
+          tracing_session->config, uuid,
+          PerfettoStatsdAtom::kTracedEnableTracingInvalidFdOutputFile);
+      tracing_sessions_.erase(tsid);
+      return PERFETTO_SVC_ERR(
+          "When write_into_file==true either a FD needs to be passed or "
+          "output_path must be populated (but not both)");
+    }
+    if (!cfg.output_path().empty()) {
+      fd = CreateTraceFile(cfg.output_path(), /*overwrite=*/false);
+      if (!fd) {
+        MaybeLogUploadEvent(
+            tracing_session->config, uuid,
+            PerfettoStatsdAtom::kTracedEnableTracingFailedToCreateFile);
+        tracing_sessions_.erase(tsid);
+        return PERFETTO_SVC_ERR("Failed to create the trace file %s",
+                                cfg.output_path().c_str());
+      }
+    }
+    tracing_session->write_into_file = std::move(fd);
+    uint32_t write_period_ms = cfg.file_write_period_ms();
+    if (write_period_ms == 0)
+      write_period_ms = kDefaultWriteIntoFilePeriodMs;
+    if (write_period_ms < min_write_period_ms_)
+      write_period_ms = min_write_period_ms_;
+    tracing_session->write_period_ms = write_period_ms;
+    tracing_session->max_file_size_bytes = cfg.max_file_size_bytes();
+    tracing_session->bytes_written_into_file = 0;
+  }
+
+  if (cfg.compression_type() == TraceConfig::COMPRESSION_TYPE_DEFLATE) {
+    if (init_opts_.compressor_fn) {
+      tracing_session->compress_deflate = true;
+    } else {
+      PERFETTO_LOG(
+          "COMPRESSION_TYPE_DEFLATE is not supported in the current build "
+          "configuration. Skipping compression");
+    }
+  }
+
+  // Initialize the log buffers.
+  bool did_allocate_all_buffers = true;
+  bool invalid_buffer_config = false;
+
+  // Allocate the trace buffers. Also create a map to translate a consumer
+  // relative index (TraceConfig.DataSourceConfig.target_buffer) into the
+  // corresponding BufferID, which is a global ID namespace for the service and
+  // all producers.
+  size_t total_buf_size_kb = 0;
+  const size_t num_buffers = static_cast<size_t>(cfg.buffers_size());
+  tracing_session->buffers_index.reserve(num_buffers);
+  for (size_t i = 0; i < num_buffers; i++) {
+    const TraceConfig::BufferConfig& buffer_cfg = cfg.buffers()[i];
+    BufferID global_id = buffer_ids_.Allocate();
+    if (!global_id) {
+      did_allocate_all_buffers = false;  // We ran out of IDs.
+      break;
+    }
+    tracing_session->buffers_index.push_back(global_id);
+    // TraceBuffer size is limited to 32-bit.
+    const uint32_t buf_size_kb = buffer_cfg.size_kb();
+    const uint64_t buf_size_bytes = buf_size_kb * static_cast<uint64_t>(1024);
+    const size_t buf_size = static_cast<size_t>(buf_size_bytes);
+    if (buf_size_bytes == 0 ||
+        buf_size_bytes > std::numeric_limits<uint32_t>::max() ||
+        buf_size != buf_size_bytes) {
+      invalid_buffer_config = true;
+      did_allocate_all_buffers = false;
+      break;
+    }
+    total_buf_size_kb += buf_size_kb;
+    TraceBuffer::OverwritePolicy policy =
+        buffer_cfg.fill_policy() == TraceConfig::BufferConfig::DISCARD
+            ? TraceBuffer::kDiscard
+            : TraceBuffer::kOverwrite;
+    auto it_and_inserted =
+        buffers_.emplace(global_id, TraceBuffer::Create(buf_size, policy));
+    PERFETTO_DCHECK(it_and_inserted.second);  // buffers_.count(global_id) == 0.
+    std::unique_ptr<TraceBuffer>& trace_buffer = it_and_inserted.first->second;
+    if (!trace_buffer) {
+      did_allocate_all_buffers = false;
+      break;
+    }
+  }
+
+  // This can happen if either:
+  // - All the kMaxTraceBufferID slots are taken.
+  // - OOM, or, more realistically, we exhausted virtual memory.
+  // - The buffer size in the config is invalid.
+  // In any case, free all the previously allocated buffers and abort.
+  if (!did_allocate_all_buffers) {
+    for (BufferID global_id : tracing_session->buffers_index) {
+      buffer_ids_.Free(global_id);
+      buffers_.erase(global_id);
+    }
+    MaybeLogUploadEvent(tracing_session->config, uuid,
+                        PerfettoStatsdAtom::kTracedEnableTracingOom);
+    tracing_sessions_.erase(tsid);
+    if (invalid_buffer_config) {
+      return PERFETTO_SVC_ERR(
+          "Failed to allocate tracing buffers: Invalid buffer sizes");
+    }
+    return PERFETTO_SVC_ERR(
+        "Failed to allocate tracing buffers: OOM or too many buffers");
+  }
+
+  UpdateMemoryGuardrail();
+
+  consumer->tracing_session_id_ = tsid;
+
+  // Setup the data sources on the producers without starting them.
+  for (const TraceConfig::DataSource& cfg_data_source : cfg.data_sources()) {
+    // Scan all the registered data sources with a matching name.
+    auto range = data_sources_.equal_range(cfg_data_source.config().name());
+    for (auto it = range.first; it != range.second; it++) {
+      TraceConfig::ProducerConfig producer_config;
+      for (const auto& config : cfg.producers()) {
+        if (GetProducer(it->second.producer_id)->name_ ==
+            config.producer_name()) {
+          producer_config = config;
+          break;
+        }
+      }
+      SetupDataSource(cfg_data_source, producer_config, it->second,
+                      tracing_session);
+    }
+  }
+
+  bool has_start_trigger = false;
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  switch (GetTriggerMode(cfg)) {
+    case TraceConfig::TriggerConfig::UNSPECIFIED:
+      // no triggers are specified so this isn't a trace that is using triggers.
+      PERFETTO_DCHECK(!has_trigger_config);
+      break;
+    case TraceConfig::TriggerConfig::START_TRACING:
+      // For traces which use START_TRACE triggers we need to ensure that the
+      // tracing session will be cleaned up when it times out.
+      has_start_trigger = true;
+      task_runner_->PostDelayedTask(
+          [weak_this, tsid]() {
+            if (weak_this)
+              weak_this->OnStartTriggersTimeout(tsid);
+          },
+          cfg.trigger_config().trigger_timeout_ms());
+      break;
+    case TraceConfig::TriggerConfig::STOP_TRACING:
+    case TraceConfig::TriggerConfig::CLONE_SNAPSHOT:
+      // Update the tracing_session's duration_ms to ensure that if no trigger
+      // is received the session will end and be cleaned up equal to the
+      // timeout.
+      //
+      // TODO(nuskos): Refactor this so that rather then modifying the config we
+      // have a field we look at on the tracing_session.
+      tracing_session->config.set_duration_ms(
+          cfg.trigger_config().trigger_timeout_ms());
+      break;
+
+      // The case of unknown modes (coming from future versions of the service)
+      // is handled few lines above (search for TriggerMode_MAX).
+  }
+
+  tracing_session->state = TracingSession::CONFIGURED;
+  PERFETTO_LOG(
+      "Configured tracing session %" PRIu64
+      ", #sources:%zu, duration:%d ms%s, #buffers:%d, total "
+      "buffer size:%zu KB, total sessions:%zu, uid:%d session name: \"%s\"",
+      tsid, cfg.data_sources().size(), tracing_session->config.duration_ms(),
+      tracing_session->config.prefer_suspend_clock_for_duration()
+          ? " (suspend_clock)"
+          : "",
+      cfg.buffers_size(), total_buf_size_kb, tracing_sessions_.size(),
+      static_cast<unsigned int>(consumer->uid_),
+      cfg.unique_session_name().c_str());
+
+  // Start the data sources, unless this is a case of early setup + fast
+  // triggering, either through TraceConfig.deferred_start or
+  // TraceConfig.trigger_config(). If both are specified which ever one occurs
+  // first will initiate the trace.
+  if (!cfg.deferred_start() && !has_start_trigger)
+    return StartTracing(tsid);
+
+  return base::OkStatus();
+}
+
+void TracingServiceImpl::ChangeTraceConfig(ConsumerEndpointImpl* consumer,
+                                           const TraceConfig& updated_cfg) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  TracingSession* tracing_session =
+      GetTracingSession(consumer->tracing_session_id_);
+  PERFETTO_DCHECK(tracing_session);
+
+  if ((tracing_session->state != TracingSession::STARTED) &&
+      (tracing_session->state != TracingSession::CONFIGURED)) {
+    PERFETTO_ELOG(
+        "ChangeTraceConfig() was called for a tracing session which isn't "
+        "running.");
+    return;
+  }
+
+  // We only support updating producer_name_{,regex}_filter (and pass-through
+  // configs) for now; null out any changeable fields and make sure the rest are
+  // identical.
+  TraceConfig new_config_copy(updated_cfg);
+  for (auto& ds_cfg : *new_config_copy.mutable_data_sources()) {
+    ds_cfg.clear_producer_name_filter();
+    ds_cfg.clear_producer_name_regex_filter();
+  }
+
+  TraceConfig current_config_copy(tracing_session->config);
+  for (auto& ds_cfg : *current_config_copy.mutable_data_sources()) {
+    ds_cfg.clear_producer_name_filter();
+    ds_cfg.clear_producer_name_regex_filter();
+  }
+
+  if (new_config_copy != current_config_copy) {
+    PERFETTO_LOG(
+        "ChangeTraceConfig() was called with a config containing unsupported "
+        "changes; only adding to the producer_name_{,regex}_filter is "
+        "currently supported and will have an effect.");
+  }
+
+  for (TraceConfig::DataSource& cfg_data_source :
+       *tracing_session->config.mutable_data_sources()) {
+    // Find the updated producer_filter in the new config.
+    std::vector<std::string> new_producer_name_filter;
+    std::vector<std::string> new_producer_name_regex_filter;
+    bool found_data_source = false;
+    for (const auto& it : updated_cfg.data_sources()) {
+      if (cfg_data_source.config().name() == it.config().name()) {
+        new_producer_name_filter = it.producer_name_filter();
+        new_producer_name_regex_filter = it.producer_name_regex_filter();
+        found_data_source = true;
+        break;
+      }
+    }
+
+    // Bail out if data source not present in the new config.
+    if (!found_data_source) {
+      PERFETTO_ELOG(
+          "ChangeTraceConfig() called without a current data source also "
+          "present in the new config: %s",
+          cfg_data_source.config().name().c_str());
+      continue;
+    }
+
+    // TODO(oysteine): Just replacing the filter means that if
+    // there are any filter entries which were present in the original config,
+    // but removed from the config passed to ChangeTraceConfig, any matching
+    // producers will keep producing but newly added producers after this
+    // point will never start.
+    *cfg_data_source.mutable_producer_name_filter() = new_producer_name_filter;
+    *cfg_data_source.mutable_producer_name_regex_filter() =
+        new_producer_name_regex_filter;
+
+    // Get the list of producers that are already set up.
+    std::unordered_set<uint16_t> set_up_producers;
+    auto& ds_instances = tracing_session->data_source_instances;
+    for (auto instance_it = ds_instances.begin();
+         instance_it != ds_instances.end(); ++instance_it) {
+      set_up_producers.insert(instance_it->first);
+    }
+
+    // Scan all the registered data sources with a matching name.
+    auto range = data_sources_.equal_range(cfg_data_source.config().name());
+    for (auto it = range.first; it != range.second; it++) {
+      ProducerEndpointImpl* producer = GetProducer(it->second.producer_id);
+      PERFETTO_DCHECK(producer);
+
+      // Check if the producer name of this data source is present
+      // in the name filters. We currently only support new filters, not
+      // removing old ones.
+      if (!NameMatchesFilter(producer->name_, new_producer_name_filter,
+                             new_producer_name_regex_filter)) {
+        continue;
+      }
+
+      // If this producer is already set up, we assume that all datasources
+      // in it started already.
+      if (set_up_producers.count(it->second.producer_id))
+        continue;
+
+      // If it wasn't previously setup, set it up now.
+      // (The per-producer config is optional).
+      TraceConfig::ProducerConfig producer_config;
+      for (const auto& config : tracing_session->config.producers()) {
+        if (producer->name_ == config.producer_name()) {
+          producer_config = config;
+          break;
+        }
+      }
+
+      DataSourceInstance* ds_inst = SetupDataSource(
+          cfg_data_source, producer_config, it->second, tracing_session);
+
+      if (ds_inst && tracing_session->state == TracingSession::STARTED)
+        StartDataSourceInstance(producer, tracing_session, ds_inst);
+    }
+  }
+}
+
+base::Status TracingServiceImpl::StartTracing(TracingSessionID tsid) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  TracingSession* tracing_session = GetTracingSession(tsid);
+  if (!tracing_session) {
+    return PERFETTO_SVC_ERR(
+        "StartTracing() failed, invalid session ID %" PRIu64, tsid);
+  }
+
+  MaybeLogUploadEvent(tracing_session->config, tracing_session->trace_uuid,
+                      PerfettoStatsdAtom::kTracedStartTracing);
+
+  if (tracing_session->state != TracingSession::CONFIGURED) {
+    MaybeLogUploadEvent(
+        tracing_session->config, tracing_session->trace_uuid,
+        PerfettoStatsdAtom::kTracedStartTracingInvalidSessionState);
+    return PERFETTO_SVC_ERR("StartTracing() failed, invalid session state: %d",
+                            tracing_session->state);
+  }
+
+  tracing_session->state = TracingSession::STARTED;
+
+  // We store the start of trace snapshot separately as it's important to make
+  // sure we can interpret all the data in the trace and storing it in the ring
+  // buffer means it could be overwritten by a later snapshot.
+  if (!tracing_session->config.builtin_data_sources()
+           .disable_clock_snapshotting()) {
+    SnapshotClocks(&tracing_session->initial_clock_snapshot);
+  }
+
+  // We don't snapshot the clocks here because we just did this above.
+  SnapshotLifecyleEvent(
+      tracing_session,
+      protos::pbzero::TracingServiceEvent::kTracingStartedFieldNumber,
+      false /* snapshot_clocks */);
+
+  // Periodically snapshot clocks, stats, sync markers while the trace is
+  // active. The snapshots are emitted on the future ReadBuffers() calls, which
+  // means that:
+  //  (a) If we're streaming to a file (or to a consumer) while tracing, we
+  //      write snapshots periodically into the trace.
+  //  (b) If ReadBuffers() is only called after tracing ends, we emit the latest
+  //      snapshot into the trace. For clock snapshots, we keep track of the
+  //      snapshot recorded at the beginning of the session
+  //      (initial_clock_snapshot above), as well as the most recent sampled
+  //      snapshots that showed significant new drift between different clocks.
+  //      The latter clock snapshots are sampled periodically and at lifecycle
+  //      events.
+  base::PeriodicTask::Args snapshot_task_args;
+  snapshot_task_args.start_first_task_immediately = true;
+  snapshot_task_args.use_suspend_aware_timer =
+      tracing_session->config.builtin_data_sources()
+          .prefer_suspend_clock_for_snapshot();
+  snapshot_task_args.task = [weak_this, tsid] {
+    if (weak_this)
+      weak_this->PeriodicSnapshotTask(tsid);
+  };
+  snapshot_task_args.period_ms =
+      tracing_session->config.builtin_data_sources().snapshot_interval_ms();
+  if (!snapshot_task_args.period_ms)
+    snapshot_task_args.period_ms = kDefaultSnapshotsIntervalMs;
+  tracing_session->snapshot_periodic_task.Start(snapshot_task_args);
+
+  // Trigger delayed task if the trace is time limited.
+  const uint32_t trace_duration_ms = tracing_session->config.duration_ms();
+  if (trace_duration_ms > 0) {
+    auto stop_task =
+        std::bind(&TracingServiceImpl::StopOnDurationMsExpiry, weak_this, tsid);
+    if (tracing_session->config.prefer_suspend_clock_for_duration()) {
+      base::PeriodicTask::Args stop_args;
+      stop_args.use_suspend_aware_timer = true;
+      stop_args.period_ms = trace_duration_ms;
+      stop_args.one_shot = true;
+      stop_args.task = std::move(stop_task);
+      tracing_session->timed_stop_task.Start(stop_args);
+    } else {
+      task_runner_->PostDelayedTask(std::move(stop_task), trace_duration_ms);
+    }
+  }  // if (trace_duration_ms > 0).
+
+  // Start the periodic drain tasks if we should to save the trace into a file.
+  if (tracing_session->config.write_into_file()) {
+    task_runner_->PostDelayedTask(
+        [weak_this, tsid] {
+          if (weak_this)
+            weak_this->ReadBuffersIntoFile(tsid);
+        },
+        tracing_session->delay_to_next_write_period_ms());
+  }
+
+  // Start the periodic flush tasks if the config specified a flush period.
+  if (tracing_session->config.flush_period_ms())
+    PeriodicFlushTask(tsid, /*post_next_only=*/true);
+
+  // Start the periodic incremental state clear tasks if the config specified a
+  // period.
+  if (tracing_session->config.incremental_state_config().clear_period_ms()) {
+    PeriodicClearIncrementalStateTask(tsid, /*post_next_only=*/true);
+  }
+
+  for (auto& [prod_id, data_source] : tracing_session->data_source_instances) {
+    ProducerEndpointImpl* producer = GetProducer(prod_id);
+    if (!producer) {
+      PERFETTO_DFATAL("Producer does not exist.");
+      continue;
+    }
+    StartDataSourceInstance(producer, tracing_session, &data_source);
+  }
+
+  MaybeNotifyAllDataSourcesStarted(tracing_session);
+  return base::OkStatus();
+}
+
+// static
+void TracingServiceImpl::StopOnDurationMsExpiry(
+    base::WeakPtr<TracingServiceImpl> weak_this,
+    TracingSessionID tsid) {
+  // Skip entirely the flush if the trace session doesn't exist anymore.
+  // This is to prevent misleading error messages to be logged.
+  if (!weak_this)
+    return;
+  auto* tracing_session_ptr = weak_this->GetTracingSession(tsid);
+  if (!tracing_session_ptr)
+    return;
+  // If this trace was using STOP_TRACING triggers and we've seen
+  // one, then the trigger overrides the normal timeout. In this
+  // case we just return and let the other task clean up this trace.
+  if (GetTriggerMode(tracing_session_ptr->config) ==
+          TraceConfig::TriggerConfig::STOP_TRACING &&
+      !tracing_session_ptr->received_triggers.empty())
+    return;
+  // In all other cases (START_TRACING or no triggers) we flush
+  // after |trace_duration_ms| unconditionally.
+  weak_this->FlushAndDisableTracing(tsid);
+}
+
+void TracingServiceImpl::StartDataSourceInstance(
+    ProducerEndpointImpl* producer,
+    TracingSession* tracing_session,
+    TracingServiceImpl::DataSourceInstance* instance) {
+  PERFETTO_DCHECK(instance->state == DataSourceInstance::CONFIGURED);
+  if (instance->will_notify_on_start) {
+    instance->state = DataSourceInstance::STARTING;
+  } else {
+    instance->state = DataSourceInstance::STARTED;
+  }
+  if (tracing_session->consumer_maybe_null) {
+    tracing_session->consumer_maybe_null->OnDataSourceInstanceStateChange(
+        *producer, *instance);
+  }
+  producer->StartDataSource(instance->instance_id, instance->config);
+
+  // If all data sources are started, notify the consumer.
+  if (instance->state == DataSourceInstance::STARTED)
+    MaybeNotifyAllDataSourcesStarted(tracing_session);
+}
+
+// DisableTracing just stops the data sources but doesn't free up any buffer.
+// This is to allow the consumer to freeze the buffers (by stopping the trace)
+// and then drain the buffers. The actual teardown of the TracingSession happens
+// in FreeBuffers().
+void TracingServiceImpl::DisableTracing(TracingSessionID tsid,
+                                        bool disable_immediately) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  TracingSession* tracing_session = GetTracingSession(tsid);
+  if (!tracing_session) {
+    // Can happen if the consumer calls this before EnableTracing() or after
+    // FreeBuffers().
+    PERFETTO_DLOG("DisableTracing() failed, invalid session ID %" PRIu64, tsid);
+    return;
+  }
+
+  MaybeLogUploadEvent(tracing_session->config, tracing_session->trace_uuid,
+                      PerfettoStatsdAtom::kTracedDisableTracing);
+
+  switch (tracing_session->state) {
+    // Spurious call to DisableTracing() while already disabled, nothing to do.
+    case TracingSession::DISABLED:
+      PERFETTO_DCHECK(tracing_session->AllDataSourceInstancesStopped());
+      return;
+
+    case TracingSession::CLONED_READ_ONLY:
+      PERFETTO_DLOG("DisableTracing() cannot be called on a cloned session");
+      return;
+
+    // This is either:
+    // A) The case of a graceful DisableTracing() call followed by a call to
+    //    FreeBuffers(), iff |disable_immediately| == true. In this case we want
+    //    to forcefully transition in the disabled state without waiting for the
+    //    outstanding acks because the buffers are going to be destroyed soon.
+    // B) A spurious call, iff |disable_immediately| == false, in which case
+    //    there is nothing to do.
+    case TracingSession::DISABLING_WAITING_STOP_ACKS:
+      PERFETTO_DCHECK(!tracing_session->AllDataSourceInstancesStopped());
+      if (disable_immediately)
+        DisableTracingNotifyConsumerAndFlushFile(tracing_session);
+      return;
+
+    // Continues below.
+    case TracingSession::CONFIGURED:
+      // If the session didn't even start there is no need to orchestrate a
+      // graceful stop of data sources.
+      disable_immediately = true;
+      break;
+
+    // This is the nominal case, continues below.
+    case TracingSession::STARTED:
+      break;
+  }
+
+  for (auto& data_source_inst : tracing_session->data_source_instances) {
+    const ProducerID producer_id = data_source_inst.first;
+    DataSourceInstance& instance = data_source_inst.second;
+    ProducerEndpointImpl* producer = GetProducer(producer_id);
+    PERFETTO_DCHECK(producer);
+    PERFETTO_DCHECK(instance.state == DataSourceInstance::CONFIGURED ||
+                    instance.state == DataSourceInstance::STARTING ||
+                    instance.state == DataSourceInstance::STARTED);
+    StopDataSourceInstance(producer, tracing_session, &instance,
+                           disable_immediately);
+  }
+
+  // If the periodic task is running, we can stop the periodic snapshot timer
+  // here instead of waiting until FreeBuffers to prevent useless snapshots
+  // which won't be read.
+  tracing_session->snapshot_periodic_task.Reset();
+
+  // Either this request is flagged with |disable_immediately| or there are no
+  // data sources that are requesting a final handshake. In both cases just mark
+  // the session as disabled immediately, notify the consumer and flush the
+  // trace file (if used).
+  if (tracing_session->AllDataSourceInstancesStopped())
+    return DisableTracingNotifyConsumerAndFlushFile(tracing_session);
+
+  tracing_session->state = TracingSession::DISABLING_WAITING_STOP_ACKS;
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostDelayedTask(
+      [weak_this, tsid] {
+        if (weak_this)
+          weak_this->OnDisableTracingTimeout(tsid);
+      },
+      tracing_session->data_source_stop_timeout_ms());
+
+  // Deliberately NOT removing the session from |tracing_session_|, it's still
+  // needed to call ReadBuffers(). FreeBuffers() will erase() the session.
+}
+
+void TracingServiceImpl::NotifyDataSourceStarted(
+    ProducerID producer_id,
+    DataSourceInstanceID instance_id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  for (auto& kv : tracing_sessions_) {
+    TracingSession& tracing_session = kv.second;
+    DataSourceInstance* instance =
+        tracing_session.GetDataSourceInstance(producer_id, instance_id);
+
+    if (!instance)
+      continue;
+
+    // If the tracing session was already stopped, ignore this notification.
+    if (tracing_session.state != TracingSession::STARTED)
+      continue;
+
+    if (instance->state != DataSourceInstance::STARTING) {
+      PERFETTO_ELOG("Started data source instance in incorrect state: %d",
+                    instance->state);
+      continue;
+    }
+
+    instance->state = DataSourceInstance::STARTED;
+
+    ProducerEndpointImpl* producer = GetProducer(producer_id);
+    PERFETTO_DCHECK(producer);
+    if (tracing_session.consumer_maybe_null) {
+      tracing_session.consumer_maybe_null->OnDataSourceInstanceStateChange(
+          *producer, *instance);
+    }
+
+    // If all data sources are started, notify the consumer.
+    MaybeNotifyAllDataSourcesStarted(&tracing_session);
+  }  // for (tracing_session)
+}
+
+void TracingServiceImpl::MaybeNotifyAllDataSourcesStarted(
+    TracingSession* tracing_session) {
+  if (!tracing_session->consumer_maybe_null)
+    return;
+
+  if (!tracing_session->AllDataSourceInstancesStarted())
+    return;
+
+  // In some rare cases, we can get in this state more than once. Consider the
+  // following scenario: 3 data sources are registered -> trace starts ->
+  // all 3 data sources ack -> OnAllDataSourcesStarted() is called.
+  // Imagine now that a 4th data source registers while the trace is ongoing.
+  // This would hit the AllDataSourceInstancesStarted() condition again.
+  // In this case, however, we don't want to re-notify the consumer again.
+  // That would be unexpected (even if, perhaps, technically correct) and
+  // trigger bugs in the consumer.
+  if (tracing_session->did_notify_all_data_source_started)
+    return;
+
+  PERFETTO_DLOG("All data sources started");
+
+  SnapshotLifecyleEvent(
+      tracing_session,
+      protos::pbzero::TracingServiceEvent::kAllDataSourcesStartedFieldNumber,
+      true /* snapshot_clocks */);
+
+  tracing_session->did_notify_all_data_source_started = true;
+  tracing_session->consumer_maybe_null->OnAllDataSourcesStarted();
+}
+
+void TracingServiceImpl::NotifyDataSourceStopped(
+    ProducerID producer_id,
+    DataSourceInstanceID instance_id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  for (auto& kv : tracing_sessions_) {
+    TracingSession& tracing_session = kv.second;
+    DataSourceInstance* instance =
+        tracing_session.GetDataSourceInstance(producer_id, instance_id);
+
+    if (!instance)
+      continue;
+
+    if (instance->state != DataSourceInstance::STOPPING) {
+      PERFETTO_ELOG("Stopped data source instance in incorrect state: %d",
+                    instance->state);
+      continue;
+    }
+
+    instance->state = DataSourceInstance::STOPPED;
+
+    ProducerEndpointImpl* producer = GetProducer(producer_id);
+    PERFETTO_DCHECK(producer);
+    if (tracing_session.consumer_maybe_null) {
+      tracing_session.consumer_maybe_null->OnDataSourceInstanceStateChange(
+          *producer, *instance);
+    }
+
+    if (!tracing_session.AllDataSourceInstancesStopped())
+      continue;
+
+    if (tracing_session.state != TracingSession::DISABLING_WAITING_STOP_ACKS)
+      continue;
+
+    // All data sources acked the termination.
+    DisableTracingNotifyConsumerAndFlushFile(&tracing_session);
+  }  // for (tracing_session)
+}
+
+void TracingServiceImpl::ActivateTriggers(
+    ProducerID producer_id,
+    const std::vector<std::string>& triggers) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto* producer = GetProducer(producer_id);
+  PERFETTO_DCHECK(producer);
+
+  int64_t now_ns = base::GetBootTimeNs().count();
+  for (const auto& trigger_name : triggers) {
+    PERFETTO_DLOG("Received ActivateTriggers request for \"%s\"",
+                  trigger_name.c_str());
+    base::Hasher hash;
+    hash.Update(trigger_name.c_str(), trigger_name.size());
+    std::string triggered_session_name;
+    base::Uuid triggered_session_uuid;
+    TracingSessionID triggered_session_id = 0;
+    auto trigger_mode = TraceConfig::TriggerConfig::UNSPECIFIED;
+
+    uint64_t trigger_name_hash = hash.digest();
+    size_t count_in_window =
+        PurgeExpiredAndCountTriggerInWindow(now_ns, trigger_name_hash);
+
+    bool trigger_matched = false;
+    bool trigger_activated = false;
+    for (auto& id_and_tracing_session : tracing_sessions_) {
+      auto& tracing_session = id_and_tracing_session.second;
+      TracingSessionID tsid = id_and_tracing_session.first;
+      auto iter = std::find_if(
+          tracing_session.config.trigger_config().triggers().begin(),
+          tracing_session.config.trigger_config().triggers().end(),
+          [&trigger_name](const TraceConfig::TriggerConfig::Trigger& trigger) {
+            return trigger.name() == trigger_name;
+          });
+      if (iter == tracing_session.config.trigger_config().triggers().end())
+        continue;
+      if (tracing_session.state == TracingSession::CLONED_READ_ONLY)
+        continue;
+
+      // If this trigger requires a certain producer to have sent it
+      // (non-empty producer_name()) ensure the producer who sent this trigger
+      // matches.
+      if (!iter->producer_name_regex().empty() &&
+          !std::regex_match(
+              producer->name_,
+              std::regex(iter->producer_name_regex(), std::regex::extended))) {
+        continue;
+      }
+
+      // Use a random number between 0 and 1 to check if we should allow this
+      // trigger through or not.
+      double trigger_rnd =
+          trigger_rnd_override_for_testing_ > 0
+              ? trigger_rnd_override_for_testing_
+              : trigger_probability_dist_(trigger_probability_rand_);
+      PERFETTO_DCHECK(trigger_rnd >= 0 && trigger_rnd < 1);
+      if (trigger_rnd < iter->skip_probability()) {
+        MaybeLogTriggerEvent(tracing_session.config,
+                             PerfettoTriggerAtom::kTracedLimitProbability,
+                             trigger_name);
+        continue;
+      }
+
+      // If we already triggered more times than the limit, silently ignore
+      // this trigger.
+      if (iter->max_per_24_h() > 0 && count_in_window >= iter->max_per_24_h()) {
+        MaybeLogTriggerEvent(tracing_session.config,
+                             PerfettoTriggerAtom::kTracedLimitMaxPer24h,
+                             trigger_name);
+        continue;
+      }
+      trigger_matched = true;
+      triggered_session_id = tracing_session.id;
+      triggered_session_name = tracing_session.config.unique_session_name();
+      triggered_session_uuid.set_lsb_msb(tracing_session.trace_uuid.lsb(),
+                                         tracing_session.trace_uuid.msb());
+      trigger_mode = GetTriggerMode(tracing_session.config);
+
+      const bool triggers_already_received =
+          !tracing_session.received_triggers.empty();
+      tracing_session.received_triggers.push_back(
+          {static_cast<uint64_t>(now_ns), iter->name(), producer->name_,
+           producer->uid()});
+      auto weak_this = weak_ptr_factory_.GetWeakPtr();
+      switch (trigger_mode) {
+        case TraceConfig::TriggerConfig::START_TRACING:
+          // If the session has already been triggered and moved past
+          // CONFIGURED then we don't need to repeat StartTracing. This would
+          // work fine (StartTracing would return false) but would add error
+          // logs.
+          if (tracing_session.state != TracingSession::CONFIGURED)
+            break;
+
+          trigger_activated = true;
+          MaybeLogUploadEvent(
+              tracing_session.config, tracing_session.trace_uuid,
+              PerfettoStatsdAtom::kTracedTriggerStartTracing, iter->name());
+
+          // We override the trace duration to be the trigger's requested
+          // value, this ensures that the trace will end after this amount
+          // of time has passed.
+          tracing_session.config.set_duration_ms(iter->stop_delay_ms());
+          StartTracing(tsid);
+          break;
+        case TraceConfig::TriggerConfig::STOP_TRACING:
+          // Only stop the trace once to avoid confusing log messages. I.E.
+          // when we've already hit the first trigger we've already Posted the
+          // task to FlushAndDisable. So all future triggers will just break
+          // out.
+          if (triggers_already_received)
+            break;
+
+          trigger_activated = true;
+          MaybeLogUploadEvent(
+              tracing_session.config, tracing_session.trace_uuid,
+              PerfettoStatsdAtom::kTracedTriggerStopTracing, iter->name());
+
+          // Now that we've seen a trigger we need to stop, flush, and disable
+          // this session after the configured |stop_delay_ms|.
+          task_runner_->PostDelayedTask(
+              [weak_this, tsid] {
+                // Skip entirely the flush if the trace session doesn't exist
+                // anymore. This is to prevent misleading error messages to be
+                // logged.
+                if (weak_this && weak_this->GetTracingSession(tsid))
+                  weak_this->FlushAndDisableTracing(tsid);
+              },
+              // If this trigger is zero this will immediately executable and
+              // will happen shortly.
+              iter->stop_delay_ms());
+          break;
+
+        case TraceConfig::TriggerConfig::CLONE_SNAPSHOT:
+          trigger_activated = true;
+          MaybeLogUploadEvent(
+              tracing_session.config, tracing_session.trace_uuid,
+              PerfettoStatsdAtom::kTracedTriggerCloneSnapshot, iter->name());
+          task_runner_->PostDelayedTask(
+              [weak_this, tsid] {
+                if (!weak_this)
+                  return;
+                auto* tsess = weak_this->GetTracingSession(tsid);
+                if (!tsess || !tsess->consumer_maybe_null)
+                  return;
+                tsess->consumer_maybe_null->NotifyCloneSnapshotTrigger();
+              },
+              iter->stop_delay_ms());
+          break;
+
+        case TraceConfig::TriggerConfig::UNSPECIFIED:
+          PERFETTO_ELOG("Trigger activated but trigger mode unspecified.");
+          break;
+      }
+    }  // for (.. : tracing_sessions_)
+
+    if (trigger_matched) {
+      trigger_history_.emplace_back(TriggerHistory{now_ns, trigger_name_hash});
+    }
+
+    if (trigger_activated) {
+      // Log only the trigger that actually caused a trace stop/start, don't log
+      // the follow-up ones, even if they matched.
+      PERFETTO_LOG(
+          "Trace trigger activated: trigger_name=\"%s\" trigger_mode=%d "
+          "trace_name=\"%s\" trace_uuid=\"%s\" tsid=%" PRIu64,
+          trigger_name.c_str(), trigger_mode, triggered_session_name.c_str(),
+          triggered_session_uuid.ToPrettyString().c_str(),
+          triggered_session_id);
+    }
+  }  // for (trigger_name : triggers)
+}
+
+// Always invoked TraceConfig.data_source_stop_timeout_ms (by default
+// kDataSourceStopTimeoutMs) after DisableTracing(). In nominal conditions all
+// data sources should have acked the stop and this will early out.
+void TracingServiceImpl::OnDisableTracingTimeout(TracingSessionID tsid) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  TracingSession* tracing_session = GetTracingSession(tsid);
+  if (!tracing_session ||
+      tracing_session->state != TracingSession::DISABLING_WAITING_STOP_ACKS) {
+    return;  // Tracing session was successfully disabled.
+  }
+
+  PERFETTO_ILOG("Timeout while waiting for ACKs for tracing session %" PRIu64,
+                tsid);
+  PERFETTO_DCHECK(!tracing_session->AllDataSourceInstancesStopped());
+  DisableTracingNotifyConsumerAndFlushFile(tracing_session);
+}
+
+void TracingServiceImpl::DisableTracingNotifyConsumerAndFlushFile(
+    TracingSession* tracing_session) {
+  PERFETTO_DCHECK(tracing_session->state != TracingSession::DISABLED);
+  for (auto& inst_kv : tracing_session->data_source_instances) {
+    if (inst_kv.second.state == DataSourceInstance::STOPPED)
+      continue;
+    inst_kv.second.state = DataSourceInstance::STOPPED;
+    ProducerEndpointImpl* producer = GetProducer(inst_kv.first);
+    PERFETTO_DCHECK(producer);
+    if (tracing_session->consumer_maybe_null) {
+      tracing_session->consumer_maybe_null->OnDataSourceInstanceStateChange(
+          *producer, inst_kv.second);
+    }
+  }
+  tracing_session->state = TracingSession::DISABLED;
+
+  // Scrape any remaining chunks that weren't flushed by the producers.
+  for (auto& producer_id_and_producer : producers_)
+    ScrapeSharedMemoryBuffers(tracing_session, producer_id_and_producer.second);
+
+  SnapshotLifecyleEvent(
+      tracing_session,
+      protos::pbzero::TracingServiceEvent::kTracingDisabledFieldNumber,
+      true /* snapshot_clocks */);
+
+  if (tracing_session->write_into_file) {
+    tracing_session->write_period_ms = 0;
+    ReadBuffersIntoFile(tracing_session->id);
+  }
+
+  MaybeLogUploadEvent(tracing_session->config, tracing_session->trace_uuid,
+                      PerfettoStatsdAtom::kTracedNotifyTracingDisabled);
+
+  if (tracing_session->consumer_maybe_null)
+    tracing_session->consumer_maybe_null->NotifyOnTracingDisabled("");
+}
+
+void TracingServiceImpl::Flush(TracingSessionID tsid,
+                               uint32_t timeout_ms,
+                               ConsumerEndpoint::FlushCallback callback,
+                               FlushFlags flush_flags) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  TracingSession* tracing_session = GetTracingSession(tsid);
+  if (!tracing_session) {
+    PERFETTO_DLOG("Flush() failed, invalid session ID %" PRIu64, tsid);
+    return;
+  }
+
+  std::map<ProducerID, std::vector<DataSourceInstanceID>> data_source_instances;
+  for (const auto& [producer_id, ds_inst] :
+       tracing_session->data_source_instances) {
+    if (ds_inst.no_flush)
+      continue;
+    data_source_instances[producer_id].push_back(ds_inst.instance_id);
+  }
+  FlushDataSourceInstances(tracing_session, timeout_ms, data_source_instances,
+                           std::move(callback), flush_flags);
+}
+
+void TracingServiceImpl::FlushDataSourceInstances(
+    TracingSession* tracing_session,
+    uint32_t timeout_ms,
+    const std::map<ProducerID, std::vector<DataSourceInstanceID>>&
+        data_source_instances,
+    ConsumerEndpoint::FlushCallback callback,
+    FlushFlags flush_flags) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!timeout_ms)
+    timeout_ms = tracing_session->flush_timeout_ms();
+
+  if (tracing_session->pending_flushes.size() > 1000) {
+    PERFETTO_ELOG("Too many flushes (%zu) pending for the tracing session",
+                  tracing_session->pending_flushes.size());
+    callback(false);
+    return;
+  }
+
+  if (tracing_session->state != TracingSession::STARTED) {
+    PERFETTO_LOG("Flush() called, but tracing has not been started");
+    callback(false);
+    return;
+  }
+
+  ++tracing_session->flushes_requested;
+  FlushRequestID flush_request_id = ++last_flush_request_id_;
+  PendingFlush& pending_flush =
+      tracing_session->pending_flushes
+          .emplace_hint(tracing_session->pending_flushes.end(),
+                        flush_request_id, PendingFlush(std::move(callback)))
+          ->second;
+
+  // Send a flush request to each producer involved in the tracing session. In
+  // order to issue a flush request we have to build a map of all data source
+  // instance ids enabled for each producer.
+
+  for (const auto& [producer_id, data_sources] : data_source_instances) {
+    ProducerEndpointImpl* producer = GetProducer(producer_id);
+    producer->Flush(flush_request_id, data_sources, flush_flags);
+    pending_flush.producers.insert(producer_id);
+  }
+
+  // If there are no producers to flush (realistically this happens only in
+  // some tests) fire OnFlushTimeout() straight away, without waiting.
+  if (data_source_instances.empty())
+    timeout_ms = 0;
+
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostDelayedTask(
+      [weak_this, tsid = tracing_session->id, flush_request_id] {
+        if (weak_this)
+          weak_this->OnFlushTimeout(tsid, flush_request_id);
+      },
+      timeout_ms);
+}
+
+void TracingServiceImpl::NotifyFlushDoneForProducer(
+    ProducerID producer_id,
+    FlushRequestID flush_request_id) {
+  for (auto& kv : tracing_sessions_) {
+    // Remove all pending flushes <= |flush_request_id| for |producer_id|.
+    auto& pending_flushes = kv.second.pending_flushes;
+    auto end_it = pending_flushes.upper_bound(flush_request_id);
+    for (auto it = pending_flushes.begin(); it != end_it;) {
+      PendingFlush& pending_flush = it->second;
+      pending_flush.producers.erase(producer_id);
+      if (pending_flush.producers.empty()) {
+        auto weak_this = weak_ptr_factory_.GetWeakPtr();
+        TracingSessionID tsid = kv.first;
+        auto callback = std::move(pending_flush.callback);
+        task_runner_->PostTask([weak_this, tsid, callback]() {
+          if (weak_this) {
+            weak_this->CompleteFlush(tsid, std::move(callback),
+                                     /*success=*/true);
+          }
+        });
+        it = pending_flushes.erase(it);
+      } else {
+        it++;
+      }
+    }  // for (pending_flushes)
+  }    // for (tracing_session)
+}
+
+void TracingServiceImpl::OnFlushTimeout(TracingSessionID tsid,
+                                        FlushRequestID flush_request_id) {
+  TracingSession* tracing_session = GetTracingSession(tsid);
+  if (!tracing_session)
+    return;
+  auto it = tracing_session->pending_flushes.find(flush_request_id);
+  if (it == tracing_session->pending_flushes.end())
+    return;  // Nominal case: flush was completed and acked on time.
+
+  // If there were no producers to flush, consider it a success.
+  bool success = it->second.producers.empty();
+  auto callback = std::move(it->second.callback);
+  tracing_session->pending_flushes.erase(it);
+  CompleteFlush(tsid, std::move(callback), success);
+}
+
+void TracingServiceImpl::CompleteFlush(TracingSessionID tsid,
+                                       ConsumerEndpoint::FlushCallback callback,
+                                       bool success) {
+  TracingSession* tracing_session = GetTracingSession(tsid);
+  if (!tracing_session) {
+    callback(false);
+    return;
+  }
+  // Producers may not have been able to flush all their data, even if they
+  // indicated flush completion. If possible, also collect uncommitted chunks
+  // to make sure we have everything they wrote so far.
+  for (auto& producer_id_and_producer : producers_) {
+    ScrapeSharedMemoryBuffers(tracing_session, producer_id_and_producer.second);
+  }
+  SnapshotLifecyleEvent(
+      tracing_session,
+      protos::pbzero::TracingServiceEvent::kAllDataSourcesFlushedFieldNumber,
+      true /* snapshot_clocks */);
+
+  tracing_session->flushes_succeeded += success ? 1 : 0;
+  tracing_session->flushes_failed += success ? 0 : 1;
+  callback(success);
+}
+
+void TracingServiceImpl::ScrapeSharedMemoryBuffers(
+    TracingSession* tracing_session,
+    ProducerEndpointImpl* producer) {
+  if (!producer->smb_scraping_enabled_)
+    return;
+
+  // Can't copy chunks if we don't know about any trace writers.
+  if (producer->writers_.empty())
+    return;
+
+  // Performance optimization: On flush or session disconnect, this method is
+  // called for each producer. If the producer doesn't participate in the
+  // session, there's no need to scape its chunks right now. We can tell if a
+  // producer participates in the session by checking if the producer is allowed
+  // to write into the session's log buffers.
+  const auto& session_buffers = tracing_session->buffers_index;
+  bool producer_in_session =
+      std::any_of(session_buffers.begin(), session_buffers.end(),
+                  [producer](BufferID buffer_id) {
+                    return producer->allowed_target_buffers_.count(buffer_id);
+                  });
+  if (!producer_in_session)
+    return;
+
+  PERFETTO_DLOG("Scraping SMB for producer %" PRIu16, producer->id_);
+
+  // Find and copy any uncommitted chunks from the SMB.
+  //
+  // In nominal conditions, the page layout of the used SMB pages should never
+  // change because the service is the only one who is supposed to modify used
+  // pages (to make them free again).
+  //
+  // However, the code here needs to deal with the case of a malicious producer
+  // altering the SMB in unpredictable ways. Thankfully the SMB size is
+  // immutable, so a chunk will always point to some valid memory, even if the
+  // producer alters the intended layout and chunk header concurrently.
+  // Ultimately a malicious producer altering the SMB's chunk layout while we
+  // are iterating in this function is not any different from the case of a
+  // malicious producer asking to commit a chunk made of random data, which is
+  // something this class has to deal with regardless.
+  //
+  // The only legitimate mutations that can happen from sane producers,
+  // concurrently to this function, are:
+  //   A. free pages being partitioned,
+  //   B. free chunks being migrated to kChunkBeingWritten,
+  //   C. kChunkBeingWritten chunks being migrated to kChunkCompleted.
+
+  SharedMemoryABI* abi = &producer->shmem_abi_;
+  // num_pages() is immutable after the SMB is initialized and cannot be changed
+  // even by a producer even if malicious.
+  for (size_t page_idx = 0; page_idx < abi->num_pages(); page_idx++) {
+    uint32_t layout = abi->GetPageLayout(page_idx);
+
+    uint32_t used_chunks = abi->GetUsedChunks(layout);  // Returns a bitmap.
+    // Skip empty pages.
+    if (used_chunks == 0)
+      continue;
+
+    // Scrape the chunks that are currently used. These should be either in
+    // state kChunkBeingWritten or kChunkComplete.
+    for (uint32_t chunk_idx = 0; used_chunks; chunk_idx++, used_chunks >>= 1) {
+      if (!(used_chunks & 1))
+        continue;
+
+      SharedMemoryABI::ChunkState state =
+          SharedMemoryABI::GetChunkStateFromLayout(layout, chunk_idx);
+      PERFETTO_DCHECK(state == SharedMemoryABI::kChunkBeingWritten ||
+                      state == SharedMemoryABI::kChunkComplete);
+      bool chunk_complete = state == SharedMemoryABI::kChunkComplete;
+
+      SharedMemoryABI::Chunk chunk =
+          abi->GetChunkUnchecked(page_idx, layout, chunk_idx);
+
+      uint16_t packet_count;
+      uint8_t flags;
+      // GetPacketCountAndFlags has acquire_load semantics.
+      std::tie(packet_count, flags) = chunk.GetPacketCountAndFlags();
+
+      // It only makes sense to copy an incomplete chunk if there's at least
+      // one full packet available. (The producer may not have completed the
+      // last packet in it yet, so we need at least 2.)
+      if (!chunk_complete && packet_count < 2)
+        continue;
+
+      // At this point, it is safe to access the remaining header fields of
+      // the chunk. Even if the chunk was only just transferred from
+      // kChunkFree into kChunkBeingWritten state, the header should be
+      // written completely once the packet count increased above 1 (it was
+      // reset to 0 by the service when the chunk was freed).
+
+      WriterID writer_id = chunk.writer_id();
+      std::optional<BufferID> target_buffer_id =
+          producer->buffer_id_for_writer(writer_id);
+
+      // We can only scrape this chunk if we know which log buffer to copy it
+      // into.
+      if (!target_buffer_id)
+        continue;
+
+      // Skip chunks that don't belong to the requested tracing session.
+      bool target_buffer_belongs_to_session =
+          std::find(session_buffers.begin(), session_buffers.end(),
+                    *target_buffer_id) != session_buffers.end();
+      if (!target_buffer_belongs_to_session)
+        continue;
+
+      uint32_t chunk_id =
+          chunk.header()->chunk_id.load(std::memory_order_relaxed);
+
+      CopyProducerPageIntoLogBuffer(
+          producer->id_, producer->client_identity_, writer_id, chunk_id,
+          *target_buffer_id, packet_count, flags, chunk_complete,
+          chunk.payload_begin(), chunk.payload_size());
+    }
+  }
+}
+
+void TracingServiceImpl::FlushAndDisableTracing(TracingSessionID tsid) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DLOG("Triggering final flush for %" PRIu64, tsid);
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  Flush(
+      tsid, 0,
+      [weak_this, tsid](bool success) {
+        // This was a DLOG up to Jun 2021 (v16, Android S).
+        PERFETTO_LOG("FlushAndDisableTracing(%" PRIu64 ") done, success=%d",
+                     tsid, success);
+        if (!weak_this)
+          return;
+        TracingSession* session = weak_this->GetTracingSession(tsid);
+        if (!session) {
+          return;
+        }
+        session->final_flush_outcome = success
+                                           ? TraceStats::FINAL_FLUSH_SUCCEEDED
+                                           : TraceStats::FINAL_FLUSH_FAILED;
+        if (session->consumer_maybe_null) {
+          // If the consumer is still attached, just disable the session but
+          // give it a chance to read the contents.
+          weak_this->DisableTracing(tsid);
+        } else {
+          // If the consumer detached, destroy the session. If the consumer did
+          // start the session in long-tracing mode, the service will have saved
+          // the contents to the passed file. If not, the contents will be
+          // destroyed.
+          weak_this->FreeBuffers(tsid);
+        }
+      },
+      FlushFlags(FlushFlags::Initiator::kTraced,
+                 FlushFlags::Reason::kTraceStop));
+}
+
+void TracingServiceImpl::PeriodicFlushTask(TracingSessionID tsid,
+                                           bool post_next_only) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  TracingSession* tracing_session = GetTracingSession(tsid);
+  if (!tracing_session || tracing_session->state != TracingSession::STARTED)
+    return;
+
+  uint32_t flush_period_ms = tracing_session->config.flush_period_ms();
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostDelayedTask(
+      [weak_this, tsid] {
+        if (weak_this)
+          weak_this->PeriodicFlushTask(tsid, /*post_next_only=*/false);
+      },
+      flush_period_ms - static_cast<uint32_t>(base::GetWallTimeMs().count() %
+                                              flush_period_ms));
+
+  if (post_next_only)
+    return;
+
+  PERFETTO_DLOG("Triggering periodic flush for trace session %" PRIu64, tsid);
+  Flush(
+      tsid, 0,
+      [](bool success) {
+        if (!success)
+          PERFETTO_ELOG("Periodic flush timed out");
+      },
+      FlushFlags(FlushFlags::Initiator::kTraced,
+                 FlushFlags::Reason::kPeriodic));
+}
+
+void TracingServiceImpl::PeriodicClearIncrementalStateTask(
+    TracingSessionID tsid,
+    bool post_next_only) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  TracingSession* tracing_session = GetTracingSession(tsid);
+  if (!tracing_session || tracing_session->state != TracingSession::STARTED)
+    return;
+
+  uint32_t clear_period_ms =
+      tracing_session->config.incremental_state_config().clear_period_ms();
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostDelayedTask(
+      [weak_this, tsid] {
+        if (weak_this)
+          weak_this->PeriodicClearIncrementalStateTask(
+              tsid, /*post_next_only=*/false);
+      },
+      clear_period_ms - static_cast<uint32_t>(base::GetWallTimeMs().count() %
+                                              clear_period_ms));
+
+  if (post_next_only)
+    return;
+
+  PERFETTO_DLOG(
+      "Performing periodic incremental state clear for trace session %" PRIu64,
+      tsid);
+
+  // Queue the IPCs to producers with active data sources that opted in.
+  std::map<ProducerID, std::vector<DataSourceInstanceID>> clear_map;
+  for (const auto& kv : tracing_session->data_source_instances) {
+    ProducerID producer_id = kv.first;
+    const DataSourceInstance& data_source = kv.second;
+    if (data_source.handles_incremental_state_clear) {
+      clear_map[producer_id].push_back(data_source.instance_id);
+    }
+  }
+
+  for (const auto& kv : clear_map) {
+    ProducerID producer_id = kv.first;
+    const std::vector<DataSourceInstanceID>& data_sources = kv.second;
+    ProducerEndpointImpl* producer = GetProducer(producer_id);
+    if (!producer) {
+      PERFETTO_DFATAL("Producer does not exist.");
+      continue;
+    }
+    producer->ClearIncrementalState(data_sources);
+  }
+}
+
+bool TracingServiceImpl::ReadBuffersIntoConsumer(
+    TracingSessionID tsid,
+    ConsumerEndpointImpl* consumer) {
+  PERFETTO_DCHECK(consumer);
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  TracingSession* tracing_session = GetTracingSession(tsid);
+  if (!tracing_session) {
+    PERFETTO_DLOG(
+        "Cannot ReadBuffersIntoConsumer(): no tracing session is active");
+    return false;
+  }
+
+  if (tracing_session->write_into_file) {
+    // If the consumer enabled tracing and asked to save the contents into the
+    // passed file makes little sense to also try to read the buffers over IPC,
+    // as that would just steal data from the periodic draining task.
+    PERFETTO_ELOG("Consumer trying to read from write_into_file session.");
+    return false;
+  }
+
+  if (IsWaitingForTrigger(tracing_session))
+    return false;
+
+  // This is a rough threshold to determine how much to read from the buffer in
+  // each task. This is to avoid executing a single huge sending task for too
+  // long and risk to hit the watchdog. This is *not* an upper bound: we just
+  // stop accumulating new packets and PostTask *after* we cross this threshold.
+  // This constant essentially balances the PostTask and IPC overhead vs the
+  // responsiveness of the service. An extremely small value will cause one IPC
+  // and one PostTask for each slice but will keep the service extremely
+  // responsive. An extremely large value will batch the send for the full
+  // buffer in one large task, will hit the blocking send() once the socket
+  // buffers are full and hang the service for a bit (until the consumer
+  // catches up).
+  static constexpr size_t kApproxBytesPerTask = 32768;
+  bool has_more;
+  std::vector<TracePacket> packets =
+      ReadBuffers(tracing_session, kApproxBytesPerTask, &has_more);
+
+  if (has_more) {
+    auto weak_consumer = consumer->weak_ptr_factory_.GetWeakPtr();
+    auto weak_this = weak_ptr_factory_.GetWeakPtr();
+    task_runner_->PostTask([weak_this, weak_consumer, tsid] {
+      if (!weak_this || !weak_consumer)
+        return;
+      weak_this->ReadBuffersIntoConsumer(tsid, weak_consumer.get());
+    });
+  }
+
+  // Keep this as tail call, just in case the consumer re-enters.
+  consumer->consumer_->OnTraceData(std::move(packets), has_more);
+  return true;
+}
+
+bool TracingServiceImpl::ReadBuffersIntoFile(TracingSessionID tsid) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  TracingSession* tracing_session = GetTracingSession(tsid);
+  if (!tracing_session) {
+    // This will be hit systematically from the PostDelayedTask. Avoid logging,
+    // it would be just spam.
+    return false;
+  }
+
+  // This can happen if the file is closed by a previous task because it reaches
+  // |max_file_size_bytes|.
+  if (!tracing_session->write_into_file)
+    return false;
+
+  if (IsWaitingForTrigger(tracing_session))
+    return false;
+
+  // ReadBuffers() can allocate memory internally, for filtering. By limiting
+  // the data that ReadBuffers() reads to kWriteIntoChunksSize per iteration,
+  // we limit the amount of memory used on each iteration.
+  //
+  // It would be tempting to split this into multiple tasks like in
+  // ReadBuffersIntoConsumer, but that's not currently possible.
+  // ReadBuffersIntoFile has to read the whole available data before returning,
+  // to support the disable_immediately=true code paths.
+  bool has_more = true;
+  bool stop_writing_into_file = false;
+  do {
+    std::vector<TracePacket> packets =
+        ReadBuffers(tracing_session, kWriteIntoFileChunkSize, &has_more);
+
+    stop_writing_into_file = WriteIntoFile(tracing_session, std::move(packets));
+  } while (has_more && !stop_writing_into_file);
+
+  if (stop_writing_into_file || tracing_session->write_period_ms == 0) {
+    // Ensure all data was written to the file before we close it.
+    base::FlushFile(tracing_session->write_into_file.get());
+    tracing_session->write_into_file.reset();
+    tracing_session->write_period_ms = 0;
+    if (tracing_session->state == TracingSession::STARTED)
+      DisableTracing(tsid);
+    return true;
+  }
+
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostDelayedTask(
+      [weak_this, tsid] {
+        if (weak_this)
+          weak_this->ReadBuffersIntoFile(tsid);
+      },
+      tracing_session->delay_to_next_write_period_ms());
+  return true;
+}
+
+bool TracingServiceImpl::IsWaitingForTrigger(TracingSession* tracing_session) {
+  // Ignore the logic below for cloned tracing sessions. In this case we
+  // actually want to read the (cloned) trace buffers even if no trigger was
+  // hit.
+  if (tracing_session->state == TracingSession::CLONED_READ_ONLY) {
+    return false;
+  }
+
+  // When a tracing session is waiting for a trigger, it is considered empty. If
+  // a tracing session finishes and moves into DISABLED without ever receiving a
+  // trigger, the trace should never return any data. This includes the
+  // synthetic packets like TraceConfig and Clock snapshots. So we bail out
+  // early and let the consumer know there is no data.
+  if (!tracing_session->config.trigger_config().triggers().empty() &&
+      tracing_session->received_triggers.empty()) {
+    PERFETTO_DLOG(
+        "ReadBuffers(): tracing session has not received a trigger yet.");
+    return true;
+  }
+
+  // Traces with CLONE_SNAPSHOT triggers are a special case of the above. They
+  // can be read only via a CloneSession() request. This is to keep the
+  // behavior consistent with the STOP_TRACING+triggers case and avoid periodic
+  // finalizations and uploads of the main CLONE_SNAPSHOT triggers.
+  if (GetTriggerMode(tracing_session->config) ==
+      TraceConfig::TriggerConfig::CLONE_SNAPSHOT) {
+    PERFETTO_DLOG(
+        "ReadBuffers(): skipping because the tracing session has "
+        "CLONE_SNAPSHOT triggers defined");
+    return true;
+  }
+
+  return false;
+}
+
+std::vector<TracePacket> TracingServiceImpl::ReadBuffers(
+    TracingSession* tracing_session,
+    size_t threshold,
+    bool* has_more) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DCHECK(tracing_session);
+  *has_more = false;
+
+  std::vector<TracePacket> packets;
+  packets.reserve(1024);  // Just an educated guess to avoid trivial expansions.
+
+  if (!tracing_session->initial_clock_snapshot.empty()) {
+    EmitClockSnapshot(tracing_session,
+                      std::move(tracing_session->initial_clock_snapshot),
+                      &packets);
+  }
+
+  for (auto& snapshot : tracing_session->clock_snapshot_ring_buffer) {
+    PERFETTO_DCHECK(!snapshot.empty());
+    EmitClockSnapshot(tracing_session, std::move(snapshot), &packets);
+  }
+  tracing_session->clock_snapshot_ring_buffer.clear();
+
+  if (tracing_session->should_emit_sync_marker) {
+    EmitSyncMarker(&packets);
+    tracing_session->should_emit_sync_marker = false;
+  }
+
+  if (!tracing_session->config.builtin_data_sources().disable_trace_config()) {
+    MaybeEmitTraceConfig(tracing_session, &packets);
+    MaybeEmitReceivedTriggers(tracing_session, &packets);
+  }
+  if (!tracing_session->did_emit_initial_packets) {
+    EmitUuid(tracing_session, &packets);
+    if (!tracing_session->config.builtin_data_sources().disable_system_info())
+      EmitSystemInfo(&packets);
+  }
+  tracing_session->did_emit_initial_packets = true;
+
+  // Note that in the proto comment, we guarantee that the tracing_started
+  // lifecycle event will be emitted before any data packets so make sure to
+  // keep this before reading the tracing buffers.
+  if (!tracing_session->config.builtin_data_sources().disable_service_events())
+    EmitLifecycleEvents(tracing_session, &packets);
+
+  // In a multi-machine tracing session, emit clock synchronization messages for
+  // remote machines.
+  if (!relay_clients_.empty())
+    MaybeEmitRemoteClockSync(tracing_session, &packets);
+
+  size_t packets_bytes = 0;  // SUM(slice.size() for each slice in |packets|).
+
+  // Add up size for packets added by the Maybe* calls above.
+  for (const TracePacket& packet : packets) {
+    packets_bytes += packet.size();
+  }
+
+  bool did_hit_threshold = false;
+
+  for (size_t buf_idx = 0;
+       buf_idx < tracing_session->num_buffers() && !did_hit_threshold;
+       buf_idx++) {
+    auto tbuf_iter = buffers_.find(tracing_session->buffers_index[buf_idx]);
+    if (tbuf_iter == buffers_.end()) {
+      PERFETTO_DFATAL("Buffer not found.");
+      continue;
+    }
+    TraceBuffer& tbuf = *tbuf_iter->second;
+    tbuf.BeginRead();
+    while (!did_hit_threshold) {
+      TracePacket packet;
+      TraceBuffer::PacketSequenceProperties sequence_properties{};
+      bool previous_packet_dropped;
+      if (!tbuf.ReadNextTracePacket(&packet, &sequence_properties,
+                                    &previous_packet_dropped)) {
+        break;
+      }
+      packet.set_buffer_index_for_stats(static_cast<uint32_t>(buf_idx));
+      PERFETTO_DCHECK(sequence_properties.producer_id_trusted != 0);
+      PERFETTO_DCHECK(sequence_properties.writer_id != 0);
+      PERFETTO_DCHECK(sequence_properties.client_identity_trusted.has_uid());
+      // Not checking sequence_properties.client_identity_trusted.has_pid():
+      // it is false if the platform doesn't support it.
+
+      PERFETTO_DCHECK(packet.size() > 0);
+      if (!PacketStreamValidator::Validate(packet.slices())) {
+        tracing_session->invalid_packets++;
+        PERFETTO_DLOG("Dropping invalid packet");
+        continue;
+      }
+
+      // Append a slice with the trusted field data. This can't be spoofed
+      // because above we validated that the existing slices don't contain any
+      // trusted fields. For added safety we append instead of prepending
+      // because according to protobuf semantics, if the same field is
+      // encountered multiple times the last instance takes priority. Note that
+      // truncated packets are also rejected, so the producer can't give us a
+      // partial packet (e.g., a truncated string) which only becomes valid when
+      // the trusted data is appended here.
+      Slice slice = Slice::Allocate(32);
+      protozero::StaticBuffered<protos::pbzero::TracePacket> trusted_packet(
+          slice.own_data(), slice.size);
+      const auto& client_identity_trusted =
+          sequence_properties.client_identity_trusted;
+      trusted_packet->set_trusted_uid(
+          static_cast<int32_t>(client_identity_trusted.uid()));
+      trusted_packet->set_trusted_packet_sequence_id(
+          tracing_session->GetPacketSequenceID(
+              client_identity_trusted.machine_id(),
+              sequence_properties.producer_id_trusted,
+              sequence_properties.writer_id));
+      if (client_identity_trusted.has_pid()) {
+        // Not supported on all platforms.
+        trusted_packet->set_trusted_pid(
+            static_cast<int32_t>(client_identity_trusted.pid()));
+      }
+      if (client_identity_trusted.has_non_default_machine_id()) {
+        trusted_packet->set_machine_id(client_identity_trusted.machine_id());
+      }
+      if (previous_packet_dropped)
+        trusted_packet->set_previous_packet_dropped(previous_packet_dropped);
+      slice.size = trusted_packet.Finalize();
+      packet.AddSlice(std::move(slice));
+
+      // Append the packet (inclusive of the trusted uid) to |packets|.
+      packets_bytes += packet.size();
+      did_hit_threshold = packets_bytes >= threshold;
+      packets.emplace_back(std::move(packet));
+    }  // for(packets...)
+  }    // for(buffers...)
+
+  *has_more = did_hit_threshold;
+
+  // Only emit the "read complete" lifetime event when there is no more trace
+  // data available to read. These events are used as safe points to limit
+  // sorting in trace processor: the code shouldn't emit the event unless the
+  // buffers are empty.
+  if (!*has_more && !tracing_session->config.builtin_data_sources()
+                         .disable_service_events()) {
+    // We don't bother snapshotting clocks here because we wouldn't be able to
+    // emit it and we shouldn't have significant drift from the last snapshot in
+    // any case.
+    SnapshotLifecyleEvent(tracing_session,
+                          protos::pbzero::TracingServiceEvent::
+                              kReadTracingBuffersCompletedFieldNumber,
+                          false /* snapshot_clocks */);
+    EmitLifecycleEvents(tracing_session, &packets);
+  }
+
+  // Only emit the stats when there is no more trace data is available to read.
+  // That way, any problems that occur while reading from the buffers are
+  // reflected in the emitted stats. This is particularly important for use
+  // cases where ReadBuffers is only ever called after the tracing session is
+  // stopped.
+  if (!*has_more && tracing_session->should_emit_stats) {
+    EmitStats(tracing_session, &packets);
+    tracing_session->should_emit_stats = false;
+  }
+
+  MaybeFilterPackets(tracing_session, &packets);
+
+  MaybeCompressPackets(tracing_session, &packets);
+
+  if (!*has_more) {
+    // We've observed some extremely high memory usage by scudo after
+    // MaybeFilterPackets in the past. The original bug (b/195145848) is fixed
+    // now, but this code asks scudo to release memory just in case.
+    base::MaybeReleaseAllocatorMemToOS();
+  }
+
+  return packets;
+}
+
+void TracingServiceImpl::MaybeFilterPackets(TracingSession* tracing_session,
+                                            std::vector<TracePacket>* packets) {
+  // If the tracing session specified a filter, run all packets through the
+  // filter and replace them with the filter results.
+  // The process below mantains the cardinality of input packets. Even if an
+  // entire packet is filtered out, we emit a zero-sized TracePacket proto. That
+  // makes debugging and reasoning about the trace stats easier.
+  // This place swaps the contents of each |packets| entry in place.
+  if (!tracing_session->trace_filter) {
+    return;
+  }
+  protozero::MessageFilter& trace_filter = *tracing_session->trace_filter;
+  // The filter root should be reset from protos.Trace to protos.TracePacket
+  // by the earlier call to SetFilterRoot() in EnableTracing().
+  PERFETTO_DCHECK(trace_filter.config().root_msg_index() != 0);
+  std::vector<protozero::MessageFilter::InputSlice> filter_input;
+  auto start = base::GetWallTimeNs();
+  for (TracePacket& packet : *packets) {
+    const auto& packet_slices = packet.slices();
+    const size_t input_packet_size = packet.size();
+    filter_input.clear();
+    filter_input.resize(packet_slices.size());
+    ++tracing_session->filter_input_packets;
+    tracing_session->filter_input_bytes += input_packet_size;
+    for (size_t i = 0; i < packet_slices.size(); ++i)
+      filter_input[i] = {packet_slices[i].start, packet_slices[i].size};
+    auto filtered_packet = trace_filter.FilterMessageFragments(
+        &filter_input[0], filter_input.size());
+
+    // Replace the packet in-place with the filtered one (unless failed).
+    std::optional<uint32_t> maybe_buffer_idx = packet.buffer_index_for_stats();
+    packet = TracePacket();
+    if (filtered_packet.error) {
+      ++tracing_session->filter_errors;
+      PERFETTO_DLOG("Trace packet filtering failed @ packet %" PRIu64,
+                    tracing_session->filter_input_packets);
+      continue;
+    }
+    tracing_session->filter_output_bytes += filtered_packet.size;
+    if (maybe_buffer_idx.has_value()) {
+      // Keep the per-buffer stats updated. Also propagate the
+      // buffer_index_for_stats in the output packet to allow accounting by
+      // other parts of the ReadBuffer pipeline.
+      uint32_t buffer_idx = maybe_buffer_idx.value();
+      packet.set_buffer_index_for_stats(buffer_idx);
+      auto& vec = tracing_session->filter_bytes_discarded_per_buffer;
+      if (static_cast<size_t>(buffer_idx) >= vec.size())
+        vec.resize(buffer_idx + 1);
+      PERFETTO_DCHECK(input_packet_size >= filtered_packet.size);
+      size_t bytes_filtered_out = input_packet_size - filtered_packet.size;
+      vec[buffer_idx] += bytes_filtered_out;
+    }
+    AppendOwnedSlicesToPacket(std::move(filtered_packet.data),
+                              filtered_packet.size, kMaxTracePacketSliceSize,
+                              &packet);
+  }
+  auto end = base::GetWallTimeNs();
+  tracing_session->filter_time_taken_ns +=
+      static_cast<uint64_t>((end - start).count());
+}
+
+void TracingServiceImpl::MaybeCompressPackets(
+    TracingSession* tracing_session,
+    std::vector<TracePacket>* packets) {
+  if (!tracing_session->compress_deflate) {
+    return;
+  }
+
+  init_opts_.compressor_fn(packets);
+}
+
+bool TracingServiceImpl::WriteIntoFile(TracingSession* tracing_session,
+                                       std::vector<TracePacket> packets) {
+  if (!tracing_session->write_into_file) {
+    return false;
+  }
+  const uint64_t max_size = tracing_session->max_file_size_bytes
+                                ? tracing_session->max_file_size_bytes
+                                : std::numeric_limits<size_t>::max();
+
+  size_t total_slices = 0;
+  for (const TracePacket& packet : packets) {
+    total_slices += packet.slices().size();
+  }
+  // When writing into a file, the file should look like a root trace.proto
+  // message. Each packet should be prepended with a proto preamble stating
+  // its field id (within trace.proto) and size. Hence the addition below.
+  const size_t max_iovecs = total_slices + packets.size();
+
+  size_t num_iovecs = 0;
+  bool stop_writing_into_file = false;
+  std::unique_ptr<struct iovec[]> iovecs(new struct iovec[max_iovecs]);
+  size_t num_iovecs_at_last_packet = 0;
+  uint64_t bytes_about_to_be_written = 0;
+  for (TracePacket& packet : packets) {
+    std::tie(iovecs[num_iovecs].iov_base, iovecs[num_iovecs].iov_len) =
+        packet.GetProtoPreamble();
+    bytes_about_to_be_written += iovecs[num_iovecs].iov_len;
+    num_iovecs++;
+    for (const Slice& slice : packet.slices()) {
+      // writev() doesn't change the passed pointer. However, struct iovec
+      // take a non-const ptr because it's the same struct used by readv().
+      // Hence the const_cast here.
+      char* start = static_cast<char*>(const_cast<void*>(slice.start));
+      bytes_about_to_be_written += slice.size;
+      iovecs[num_iovecs++] = {start, slice.size};
+    }
+
+    if (tracing_session->bytes_written_into_file + bytes_about_to_be_written >=
+        max_size) {
+      stop_writing_into_file = true;
+      num_iovecs = num_iovecs_at_last_packet;
+      break;
+    }
+
+    num_iovecs_at_last_packet = num_iovecs;
+  }
+  PERFETTO_DCHECK(num_iovecs <= max_iovecs);
+  int fd = *tracing_session->write_into_file;
+
+  uint64_t total_wr_size = 0;
+
+  // writev() can take at most IOV_MAX entries per call. Batch them.
+  constexpr size_t kIOVMax = IOV_MAX;
+  for (size_t i = 0; i < num_iovecs; i += kIOVMax) {
+    int iov_batch_size = static_cast<int>(std::min(num_iovecs - i, kIOVMax));
+    ssize_t wr_size = PERFETTO_EINTR(writev(fd, &iovecs[i], iov_batch_size));
+    if (wr_size <= 0) {
+      PERFETTO_PLOG("writev() failed");
+      stop_writing_into_file = true;
+      break;
+    }
+    total_wr_size += static_cast<size_t>(wr_size);
+  }
+
+  tracing_session->bytes_written_into_file += total_wr_size;
+
+  PERFETTO_DLOG("Draining into file, written: %" PRIu64 " KB, stop: %d",
+                (total_wr_size + 1023) / 1024, stop_writing_into_file);
+  return stop_writing_into_file;
+}
+
+void TracingServiceImpl::FreeBuffers(TracingSessionID tsid) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DLOG("Freeing buffers for session %" PRIu64, tsid);
+  TracingSession* tracing_session = GetTracingSession(tsid);
+  if (!tracing_session) {
+    PERFETTO_DLOG("FreeBuffers() failed, invalid session ID %" PRIu64, tsid);
+    return;  // TODO(primiano): signal failure?
+  }
+  DisableTracing(tsid, /*disable_immediately=*/true);
+
+  PERFETTO_DCHECK(tracing_session->AllDataSourceInstancesStopped());
+  tracing_session->data_source_instances.clear();
+
+  for (auto& producer_entry : producers_) {
+    ProducerEndpointImpl* producer = producer_entry.second;
+    producer->OnFreeBuffers(tracing_session->buffers_index);
+  }
+
+  for (BufferID buffer_id : tracing_session->buffers_index) {
+    buffer_ids_.Free(buffer_id);
+    PERFETTO_DCHECK(buffers_.count(buffer_id) == 1);
+    buffers_.erase(buffer_id);
+  }
+  bool notify_traceur =
+      tracing_session->config.notify_traceur() &&
+      tracing_session->state != TracingSession::CLONED_READ_ONLY;
+  bool is_long_trace =
+      (tracing_session->config.write_into_file() &&
+       tracing_session->config.file_write_period_ms() < kMillisPerDay);
+  tracing_sessions_.erase(tsid);
+  tracing_session = nullptr;
+  UpdateMemoryGuardrail();
+
+  PERFETTO_LOG("Tracing session %" PRIu64 " ended, total sessions:%zu", tsid,
+               tracing_sessions_.size());
+#if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD) && \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  if (notify_traceur && is_long_trace) {
+    PERFETTO_LAZY_LOAD(android_internal::NotifyTraceSessionEnded, notify_fn);
+    if (!notify_fn || !notify_fn(/*session_stolen=*/false))
+      PERFETTO_ELOG("Failed to notify Traceur long tracing has ended");
+  }
+#else
+  base::ignore_result(notify_traceur);
+  base::ignore_result(is_long_trace);
+#endif
+}
+
+void TracingServiceImpl::RegisterDataSource(ProducerID producer_id,
+                                            const DataSourceDescriptor& desc) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (desc.name().empty()) {
+    PERFETTO_DLOG("Received RegisterDataSource() with empty name");
+    return;
+  }
+
+  ProducerEndpointImpl* producer = GetProducer(producer_id);
+  if (!producer) {
+    PERFETTO_DFATAL("Producer not found.");
+    return;
+  }
+
+  // Check that the producer doesn't register two data sources with the same ID.
+  // Note that we tolerate |id| == 0 because until Android T / v22 the |id|
+  // field didn't exist.
+  for (const auto& kv : data_sources_) {
+    if (desc.id() && kv.second.producer_id == producer_id &&
+        kv.second.descriptor.id() == desc.id()) {
+      PERFETTO_ELOG(
+          "Failed to register data source \"%s\". A data source with the same "
+          "id %" PRIu64 " (name=\"%s\") is already registered for producer %d",
+          desc.name().c_str(), desc.id(), kv.second.descriptor.name().c_str(),
+          producer_id);
+      return;
+    }
+  }
+
+  PERFETTO_DLOG("Producer %" PRIu16 " registered data source \"%s\"",
+                producer_id, desc.name().c_str());
+
+  auto reg_ds = data_sources_.emplace(desc.name(),
+                                      RegisteredDataSource{producer_id, desc});
+
+  // If there are existing tracing sessions, we need to check if the new
+  // data source is enabled by any of them.
+  for (auto& iter : tracing_sessions_) {
+    TracingSession& tracing_session = iter.second;
+    if (tracing_session.state != TracingSession::STARTED &&
+        tracing_session.state != TracingSession::CONFIGURED) {
+      continue;
+    }
+
+    TraceConfig::ProducerConfig producer_config;
+    for (const auto& config : tracing_session.config.producers()) {
+      if (producer->name_ == config.producer_name()) {
+        producer_config = config;
+        break;
+      }
+    }
+    for (const TraceConfig::DataSource& cfg_data_source :
+         tracing_session.config.data_sources()) {
+      if (cfg_data_source.config().name() != desc.name())
+        continue;
+      DataSourceInstance* ds_inst = SetupDataSource(
+          cfg_data_source, producer_config, reg_ds->second, &tracing_session);
+      if (ds_inst && tracing_session.state == TracingSession::STARTED)
+        StartDataSourceInstance(producer, &tracing_session, ds_inst);
+    }
+  }  // for(iter : tracing_sessions_)
+}
+
+void TracingServiceImpl::UpdateDataSource(
+    ProducerID producer_id,
+    const DataSourceDescriptor& new_desc) {
+  if (new_desc.id() == 0) {
+    PERFETTO_ELOG("UpdateDataSource() must have a non-zero id");
+    return;
+  }
+
+  // If this producer has already registered a matching descriptor name and id,
+  // just update the descriptor.
+  RegisteredDataSource* data_source = nullptr;
+  auto range = data_sources_.equal_range(new_desc.name());
+  for (auto it = range.first; it != range.second; ++it) {
+    if (it->second.producer_id == producer_id &&
+        it->second.descriptor.id() == new_desc.id()) {
+      data_source = &it->second;
+      break;
+    }
+  }
+
+  if (!data_source) {
+    PERFETTO_ELOG(
+        "UpdateDataSource() failed, could not find an existing data source "
+        "with name=\"%s\" id=%" PRIu64,
+        new_desc.name().c_str(), new_desc.id());
+    return;
+  }
+
+  data_source->descriptor = new_desc;
+}
+
+void TracingServiceImpl::StopDataSourceInstance(ProducerEndpointImpl* producer,
+                                                TracingSession* tracing_session,
+                                                DataSourceInstance* instance,
+                                                bool disable_immediately) {
+  const DataSourceInstanceID ds_inst_id = instance->instance_id;
+  if (instance->will_notify_on_stop && !disable_immediately) {
+    instance->state = DataSourceInstance::STOPPING;
+  } else {
+    instance->state = DataSourceInstance::STOPPED;
+  }
+  if (tracing_session->consumer_maybe_null) {
+    tracing_session->consumer_maybe_null->OnDataSourceInstanceStateChange(
+        *producer, *instance);
+  }
+  producer->StopDataSource(ds_inst_id);
+}
+
+void TracingServiceImpl::UnregisterDataSource(ProducerID producer_id,
+                                              const std::string& name) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DLOG("Producer %" PRIu16 " unregistered data source \"%s\"",
+                producer_id, name.c_str());
+  PERFETTO_CHECK(producer_id);
+  ProducerEndpointImpl* producer = GetProducer(producer_id);
+  PERFETTO_DCHECK(producer);
+  for (auto& kv : tracing_sessions_) {
+    auto& ds_instances = kv.second.data_source_instances;
+    bool removed = false;
+    for (auto it = ds_instances.begin(); it != ds_instances.end();) {
+      if (it->first == producer_id && it->second.data_source_name == name) {
+        DataSourceInstanceID ds_inst_id = it->second.instance_id;
+        if (it->second.state != DataSourceInstance::STOPPED) {
+          if (it->second.state != DataSourceInstance::STOPPING) {
+            StopDataSourceInstance(producer, &kv.second, &it->second,
+                                   /* disable_immediately = */ false);
+          }
+
+          // Mark the instance as stopped immediately, since we are
+          // unregistering it below.
+          //
+          //  The StopDataSourceInstance above might have set the state to
+          //  STOPPING so this condition isn't an else.
+          if (it->second.state == DataSourceInstance::STOPPING)
+            NotifyDataSourceStopped(producer_id, ds_inst_id);
+        }
+        it = ds_instances.erase(it);
+        removed = true;
+      } else {
+        ++it;
+      }
+    }  // for (data_source_instances)
+    if (removed)
+      MaybeNotifyAllDataSourcesStarted(&kv.second);
+  }  // for (tracing_session)
+
+  for (auto it = data_sources_.begin(); it != data_sources_.end(); ++it) {
+    if (it->second.producer_id == producer_id &&
+        it->second.descriptor.name() == name) {
+      data_sources_.erase(it);
+      return;
+    }
+  }
+
+  PERFETTO_DFATAL(
+      "Tried to unregister a non-existent data source \"%s\" for "
+      "producer %" PRIu16,
+      name.c_str(), producer_id);
+}
+
+bool TracingServiceImpl::IsInitiatorPrivileged(
+    const TracingSession& tracing_session) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  if (tracing_session.consumer_uid == 1066 /* AID_STATSD */ &&
+      tracing_session.config.statsd_metadata().triggering_config_uid() !=
+          2000 /* AID_SHELL */
+      && tracing_session.config.statsd_metadata().triggering_config_uid() !=
+             0 /* AID_ROOT */) {
+    // StatsD can be triggered either by shell, root or an app that has DUMP and
+    // USAGE_STATS permission. When triggered by shell or root, we do not want
+    // to consider the trace a trusted system trace, as it was initiated by the
+    // user. Otherwise, it has to come from an app with DUMP and
+    // PACKAGE_USAGE_STATS, which has to be preinstalled and trusted by the
+    // system.
+    // Check for shell / root: https://bit.ly/3b7oZNi
+    // Check for DUMP or PACKAGE_USAGE_STATS: https://bit.ly/3ep0NrR
+    return true;
+  }
+  if (tracing_session.consumer_uid == 1000 /* AID_SYSTEM */) {
+    // AID_SYSTEM is considered a privileged initiator so that system_server can
+    // profile apps that are not profileable by shell. Other AID_SYSTEM
+    // processes are not allowed by SELinux to connect to the consumer socket or
+    // to exec perfetto.
+    return true;
+  }
+#else
+  base::ignore_result(tracing_session);
+#endif
+  return false;
+}
+
+TracingServiceImpl::DataSourceInstance* TracingServiceImpl::SetupDataSource(
+    const TraceConfig::DataSource& cfg_data_source,
+    const TraceConfig::ProducerConfig& producer_config,
+    const RegisteredDataSource& data_source,
+    TracingSession* tracing_session) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  ProducerEndpointImpl* producer = GetProducer(data_source.producer_id);
+  PERFETTO_DCHECK(producer);
+  // An existing producer that is not ftrace could have registered itself as
+  // ftrace, we must not enable it in that case.
+  if (lockdown_mode_ && producer->uid() != uid_) {
+    PERFETTO_DLOG("Lockdown mode: not enabling producer %hu", producer->id_);
+    return nullptr;
+  }
+  // TODO(primiano): Add tests for registration ordering (data sources vs
+  // consumers).
+  if (!NameMatchesFilter(producer->name_,
+                         cfg_data_source.producer_name_filter(),
+                         cfg_data_source.producer_name_regex_filter())) {
+    PERFETTO_DLOG("Data source: %s is filtered out for producer: %s",
+                  cfg_data_source.config().name().c_str(),
+                  producer->name_.c_str());
+    return nullptr;
+  }
+
+  auto relative_buffer_id = cfg_data_source.config().target_buffer();
+  if (relative_buffer_id >= tracing_session->num_buffers()) {
+    PERFETTO_LOG(
+        "The TraceConfig for DataSource %s specified a target_buffer out of "
+        "bound (%d). Skipping it.",
+        cfg_data_source.config().name().c_str(), relative_buffer_id);
+    return nullptr;
+  }
+
+  // Create a copy of the DataSourceConfig specified in the trace config. This
+  // will be passed to the producer after translating the |target_buffer| id.
+  // The |target_buffer| parameter passed by the consumer in the trace config is
+  // relative to the buffers declared in the same trace config. This has to be
+  // translated to the global BufferID before passing it to the producers, which
+  // don't know anything about tracing sessions and consumers.
+
+  DataSourceInstanceID inst_id = ++last_data_source_instance_id_;
+  auto insert_iter = tracing_session->data_source_instances.emplace(
+      std::piecewise_construct,  //
+      std::forward_as_tuple(producer->id_),
+      std::forward_as_tuple(
+          inst_id,
+          cfg_data_source.config(),  //  Deliberate copy.
+          data_source.descriptor.name(),
+          data_source.descriptor.will_notify_on_start(),
+          data_source.descriptor.will_notify_on_stop(),
+          data_source.descriptor.handles_incremental_state_clear(),
+          data_source.descriptor.no_flush()));
+  DataSourceInstance* ds_instance = &insert_iter->second;
+
+  // New data source instance starts out in CONFIGURED state.
+  if (tracing_session->consumer_maybe_null) {
+    tracing_session->consumer_maybe_null->OnDataSourceInstanceStateChange(
+        *producer, *ds_instance);
+  }
+
+  DataSourceConfig& ds_config = ds_instance->config;
+  ds_config.set_trace_duration_ms(tracing_session->config.duration_ms());
+
+  // Rationale for `if (prefer) set_prefer(true)`, rather than `set(prefer)`:
+  // ComputeStartupConfigHash() in tracing_muxer_impl.cc compares hashes of the
+  // DataSourceConfig and expects to know (and clear) the fields generated by
+  // the tracing service. Unconditionally adding a new field breaks backward
+  // compatibility of startup tracing with older SDKs, because the serialization
+  // also propagates unkonwn fields, breaking the hash matching check.
+  if (tracing_session->config.prefer_suspend_clock_for_duration())
+    ds_config.set_prefer_suspend_clock_for_duration(true);
+
+  ds_config.set_stop_timeout_ms(tracing_session->data_source_stop_timeout_ms());
+  ds_config.set_enable_extra_guardrails(
+      tracing_session->config.enable_extra_guardrails());
+  if (IsInitiatorPrivileged(*tracing_session)) {
+    ds_config.set_session_initiator(
+        DataSourceConfig::SESSION_INITIATOR_TRUSTED_SYSTEM);
+  } else {
+    // Unset in case the consumer set it.
+    // We need to be able to trust this field.
+    ds_config.set_session_initiator(
+        DataSourceConfig::SESSION_INITIATOR_UNSPECIFIED);
+  }
+  ds_config.set_tracing_session_id(tracing_session->id);
+  BufferID global_id = tracing_session->buffers_index[relative_buffer_id];
+  PERFETTO_DCHECK(global_id);
+  ds_config.set_target_buffer(global_id);
+
+  PERFETTO_DLOG("Setting up data source %s with target buffer %" PRIu16,
+                ds_config.name().c_str(), global_id);
+  if (!producer->shared_memory()) {
+    // Determine the SMB page size. Must be an integer multiple of 4k.
+    // As for the SMB size below, the decision tree is as follows:
+    // 1. Give priority to what is defined in the trace config.
+    // 2. If unset give priority to the hint passed by the producer.
+    // 3. Keep within bounds and ensure it's a multiple of 4k.
+    size_t page_size = producer_config.page_size_kb() * 1024;
+    if (page_size == 0)
+      page_size = producer->shmem_page_size_hint_bytes_;
+
+    // Determine the SMB size. Must be an integer multiple of the SMB page size.
+    // The decision tree is as follows:
+    // 1. Give priority to what defined in the trace config.
+    // 2. If unset give priority to the hint passed by the producer.
+    // 3. Keep within bounds and ensure it's a multiple of the page size.
+    size_t shm_size = producer_config.shm_size_kb() * 1024;
+    if (shm_size == 0)
+      shm_size = producer->shmem_size_hint_bytes_;
+
+    auto valid_sizes = EnsureValidShmSizes(shm_size, page_size);
+    if (valid_sizes != std::tie(shm_size, page_size)) {
+      PERFETTO_DLOG(
+          "Invalid configured SMB sizes: shm_size %zu page_size %zu. Falling "
+          "back to shm_size %zu page_size %zu.",
+          shm_size, page_size, std::get<0>(valid_sizes),
+          std::get<1>(valid_sizes));
+    }
+    std::tie(shm_size, page_size) = valid_sizes;
+
+    // TODO(primiano): right now Create() will suicide in case of OOM if the
+    // mmap fails. We should instead gracefully fail the request and tell the
+    // client to go away.
+    PERFETTO_DLOG("Creating SMB of %zu KB for producer \"%s\"", shm_size / 1024,
+                  producer->name_.c_str());
+    auto shared_memory = shm_factory_->CreateSharedMemory(shm_size);
+    producer->SetupSharedMemory(std::move(shared_memory), page_size,
+                                /*provided_by_producer=*/false);
+  }
+  producer->SetupDataSource(inst_id, ds_config);
+  return ds_instance;
+}
+
+// Note: all the fields % *_trusted ones are untrusted, as in, the Producer
+// might be lying / returning garbage contents. |src| and |size| can be trusted
+// in terms of being a valid pointer, but not the contents.
+void TracingServiceImpl::CopyProducerPageIntoLogBuffer(
+    ProducerID producer_id_trusted,
+    const ClientIdentity& client_identity_trusted,
+    WriterID writer_id,
+    ChunkID chunk_id,
+    BufferID buffer_id,
+    uint16_t num_fragments,
+    uint8_t chunk_flags,
+    bool chunk_complete,
+    const uint8_t* src,
+    size_t size) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  ProducerEndpointImpl* producer = GetProducer(producer_id_trusted);
+  if (!producer) {
+    PERFETTO_DFATAL("Producer not found.");
+    chunks_discarded_++;
+    return;
+  }
+
+  TraceBuffer* buf = GetBufferByID(buffer_id);
+  if (!buf) {
+    PERFETTO_DLOG("Could not find target buffer %" PRIu16
+                  " for producer %" PRIu16,
+                  buffer_id, producer_id_trusted);
+    chunks_discarded_++;
+    return;
+  }
+
+  // Verify that the producer is actually allowed to write into the target
+  // buffer specified in the request. This prevents a malicious producer from
+  // injecting data into a log buffer that belongs to a tracing session the
+  // producer is not part of.
+  if (!producer->is_allowed_target_buffer(buffer_id)) {
+    PERFETTO_ELOG("Producer %" PRIu16
+                  " tried to write into forbidden target buffer %" PRIu16,
+                  producer_id_trusted, buffer_id);
+    PERFETTO_DFATAL("Forbidden target buffer");
+    chunks_discarded_++;
+    return;
+  }
+
+  // If the writer was registered by the producer, it should only write into the
+  // buffer it was registered with.
+  std::optional<BufferID> associated_buffer =
+      producer->buffer_id_for_writer(writer_id);
+  if (associated_buffer && *associated_buffer != buffer_id) {
+    PERFETTO_ELOG("Writer %" PRIu16 " of producer %" PRIu16
+                  " was registered to write into target buffer %" PRIu16
+                  ", but tried to write into buffer %" PRIu16,
+                  writer_id, producer_id_trusted, *associated_buffer,
+                  buffer_id);
+    PERFETTO_DFATAL("Wrong target buffer");
+    chunks_discarded_++;
+    return;
+  }
+
+  buf->CopyChunkUntrusted(producer_id_trusted, client_identity_trusted,
+                          writer_id, chunk_id, num_fragments, chunk_flags,
+                          chunk_complete, src, size);
+}
+
+void TracingServiceImpl::ApplyChunkPatches(
+    ProducerID producer_id_trusted,
+    const std::vector<CommitDataRequest::ChunkToPatch>& chunks_to_patch) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  for (const auto& chunk : chunks_to_patch) {
+    const ChunkID chunk_id = static_cast<ChunkID>(chunk.chunk_id());
+    const WriterID writer_id = static_cast<WriterID>(chunk.writer_id());
+    TraceBuffer* buf =
+        GetBufferByID(static_cast<BufferID>(chunk.target_buffer()));
+    static_assert(std::numeric_limits<ChunkID>::max() == kMaxChunkID,
+                  "Add a '|| chunk_id > kMaxChunkID' below if this fails");
+    if (!writer_id || writer_id > kMaxWriterID || !buf) {
+      // This can genuinely happen when the trace is stopped. The producers
+      // might see the stop signal with some delay and try to keep sending
+      // patches left soon after.
+      PERFETTO_DLOG(
+          "Received invalid chunks_to_patch request from Producer: %" PRIu16
+          ", BufferID: %" PRIu32 " ChunkdID: %" PRIu32 " WriterID: %" PRIu16,
+          producer_id_trusted, chunk.target_buffer(), chunk_id, writer_id);
+      patches_discarded_ += static_cast<uint64_t>(chunk.patches_size());
+      continue;
+    }
+
+    // Note, there's no need to validate that the producer is allowed to write
+    // to the specified buffer ID (or that it's the correct buffer ID for a
+    // registered TraceWriter). That's because TraceBuffer uses the producer ID
+    // and writer ID to look up the chunk to patch. If the producer specifies an
+    // incorrect buffer, this lookup will fail and TraceBuffer will ignore the
+    // patches. Because the producer ID is trusted, there's also no way for a
+    // malicious producer to patch another producer's data.
+
+    // Speculate on the fact that there are going to be a limited amount of
+    // patches per request, so we can allocate the |patches| array on the stack.
+    std::array<TraceBuffer::Patch, 1024> patches;  // Uninitialized.
+    if (chunk.patches().size() > patches.size()) {
+      PERFETTO_ELOG("Too many patches (%zu) batched in the same request",
+                    patches.size());
+      PERFETTO_DFATAL("Too many patches");
+      patches_discarded_ += static_cast<uint64_t>(chunk.patches_size());
+      continue;
+    }
+
+    size_t i = 0;
+    for (const auto& patch : chunk.patches()) {
+      const std::string& patch_data = patch.data();
+      if (patch_data.size() != patches[i].data.size()) {
+        PERFETTO_ELOG("Received patch from producer: %" PRIu16
+                      " of unexpected size %zu",
+                      producer_id_trusted, patch_data.size());
+        patches_discarded_++;
+        continue;
+      }
+      patches[i].offset_untrusted = patch.offset();
+      memcpy(&patches[i].data[0], patch_data.data(), patches[i].data.size());
+      i++;
+    }
+    buf->TryPatchChunkContents(producer_id_trusted, writer_id, chunk_id,
+                               &patches[0], i, chunk.has_more_patches());
+  }
+}
+
+TracingServiceImpl::TracingSession* TracingServiceImpl::GetDetachedSession(
+    uid_t uid,
+    const std::string& key) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  for (auto& kv : tracing_sessions_) {
+    TracingSession* session = &kv.second;
+    if (session->consumer_uid == uid && session->detach_key == key) {
+      PERFETTO_DCHECK(session->consumer_maybe_null == nullptr);
+      return session;
+    }
+  }
+  return nullptr;
+}
+
+TracingServiceImpl::TracingSession* TracingServiceImpl::GetTracingSession(
+    TracingSessionID tsid) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto it = tsid ? tracing_sessions_.find(tsid) : tracing_sessions_.end();
+  if (it == tracing_sessions_.end())
+    return nullptr;
+  return &it->second;
+}
+
+TracingServiceImpl::TracingSession*
+TracingServiceImpl::FindTracingSessionWithMaxBugreportScore() {
+  TracingSession* max_session = nullptr;
+  for (auto& session_id_and_session : tracing_sessions_) {
+    auto& session = session_id_and_session.second;
+    const int32_t score = session.config.bugreport_score();
+    // Exclude sessions with 0 (or below) score. By default tracing sessions
+    // should NOT be eligible to be attached to bugreports.
+    if (score <= 0 || session.state != TracingSession::STARTED)
+      continue;
+
+    if (!max_session || score > max_session->config.bugreport_score())
+      max_session = &session;
+  }
+  return max_session;
+}
+
+ProducerID TracingServiceImpl::GetNextProducerID() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_CHECK(producers_.size() < kMaxProducerID);
+  do {
+    ++last_producer_id_;
+  } while (producers_.count(last_producer_id_) || last_producer_id_ == 0);
+  PERFETTO_DCHECK(last_producer_id_ > 0 && last_producer_id_ <= kMaxProducerID);
+  return last_producer_id_;
+}
+
+TraceBuffer* TracingServiceImpl::GetBufferByID(BufferID buffer_id) {
+  auto buf_iter = buffers_.find(buffer_id);
+  if (buf_iter == buffers_.end())
+    return nullptr;
+  return &*buf_iter->second;
+}
+
+void TracingServiceImpl::OnStartTriggersTimeout(TracingSessionID tsid) {
+  // Skip entirely the flush if the trace session doesn't exist anymore.
+  // This is to prevent misleading error messages to be logged.
+  //
+  // if the trace has started from the trigger we rely on
+  // the |stop_delay_ms| from the trigger so don't flush and
+  // disable if we've moved beyond a CONFIGURED state
+  auto* tracing_session_ptr = GetTracingSession(tsid);
+  if (tracing_session_ptr &&
+      tracing_session_ptr->state == TracingSession::CONFIGURED) {
+    PERFETTO_DLOG("Disabling TracingSession %" PRIu64
+                  " since no triggers activated.",
+                  tsid);
+    // No data should be returned from ReadBuffers() regardless of if we
+    // call FreeBuffers() or DisableTracing(). This is because in
+    // STOP_TRACING we need this promise in either case, and using
+    // DisableTracing() allows a graceful shutdown. Consumers can follow
+    // their normal path and check the buffers through ReadBuffers() and
+    // the code won't hang because the tracing session will still be
+    // alive just disabled.
+    DisableTracing(tsid);
+  }
+}
+
+void TracingServiceImpl::UpdateMemoryGuardrail() {
+#if PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
+  uint64_t total_buffer_bytes = 0;
+
+  // Sum up all the shared memory buffers.
+  for (const auto& id_to_producer : producers_) {
+    if (id_to_producer.second->shared_memory())
+      total_buffer_bytes += id_to_producer.second->shared_memory()->size();
+  }
+
+  // Sum up all the trace buffers.
+  for (const auto& id_to_buffer : buffers_) {
+    total_buffer_bytes += id_to_buffer.second->size();
+  }
+
+  // Sum up all the cloned traced buffers.
+  for (const auto& id_to_ts : tracing_sessions_) {
+    const TracingSession& ts = id_to_ts.second;
+    for (const auto& id_to_pending_clone : ts.pending_clones) {
+      const PendingClone& pending_clone = id_to_pending_clone.second;
+      for (const std::unique_ptr<TraceBuffer>& buf : pending_clone.buffers) {
+        if (buf) {
+          total_buffer_bytes += buf->size();
+        }
+      }
+    }
+  }
+
+  // Set the guard rail to 32MB + the sum of all the buffers over a 30 second
+  // interval.
+  uint64_t guardrail = base::kWatchdogDefaultMemorySlack + total_buffer_bytes;
+  base::Watchdog::GetInstance()->SetMemoryLimit(guardrail, 30 * 1000);
+#endif
+}
+
+void TracingServiceImpl::PeriodicSnapshotTask(TracingSessionID tsid) {
+  auto* tracing_session = GetTracingSession(tsid);
+  if (!tracing_session)
+    return;
+  if (tracing_session->state != TracingSession::STARTED)
+    return;
+  tracing_session->should_emit_sync_marker = true;
+  tracing_session->should_emit_stats = true;
+  MaybeSnapshotClocksIntoRingBuffer(tracing_session);
+}
+
+void TracingServiceImpl::SnapshotLifecyleEvent(TracingSession* tracing_session,
+                                               uint32_t field_id,
+                                               bool snapshot_clocks) {
+  // field_id should be an id of a field in TracingServiceEvent.
+  auto& lifecycle_events = tracing_session->lifecycle_events;
+  auto event_it =
+      std::find_if(lifecycle_events.begin(), lifecycle_events.end(),
+                   [field_id](const TracingSession::LifecycleEvent& event) {
+                     return event.field_id == field_id;
+                   });
+
+  TracingSession::LifecycleEvent* event;
+  if (event_it == lifecycle_events.end()) {
+    lifecycle_events.emplace_back(field_id);
+    event = &lifecycle_events.back();
+  } else {
+    event = &*event_it;
+  }
+
+  // Snapshot the clocks before capturing the timestamp for the event so we can
+  // use this snapshot to resolve the event timestamp if necessary.
+  if (snapshot_clocks)
+    MaybeSnapshotClocksIntoRingBuffer(tracing_session);
+
+  // Erase before emplacing to prevent a unncessary doubling of memory if
+  // not needed.
+  if (event->timestamps.size() >= event->max_size) {
+    event->timestamps.erase_front(1 + event->timestamps.size() -
+                                  event->max_size);
+  }
+  event->timestamps.emplace_back(base::GetBootTimeNs().count());
+}
+
+void TracingServiceImpl::MaybeSnapshotClocksIntoRingBuffer(
+    TracingSession* tracing_session) {
+  if (tracing_session->config.builtin_data_sources()
+          .disable_clock_snapshotting()) {
+    return;
+  }
+
+  // We are making an explicit copy of the latest snapshot (if it exists)
+  // because SnapshotClocks reads this data and computes the drift based on its
+  // content. If the clock drift is high enough, it will update the contents of
+  // |snapshot| and return true. Otherwise, it will return false.
+  TracingSession::ClockSnapshotData snapshot =
+      tracing_session->clock_snapshot_ring_buffer.empty()
+          ? TracingSession::ClockSnapshotData()
+          : tracing_session->clock_snapshot_ring_buffer.back();
+  bool did_update = SnapshotClocks(&snapshot);
+  if (did_update) {
+    // This means clocks drifted enough since last snapshot. See the comment
+    // in SnapshotClocks.
+    auto* snapshot_buffer = &tracing_session->clock_snapshot_ring_buffer;
+
+    // Erase before emplacing to prevent a unncessary doubling of memory if
+    // not needed.
+    static constexpr uint32_t kClockSnapshotRingBufferSize = 16;
+    if (snapshot_buffer->size() >= kClockSnapshotRingBufferSize) {
+      snapshot_buffer->erase_front(1 + snapshot_buffer->size() -
+                                   kClockSnapshotRingBufferSize);
+    }
+    snapshot_buffer->emplace_back(std::move(snapshot));
+  }
+}
+
+// Returns true when the data in |snapshot_data| is updated with the new state
+// of the clocks and false otherwise.
+bool TracingServiceImpl::SnapshotClocks(
+    TracingSession::ClockSnapshotData* snapshot_data) {
+  // Minimum drift that justifies replacing a prior clock snapshot that hasn't
+  // been emitted into the trace yet (see comment below).
+  static constexpr int64_t kSignificantDriftNs = 10 * 1000 * 1000;  // 10 ms
+
+  TracingSession::ClockSnapshotData new_snapshot_data = CaptureClockSnapshots();
+  // If we're about to update a session's latest clock snapshot that hasn't been
+  // emitted into the trace yet, check whether the clocks have drifted enough to
+  // warrant overriding the current snapshot values. The older snapshot would be
+  // valid for a larger part of the currently buffered trace data because the
+  // clock sync protocol in trace processor uses the latest clock <= timestamp
+  // to translate times (see https://perfetto.dev/docs/concepts/clock-sync), so
+  // we try to keep it if we can.
+  if (!snapshot_data->empty()) {
+    PERFETTO_DCHECK(snapshot_data->size() == new_snapshot_data.size());
+    PERFETTO_DCHECK((*snapshot_data)[0].clock_id ==
+                    protos::gen::BUILTIN_CLOCK_BOOTTIME);
+
+    bool update_snapshot = false;
+    uint64_t old_boot_ns = (*snapshot_data)[0].timestamp;
+    uint64_t new_boot_ns = new_snapshot_data[0].timestamp;
+    int64_t boot_diff =
+        static_cast<int64_t>(new_boot_ns) - static_cast<int64_t>(old_boot_ns);
+
+    for (size_t i = 1; i < snapshot_data->size(); i++) {
+      uint64_t old_ns = (*snapshot_data)[i].timestamp;
+      uint64_t new_ns = new_snapshot_data[i].timestamp;
+
+      int64_t diff =
+          static_cast<int64_t>(new_ns) - static_cast<int64_t>(old_ns);
+
+      // Compare the boottime delta against the delta of this clock.
+      if (std::abs(boot_diff - diff) >= kSignificantDriftNs) {
+        update_snapshot = true;
+        break;
+      }
+    }
+    if (!update_snapshot)
+      return false;
+    snapshot_data->clear();
+  }
+
+  *snapshot_data = std::move(new_snapshot_data);
+  return true;
+}
+
+void TracingServiceImpl::EmitClockSnapshot(
+    TracingSession* tracing_session,
+    TracingSession::ClockSnapshotData snapshot_data,
+    std::vector<TracePacket>* packets) {
+  PERFETTO_DCHECK(!tracing_session->config.builtin_data_sources()
+                       .disable_clock_snapshotting());
+
+  protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
+  auto* snapshot = packet->set_clock_snapshot();
+
+  protos::gen::BuiltinClock trace_clock =
+      tracing_session->config.builtin_data_sources().primary_trace_clock();
+  if (!trace_clock)
+    trace_clock = protos::gen::BUILTIN_CLOCK_BOOTTIME;
+  snapshot->set_primary_trace_clock(
+      static_cast<protos::pbzero::BuiltinClock>(trace_clock));
+
+  for (auto& clock_id_and_ts : snapshot_data) {
+    auto* c = snapshot->add_clocks();
+    c->set_clock_id(clock_id_and_ts.clock_id);
+    c->set_timestamp(clock_id_and_ts.timestamp);
+  }
+
+  packet->set_trusted_uid(static_cast<int32_t>(uid_));
+  packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
+  SerializeAndAppendPacket(packets, packet.SerializeAsArray());
+}
+
+void TracingServiceImpl::EmitSyncMarker(std::vector<TracePacket>* packets) {
+  // The sync marks are used to tokenize large traces efficiently.
+  // See description in trace_packet.proto.
+  if (sync_marker_packet_size_ == 0) {
+    // The marker ABI expects that the marker is written after the uid.
+    // Protozero guarantees that fields are written in the same order of the
+    // calls. The ResynchronizeTraceStreamUsingSyncMarker test verifies the ABI.
+    protozero::StaticBuffered<protos::pbzero::TracePacket> packet(
+        &sync_marker_packet_[0], sizeof(sync_marker_packet_));
+    packet->set_trusted_uid(static_cast<int32_t>(uid_));
+    packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
+
+    // Keep this last.
+    packet->set_synchronization_marker(kSyncMarker, sizeof(kSyncMarker));
+    sync_marker_packet_size_ = packet.Finalize();
+  }
+  packets->emplace_back();
+  packets->back().AddSlice(&sync_marker_packet_[0], sync_marker_packet_size_);
+}
+
+void TracingServiceImpl::EmitStats(TracingSession* tracing_session,
+                                   std::vector<TracePacket>* packets) {
+  protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
+  packet->set_trusted_uid(static_cast<int32_t>(uid_));
+  packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
+  GetTraceStats(tracing_session).Serialize(packet->set_trace_stats());
+  SerializeAndAppendPacket(packets, packet.SerializeAsArray());
+}
+
+TraceStats TracingServiceImpl::GetTraceStats(TracingSession* tracing_session) {
+  TraceStats trace_stats;
+  trace_stats.set_producers_connected(static_cast<uint32_t>(producers_.size()));
+  trace_stats.set_producers_seen(last_producer_id_);
+  trace_stats.set_data_sources_registered(
+      static_cast<uint32_t>(data_sources_.size()));
+  trace_stats.set_data_sources_seen(last_data_source_instance_id_);
+  trace_stats.set_tracing_sessions(
+      static_cast<uint32_t>(tracing_sessions_.size()));
+  trace_stats.set_total_buffers(static_cast<uint32_t>(buffers_.size()));
+  trace_stats.set_chunks_discarded(chunks_discarded_);
+  trace_stats.set_patches_discarded(patches_discarded_);
+  trace_stats.set_invalid_packets(tracing_session->invalid_packets);
+  trace_stats.set_flushes_requested(tracing_session->flushes_requested);
+  trace_stats.set_flushes_succeeded(tracing_session->flushes_succeeded);
+  trace_stats.set_flushes_failed(tracing_session->flushes_failed);
+  trace_stats.set_final_flush_outcome(tracing_session->final_flush_outcome);
+
+  if (tracing_session->trace_filter) {
+    auto* filt_stats = trace_stats.mutable_filter_stats();
+    filt_stats->set_input_packets(tracing_session->filter_input_packets);
+    filt_stats->set_input_bytes(tracing_session->filter_input_bytes);
+    filt_stats->set_output_bytes(tracing_session->filter_output_bytes);
+    filt_stats->set_errors(tracing_session->filter_errors);
+    filt_stats->set_time_taken_ns(tracing_session->filter_time_taken_ns);
+    for (uint64_t value : tracing_session->filter_bytes_discarded_per_buffer)
+      filt_stats->add_bytes_discarded_per_buffer(value);
+  }
+
+  for (BufferID buf_id : tracing_session->buffers_index) {
+    TraceBuffer* buf = GetBufferByID(buf_id);
+    if (!buf) {
+      PERFETTO_DFATAL("Buffer not found.");
+      continue;
+    }
+    *trace_stats.add_buffer_stats() = buf->stats();
+  }  // for (buf in session).
+
+  if (!tracing_session->config.builtin_data_sources()
+           .disable_chunk_usage_histograms()) {
+    // Emit chunk usage stats broken down by sequence ID (i.e. by trace-writer).
+    // Writer stats are updated by each TraceBuffer object at ReadBuffers time,
+    // and there can be >1 buffer per session. A trace writer never writes to
+    // more than one buffer (it's technically allowed but doesn't happen in the
+    // current impl of the tracing SDK).
+
+    bool has_written_bucket_definition = false;
+    uint32_t buf_idx = static_cast<uint32_t>(-1);
+    for (const BufferID buf_id : tracing_session->buffers_index) {
+      ++buf_idx;
+      const TraceBuffer* buf = GetBufferByID(buf_id);
+      if (!buf)
+        continue;
+      for (auto it = buf->writer_stats().GetIterator(); it; ++it) {
+        const auto& hist = it.value().used_chunk_hist;
+        ProducerID p;
+        WriterID w;
+        GetProducerAndWriterID(it.key(), &p, &w);
+        if (!has_written_bucket_definition) {
+          // Serialize one-off the histogram bucket definition, which is the
+          // same for all entries in the map.
+          has_written_bucket_definition = true;
+          // The -1 in the loop below is to skip the implicit overflow bucket.
+          for (size_t i = 0; i < hist.num_buckets() - 1; ++i) {
+            trace_stats.add_chunk_payload_histogram_def(hist.GetBucketThres(i));
+          }
+        }  // if(!has_written_bucket_definition)
+        auto* wri_stats = trace_stats.add_writer_stats();
+        wri_stats->set_sequence_id(
+            tracing_session->GetPacketSequenceID(kDefaultMachineID, p, w));
+        wri_stats->set_buffer(buf_idx);
+        for (size_t i = 0; i < hist.num_buckets(); ++i) {
+          wri_stats->add_chunk_payload_histogram_counts(hist.GetBucketCount(i));
+          wri_stats->add_chunk_payload_histogram_sum(hist.GetBucketSum(i));
+        }
+      }  // for each sequence (writer).
+    }    // for each buffer.
+  }      // if (!disable_chunk_usage_histograms)
+
+  return trace_stats;
+}
+
+void TracingServiceImpl::EmitUuid(TracingSession* tracing_session,
+                                  std::vector<TracePacket>* packets) {
+  protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
+  packet->set_trusted_uid(static_cast<int32_t>(uid_));
+  packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
+  auto* uuid = packet->set_trace_uuid();
+  uuid->set_lsb(tracing_session->trace_uuid.lsb());
+  uuid->set_msb(tracing_session->trace_uuid.msb());
+  SerializeAndAppendPacket(packets, packet.SerializeAsArray());
+}
+
+void TracingServiceImpl::MaybeEmitTraceConfig(
+    TracingSession* tracing_session,
+    std::vector<TracePacket>* packets) {
+  if (tracing_session->did_emit_initial_packets)
+    return;
+  protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
+  packet->set_trusted_uid(static_cast<int32_t>(uid_));
+  packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
+  tracing_session->config.Serialize(packet->set_trace_config());
+  SerializeAndAppendPacket(packets, packet.SerializeAsArray());
+}
+
+void TracingServiceImpl::EmitSystemInfo(std::vector<TracePacket>* packets) {
+  protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
+  auto* info = packet->set_system_info();
+  info->set_tracing_service_version(base::GetVersionString());
+
+  std::optional<int32_t> tzoff = base::GetTimezoneOffsetMins();
+  if (tzoff.has_value())
+    info->set_timezone_off_mins(*tzoff);
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
+    !PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
+  struct utsname uname_info;
+  if (uname(&uname_info) == 0) {
+    auto* utsname_info = info->set_utsname();
+    utsname_info->set_sysname(uname_info.sysname);
+    utsname_info->set_version(uname_info.version);
+    utsname_info->set_machine(uname_info.machine);
+    utsname_info->set_release(uname_info.release);
+  }
+  info->set_page_size(static_cast<uint32_t>(sysconf(_SC_PAGESIZE)));
+  info->set_num_cpus(static_cast<uint32_t>(sysconf(_SC_NPROCESSORS_CONF)));
+#endif  // !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  std::string fingerprint_value = base::GetAndroidProp("ro.build.fingerprint");
+  if (!fingerprint_value.empty()) {
+    info->set_android_build_fingerprint(fingerprint_value);
+  } else {
+    PERFETTO_ELOG("Unable to read ro.build.fingerprint");
+  }
+
+  std::string sdk_str_value = base::GetAndroidProp("ro.build.version.sdk");
+  std::optional<uint64_t> sdk_value = base::StringToUInt64(sdk_str_value);
+  if (sdk_value.has_value()) {
+    info->set_android_sdk_version(*sdk_value);
+  } else {
+    PERFETTO_ELOG("Unable to read ro.build.version.sdk");
+  }
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  packet->set_trusted_uid(static_cast<int32_t>(uid_));
+  packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
+  SerializeAndAppendPacket(packets, packet.SerializeAsArray());
+}
+
+void TracingServiceImpl::EmitLifecycleEvents(
+    TracingSession* tracing_session,
+    std::vector<TracePacket>* packets) {
+  using TimestampedPacket =
+      std::pair<int64_t /* ts */, std::vector<uint8_t> /* serialized packet */>;
+
+  std::vector<TimestampedPacket> timestamped_packets;
+  for (auto& event : tracing_session->lifecycle_events) {
+    for (int64_t ts : event.timestamps) {
+      protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
+      packet->set_timestamp(static_cast<uint64_t>(ts));
+      packet->set_trusted_uid(static_cast<int32_t>(uid_));
+      packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
+
+      auto* service_event = packet->set_service_event();
+      service_event->AppendVarInt(event.field_id, 1);
+      timestamped_packets.emplace_back(ts, packet.SerializeAsArray());
+    }
+    event.timestamps.clear();
+  }
+
+  // We sort by timestamp here to ensure that the "sequence" of lifecycle
+  // packets has monotonic timestamps like other sequences in the trace.
+  // Note that these events could still be out of order with respect to other
+  // events on the service packet sequence (e.g. trigger received packets).
+  std::sort(timestamped_packets.begin(), timestamped_packets.end(),
+            [](const TimestampedPacket& a, const TimestampedPacket& b) {
+              return a.first < b.first;
+            });
+
+  for (auto& pair : timestamped_packets)
+    SerializeAndAppendPacket(packets, std::move(pair.second));
+}
+
+void TracingServiceImpl::MaybeEmitRemoteClockSync(
+    TracingSession* tracing_session,
+    std::vector<TracePacket>* packets) {
+  if (tracing_session->did_emit_remote_clock_sync_)
+    return;
+
+  std::unordered_set<MachineID> did_emit_machines;
+  for (const auto& id_and_relay_client : relay_clients_) {
+    const auto& relay_client = id_and_relay_client.second;
+    auto machine_id = relay_client->machine_id();
+    if (did_emit_machines.find(machine_id) != did_emit_machines.end())
+      continue;  // Already emitted for the machine (e.g. multiple clients).
+
+    auto& sync_clock_snapshots = relay_client->synced_clocks();
+    if (sync_clock_snapshots.empty()) {
+      PERFETTO_DLOG("Clock not synchronized for machine ID = %" PRIu32,
+                    machine_id);
+      continue;
+    }
+
+    // Don't emit twice for the same machine.
+    did_emit_machines.insert(machine_id);
+
+    protozero::HeapBuffered<protos::pbzero::TracePacket> sync_packet;
+    sync_packet->set_machine_id(machine_id);
+    sync_packet->set_trusted_uid(static_cast<int32_t>(uid_));
+    auto* remote_clock_sync = sync_packet->set_remote_clock_sync();
+    for (const auto& sync_exchange : relay_client->synced_clocks()) {
+      auto* sync_exchange_msg = remote_clock_sync->add_synced_clocks();
+
+      auto* client_snapshots = sync_exchange_msg->set_client_clocks();
+      for (const auto& client_clock : sync_exchange.client_clocks) {
+        auto* clock = client_snapshots->add_clocks();
+        clock->set_clock_id(client_clock.clock_id);
+        clock->set_timestamp(client_clock.timestamp);
+      }
+
+      auto* host_snapshots = sync_exchange_msg->set_host_clocks();
+      for (const auto& host_clock : sync_exchange.host_clocks) {
+        auto* clock = host_snapshots->add_clocks();
+        clock->set_clock_id(host_clock.clock_id);
+        clock->set_timestamp(host_clock.timestamp);
+      }
+    }
+
+    SerializeAndAppendPacket(packets, sync_packet.SerializeAsArray());
+  }
+
+  tracing_session->did_emit_remote_clock_sync_ = true;
+}
+
+void TracingServiceImpl::MaybeEmitReceivedTriggers(
+    TracingSession* tracing_session,
+    std::vector<TracePacket>* packets) {
+  PERFETTO_DCHECK(tracing_session->num_triggers_emitted_into_trace <=
+                  tracing_session->received_triggers.size());
+  for (size_t i = tracing_session->num_triggers_emitted_into_trace;
+       i < tracing_session->received_triggers.size(); ++i) {
+    const auto& info = tracing_session->received_triggers[i];
+    protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
+    auto* trigger = packet->set_trigger();
+    trigger->set_trigger_name(info.trigger_name);
+    trigger->set_producer_name(info.producer_name);
+    trigger->set_trusted_producer_uid(static_cast<int32_t>(info.producer_uid));
+
+    packet->set_timestamp(info.boot_time_ns);
+    packet->set_trusted_uid(static_cast<int32_t>(uid_));
+    packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
+    SerializeAndAppendPacket(packets, packet.SerializeAsArray());
+    ++tracing_session->num_triggers_emitted_into_trace;
+  }
+}
+
+void TracingServiceImpl::MaybeLogUploadEvent(const TraceConfig& cfg,
+                                             const base::Uuid& uuid,
+                                             PerfettoStatsdAtom atom,
+                                             const std::string& trigger_name) {
+  if (!ShouldLogEvent(cfg))
+    return;
+
+  PERFETTO_DCHECK(uuid);  // The UUID must be set at this point.
+  android_stats::MaybeLogUploadEvent(atom, uuid.lsb(), uuid.msb(),
+                                     trigger_name);
+}
+
+void TracingServiceImpl::MaybeLogTriggerEvent(const TraceConfig& cfg,
+                                              PerfettoTriggerAtom atom,
+                                              const std::string& trigger_name) {
+  if (!ShouldLogEvent(cfg))
+    return;
+  android_stats::MaybeLogTriggerEvent(atom, trigger_name);
+}
+
+size_t TracingServiceImpl::PurgeExpiredAndCountTriggerInWindow(
+    int64_t now_ns,
+    uint64_t trigger_name_hash) {
+  PERFETTO_DCHECK(
+      std::is_sorted(trigger_history_.begin(), trigger_history_.end()));
+  size_t remove_count = 0;
+  size_t trigger_count = 0;
+  for (const TriggerHistory& h : trigger_history_) {
+    if (h.timestamp_ns < now_ns - trigger_window_ns_) {
+      remove_count++;
+    } else if (h.name_hash == trigger_name_hash) {
+      trigger_count++;
+    }
+  }
+  trigger_history_.erase_front(remove_count);
+  return trigger_count;
+}
+
+void TracingServiceImpl::FlushAndCloneSession(ConsumerEndpointImpl* consumer,
+                                              TracingSessionID tsid,
+                                              bool skip_trace_filter,
+                                              bool for_bugreport) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto clone_target = FlushFlags::CloneTarget::kUnknown;
+
+  if (tsid == kBugreportSessionId) {
+    // This branch is only here to support the legacy protocol where we could
+    // clone only a single session using the magic ID kBugreportSessionId.
+    // The newer perfetto --clone-all-for-bugreport first queries the existing
+    // sessions and then issues individual clone requests specifying real
+    // session IDs, setting args.{for_bugreport,skip_trace_filter}=true.
+    PERFETTO_LOG("Looking for sessions for bugreport");
+    TracingSession* session = FindTracingSessionWithMaxBugreportScore();
+    if (!session) {
+      consumer->consumer_->OnSessionCloned(
+          {false, "No tracing sessions eligible for bugreport found", {}});
+      return;
+    }
+    tsid = session->id;
+    clone_target = FlushFlags::CloneTarget::kBugreport;
+    skip_trace_filter = true;
+    for_bugreport = true;
+  } else if (for_bugreport) {
+    clone_target = FlushFlags::CloneTarget::kBugreport;
+  }
+
+  TracingSession* session = GetTracingSession(tsid);
+  if (!session) {
+    consumer->consumer_->OnSessionCloned(
+        {false, "Tracing session not found", {}});
+    return;
+  }
+
+  // If any of the buffers are marked as clear_before_clone, reset them before
+  // issuing the Flush(kCloneReason).
+  size_t buf_idx = 0;
+  for (BufferID src_buf_id : session->buffers_index) {
+    if (!session->config.buffers()[buf_idx++].clear_before_clone())
+      continue;
+    auto buf_iter = buffers_.find(src_buf_id);
+    PERFETTO_CHECK(buf_iter != buffers_.end());
+    std::unique_ptr<TraceBuffer>& buf = buf_iter->second;
+
+    // No need to reset the buffer if nothing has been written into it yet.
+    // This is the canonical case if producers behive nicely and don't timeout
+    // the handling of writes during the flush.
+    // This check avoids a useless re-mmap upon every Clone() if the buffer is
+    // already empty (when used in combination with `transfer_on_clone`).
+    if (!buf->has_data())
+      continue;
+
+    // Some leftover data was left in the buffer. Recreate it to empty it.
+    const auto buf_policy = buf->overwrite_policy();
+    const auto buf_size = buf->size();
+    std::unique_ptr<TraceBuffer> old_buf = std::move(buf);
+    buf = TraceBuffer::Create(buf_size, buf_policy);
+    if (!buf) {
+      // This is extremely rare but could happen on 32-bit. If the new buffer
+      // allocation failed, put back the buffer where it was and fail the clone.
+      // We cannot leave the original tracing session buffer-less as it would
+      // cause crashes when data sources commit new data.
+      buf = std::move(old_buf);
+      consumer->consumer_->OnSessionCloned(
+          {false, "Buffer allocation failed while attempting to clone", {}});
+      return;
+    }
+  }
+
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  auto weak_consumer = consumer->GetWeakPtr();
+
+  const PendingCloneID clone_id = session->last_pending_clone_id_++;
+
+  auto& clone_op = session->pending_clones[clone_id];
+  clone_op.pending_flush_cnt = 0;
+  clone_op.buffers =
+      std::vector<std::unique_ptr<TraceBuffer>>(session->buffers_index.size());
+  clone_op.weak_consumer = weak_consumer;
+  clone_op.skip_trace_filter = skip_trace_filter;
+
+  // Issue separate flush requests for separate buffer groups. The buffer marked
+  // as transfer_on_clone will be flushed and cloned separately: even if they're
+  // slower (like in the case of Winscope tracing), they will not delay the
+  // snapshot of the other buffers.
+  //
+  // In the future we might want to split the buffer into more groups and maybe
+  // allow this to be configurable.
+  std::array<std::set<BufferID>, 2> bufs_groups;
+  for (size_t i = 0; i < session->buffers_index.size(); i++) {
+    if (session->config.buffers()[i].transfer_on_clone()) {
+      bufs_groups[0].insert(session->buffers_index[i]);
+    } else {
+      bufs_groups[1].insert(session->buffers_index[i]);
+    }
+  }
+
+  clone_op.pending_flush_cnt = bufs_groups.size();
+  for (const std::set<BufferID>& buf_group : bufs_groups) {
+    FlushDataSourceInstances(
+        session, 0,
+        GetFlushableDataSourceInstancesForBuffers(session, buf_group),
+        [tsid, clone_id, buf_group, weak_this](bool final_flush) {
+          if (!weak_this)
+            return;
+          weak_this->OnFlushDoneForClone(tsid, clone_id, buf_group,
+                                         final_flush);
+        },
+        FlushFlags(FlushFlags::Initiator::kTraced,
+                   FlushFlags::Reason::kTraceClone, clone_target));
+  }
+}
+
+std::map<ProducerID, std::vector<DataSourceInstanceID>>
+TracingServiceImpl::GetFlushableDataSourceInstancesForBuffers(
+    TracingSession* session,
+    const std::set<BufferID>& bufs) {
+  std::map<ProducerID, std::vector<DataSourceInstanceID>> data_source_instances;
+
+  for (const auto& [producer_id, ds_inst] : session->data_source_instances) {
+    // TODO(ddiproietto): Consider if we should skip instances if ds_inst.state
+    // != DataSourceInstance::STARTED
+    if (ds_inst.no_flush) {
+      continue;
+    }
+    if (!bufs.count(static_cast<BufferID>(ds_inst.config.target_buffer()))) {
+      continue;
+    }
+    data_source_instances[producer_id].push_back(ds_inst.instance_id);
+  }
+
+  return data_source_instances;
+}
+
+void TracingServiceImpl::OnFlushDoneForClone(TracingSessionID tsid,
+                                             PendingCloneID clone_id,
+                                             const std::set<BufferID>& buf_ids,
+                                             bool final_flush_outcome) {
+  TracingSession* src = GetTracingSession(tsid);
+  // The session might be gone by the time we try to clone it.
+  if (!src) {
+    return;
+  }
+
+  auto it = src->pending_clones.find(clone_id);
+  if (it == src->pending_clones.end()) {
+    return;
+  }
+  auto& clone_op = it->second;
+
+  if (final_flush_outcome == false) {
+    clone_op.flush_failed = true;
+  }
+
+  base::Status result;
+  base::Uuid uuid;
+
+  // First clone the flushed TraceBuffer(s). This can fail because of ENOMEM. If
+  // it happens bail out early before creating any session.
+  if (!DoCloneBuffers(src, buf_ids, &clone_op.buffers)) {
+    result = PERFETTO_SVC_ERR("Buffer allocation failed");
+  }
+
+  if (result.ok()) {
+    UpdateMemoryGuardrail();
+
+    if (--clone_op.pending_flush_cnt != 0) {
+      // Wait for more pending flushes.
+      return;
+    }
+
+    PERFETTO_LOG("FlushAndCloneSession(%" PRIu64 ") started, success=%d", tsid,
+                 final_flush_outcome);
+
+    if (clone_op.weak_consumer) {
+      result = FinishCloneSession(
+          &*clone_op.weak_consumer, tsid, std::move(clone_op.buffers),
+          clone_op.skip_trace_filter, !clone_op.flush_failed, &uuid);
+    }
+  }  // if (result.ok())
+
+  if (clone_op.weak_consumer) {
+    clone_op.weak_consumer->consumer_->OnSessionCloned(
+        {result.ok(), result.message(), uuid});
+  }
+
+  src->pending_clones.erase(it);
+  UpdateMemoryGuardrail();
+}
+
+bool TracingServiceImpl::DoCloneBuffers(
+    TracingSession* src,
+    const std::set<BufferID>& buf_ids,
+    std::vector<std::unique_ptr<TraceBuffer>>* buf_snaps) {
+  PERFETTO_DCHECK(src->num_buffers() == src->config.buffers().size());
+  buf_snaps->resize(src->buffers_index.size());
+
+  for (size_t buf_idx = 0; buf_idx < src->buffers_index.size(); buf_idx++) {
+    BufferID src_buf_id = src->buffers_index[buf_idx];
+    if (buf_ids.count(src_buf_id) == 0)
+      continue;
+    auto buf_iter = buffers_.find(src_buf_id);
+    PERFETTO_CHECK(buf_iter != buffers_.end());
+    std::unique_ptr<TraceBuffer>& src_buf = buf_iter->second;
+    std::unique_ptr<TraceBuffer> new_buf;
+    if (src->config.buffers()[buf_idx].transfer_on_clone()) {
+      const auto buf_policy = src_buf->overwrite_policy();
+      const auto buf_size = src_buf->size();
+      new_buf = std::move(src_buf);
+      src_buf = TraceBuffer::Create(buf_size, buf_policy);
+      if (!src_buf) {
+        // If the allocation fails put the buffer back and let the code below
+        // handle the failure gracefully.
+        src_buf = std::move(new_buf);
+      }
+    } else {
+      new_buf = src_buf->CloneReadOnly();
+    }
+    if (!new_buf.get()) {
+      return false;
+    }
+    (*buf_snaps)[buf_idx] = std::move(new_buf);
+  }
+  return true;
+}
+
+base::Status TracingServiceImpl::FinishCloneSession(
+    ConsumerEndpointImpl* consumer,
+    TracingSessionID src_tsid,
+    std::vector<std::unique_ptr<TraceBuffer>> buf_snaps,
+    bool skip_trace_filter,
+    bool final_flush_outcome,
+    base::Uuid* new_uuid) {
+  PERFETTO_DLOG("CloneSession(%" PRIu64
+                ", skip_trace_filter=%d) started, consumer uid: %d",
+                src_tsid, skip_trace_filter, static_cast<int>(consumer->uid_));
+
+  TracingSession* src = GetTracingSession(src_tsid);
+
+  // The session might be gone by the time we try to clone it.
+  if (!src)
+    return PERFETTO_SVC_ERR("session not found");
+
+  if (consumer->tracing_session_id_) {
+    return PERFETTO_SVC_ERR(
+        "The consumer is already attached to another tracing session");
+  }
+
+  // Skip the UID check for sessions marked with a bugreport_score > 0.
+  // Those sessions, by design, can be stolen by any other consumer for the
+  // sake of creating snapshots for bugreports.
+  if (!src->IsCloneAllowed(consumer->uid_)) {
+    return PERFETTO_SVC_ERR("Not allowed to clone a session from another UID");
+  }
+
+  std::vector<BufferID> buf_ids =
+      buffer_ids_.AllocateMultiple(buf_snaps.size());
+  if (buf_ids.size() != buf_snaps.size()) {
+    return PERFETTO_SVC_ERR("Buffer id allocation failed");
+  }
+
+  PERFETTO_CHECK(std::none_of(
+      buf_snaps.begin(), buf_snaps.end(),
+      [](const std::unique_ptr<TraceBuffer>& buf) { return buf == nullptr; }));
+
+  const TracingSessionID tsid = ++last_tracing_session_id_;
+  TracingSession* cloned_session =
+      &tracing_sessions_
+           .emplace(
+               std::piecewise_construct, std::forward_as_tuple(tsid),
+               std::forward_as_tuple(tsid, consumer, src->config, task_runner_))
+           .first->second;
+
+  // Generate a new UUID for the cloned session, but preserve the LSB. In some
+  // contexts the LSB is used to tie the trace back to the statsd subscription
+  // that triggered it. See the corresponding code in perfetto_cmd.cc which
+  // reads at triggering_subscription_id().
+  const int64_t orig_uuid_lsb = src->trace_uuid.lsb();
+  cloned_session->state = TracingSession::CLONED_READ_ONLY;
+  cloned_session->trace_uuid = base::Uuidv4();
+  cloned_session->trace_uuid.set_lsb(orig_uuid_lsb);
+  *new_uuid = cloned_session->trace_uuid;
+
+  for (size_t i = 0; i < buf_snaps.size(); i++) {
+    BufferID buf_global_id = buf_ids[i];
+    std::unique_ptr<TraceBuffer>& buf = buf_snaps[i];
+    // This is only needed for transfer_on_clone. Other buffers are already
+    // marked as read-only by CloneReadOnly(). We cannot do this early because
+    // in case of an allocation failure we will put std::move() the original
+    // buffer back in its place and in that case should not be made read-only.
+    buf->set_read_only();
+    buffers_.emplace(buf_global_id, std::move(buf));
+    cloned_session->buffers_index.emplace_back(buf_global_id);
+  }
+  UpdateMemoryGuardrail();
+
+  // Copy over relevant state that we want to persist in the cloned session.
+  // Mostly stats and metadata that is emitted in the trace file by the service.
+  // Also clear the received trigger list in the main tracing session. A
+  // CLONE_SNAPSHOT session can go in ring buffer mode for several hours and get
+  // snapshotted several times. This causes two issues with `received_triggers`:
+  // 1. Adding noise in the cloned trace emitting triggers that happened too
+  //    far back (see b/290799105).
+  // 2. Bloating memory (see b/290798988).
+  cloned_session->should_emit_stats = true;
+  cloned_session->received_triggers = std::move(src->received_triggers);
+  src->received_triggers.clear();
+  src->num_triggers_emitted_into_trace = 0;
+  cloned_session->lifecycle_events =
+      std::vector<TracingSession::LifecycleEvent>(src->lifecycle_events);
+  cloned_session->initial_clock_snapshot = src->initial_clock_snapshot;
+  cloned_session->clock_snapshot_ring_buffer = src->clock_snapshot_ring_buffer;
+  cloned_session->invalid_packets = src->invalid_packets;
+  cloned_session->flushes_requested = src->flushes_requested;
+  cloned_session->flushes_succeeded = src->flushes_succeeded;
+  cloned_session->flushes_failed = src->flushes_failed;
+  cloned_session->compress_deflate = src->compress_deflate;
+  if (src->trace_filter && !skip_trace_filter) {
+    // Copy the trace filter, unless it's a clone-for-bugreport (b/317065412).
+    cloned_session->trace_filter.reset(
+        new protozero::MessageFilter(src->trace_filter->config()));
+  }
+
+  SnapshotLifecyleEvent(
+      cloned_session,
+      protos::pbzero::TracingServiceEvent::kTracingDisabledFieldNumber,
+      true /* snapshot_clocks */);
+
+  PERFETTO_DLOG("Consumer (uid:%d) cloned tracing session %" PRIu64
+                " -> %" PRIu64,
+                static_cast<int>(consumer->uid_), src_tsid, tsid);
+
+  consumer->tracing_session_id_ = tsid;
+  cloned_session->final_flush_outcome = final_flush_outcome
+                                            ? TraceStats::FINAL_FLUSH_SUCCEEDED
+                                            : TraceStats::FINAL_FLUSH_FAILED;
+  return base::OkStatus();
+}
+
+bool TracingServiceImpl::TracingSession::IsCloneAllowed(uid_t clone_uid) const {
+  if (clone_uid == 0)
+    return true;  // Root is always allowed to clone everything.
+  if (clone_uid == this->consumer_uid)
+    return true;  // Allow cloning if the uids match.
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  // On Android allow shell to clone sessions marked as exported for bugreport.
+  // Dumpstate (invoked by adb bugreport) invokes commands as shell.
+  if (clone_uid == AID_SHELL && this->config.bugreport_score() > 0)
+    return true;
+#endif
+  return false;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// TracingServiceImpl::ConsumerEndpointImpl implementation
+////////////////////////////////////////////////////////////////////////////////
+
+TracingServiceImpl::ConsumerEndpointImpl::ConsumerEndpointImpl(
+    TracingServiceImpl* service,
+    base::TaskRunner* task_runner,
+    Consumer* consumer,
+    uid_t uid)
+    : task_runner_(task_runner),
+      service_(service),
+      consumer_(consumer),
+      uid_(uid),
+      weak_ptr_factory_(this) {}
+
+TracingServiceImpl::ConsumerEndpointImpl::~ConsumerEndpointImpl() {
+  service_->DisconnectConsumer(this);
+  consumer_->OnDisconnect();
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::NotifyOnTracingDisabled(
+    const std::string& error) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostTask([weak_this, error /* deliberate copy */] {
+    if (weak_this)
+      weak_this->consumer_->OnTracingDisabled(error);
+  });
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::EnableTracing(
+    const TraceConfig& cfg,
+    base::ScopedFile fd) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto status = service_->EnableTracing(this, cfg, std::move(fd));
+  if (!status.ok())
+    NotifyOnTracingDisabled(status.message());
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::ChangeTraceConfig(
+    const TraceConfig& cfg) {
+  if (!tracing_session_id_) {
+    PERFETTO_LOG(
+        "Consumer called ChangeTraceConfig() but tracing was "
+        "not active");
+    return;
+  }
+  service_->ChangeTraceConfig(this, cfg);
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::StartTracing() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!tracing_session_id_) {
+    PERFETTO_LOG("Consumer called StartTracing() but tracing was not active");
+    return;
+  }
+  service_->StartTracing(tracing_session_id_);
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::DisableTracing() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!tracing_session_id_) {
+    PERFETTO_LOG("Consumer called DisableTracing() but tracing was not active");
+    return;
+  }
+  service_->DisableTracing(tracing_session_id_);
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::ReadBuffers() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!tracing_session_id_) {
+    PERFETTO_LOG("Consumer called ReadBuffers() but tracing was not active");
+    consumer_->OnTraceData({}, /* has_more = */ false);
+    return;
+  }
+  if (!service_->ReadBuffersIntoConsumer(tracing_session_id_, this)) {
+    consumer_->OnTraceData({}, /* has_more = */ false);
+  }
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::FreeBuffers() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!tracing_session_id_) {
+    PERFETTO_LOG("Consumer called FreeBuffers() but tracing was not active");
+    return;
+  }
+  service_->FreeBuffers(tracing_session_id_);
+  tracing_session_id_ = 0;
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::Flush(uint32_t timeout_ms,
+                                                     FlushCallback callback,
+                                                     FlushFlags flush_flags) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!tracing_session_id_) {
+    PERFETTO_LOG("Consumer called Flush() but tracing was not active");
+    return;
+  }
+  service_->Flush(tracing_session_id_, timeout_ms, callback, flush_flags);
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::Detach(const std::string& key) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  bool success = service_->DetachConsumer(this, key);
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostTask([weak_this, success] {
+    if (weak_this)
+      weak_this->consumer_->OnDetach(success);
+  });
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::Attach(const std::string& key) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  bool success = service_->AttachConsumer(this, key);
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostTask([weak_this, success] {
+    if (!weak_this)
+      return;
+    Consumer* consumer = weak_this->consumer_;
+    TracingSession* session =
+        weak_this->service_->GetTracingSession(weak_this->tracing_session_id_);
+    if (!session) {
+      consumer->OnAttach(false, TraceConfig());
+      return;
+    }
+    consumer->OnAttach(success, session->config);
+  });
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::GetTraceStats() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  bool success = false;
+  TraceStats stats;
+  TracingSession* session = service_->GetTracingSession(tracing_session_id_);
+  if (session) {
+    success = true;
+    stats = service_->GetTraceStats(session);
+  }
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostTask([weak_this, success, stats] {
+    if (weak_this)
+      weak_this->consumer_->OnTraceStats(success, stats);
+  });
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::ObserveEvents(
+    uint32_t events_mask) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  observable_events_mask_ = events_mask;
+  TracingSession* session = service_->GetTracingSession(tracing_session_id_);
+  if (!session)
+    return;
+
+  if (observable_events_mask_ & ObservableEvents::TYPE_DATA_SOURCES_INSTANCES) {
+    // Issue initial states.
+    for (const auto& kv : session->data_source_instances) {
+      ProducerEndpointImpl* producer = service_->GetProducer(kv.first);
+      PERFETTO_DCHECK(producer);
+      OnDataSourceInstanceStateChange(*producer, kv.second);
+    }
+  }
+
+  // If the ObserveEvents() call happens after data sources have acked already
+  // notify immediately.
+  if (observable_events_mask_ &
+      ObservableEvents::TYPE_ALL_DATA_SOURCES_STARTED) {
+    service_->MaybeNotifyAllDataSourcesStarted(session);
+  }
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::OnDataSourceInstanceStateChange(
+    const ProducerEndpointImpl& producer,
+    const DataSourceInstance& instance) {
+  if (!(observable_events_mask_ &
+        ObservableEvents::TYPE_DATA_SOURCES_INSTANCES)) {
+    return;
+  }
+
+  if (instance.state != DataSourceInstance::CONFIGURED &&
+      instance.state != DataSourceInstance::STARTED &&
+      instance.state != DataSourceInstance::STOPPED) {
+    return;
+  }
+
+  auto* observable_events = AddObservableEvents();
+  auto* change = observable_events->add_instance_state_changes();
+  change->set_producer_name(producer.name_);
+  change->set_data_source_name(instance.data_source_name);
+  if (instance.state == DataSourceInstance::STARTED) {
+    change->set_state(ObservableEvents::DATA_SOURCE_INSTANCE_STATE_STARTED);
+  } else {
+    change->set_state(ObservableEvents::DATA_SOURCE_INSTANCE_STATE_STOPPED);
+  }
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::OnAllDataSourcesStarted() {
+  if (!(observable_events_mask_ &
+        ObservableEvents::TYPE_ALL_DATA_SOURCES_STARTED)) {
+    return;
+  }
+  auto* observable_events = AddObservableEvents();
+  observable_events->set_all_data_sources_started(true);
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::NotifyCloneSnapshotTrigger() {
+  if (!(observable_events_mask_ & ObservableEvents::TYPE_CLONE_TRIGGER_HIT)) {
+    return;
+  }
+  auto* observable_events = AddObservableEvents();
+  auto* clone_trig = observable_events->mutable_clone_trigger_hit();
+  clone_trig->set_tracing_session_id(static_cast<int64_t>(tracing_session_id_));
+}
+
+ObservableEvents*
+TracingServiceImpl::ConsumerEndpointImpl::AddObservableEvents() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!observable_events_) {
+    observable_events_.reset(new ObservableEvents());
+    auto weak_this = weak_ptr_factory_.GetWeakPtr();
+    task_runner_->PostTask([weak_this] {
+      if (!weak_this)
+        return;
+
+      // Move into a temporary to allow reentrancy in OnObservableEvents.
+      auto observable_events = std::move(weak_this->observable_events_);
+      weak_this->consumer_->OnObservableEvents(*observable_events);
+    });
+  }
+  return observable_events_.get();
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::QueryServiceState(
+    QueryServiceStateArgs args,
+    QueryServiceStateCallback callback) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  TracingServiceState svc_state;
+
+  const auto& sessions = service_->tracing_sessions_;
+  svc_state.set_tracing_service_version(base::GetVersionString());
+  svc_state.set_num_sessions(static_cast<int>(sessions.size()));
+
+  int num_started = 0;
+  for (const auto& kv : sessions)
+    num_started += kv.second.state == TracingSession::State::STARTED ? 1 : 0;
+  svc_state.set_num_sessions_started(num_started);
+
+  for (const auto& kv : service_->producers_) {
+    if (args.sessions_only)
+      break;
+    auto* producer = svc_state.add_producers();
+    producer->set_id(static_cast<int>(kv.first));
+    producer->set_name(kv.second->name_);
+    producer->set_sdk_version(kv.second->sdk_version_);
+    producer->set_uid(static_cast<int32_t>(kv.second->uid()));
+    producer->set_pid(static_cast<int32_t>(kv.second->pid()));
+  }
+
+  for (const auto& kv : service_->data_sources_) {
+    if (args.sessions_only)
+      break;
+    const auto& registered_data_source = kv.second;
+    auto* data_source = svc_state.add_data_sources();
+    *data_source->mutable_ds_descriptor() = registered_data_source.descriptor;
+    data_source->set_producer_id(
+        static_cast<int>(registered_data_source.producer_id));
+  }
+
+  svc_state.set_supports_tracing_sessions(true);
+  for (const auto& kv : service_->tracing_sessions_) {
+    const TracingSession& s = kv.second;
+    if (!s.IsCloneAllowed(uid_))
+      continue;
+    auto* session = svc_state.add_tracing_sessions();
+    session->set_id(s.id);
+    session->set_consumer_uid(static_cast<int>(s.consumer_uid));
+    session->set_duration_ms(s.config.duration_ms());
+    session->set_num_data_sources(
+        static_cast<uint32_t>(s.data_source_instances.size()));
+    session->set_unique_session_name(s.config.unique_session_name());
+    if (s.config.has_bugreport_score())
+      session->set_bugreport_score(s.config.bugreport_score());
+    if (s.config.has_bugreport_filename())
+      session->set_bugreport_filename(s.config.bugreport_filename());
+    for (const auto& snap_kv : s.initial_clock_snapshot) {
+      if (snap_kv.clock_id == protos::pbzero::BUILTIN_CLOCK_REALTIME)
+        session->set_start_realtime_ns(static_cast<int64_t>(snap_kv.timestamp));
+    }
+    for (const auto& buf : s.config.buffers())
+      session->add_buffer_size_kb(buf.size_kb());
+
+    switch (s.state) {
+      case TracingSession::State::DISABLED:
+        session->set_state("DISABLED");
+        break;
+      case TracingSession::State::CONFIGURED:
+        session->set_state("CONFIGURED");
+        break;
+      case TracingSession::State::STARTED:
+        session->set_is_started(true);
+        session->set_state("STARTED");
+        break;
+      case TracingSession::State::DISABLING_WAITING_STOP_ACKS:
+        session->set_state("STOP_WAIT");
+        break;
+      case TracingSession::State::CLONED_READ_ONLY:
+        session->set_state("CLONED_READ_ONLY");
+        break;
+    }
+  }
+  callback(/*success=*/true, svc_state);
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::QueryCapabilities(
+    QueryCapabilitiesCallback callback) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  TracingServiceCapabilities caps;
+  caps.set_has_query_capabilities(true);
+  caps.set_has_trace_config_output_path(true);
+  caps.set_has_clone_session(true);
+  caps.add_observable_events(ObservableEvents::TYPE_DATA_SOURCES_INSTANCES);
+  caps.add_observable_events(ObservableEvents::TYPE_ALL_DATA_SOURCES_STARTED);
+  caps.add_observable_events(ObservableEvents::TYPE_CLONE_TRIGGER_HIT);
+  static_assert(
+      ObservableEvents::Type_MAX == ObservableEvents::TYPE_CLONE_TRIGGER_HIT,
+      "");
+  callback(caps);
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::SaveTraceForBugreport(
+    SaveTraceForBugreportCallback consumer_callback) {
+  consumer_callback(false,
+                    "SaveTraceForBugreport is deprecated. Use "
+                    "CloneSession(kBugreportSessionId) instead.");
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::CloneSession(
+    TracingSessionID tsid,
+    CloneSessionArgs args) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  // FlushAndCloneSession will call OnSessionCloned after the async flush.
+  service_->FlushAndCloneSession(this, tsid, args.skip_trace_filter,
+                                 args.for_bugreport);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// TracingServiceImpl::ProducerEndpointImpl implementation
+////////////////////////////////////////////////////////////////////////////////
+
+TracingServiceImpl::ProducerEndpointImpl::ProducerEndpointImpl(
+    ProducerID id,
+    const ClientIdentity& client_identity,
+    TracingServiceImpl* service,
+    base::TaskRunner* task_runner,
+    Producer* producer,
+    const std::string& producer_name,
+    const std::string& sdk_version,
+    bool in_process,
+    bool smb_scraping_enabled)
+    : id_(id),
+      client_identity_(client_identity),
+      service_(service),
+      task_runner_(task_runner),
+      producer_(producer),
+      name_(producer_name),
+      sdk_version_(sdk_version),
+      in_process_(in_process),
+      smb_scraping_enabled_(smb_scraping_enabled),
+      weak_ptr_factory_(this) {}
+
+TracingServiceImpl::ProducerEndpointImpl::~ProducerEndpointImpl() {
+  service_->DisconnectProducer(id_);
+  producer_->OnDisconnect();
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::Disconnect() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  // Disconnection is only supported via destroying the ProducerEndpoint.
+  PERFETTO_FATAL("Not supported");
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::RegisterDataSource(
+    const DataSourceDescriptor& desc) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  service_->RegisterDataSource(id_, desc);
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::UpdateDataSource(
+    const DataSourceDescriptor& desc) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  service_->UpdateDataSource(id_, desc);
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::UnregisterDataSource(
+    const std::string& name) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  service_->UnregisterDataSource(id_, name);
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::RegisterTraceWriter(
+    uint32_t writer_id,
+    uint32_t target_buffer) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  writers_[static_cast<WriterID>(writer_id)] =
+      static_cast<BufferID>(target_buffer);
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::UnregisterTraceWriter(
+    uint32_t writer_id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  writers_.erase(static_cast<WriterID>(writer_id));
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::CommitData(
+    const CommitDataRequest& req_untrusted,
+    CommitDataCallback callback) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  if (metatrace::IsEnabled(metatrace::TAG_TRACE_SERVICE)) {
+    PERFETTO_METATRACE_COUNTER(TAG_TRACE_SERVICE, TRACE_SERVICE_COMMIT_DATA,
+                               EncodeCommitDataRequest(id_, req_untrusted));
+  }
+
+  if (!shared_memory_) {
+    PERFETTO_DLOG(
+        "Attempted to commit data before the shared memory was allocated.");
+    return;
+  }
+  PERFETTO_DCHECK(shmem_abi_.is_valid());
+  for (const auto& entry : req_untrusted.chunks_to_move()) {
+    const uint32_t page_idx = entry.page();
+    if (page_idx >= shmem_abi_.num_pages())
+      continue;  // A buggy or malicious producer.
+
+    SharedMemoryABI::Chunk chunk;
+    bool commit_data_over_ipc = entry.has_data();
+    if (PERFETTO_UNLIKELY(commit_data_over_ipc)) {
+      // Chunk data is passed over the wire. Create a chunk using the serialized
+      // protobuf message.
+      const std::string& data = entry.data();
+      if (data.size() > SharedMemoryABI::Chunk::kMaxSize) {
+        PERFETTO_DFATAL("IPC data commit too large: %zu", data.size());
+        continue;  // A malicious or buggy producer
+      }
+      // |data| is not altered, but we need to const_cast becasue Chunk data
+      // members are non-const.
+      chunk = SharedMemoryABI::MakeChunkFromSerializedData(
+          reinterpret_cast<uint8_t*>(const_cast<char*>(data.data())),
+          static_cast<uint16_t>(entry.data().size()),
+          static_cast<uint8_t>(entry.chunk()));
+    } else
+      chunk = shmem_abi_.TryAcquireChunkForReading(page_idx, entry.chunk());
+    if (!chunk.is_valid()) {
+      PERFETTO_DLOG("Asked to move chunk %d:%d, but it's not complete",
+                    entry.page(), entry.chunk());
+      continue;
+    }
+
+    // TryAcquireChunkForReading() has load-acquire semantics. Once acquired,
+    // the ABI contract expects the producer to not touch the chunk anymore
+    // (until the service marks that as free). This is why all the reads below
+    // are just memory_order_relaxed. Also, the code here assumes that all this
+    // data can be malicious and just gives up if anything is malformed.
+    BufferID buffer_id = static_cast<BufferID>(entry.target_buffer());
+    const SharedMemoryABI::ChunkHeader& chunk_header = *chunk.header();
+    WriterID writer_id = chunk_header.writer_id.load(std::memory_order_relaxed);
+    ChunkID chunk_id = chunk_header.chunk_id.load(std::memory_order_relaxed);
+    auto packets = chunk_header.packets.load(std::memory_order_relaxed);
+    uint16_t num_fragments = packets.count;
+    uint8_t chunk_flags = packets.flags;
+
+    service_->CopyProducerPageIntoLogBuffer(
+        id_, client_identity_, writer_id, chunk_id, buffer_id, num_fragments,
+        chunk_flags,
+        /*chunk_complete=*/true, chunk.payload_begin(), chunk.payload_size());
+
+    if (!commit_data_over_ipc) {
+      // This one has release-store semantics.
+      shmem_abi_.ReleaseChunkAsFree(std::move(chunk));
+    }
+  }  // for(chunks_to_move)
+
+  service_->ApplyChunkPatches(id_, req_untrusted.chunks_to_patch());
+
+  if (req_untrusted.flush_request_id()) {
+    service_->NotifyFlushDoneForProducer(id_, req_untrusted.flush_request_id());
+  }
+
+  // Keep this invocation last. ProducerIPCService::CommitData() relies on this
+  // callback being invoked within the same callstack and not posted. If this
+  // changes, the code there needs to be changed accordingly.
+  if (callback)
+    callback();
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::SetupSharedMemory(
+    std::unique_ptr<SharedMemory> shared_memory,
+    size_t page_size_bytes,
+    bool provided_by_producer) {
+  PERFETTO_DCHECK(!shared_memory_ && !shmem_abi_.is_valid());
+  PERFETTO_DCHECK(page_size_bytes % 1024 == 0);
+
+  shared_memory_ = std::move(shared_memory);
+  shared_buffer_page_size_kb_ = page_size_bytes / 1024;
+  is_shmem_provided_by_producer_ = provided_by_producer;
+
+  shmem_abi_.Initialize(reinterpret_cast<uint8_t*>(shared_memory_->start()),
+                        shared_memory_->size(),
+                        shared_buffer_page_size_kb() * 1024,
+                        SharedMemoryABI::ShmemMode::kDefault);
+  if (in_process_) {
+    inproc_shmem_arbiter_.reset(new SharedMemoryArbiterImpl(
+        shared_memory_->start(), shared_memory_->size(),
+        SharedMemoryABI::ShmemMode::kDefault,
+        shared_buffer_page_size_kb_ * 1024, this, task_runner_));
+    inproc_shmem_arbiter_->SetDirectSMBPatchingSupportedByService();
+  }
+
+  OnTracingSetup();
+  service_->UpdateMemoryGuardrail();
+}
+
+SharedMemory* TracingServiceImpl::ProducerEndpointImpl::shared_memory() const {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  return shared_memory_.get();
+}
+
+size_t TracingServiceImpl::ProducerEndpointImpl::shared_buffer_page_size_kb()
+    const {
+  return shared_buffer_page_size_kb_;
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::ActivateTriggers(
+    const std::vector<std::string>& triggers) {
+  service_->ActivateTriggers(id_, triggers);
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::StopDataSource(
+    DataSourceInstanceID ds_inst_id) {
+  // TODO(primiano): When we'll support tearing down the SMB, at this point we
+  // should send the Producer a TearDownTracing if all its data sources have
+  // been disabled (see b/77532839 and aosp/655179 PS1).
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostTask([weak_this, ds_inst_id] {
+    if (weak_this)
+      weak_this->producer_->StopDataSource(ds_inst_id);
+  });
+}
+
+SharedMemoryArbiter*
+TracingServiceImpl::ProducerEndpointImpl::MaybeSharedMemoryArbiter() {
+  if (!inproc_shmem_arbiter_) {
+    PERFETTO_FATAL(
+        "The in-process SharedMemoryArbiter can only be used when "
+        "CreateProducer has been called with in_process=true and after tracing "
+        "has started.");
+  }
+
+  PERFETTO_DCHECK(in_process_);
+  return inproc_shmem_arbiter_.get();
+}
+
+bool TracingServiceImpl::ProducerEndpointImpl::IsShmemProvidedByProducer()
+    const {
+  return is_shmem_provided_by_producer_;
+}
+
+// Can be called on any thread.
+std::unique_ptr<TraceWriter>
+TracingServiceImpl::ProducerEndpointImpl::CreateTraceWriter(
+    BufferID buf_id,
+    BufferExhaustedPolicy buffer_exhausted_policy) {
+  PERFETTO_DCHECK(MaybeSharedMemoryArbiter());
+  return MaybeSharedMemoryArbiter()->CreateTraceWriter(buf_id,
+                                                       buffer_exhausted_policy);
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::NotifyFlushComplete(
+    FlushRequestID id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DCHECK(MaybeSharedMemoryArbiter());
+  return MaybeSharedMemoryArbiter()->NotifyFlushComplete(id);
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::OnTracingSetup() {
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostTask([weak_this] {
+    if (weak_this)
+      weak_this->producer_->OnTracingSetup();
+  });
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::Flush(
+    FlushRequestID flush_request_id,
+    const std::vector<DataSourceInstanceID>& data_sources,
+    FlushFlags flush_flags) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostTask(
+      [weak_this, flush_request_id, data_sources, flush_flags] {
+        if (weak_this) {
+          weak_this->producer_->Flush(flush_request_id, data_sources.data(),
+                                      data_sources.size(), flush_flags);
+        }
+      });
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::SetupDataSource(
+    DataSourceInstanceID ds_id,
+    const DataSourceConfig& config) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  allowed_target_buffers_.insert(static_cast<BufferID>(config.target_buffer()));
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostTask([weak_this, ds_id, config] {
+    if (weak_this)
+      weak_this->producer_->SetupDataSource(ds_id, std::move(config));
+  });
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::StartDataSource(
+    DataSourceInstanceID ds_id,
+    const DataSourceConfig& config) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostTask([weak_this, ds_id, config] {
+    if (weak_this)
+      weak_this->producer_->StartDataSource(ds_id, std::move(config));
+  });
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::NotifyDataSourceStarted(
+    DataSourceInstanceID data_source_id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  service_->NotifyDataSourceStarted(id_, data_source_id);
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::NotifyDataSourceStopped(
+    DataSourceInstanceID data_source_id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  service_->NotifyDataSourceStopped(id_, data_source_id);
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::OnFreeBuffers(
+    const std::vector<BufferID>& target_buffers) {
+  if (allowed_target_buffers_.empty())
+    return;
+  for (BufferID buffer : target_buffers)
+    allowed_target_buffers_.erase(buffer);
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::ClearIncrementalState(
+    const std::vector<DataSourceInstanceID>& data_sources) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostTask([weak_this, data_sources] {
+    if (weak_this) {
+      base::StringView producer_name(weak_this->name_);
+      weak_this->producer_->ClearIncrementalState(data_sources.data(),
+                                                  data_sources.size());
+    }
+  });
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::Sync(
+    std::function<void()> callback) {
+  task_runner_->PostTask(callback);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// TracingServiceImpl::TracingSession implementation
+////////////////////////////////////////////////////////////////////////////////
+
+TracingServiceImpl::TracingSession::TracingSession(
+    TracingSessionID session_id,
+    ConsumerEndpointImpl* consumer,
+    const TraceConfig& new_config,
+    base::TaskRunner* task_runner)
+    : id(session_id),
+      consumer_maybe_null(consumer),
+      consumer_uid(consumer->uid_),
+      config(new_config),
+      snapshot_periodic_task(task_runner),
+      timed_stop_task(task_runner) {
+  // all_data_sources_flushed is special because we store up to 64 events of
+  // this type. Other events will go through the default case in
+  // SnapshotLifecycleEvent() where they will be given a max history of 1.
+  lifecycle_events.emplace_back(
+      protos::pbzero::TracingServiceEvent::kAllDataSourcesFlushedFieldNumber,
+      64 /* max_size */);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// TracingServiceImpl::RelayEndpointImpl implementation
+////////////////////////////////////////////////////////////////////////////////
+TracingServiceImpl::RelayEndpointImpl::RelayEndpointImpl(
+    RelayClientID relay_client_id,
+    TracingServiceImpl* service)
+    : relay_client_id_(relay_client_id), service_(service) {}
+TracingServiceImpl::RelayEndpointImpl::~RelayEndpointImpl() = default;
+
+void TracingServiceImpl::RelayEndpointImpl::SyncClocks(
+    SyncMode sync_mode,
+    ClockSnapshotVector client_clocks,
+    ClockSnapshotVector host_clocks) {
+  // We keep only the most recent 5 clock sync snapshots.
+  static constexpr size_t kNumSyncClocks = 5;
+  if (synced_clocks_.size() >= kNumSyncClocks)
+    synced_clocks_.pop_front();
+
+  synced_clocks_.emplace_back(sync_mode, std::move(client_clocks),
+                              std::move(host_clocks));
+}
+
+void TracingServiceImpl::RelayEndpointImpl::Disconnect() {
+  service_->DisconnectRelayClient(relay_client_id_);
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/internal/in_process_tracing_backend.cc
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/in_process_tracing_backend.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/paged_memory.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/client_identity.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
+
+// gen_amalgamated expanded: #include "src/tracing/core/in_process_shared_memory.h"
+
+// TODO(primiano): When the in-process backend is used, we should never end up
+// in a situation where the thread where the TracingService and Producer live
+// writes a packet and hence can get into the GetNewChunk() stall.
+// This would happen only if the API client code calls Trace() from one of the
+// callbacks it receives (e.g. OnStart(), OnStop()). We should either cause a
+// hard crash or ignore traces from that thread if that happens, because it
+// will deadlock (the Service will never free up the SMB because won't ever get
+// to run the task).
+
+namespace perfetto {
+namespace internal {
+
+// static
+TracingBackend* InProcessTracingBackend::GetInstance() {
+  static auto* instance = new InProcessTracingBackend();
+  return instance;
+}
+
+InProcessTracingBackend::InProcessTracingBackend() = default;
+InProcessTracingBackend::~InProcessTracingBackend() = default;
+
+std::unique_ptr<ProducerEndpoint> InProcessTracingBackend::ConnectProducer(
+    const ConnectProducerArgs& args) {
+  PERFETTO_DCHECK(args.task_runner->RunsTasksOnCurrentThread());
+  return GetOrCreateService(args.task_runner)
+      ->ConnectProducer(args.producer, ClientIdentity(/*uid=*/0, /*pid=*/0),
+                        args.producer_name, args.shmem_size_hint_bytes,
+                        /*in_process=*/true,
+                        TracingService::ProducerSMBScrapingMode::kEnabled,
+                        args.shmem_page_size_hint_bytes);
+}
+
+std::unique_ptr<ConsumerEndpoint> InProcessTracingBackend::ConnectConsumer(
+    const ConnectConsumerArgs& args) {
+  return GetOrCreateService(args.task_runner)
+      ->ConnectConsumer(args.consumer, /*uid=*/0);
+}
+
+TracingService* InProcessTracingBackend::GetOrCreateService(
+    base::TaskRunner* task_runner) {
+  if (!service_) {
+    std::unique_ptr<InProcessSharedMemory::Factory> shm(
+        new InProcessSharedMemory::Factory());
+    service_ = TracingService::CreateInstance(std::move(shm), task_runner);
+    service_->SetSMBScrapingEnabled(true);
+  }
+  return service_.get();
+}
+
+}  // namespace internal
+}  // namespace perfetto
+// gen_amalgamated begin source: gen/protos/perfetto/ipc/consumer_port.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/ipc/consumer_port.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/trace_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/system_info/system_info.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/track_event/track_event_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/sys_stats/sys_stats_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/perf_event_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/perf_events.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/java_hprof_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/heapprofd_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/process_stats/process_stats_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/statsd_tracing_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/atom_ids.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/power/android_power_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/inode_file/inode_file_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/gpu/vulkan_memory_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/gpu/gpu_counter_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/ftrace/ftrace_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/etw/etw_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/chrome/v8_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_transactions_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_layers_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/protolog_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/protolog_common.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/pixel_modem_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/packages_list_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/network_trace_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_sdk_sysprop_guard_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_system_property_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_polled_state_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_log_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_input_event_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_game_intervention_list_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/trace_stats.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_capabilities.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/observable_events.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_state.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/track_event_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/gpu_counter_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/ftrace_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/observable_events.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+CloneSessionResponse::CloneSessionResponse() = default;
+CloneSessionResponse::~CloneSessionResponse() = default;
+CloneSessionResponse::CloneSessionResponse(const CloneSessionResponse&) = default;
+CloneSessionResponse& CloneSessionResponse::operator=(const CloneSessionResponse&) = default;
+CloneSessionResponse::CloneSessionResponse(CloneSessionResponse&&) noexcept = default;
+CloneSessionResponse& CloneSessionResponse::operator=(CloneSessionResponse&&) = default;
+
+bool CloneSessionResponse::operator==(const CloneSessionResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(success_, other.success_)
+   && ::protozero::internal::gen_helpers::EqualsField(error_, other.error_)
+   && ::protozero::internal::gen_helpers::EqualsField(uuid_msb_, other.uuid_msb_)
+   && ::protozero::internal::gen_helpers::EqualsField(uuid_lsb_, other.uuid_lsb_);
+}
+
+bool CloneSessionResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* success */:
+        field.get(&success_);
+        break;
+      case 2 /* error */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &error_);
+        break;
+      case 3 /* uuid_msb */:
+        field.get(&uuid_msb_);
+        break;
+      case 4 /* uuid_lsb */:
+        field.get(&uuid_lsb_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string CloneSessionResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> CloneSessionResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void CloneSessionResponse::Serialize(::protozero::Message* msg) const {
+  // Field 1: success
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, success_, msg);
+  }
+
+  // Field 2: error
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, error_, msg);
+  }
+
+  // Field 3: uuid_msb
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, uuid_msb_, msg);
+  }
+
+  // Field 4: uuid_lsb
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, uuid_lsb_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+CloneSessionRequest::CloneSessionRequest() = default;
+CloneSessionRequest::~CloneSessionRequest() = default;
+CloneSessionRequest::CloneSessionRequest(const CloneSessionRequest&) = default;
+CloneSessionRequest& CloneSessionRequest::operator=(const CloneSessionRequest&) = default;
+CloneSessionRequest::CloneSessionRequest(CloneSessionRequest&&) noexcept = default;
+CloneSessionRequest& CloneSessionRequest::operator=(CloneSessionRequest&&) = default;
+
+bool CloneSessionRequest::operator==(const CloneSessionRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(session_id_, other.session_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(skip_trace_filter_, other.skip_trace_filter_)
+   && ::protozero::internal::gen_helpers::EqualsField(for_bugreport_, other.for_bugreport_);
+}
+
+bool CloneSessionRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* session_id */:
+        field.get(&session_id_);
+        break;
+      case 2 /* skip_trace_filter */:
+        field.get(&skip_trace_filter_);
+        break;
+      case 3 /* for_bugreport */:
+        field.get(&for_bugreport_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string CloneSessionRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> CloneSessionRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void CloneSessionRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: session_id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, session_id_, msg);
+  }
+
+  // Field 2: skip_trace_filter
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, skip_trace_filter_, msg);
+  }
+
+  // Field 3: for_bugreport
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, for_bugreport_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+SaveTraceForBugreportResponse::SaveTraceForBugreportResponse() = default;
+SaveTraceForBugreportResponse::~SaveTraceForBugreportResponse() = default;
+SaveTraceForBugreportResponse::SaveTraceForBugreportResponse(const SaveTraceForBugreportResponse&) = default;
+SaveTraceForBugreportResponse& SaveTraceForBugreportResponse::operator=(const SaveTraceForBugreportResponse&) = default;
+SaveTraceForBugreportResponse::SaveTraceForBugreportResponse(SaveTraceForBugreportResponse&&) noexcept = default;
+SaveTraceForBugreportResponse& SaveTraceForBugreportResponse::operator=(SaveTraceForBugreportResponse&&) = default;
+
+bool SaveTraceForBugreportResponse::operator==(const SaveTraceForBugreportResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(success_, other.success_)
+   && ::protozero::internal::gen_helpers::EqualsField(msg_, other.msg_);
+}
+
+bool SaveTraceForBugreportResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* success */:
+        field.get(&success_);
+        break;
+      case 2 /* msg */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &msg_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string SaveTraceForBugreportResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> SaveTraceForBugreportResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void SaveTraceForBugreportResponse::Serialize(::protozero::Message* msg) const {
+  // Field 1: success
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, success_, msg);
+  }
+
+  // Field 2: msg
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, msg_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+SaveTraceForBugreportRequest::SaveTraceForBugreportRequest() = default;
+SaveTraceForBugreportRequest::~SaveTraceForBugreportRequest() = default;
+SaveTraceForBugreportRequest::SaveTraceForBugreportRequest(const SaveTraceForBugreportRequest&) = default;
+SaveTraceForBugreportRequest& SaveTraceForBugreportRequest::operator=(const SaveTraceForBugreportRequest&) = default;
+SaveTraceForBugreportRequest::SaveTraceForBugreportRequest(SaveTraceForBugreportRequest&&) noexcept = default;
+SaveTraceForBugreportRequest& SaveTraceForBugreportRequest::operator=(SaveTraceForBugreportRequest&&) = default;
+
+bool SaveTraceForBugreportRequest::operator==(const SaveTraceForBugreportRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool SaveTraceForBugreportRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string SaveTraceForBugreportRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> SaveTraceForBugreportRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void SaveTraceForBugreportRequest::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+QueryCapabilitiesResponse::QueryCapabilitiesResponse() = default;
+QueryCapabilitiesResponse::~QueryCapabilitiesResponse() = default;
+QueryCapabilitiesResponse::QueryCapabilitiesResponse(const QueryCapabilitiesResponse&) = default;
+QueryCapabilitiesResponse& QueryCapabilitiesResponse::operator=(const QueryCapabilitiesResponse&) = default;
+QueryCapabilitiesResponse::QueryCapabilitiesResponse(QueryCapabilitiesResponse&&) noexcept = default;
+QueryCapabilitiesResponse& QueryCapabilitiesResponse::operator=(QueryCapabilitiesResponse&&) = default;
+
+bool QueryCapabilitiesResponse::operator==(const QueryCapabilitiesResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(capabilities_, other.capabilities_);
+}
+
+bool QueryCapabilitiesResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* capabilities */:
+        (*capabilities_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string QueryCapabilitiesResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> QueryCapabilitiesResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void QueryCapabilitiesResponse::Serialize(::protozero::Message* msg) const {
+  // Field 1: capabilities
+  if (_has_field_[1]) {
+    (*capabilities_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+QueryCapabilitiesRequest::QueryCapabilitiesRequest() = default;
+QueryCapabilitiesRequest::~QueryCapabilitiesRequest() = default;
+QueryCapabilitiesRequest::QueryCapabilitiesRequest(const QueryCapabilitiesRequest&) = default;
+QueryCapabilitiesRequest& QueryCapabilitiesRequest::operator=(const QueryCapabilitiesRequest&) = default;
+QueryCapabilitiesRequest::QueryCapabilitiesRequest(QueryCapabilitiesRequest&&) noexcept = default;
+QueryCapabilitiesRequest& QueryCapabilitiesRequest::operator=(QueryCapabilitiesRequest&&) = default;
+
+bool QueryCapabilitiesRequest::operator==(const QueryCapabilitiesRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool QueryCapabilitiesRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string QueryCapabilitiesRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> QueryCapabilitiesRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void QueryCapabilitiesRequest::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+QueryServiceStateResponse::QueryServiceStateResponse() = default;
+QueryServiceStateResponse::~QueryServiceStateResponse() = default;
+QueryServiceStateResponse::QueryServiceStateResponse(const QueryServiceStateResponse&) = default;
+QueryServiceStateResponse& QueryServiceStateResponse::operator=(const QueryServiceStateResponse&) = default;
+QueryServiceStateResponse::QueryServiceStateResponse(QueryServiceStateResponse&&) noexcept = default;
+QueryServiceStateResponse& QueryServiceStateResponse::operator=(QueryServiceStateResponse&&) = default;
+
+bool QueryServiceStateResponse::operator==(const QueryServiceStateResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(service_state_, other.service_state_);
+}
+
+bool QueryServiceStateResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* service_state */:
+        (*service_state_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string QueryServiceStateResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> QueryServiceStateResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void QueryServiceStateResponse::Serialize(::protozero::Message* msg) const {
+  // Field 1: service_state
+  if (_has_field_[1]) {
+    (*service_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+QueryServiceStateRequest::QueryServiceStateRequest() = default;
+QueryServiceStateRequest::~QueryServiceStateRequest() = default;
+QueryServiceStateRequest::QueryServiceStateRequest(const QueryServiceStateRequest&) = default;
+QueryServiceStateRequest& QueryServiceStateRequest::operator=(const QueryServiceStateRequest&) = default;
+QueryServiceStateRequest::QueryServiceStateRequest(QueryServiceStateRequest&&) noexcept = default;
+QueryServiceStateRequest& QueryServiceStateRequest::operator=(QueryServiceStateRequest&&) = default;
+
+bool QueryServiceStateRequest::operator==(const QueryServiceStateRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(sessions_only_, other.sessions_only_);
+}
+
+bool QueryServiceStateRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* sessions_only */:
+        field.get(&sessions_only_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string QueryServiceStateRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> QueryServiceStateRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void QueryServiceStateRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: sessions_only
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, sessions_only_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+ObserveEventsResponse::ObserveEventsResponse() = default;
+ObserveEventsResponse::~ObserveEventsResponse() = default;
+ObserveEventsResponse::ObserveEventsResponse(const ObserveEventsResponse&) = default;
+ObserveEventsResponse& ObserveEventsResponse::operator=(const ObserveEventsResponse&) = default;
+ObserveEventsResponse::ObserveEventsResponse(ObserveEventsResponse&&) noexcept = default;
+ObserveEventsResponse& ObserveEventsResponse::operator=(ObserveEventsResponse&&) = default;
+
+bool ObserveEventsResponse::operator==(const ObserveEventsResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(events_, other.events_);
+}
+
+bool ObserveEventsResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* events */:
+        (*events_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ObserveEventsResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ObserveEventsResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ObserveEventsResponse::Serialize(::protozero::Message* msg) const {
+  // Field 1: events
+  if (_has_field_[1]) {
+    (*events_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+ObserveEventsRequest::ObserveEventsRequest() = default;
+ObserveEventsRequest::~ObserveEventsRequest() = default;
+ObserveEventsRequest::ObserveEventsRequest(const ObserveEventsRequest&) = default;
+ObserveEventsRequest& ObserveEventsRequest::operator=(const ObserveEventsRequest&) = default;
+ObserveEventsRequest::ObserveEventsRequest(ObserveEventsRequest&&) noexcept = default;
+ObserveEventsRequest& ObserveEventsRequest::operator=(ObserveEventsRequest&&) = default;
+
+bool ObserveEventsRequest::operator==(const ObserveEventsRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(events_to_observe_, other.events_to_observe_);
+}
+
+bool ObserveEventsRequest::ParseFromArray(const void* raw, size_t size) {
+  events_to_observe_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* events_to_observe */:
+        events_to_observe_.emplace_back();
+        field.get(&events_to_observe_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ObserveEventsRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ObserveEventsRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ObserveEventsRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: events_to_observe
+  for (auto& it : events_to_observe_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+GetTraceStatsResponse::GetTraceStatsResponse() = default;
+GetTraceStatsResponse::~GetTraceStatsResponse() = default;
+GetTraceStatsResponse::GetTraceStatsResponse(const GetTraceStatsResponse&) = default;
+GetTraceStatsResponse& GetTraceStatsResponse::operator=(const GetTraceStatsResponse&) = default;
+GetTraceStatsResponse::GetTraceStatsResponse(GetTraceStatsResponse&&) noexcept = default;
+GetTraceStatsResponse& GetTraceStatsResponse::operator=(GetTraceStatsResponse&&) = default;
+
+bool GetTraceStatsResponse::operator==(const GetTraceStatsResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(trace_stats_, other.trace_stats_);
+}
+
+bool GetTraceStatsResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* trace_stats */:
+        (*trace_stats_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string GetTraceStatsResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GetTraceStatsResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void GetTraceStatsResponse::Serialize(::protozero::Message* msg) const {
+  // Field 1: trace_stats
+  if (_has_field_[1]) {
+    (*trace_stats_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+GetTraceStatsRequest::GetTraceStatsRequest() = default;
+GetTraceStatsRequest::~GetTraceStatsRequest() = default;
+GetTraceStatsRequest::GetTraceStatsRequest(const GetTraceStatsRequest&) = default;
+GetTraceStatsRequest& GetTraceStatsRequest::operator=(const GetTraceStatsRequest&) = default;
+GetTraceStatsRequest::GetTraceStatsRequest(GetTraceStatsRequest&&) noexcept = default;
+GetTraceStatsRequest& GetTraceStatsRequest::operator=(GetTraceStatsRequest&&) = default;
+
+bool GetTraceStatsRequest::operator==(const GetTraceStatsRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool GetTraceStatsRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string GetTraceStatsRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GetTraceStatsRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void GetTraceStatsRequest::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+AttachResponse::AttachResponse() = default;
+AttachResponse::~AttachResponse() = default;
+AttachResponse::AttachResponse(const AttachResponse&) = default;
+AttachResponse& AttachResponse::operator=(const AttachResponse&) = default;
+AttachResponse::AttachResponse(AttachResponse&&) noexcept = default;
+AttachResponse& AttachResponse::operator=(AttachResponse&&) = default;
+
+bool AttachResponse::operator==(const AttachResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(trace_config_, other.trace_config_);
+}
+
+bool AttachResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* trace_config */:
+        (*trace_config_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string AttachResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> AttachResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void AttachResponse::Serialize(::protozero::Message* msg) const {
+  // Field 1: trace_config
+  if (_has_field_[1]) {
+    (*trace_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+AttachRequest::AttachRequest() = default;
+AttachRequest::~AttachRequest() = default;
+AttachRequest::AttachRequest(const AttachRequest&) = default;
+AttachRequest& AttachRequest::operator=(const AttachRequest&) = default;
+AttachRequest::AttachRequest(AttachRequest&&) noexcept = default;
+AttachRequest& AttachRequest::operator=(AttachRequest&&) = default;
+
+bool AttachRequest::operator==(const AttachRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(key_, other.key_);
+}
+
+bool AttachRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* key */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &key_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string AttachRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> AttachRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void AttachRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: key
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, key_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+DetachResponse::DetachResponse() = default;
+DetachResponse::~DetachResponse() = default;
+DetachResponse::DetachResponse(const DetachResponse&) = default;
+DetachResponse& DetachResponse::operator=(const DetachResponse&) = default;
+DetachResponse::DetachResponse(DetachResponse&&) noexcept = default;
+DetachResponse& DetachResponse::operator=(DetachResponse&&) = default;
+
+bool DetachResponse::operator==(const DetachResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool DetachResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string DetachResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> DetachResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void DetachResponse::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+DetachRequest::DetachRequest() = default;
+DetachRequest::~DetachRequest() = default;
+DetachRequest::DetachRequest(const DetachRequest&) = default;
+DetachRequest& DetachRequest::operator=(const DetachRequest&) = default;
+DetachRequest::DetachRequest(DetachRequest&&) noexcept = default;
+DetachRequest& DetachRequest::operator=(DetachRequest&&) = default;
+
+bool DetachRequest::operator==(const DetachRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(key_, other.key_);
+}
+
+bool DetachRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* key */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &key_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string DetachRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> DetachRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void DetachRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: key
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, key_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+FlushResponse::FlushResponse() = default;
+FlushResponse::~FlushResponse() = default;
+FlushResponse::FlushResponse(const FlushResponse&) = default;
+FlushResponse& FlushResponse::operator=(const FlushResponse&) = default;
+FlushResponse::FlushResponse(FlushResponse&&) noexcept = default;
+FlushResponse& FlushResponse::operator=(FlushResponse&&) = default;
+
+bool FlushResponse::operator==(const FlushResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool FlushResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string FlushResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FlushResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FlushResponse::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+FlushRequest::FlushRequest() = default;
+FlushRequest::~FlushRequest() = default;
+FlushRequest::FlushRequest(const FlushRequest&) = default;
+FlushRequest& FlushRequest::operator=(const FlushRequest&) = default;
+FlushRequest::FlushRequest(FlushRequest&&) noexcept = default;
+FlushRequest& FlushRequest::operator=(FlushRequest&&) = default;
+
+bool FlushRequest::operator==(const FlushRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(timeout_ms_, other.timeout_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(flags_, other.flags_);
+}
+
+bool FlushRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* timeout_ms */:
+        field.get(&timeout_ms_);
+        break;
+      case 2 /* flags */:
+        field.get(&flags_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string FlushRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FlushRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FlushRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: timeout_ms
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, timeout_ms_, msg);
+  }
+
+  // Field 2: flags
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, flags_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+FreeBuffersResponse::FreeBuffersResponse() = default;
+FreeBuffersResponse::~FreeBuffersResponse() = default;
+FreeBuffersResponse::FreeBuffersResponse(const FreeBuffersResponse&) = default;
+FreeBuffersResponse& FreeBuffersResponse::operator=(const FreeBuffersResponse&) = default;
+FreeBuffersResponse::FreeBuffersResponse(FreeBuffersResponse&&) noexcept = default;
+FreeBuffersResponse& FreeBuffersResponse::operator=(FreeBuffersResponse&&) = default;
+
+bool FreeBuffersResponse::operator==(const FreeBuffersResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool FreeBuffersResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string FreeBuffersResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FreeBuffersResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FreeBuffersResponse::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+FreeBuffersRequest::FreeBuffersRequest() = default;
+FreeBuffersRequest::~FreeBuffersRequest() = default;
+FreeBuffersRequest::FreeBuffersRequest(const FreeBuffersRequest&) = default;
+FreeBuffersRequest& FreeBuffersRequest::operator=(const FreeBuffersRequest&) = default;
+FreeBuffersRequest::FreeBuffersRequest(FreeBuffersRequest&&) noexcept = default;
+FreeBuffersRequest& FreeBuffersRequest::operator=(FreeBuffersRequest&&) = default;
+
+bool FreeBuffersRequest::operator==(const FreeBuffersRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(buffer_ids_, other.buffer_ids_);
+}
+
+bool FreeBuffersRequest::ParseFromArray(const void* raw, size_t size) {
+  buffer_ids_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* buffer_ids */:
+        buffer_ids_.emplace_back();
+        field.get(&buffer_ids_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string FreeBuffersRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FreeBuffersRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FreeBuffersRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: buffer_ids
+  for (auto& it : buffer_ids_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+ReadBuffersResponse::ReadBuffersResponse() = default;
+ReadBuffersResponse::~ReadBuffersResponse() = default;
+ReadBuffersResponse::ReadBuffersResponse(const ReadBuffersResponse&) = default;
+ReadBuffersResponse& ReadBuffersResponse::operator=(const ReadBuffersResponse&) = default;
+ReadBuffersResponse::ReadBuffersResponse(ReadBuffersResponse&&) noexcept = default;
+ReadBuffersResponse& ReadBuffersResponse::operator=(ReadBuffersResponse&&) = default;
+
+bool ReadBuffersResponse::operator==(const ReadBuffersResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(slices_, other.slices_);
+}
+
+int ReadBuffersResponse::slices_size() const { return static_cast<int>(slices_.size()); }
+void ReadBuffersResponse::clear_slices() { slices_.clear(); }
+ReadBuffersResponse_Slice* ReadBuffersResponse::add_slices() { slices_.emplace_back(); return &slices_.back(); }
+bool ReadBuffersResponse::ParseFromArray(const void* raw, size_t size) {
+  slices_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 2 /* slices */:
+        slices_.emplace_back();
+        slices_.back().ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ReadBuffersResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ReadBuffersResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ReadBuffersResponse::Serialize(::protozero::Message* msg) const {
+  // Field 2: slices
+  for (auto& it : slices_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+ReadBuffersResponse_Slice::ReadBuffersResponse_Slice() = default;
+ReadBuffersResponse_Slice::~ReadBuffersResponse_Slice() = default;
+ReadBuffersResponse_Slice::ReadBuffersResponse_Slice(const ReadBuffersResponse_Slice&) = default;
+ReadBuffersResponse_Slice& ReadBuffersResponse_Slice::operator=(const ReadBuffersResponse_Slice&) = default;
+ReadBuffersResponse_Slice::ReadBuffersResponse_Slice(ReadBuffersResponse_Slice&&) noexcept = default;
+ReadBuffersResponse_Slice& ReadBuffersResponse_Slice::operator=(ReadBuffersResponse_Slice&&) = default;
+
+bool ReadBuffersResponse_Slice::operator==(const ReadBuffersResponse_Slice& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(data_, other.data_)
+   && ::protozero::internal::gen_helpers::EqualsField(last_slice_for_packet_, other.last_slice_for_packet_);
+}
+
+bool ReadBuffersResponse_Slice::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* data */:
+        field.get(&data_);
+        break;
+      case 2 /* last_slice_for_packet */:
+        field.get(&last_slice_for_packet_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ReadBuffersResponse_Slice::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ReadBuffersResponse_Slice::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ReadBuffersResponse_Slice::Serialize(::protozero::Message* msg) const {
+  // Field 1: data
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, data_, msg);
+  }
+
+  // Field 2: last_slice_for_packet
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, last_slice_for_packet_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+ReadBuffersRequest::ReadBuffersRequest() = default;
+ReadBuffersRequest::~ReadBuffersRequest() = default;
+ReadBuffersRequest::ReadBuffersRequest(const ReadBuffersRequest&) = default;
+ReadBuffersRequest& ReadBuffersRequest::operator=(const ReadBuffersRequest&) = default;
+ReadBuffersRequest::ReadBuffersRequest(ReadBuffersRequest&&) noexcept = default;
+ReadBuffersRequest& ReadBuffersRequest::operator=(ReadBuffersRequest&&) = default;
+
+bool ReadBuffersRequest::operator==(const ReadBuffersRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool ReadBuffersRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ReadBuffersRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ReadBuffersRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ReadBuffersRequest::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+DisableTracingResponse::DisableTracingResponse() = default;
+DisableTracingResponse::~DisableTracingResponse() = default;
+DisableTracingResponse::DisableTracingResponse(const DisableTracingResponse&) = default;
+DisableTracingResponse& DisableTracingResponse::operator=(const DisableTracingResponse&) = default;
+DisableTracingResponse::DisableTracingResponse(DisableTracingResponse&&) noexcept = default;
+DisableTracingResponse& DisableTracingResponse::operator=(DisableTracingResponse&&) = default;
+
+bool DisableTracingResponse::operator==(const DisableTracingResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool DisableTracingResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string DisableTracingResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> DisableTracingResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void DisableTracingResponse::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+DisableTracingRequest::DisableTracingRequest() = default;
+DisableTracingRequest::~DisableTracingRequest() = default;
+DisableTracingRequest::DisableTracingRequest(const DisableTracingRequest&) = default;
+DisableTracingRequest& DisableTracingRequest::operator=(const DisableTracingRequest&) = default;
+DisableTracingRequest::DisableTracingRequest(DisableTracingRequest&&) noexcept = default;
+DisableTracingRequest& DisableTracingRequest::operator=(DisableTracingRequest&&) = default;
+
+bool DisableTracingRequest::operator==(const DisableTracingRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool DisableTracingRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string DisableTracingRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> DisableTracingRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void DisableTracingRequest::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+ChangeTraceConfigResponse::ChangeTraceConfigResponse() = default;
+ChangeTraceConfigResponse::~ChangeTraceConfigResponse() = default;
+ChangeTraceConfigResponse::ChangeTraceConfigResponse(const ChangeTraceConfigResponse&) = default;
+ChangeTraceConfigResponse& ChangeTraceConfigResponse::operator=(const ChangeTraceConfigResponse&) = default;
+ChangeTraceConfigResponse::ChangeTraceConfigResponse(ChangeTraceConfigResponse&&) noexcept = default;
+ChangeTraceConfigResponse& ChangeTraceConfigResponse::operator=(ChangeTraceConfigResponse&&) = default;
+
+bool ChangeTraceConfigResponse::operator==(const ChangeTraceConfigResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool ChangeTraceConfigResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChangeTraceConfigResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChangeTraceConfigResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChangeTraceConfigResponse::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+ChangeTraceConfigRequest::ChangeTraceConfigRequest() = default;
+ChangeTraceConfigRequest::~ChangeTraceConfigRequest() = default;
+ChangeTraceConfigRequest::ChangeTraceConfigRequest(const ChangeTraceConfigRequest&) = default;
+ChangeTraceConfigRequest& ChangeTraceConfigRequest::operator=(const ChangeTraceConfigRequest&) = default;
+ChangeTraceConfigRequest::ChangeTraceConfigRequest(ChangeTraceConfigRequest&&) noexcept = default;
+ChangeTraceConfigRequest& ChangeTraceConfigRequest::operator=(ChangeTraceConfigRequest&&) = default;
+
+bool ChangeTraceConfigRequest::operator==(const ChangeTraceConfigRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(trace_config_, other.trace_config_);
+}
+
+bool ChangeTraceConfigRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* trace_config */:
+        (*trace_config_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChangeTraceConfigRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChangeTraceConfigRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChangeTraceConfigRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: trace_config
+  if (_has_field_[1]) {
+    (*trace_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+StartTracingResponse::StartTracingResponse() = default;
+StartTracingResponse::~StartTracingResponse() = default;
+StartTracingResponse::StartTracingResponse(const StartTracingResponse&) = default;
+StartTracingResponse& StartTracingResponse::operator=(const StartTracingResponse&) = default;
+StartTracingResponse::StartTracingResponse(StartTracingResponse&&) noexcept = default;
+StartTracingResponse& StartTracingResponse::operator=(StartTracingResponse&&) = default;
+
+bool StartTracingResponse::operator==(const StartTracingResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool StartTracingResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string StartTracingResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> StartTracingResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void StartTracingResponse::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+StartTracingRequest::StartTracingRequest() = default;
+StartTracingRequest::~StartTracingRequest() = default;
+StartTracingRequest::StartTracingRequest(const StartTracingRequest&) = default;
+StartTracingRequest& StartTracingRequest::operator=(const StartTracingRequest&) = default;
+StartTracingRequest::StartTracingRequest(StartTracingRequest&&) noexcept = default;
+StartTracingRequest& StartTracingRequest::operator=(StartTracingRequest&&) = default;
+
+bool StartTracingRequest::operator==(const StartTracingRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool StartTracingRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string StartTracingRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> StartTracingRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void StartTracingRequest::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+EnableTracingResponse::EnableTracingResponse() = default;
+EnableTracingResponse::~EnableTracingResponse() = default;
+EnableTracingResponse::EnableTracingResponse(const EnableTracingResponse&) = default;
+EnableTracingResponse& EnableTracingResponse::operator=(const EnableTracingResponse&) = default;
+EnableTracingResponse::EnableTracingResponse(EnableTracingResponse&&) noexcept = default;
+EnableTracingResponse& EnableTracingResponse::operator=(EnableTracingResponse&&) = default;
+
+bool EnableTracingResponse::operator==(const EnableTracingResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(disabled_, other.disabled_)
+   && ::protozero::internal::gen_helpers::EqualsField(error_, other.error_);
+}
+
+bool EnableTracingResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* disabled */:
+        field.get(&disabled_);
+        break;
+      case 3 /* error */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &error_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string EnableTracingResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> EnableTracingResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void EnableTracingResponse::Serialize(::protozero::Message* msg) const {
+  // Field 1: disabled
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, disabled_, msg);
+  }
+
+  // Field 3: error
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeString(3, error_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+EnableTracingRequest::EnableTracingRequest() = default;
+EnableTracingRequest::~EnableTracingRequest() = default;
+EnableTracingRequest::EnableTracingRequest(const EnableTracingRequest&) = default;
+EnableTracingRequest& EnableTracingRequest::operator=(const EnableTracingRequest&) = default;
+EnableTracingRequest::EnableTracingRequest(EnableTracingRequest&&) noexcept = default;
+EnableTracingRequest& EnableTracingRequest::operator=(EnableTracingRequest&&) = default;
+
+bool EnableTracingRequest::operator==(const EnableTracingRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(trace_config_, other.trace_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(attach_notification_only_, other.attach_notification_only_);
+}
+
+bool EnableTracingRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* trace_config */:
+        (*trace_config_).ParseFromArray(field.data(), field.size());
+        break;
+      case 2 /* attach_notification_only */:
+        field.get(&attach_notification_only_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string EnableTracingRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> EnableTracingRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void EnableTracingRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: trace_config
+  if (_has_field_[1]) {
+    (*trace_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  // Field 2: attach_notification_only
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, attach_notification_only_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/ipc/producer_port.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/ipc/producer_port.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/track_event_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/gpu_counter_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/ftrace_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/system_info/system_info.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/track_event/track_event_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/sys_stats/sys_stats_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/perf_event_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/perf_events.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/java_hprof_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/heapprofd_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/process_stats/process_stats_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/statsd_tracing_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/atom_ids.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/power/android_power_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/inode_file/inode_file_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/gpu/vulkan_memory_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/gpu/gpu_counter_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/ftrace/ftrace_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/etw/etw_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/chrome/v8_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_transactions_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_layers_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/protolog_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/protolog_common.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/pixel_modem_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/packages_list_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/network_trace_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_sdk_sysprop_guard_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_system_property_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_polled_state_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_log_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_input_event_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_game_intervention_list_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/commit_data_request.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+SyncResponse::SyncResponse() = default;
+SyncResponse::~SyncResponse() = default;
+SyncResponse::SyncResponse(const SyncResponse&) = default;
+SyncResponse& SyncResponse::operator=(const SyncResponse&) = default;
+SyncResponse::SyncResponse(SyncResponse&&) noexcept = default;
+SyncResponse& SyncResponse::operator=(SyncResponse&&) = default;
+
+bool SyncResponse::operator==(const SyncResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool SyncResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string SyncResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> SyncResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void SyncResponse::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+SyncRequest::SyncRequest() = default;
+SyncRequest::~SyncRequest() = default;
+SyncRequest::SyncRequest(const SyncRequest&) = default;
+SyncRequest& SyncRequest::operator=(const SyncRequest&) = default;
+SyncRequest::SyncRequest(SyncRequest&&) noexcept = default;
+SyncRequest& SyncRequest::operator=(SyncRequest&&) = default;
+
+bool SyncRequest::operator==(const SyncRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool SyncRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string SyncRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> SyncRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void SyncRequest::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+GetAsyncCommandResponse::GetAsyncCommandResponse() = default;
+GetAsyncCommandResponse::~GetAsyncCommandResponse() = default;
+GetAsyncCommandResponse::GetAsyncCommandResponse(const GetAsyncCommandResponse&) = default;
+GetAsyncCommandResponse& GetAsyncCommandResponse::operator=(const GetAsyncCommandResponse&) = default;
+GetAsyncCommandResponse::GetAsyncCommandResponse(GetAsyncCommandResponse&&) noexcept = default;
+GetAsyncCommandResponse& GetAsyncCommandResponse::operator=(GetAsyncCommandResponse&&) = default;
+
+bool GetAsyncCommandResponse::operator==(const GetAsyncCommandResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(setup_tracing_, other.setup_tracing_)
+   && ::protozero::internal::gen_helpers::EqualsField(setup_data_source_, other.setup_data_source_)
+   && ::protozero::internal::gen_helpers::EqualsField(start_data_source_, other.start_data_source_)
+   && ::protozero::internal::gen_helpers::EqualsField(stop_data_source_, other.stop_data_source_)
+   && ::protozero::internal::gen_helpers::EqualsField(flush_, other.flush_)
+   && ::protozero::internal::gen_helpers::EqualsField(clear_incremental_state_, other.clear_incremental_state_);
+}
+
+bool GetAsyncCommandResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 3 /* setup_tracing */:
+        (*setup_tracing_).ParseFromArray(field.data(), field.size());
+        break;
+      case 6 /* setup_data_source */:
+        (*setup_data_source_).ParseFromArray(field.data(), field.size());
+        break;
+      case 1 /* start_data_source */:
+        (*start_data_source_).ParseFromArray(field.data(), field.size());
+        break;
+      case 2 /* stop_data_source */:
+        (*stop_data_source_).ParseFromArray(field.data(), field.size());
+        break;
+      case 5 /* flush */:
+        (*flush_).ParseFromArray(field.data(), field.size());
+        break;
+      case 7 /* clear_incremental_state */:
+        (*clear_incremental_state_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string GetAsyncCommandResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GetAsyncCommandResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void GetAsyncCommandResponse::Serialize(::protozero::Message* msg) const {
+  // Field 3: setup_tracing
+  if (_has_field_[3]) {
+    (*setup_tracing_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
+  }
+
+  // Field 6: setup_data_source
+  if (_has_field_[6]) {
+    (*setup_data_source_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
+  }
+
+  // Field 1: start_data_source
+  if (_has_field_[1]) {
+    (*start_data_source_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  // Field 2: stop_data_source
+  if (_has_field_[2]) {
+    (*stop_data_source_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  // Field 5: flush
+  if (_has_field_[5]) {
+    (*flush_).Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
+  }
+
+  // Field 7: clear_incremental_state
+  if (_has_field_[7]) {
+    (*clear_incremental_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(7));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+GetAsyncCommandResponse_ClearIncrementalState::GetAsyncCommandResponse_ClearIncrementalState() = default;
+GetAsyncCommandResponse_ClearIncrementalState::~GetAsyncCommandResponse_ClearIncrementalState() = default;
+GetAsyncCommandResponse_ClearIncrementalState::GetAsyncCommandResponse_ClearIncrementalState(const GetAsyncCommandResponse_ClearIncrementalState&) = default;
+GetAsyncCommandResponse_ClearIncrementalState& GetAsyncCommandResponse_ClearIncrementalState::operator=(const GetAsyncCommandResponse_ClearIncrementalState&) = default;
+GetAsyncCommandResponse_ClearIncrementalState::GetAsyncCommandResponse_ClearIncrementalState(GetAsyncCommandResponse_ClearIncrementalState&&) noexcept = default;
+GetAsyncCommandResponse_ClearIncrementalState& GetAsyncCommandResponse_ClearIncrementalState::operator=(GetAsyncCommandResponse_ClearIncrementalState&&) = default;
+
+bool GetAsyncCommandResponse_ClearIncrementalState::operator==(const GetAsyncCommandResponse_ClearIncrementalState& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(data_source_ids_, other.data_source_ids_);
+}
+
+bool GetAsyncCommandResponse_ClearIncrementalState::ParseFromArray(const void* raw, size_t size) {
+  data_source_ids_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* data_source_ids */:
+        data_source_ids_.emplace_back();
+        field.get(&data_source_ids_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string GetAsyncCommandResponse_ClearIncrementalState::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GetAsyncCommandResponse_ClearIncrementalState::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void GetAsyncCommandResponse_ClearIncrementalState::Serialize(::protozero::Message* msg) const {
+  // Field 1: data_source_ids
+  for (auto& it : data_source_ids_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+GetAsyncCommandResponse_Flush::GetAsyncCommandResponse_Flush() = default;
+GetAsyncCommandResponse_Flush::~GetAsyncCommandResponse_Flush() = default;
+GetAsyncCommandResponse_Flush::GetAsyncCommandResponse_Flush(const GetAsyncCommandResponse_Flush&) = default;
+GetAsyncCommandResponse_Flush& GetAsyncCommandResponse_Flush::operator=(const GetAsyncCommandResponse_Flush&) = default;
+GetAsyncCommandResponse_Flush::GetAsyncCommandResponse_Flush(GetAsyncCommandResponse_Flush&&) noexcept = default;
+GetAsyncCommandResponse_Flush& GetAsyncCommandResponse_Flush::operator=(GetAsyncCommandResponse_Flush&&) = default;
+
+bool GetAsyncCommandResponse_Flush::operator==(const GetAsyncCommandResponse_Flush& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(data_source_ids_, other.data_source_ids_)
+   && ::protozero::internal::gen_helpers::EqualsField(request_id_, other.request_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(flags_, other.flags_);
+}
+
+bool GetAsyncCommandResponse_Flush::ParseFromArray(const void* raw, size_t size) {
+  data_source_ids_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* data_source_ids */:
+        data_source_ids_.emplace_back();
+        field.get(&data_source_ids_.back());
+        break;
+      case 2 /* request_id */:
+        field.get(&request_id_);
+        break;
+      case 3 /* flags */:
+        field.get(&flags_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string GetAsyncCommandResponse_Flush::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GetAsyncCommandResponse_Flush::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void GetAsyncCommandResponse_Flush::Serialize(::protozero::Message* msg) const {
+  // Field 1: data_source_ids
+  for (auto& it : data_source_ids_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, it, msg);
+  }
+
+  // Field 2: request_id
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, request_id_, msg);
+  }
+
+  // Field 3: flags
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, flags_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+GetAsyncCommandResponse_StopDataSource::GetAsyncCommandResponse_StopDataSource() = default;
+GetAsyncCommandResponse_StopDataSource::~GetAsyncCommandResponse_StopDataSource() = default;
+GetAsyncCommandResponse_StopDataSource::GetAsyncCommandResponse_StopDataSource(const GetAsyncCommandResponse_StopDataSource&) = default;
+GetAsyncCommandResponse_StopDataSource& GetAsyncCommandResponse_StopDataSource::operator=(const GetAsyncCommandResponse_StopDataSource&) = default;
+GetAsyncCommandResponse_StopDataSource::GetAsyncCommandResponse_StopDataSource(GetAsyncCommandResponse_StopDataSource&&) noexcept = default;
+GetAsyncCommandResponse_StopDataSource& GetAsyncCommandResponse_StopDataSource::operator=(GetAsyncCommandResponse_StopDataSource&&) = default;
+
+bool GetAsyncCommandResponse_StopDataSource::operator==(const GetAsyncCommandResponse_StopDataSource& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(instance_id_, other.instance_id_);
+}
+
+bool GetAsyncCommandResponse_StopDataSource::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* instance_id */:
+        field.get(&instance_id_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string GetAsyncCommandResponse_StopDataSource::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GetAsyncCommandResponse_StopDataSource::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void GetAsyncCommandResponse_StopDataSource::Serialize(::protozero::Message* msg) const {
+  // Field 1: instance_id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, instance_id_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+GetAsyncCommandResponse_StartDataSource::GetAsyncCommandResponse_StartDataSource() = default;
+GetAsyncCommandResponse_StartDataSource::~GetAsyncCommandResponse_StartDataSource() = default;
+GetAsyncCommandResponse_StartDataSource::GetAsyncCommandResponse_StartDataSource(const GetAsyncCommandResponse_StartDataSource&) = default;
+GetAsyncCommandResponse_StartDataSource& GetAsyncCommandResponse_StartDataSource::operator=(const GetAsyncCommandResponse_StartDataSource&) = default;
+GetAsyncCommandResponse_StartDataSource::GetAsyncCommandResponse_StartDataSource(GetAsyncCommandResponse_StartDataSource&&) noexcept = default;
+GetAsyncCommandResponse_StartDataSource& GetAsyncCommandResponse_StartDataSource::operator=(GetAsyncCommandResponse_StartDataSource&&) = default;
+
+bool GetAsyncCommandResponse_StartDataSource::operator==(const GetAsyncCommandResponse_StartDataSource& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(new_instance_id_, other.new_instance_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(config_, other.config_);
+}
+
+bool GetAsyncCommandResponse_StartDataSource::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* new_instance_id */:
+        field.get(&new_instance_id_);
+        break;
+      case 2 /* config */:
+        (*config_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string GetAsyncCommandResponse_StartDataSource::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GetAsyncCommandResponse_StartDataSource::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void GetAsyncCommandResponse_StartDataSource::Serialize(::protozero::Message* msg) const {
+  // Field 1: new_instance_id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, new_instance_id_, msg);
+  }
+
+  // Field 2: config
+  if (_has_field_[2]) {
+    (*config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+GetAsyncCommandResponse_SetupDataSource::GetAsyncCommandResponse_SetupDataSource() = default;
+GetAsyncCommandResponse_SetupDataSource::~GetAsyncCommandResponse_SetupDataSource() = default;
+GetAsyncCommandResponse_SetupDataSource::GetAsyncCommandResponse_SetupDataSource(const GetAsyncCommandResponse_SetupDataSource&) = default;
+GetAsyncCommandResponse_SetupDataSource& GetAsyncCommandResponse_SetupDataSource::operator=(const GetAsyncCommandResponse_SetupDataSource&) = default;
+GetAsyncCommandResponse_SetupDataSource::GetAsyncCommandResponse_SetupDataSource(GetAsyncCommandResponse_SetupDataSource&&) noexcept = default;
+GetAsyncCommandResponse_SetupDataSource& GetAsyncCommandResponse_SetupDataSource::operator=(GetAsyncCommandResponse_SetupDataSource&&) = default;
+
+bool GetAsyncCommandResponse_SetupDataSource::operator==(const GetAsyncCommandResponse_SetupDataSource& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(new_instance_id_, other.new_instance_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(config_, other.config_);
+}
+
+bool GetAsyncCommandResponse_SetupDataSource::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* new_instance_id */:
+        field.get(&new_instance_id_);
+        break;
+      case 2 /* config */:
+        (*config_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string GetAsyncCommandResponse_SetupDataSource::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GetAsyncCommandResponse_SetupDataSource::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void GetAsyncCommandResponse_SetupDataSource::Serialize(::protozero::Message* msg) const {
+  // Field 1: new_instance_id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, new_instance_id_, msg);
+  }
+
+  // Field 2: config
+  if (_has_field_[2]) {
+    (*config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+GetAsyncCommandResponse_SetupTracing::GetAsyncCommandResponse_SetupTracing() = default;
+GetAsyncCommandResponse_SetupTracing::~GetAsyncCommandResponse_SetupTracing() = default;
+GetAsyncCommandResponse_SetupTracing::GetAsyncCommandResponse_SetupTracing(const GetAsyncCommandResponse_SetupTracing&) = default;
+GetAsyncCommandResponse_SetupTracing& GetAsyncCommandResponse_SetupTracing::operator=(const GetAsyncCommandResponse_SetupTracing&) = default;
+GetAsyncCommandResponse_SetupTracing::GetAsyncCommandResponse_SetupTracing(GetAsyncCommandResponse_SetupTracing&&) noexcept = default;
+GetAsyncCommandResponse_SetupTracing& GetAsyncCommandResponse_SetupTracing::operator=(GetAsyncCommandResponse_SetupTracing&&) = default;
+
+bool GetAsyncCommandResponse_SetupTracing::operator==(const GetAsyncCommandResponse_SetupTracing& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(shared_buffer_page_size_kb_, other.shared_buffer_page_size_kb_)
+   && ::protozero::internal::gen_helpers::EqualsField(shm_key_windows_, other.shm_key_windows_);
+}
+
+bool GetAsyncCommandResponse_SetupTracing::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* shared_buffer_page_size_kb */:
+        field.get(&shared_buffer_page_size_kb_);
+        break;
+      case 2 /* shm_key_windows */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &shm_key_windows_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string GetAsyncCommandResponse_SetupTracing::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GetAsyncCommandResponse_SetupTracing::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void GetAsyncCommandResponse_SetupTracing::Serialize(::protozero::Message* msg) const {
+  // Field 1: shared_buffer_page_size_kb
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, shared_buffer_page_size_kb_, msg);
+  }
+
+  // Field 2: shm_key_windows
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, shm_key_windows_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+GetAsyncCommandRequest::GetAsyncCommandRequest() = default;
+GetAsyncCommandRequest::~GetAsyncCommandRequest() = default;
+GetAsyncCommandRequest::GetAsyncCommandRequest(const GetAsyncCommandRequest&) = default;
+GetAsyncCommandRequest& GetAsyncCommandRequest::operator=(const GetAsyncCommandRequest&) = default;
+GetAsyncCommandRequest::GetAsyncCommandRequest(GetAsyncCommandRequest&&) noexcept = default;
+GetAsyncCommandRequest& GetAsyncCommandRequest::operator=(GetAsyncCommandRequest&&) = default;
+
+bool GetAsyncCommandRequest::operator==(const GetAsyncCommandRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool GetAsyncCommandRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string GetAsyncCommandRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GetAsyncCommandRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void GetAsyncCommandRequest::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+ActivateTriggersResponse::ActivateTriggersResponse() = default;
+ActivateTriggersResponse::~ActivateTriggersResponse() = default;
+ActivateTriggersResponse::ActivateTriggersResponse(const ActivateTriggersResponse&) = default;
+ActivateTriggersResponse& ActivateTriggersResponse::operator=(const ActivateTriggersResponse&) = default;
+ActivateTriggersResponse::ActivateTriggersResponse(ActivateTriggersResponse&&) noexcept = default;
+ActivateTriggersResponse& ActivateTriggersResponse::operator=(ActivateTriggersResponse&&) = default;
+
+bool ActivateTriggersResponse::operator==(const ActivateTriggersResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool ActivateTriggersResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ActivateTriggersResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ActivateTriggersResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ActivateTriggersResponse::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+ActivateTriggersRequest::ActivateTriggersRequest() = default;
+ActivateTriggersRequest::~ActivateTriggersRequest() = default;
+ActivateTriggersRequest::ActivateTriggersRequest(const ActivateTriggersRequest&) = default;
+ActivateTriggersRequest& ActivateTriggersRequest::operator=(const ActivateTriggersRequest&) = default;
+ActivateTriggersRequest::ActivateTriggersRequest(ActivateTriggersRequest&&) noexcept = default;
+ActivateTriggersRequest& ActivateTriggersRequest::operator=(ActivateTriggersRequest&&) = default;
+
+bool ActivateTriggersRequest::operator==(const ActivateTriggersRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(trigger_names_, other.trigger_names_);
+}
+
+bool ActivateTriggersRequest::ParseFromArray(const void* raw, size_t size) {
+  trigger_names_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* trigger_names */:
+        trigger_names_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &trigger_names_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ActivateTriggersRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ActivateTriggersRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ActivateTriggersRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: trigger_names
+  for (auto& it : trigger_names_) {
+    ::protozero::internal::gen_helpers::SerializeString(1, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+NotifyDataSourceStoppedResponse::NotifyDataSourceStoppedResponse() = default;
+NotifyDataSourceStoppedResponse::~NotifyDataSourceStoppedResponse() = default;
+NotifyDataSourceStoppedResponse::NotifyDataSourceStoppedResponse(const NotifyDataSourceStoppedResponse&) = default;
+NotifyDataSourceStoppedResponse& NotifyDataSourceStoppedResponse::operator=(const NotifyDataSourceStoppedResponse&) = default;
+NotifyDataSourceStoppedResponse::NotifyDataSourceStoppedResponse(NotifyDataSourceStoppedResponse&&) noexcept = default;
+NotifyDataSourceStoppedResponse& NotifyDataSourceStoppedResponse::operator=(NotifyDataSourceStoppedResponse&&) = default;
+
+bool NotifyDataSourceStoppedResponse::operator==(const NotifyDataSourceStoppedResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool NotifyDataSourceStoppedResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string NotifyDataSourceStoppedResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> NotifyDataSourceStoppedResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void NotifyDataSourceStoppedResponse::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+NotifyDataSourceStoppedRequest::NotifyDataSourceStoppedRequest() = default;
+NotifyDataSourceStoppedRequest::~NotifyDataSourceStoppedRequest() = default;
+NotifyDataSourceStoppedRequest::NotifyDataSourceStoppedRequest(const NotifyDataSourceStoppedRequest&) = default;
+NotifyDataSourceStoppedRequest& NotifyDataSourceStoppedRequest::operator=(const NotifyDataSourceStoppedRequest&) = default;
+NotifyDataSourceStoppedRequest::NotifyDataSourceStoppedRequest(NotifyDataSourceStoppedRequest&&) noexcept = default;
+NotifyDataSourceStoppedRequest& NotifyDataSourceStoppedRequest::operator=(NotifyDataSourceStoppedRequest&&) = default;
+
+bool NotifyDataSourceStoppedRequest::operator==(const NotifyDataSourceStoppedRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(data_source_id_, other.data_source_id_);
+}
+
+bool NotifyDataSourceStoppedRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* data_source_id */:
+        field.get(&data_source_id_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string NotifyDataSourceStoppedRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> NotifyDataSourceStoppedRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void NotifyDataSourceStoppedRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: data_source_id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, data_source_id_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+NotifyDataSourceStartedResponse::NotifyDataSourceStartedResponse() = default;
+NotifyDataSourceStartedResponse::~NotifyDataSourceStartedResponse() = default;
+NotifyDataSourceStartedResponse::NotifyDataSourceStartedResponse(const NotifyDataSourceStartedResponse&) = default;
+NotifyDataSourceStartedResponse& NotifyDataSourceStartedResponse::operator=(const NotifyDataSourceStartedResponse&) = default;
+NotifyDataSourceStartedResponse::NotifyDataSourceStartedResponse(NotifyDataSourceStartedResponse&&) noexcept = default;
+NotifyDataSourceStartedResponse& NotifyDataSourceStartedResponse::operator=(NotifyDataSourceStartedResponse&&) = default;
+
+bool NotifyDataSourceStartedResponse::operator==(const NotifyDataSourceStartedResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool NotifyDataSourceStartedResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string NotifyDataSourceStartedResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> NotifyDataSourceStartedResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void NotifyDataSourceStartedResponse::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+NotifyDataSourceStartedRequest::NotifyDataSourceStartedRequest() = default;
+NotifyDataSourceStartedRequest::~NotifyDataSourceStartedRequest() = default;
+NotifyDataSourceStartedRequest::NotifyDataSourceStartedRequest(const NotifyDataSourceStartedRequest&) = default;
+NotifyDataSourceStartedRequest& NotifyDataSourceStartedRequest::operator=(const NotifyDataSourceStartedRequest&) = default;
+NotifyDataSourceStartedRequest::NotifyDataSourceStartedRequest(NotifyDataSourceStartedRequest&&) noexcept = default;
+NotifyDataSourceStartedRequest& NotifyDataSourceStartedRequest::operator=(NotifyDataSourceStartedRequest&&) = default;
+
+bool NotifyDataSourceStartedRequest::operator==(const NotifyDataSourceStartedRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(data_source_id_, other.data_source_id_);
+}
+
+bool NotifyDataSourceStartedRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* data_source_id */:
+        field.get(&data_source_id_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string NotifyDataSourceStartedRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> NotifyDataSourceStartedRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void NotifyDataSourceStartedRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: data_source_id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, data_source_id_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+CommitDataResponse::CommitDataResponse() = default;
+CommitDataResponse::~CommitDataResponse() = default;
+CommitDataResponse::CommitDataResponse(const CommitDataResponse&) = default;
+CommitDataResponse& CommitDataResponse::operator=(const CommitDataResponse&) = default;
+CommitDataResponse::CommitDataResponse(CommitDataResponse&&) noexcept = default;
+CommitDataResponse& CommitDataResponse::operator=(CommitDataResponse&&) = default;
+
+bool CommitDataResponse::operator==(const CommitDataResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool CommitDataResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string CommitDataResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> CommitDataResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void CommitDataResponse::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+UnregisterTraceWriterResponse::UnregisterTraceWriterResponse() = default;
+UnregisterTraceWriterResponse::~UnregisterTraceWriterResponse() = default;
+UnregisterTraceWriterResponse::UnregisterTraceWriterResponse(const UnregisterTraceWriterResponse&) = default;
+UnregisterTraceWriterResponse& UnregisterTraceWriterResponse::operator=(const UnregisterTraceWriterResponse&) = default;
+UnregisterTraceWriterResponse::UnregisterTraceWriterResponse(UnregisterTraceWriterResponse&&) noexcept = default;
+UnregisterTraceWriterResponse& UnregisterTraceWriterResponse::operator=(UnregisterTraceWriterResponse&&) = default;
+
+bool UnregisterTraceWriterResponse::operator==(const UnregisterTraceWriterResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool UnregisterTraceWriterResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string UnregisterTraceWriterResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> UnregisterTraceWriterResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void UnregisterTraceWriterResponse::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+UnregisterTraceWriterRequest::UnregisterTraceWriterRequest() = default;
+UnregisterTraceWriterRequest::~UnregisterTraceWriterRequest() = default;
+UnregisterTraceWriterRequest::UnregisterTraceWriterRequest(const UnregisterTraceWriterRequest&) = default;
+UnregisterTraceWriterRequest& UnregisterTraceWriterRequest::operator=(const UnregisterTraceWriterRequest&) = default;
+UnregisterTraceWriterRequest::UnregisterTraceWriterRequest(UnregisterTraceWriterRequest&&) noexcept = default;
+UnregisterTraceWriterRequest& UnregisterTraceWriterRequest::operator=(UnregisterTraceWriterRequest&&) = default;
+
+bool UnregisterTraceWriterRequest::operator==(const UnregisterTraceWriterRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(trace_writer_id_, other.trace_writer_id_);
+}
+
+bool UnregisterTraceWriterRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* trace_writer_id */:
+        field.get(&trace_writer_id_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string UnregisterTraceWriterRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> UnregisterTraceWriterRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void UnregisterTraceWriterRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: trace_writer_id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, trace_writer_id_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+RegisterTraceWriterResponse::RegisterTraceWriterResponse() = default;
+RegisterTraceWriterResponse::~RegisterTraceWriterResponse() = default;
+RegisterTraceWriterResponse::RegisterTraceWriterResponse(const RegisterTraceWriterResponse&) = default;
+RegisterTraceWriterResponse& RegisterTraceWriterResponse::operator=(const RegisterTraceWriterResponse&) = default;
+RegisterTraceWriterResponse::RegisterTraceWriterResponse(RegisterTraceWriterResponse&&) noexcept = default;
+RegisterTraceWriterResponse& RegisterTraceWriterResponse::operator=(RegisterTraceWriterResponse&&) = default;
+
+bool RegisterTraceWriterResponse::operator==(const RegisterTraceWriterResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool RegisterTraceWriterResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string RegisterTraceWriterResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> RegisterTraceWriterResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void RegisterTraceWriterResponse::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+RegisterTraceWriterRequest::RegisterTraceWriterRequest() = default;
+RegisterTraceWriterRequest::~RegisterTraceWriterRequest() = default;
+RegisterTraceWriterRequest::RegisterTraceWriterRequest(const RegisterTraceWriterRequest&) = default;
+RegisterTraceWriterRequest& RegisterTraceWriterRequest::operator=(const RegisterTraceWriterRequest&) = default;
+RegisterTraceWriterRequest::RegisterTraceWriterRequest(RegisterTraceWriterRequest&&) noexcept = default;
+RegisterTraceWriterRequest& RegisterTraceWriterRequest::operator=(RegisterTraceWriterRequest&&) = default;
+
+bool RegisterTraceWriterRequest::operator==(const RegisterTraceWriterRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(trace_writer_id_, other.trace_writer_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(target_buffer_, other.target_buffer_);
+}
+
+bool RegisterTraceWriterRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* trace_writer_id */:
+        field.get(&trace_writer_id_);
+        break;
+      case 2 /* target_buffer */:
+        field.get(&target_buffer_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string RegisterTraceWriterRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> RegisterTraceWriterRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void RegisterTraceWriterRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: trace_writer_id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, trace_writer_id_, msg);
+  }
+
+  // Field 2: target_buffer
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, target_buffer_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+UnregisterDataSourceResponse::UnregisterDataSourceResponse() = default;
+UnregisterDataSourceResponse::~UnregisterDataSourceResponse() = default;
+UnregisterDataSourceResponse::UnregisterDataSourceResponse(const UnregisterDataSourceResponse&) = default;
+UnregisterDataSourceResponse& UnregisterDataSourceResponse::operator=(const UnregisterDataSourceResponse&) = default;
+UnregisterDataSourceResponse::UnregisterDataSourceResponse(UnregisterDataSourceResponse&&) noexcept = default;
+UnregisterDataSourceResponse& UnregisterDataSourceResponse::operator=(UnregisterDataSourceResponse&&) = default;
+
+bool UnregisterDataSourceResponse::operator==(const UnregisterDataSourceResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool UnregisterDataSourceResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string UnregisterDataSourceResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> UnregisterDataSourceResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void UnregisterDataSourceResponse::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+UnregisterDataSourceRequest::UnregisterDataSourceRequest() = default;
+UnregisterDataSourceRequest::~UnregisterDataSourceRequest() = default;
+UnregisterDataSourceRequest::UnregisterDataSourceRequest(const UnregisterDataSourceRequest&) = default;
+UnregisterDataSourceRequest& UnregisterDataSourceRequest::operator=(const UnregisterDataSourceRequest&) = default;
+UnregisterDataSourceRequest::UnregisterDataSourceRequest(UnregisterDataSourceRequest&&) noexcept = default;
+UnregisterDataSourceRequest& UnregisterDataSourceRequest::operator=(UnregisterDataSourceRequest&&) = default;
+
+bool UnregisterDataSourceRequest::operator==(const UnregisterDataSourceRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(data_source_name_, other.data_source_name_);
+}
+
+bool UnregisterDataSourceRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* data_source_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &data_source_name_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string UnregisterDataSourceRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> UnregisterDataSourceRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void UnregisterDataSourceRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: data_source_name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, data_source_name_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+UpdateDataSourceResponse::UpdateDataSourceResponse() = default;
+UpdateDataSourceResponse::~UpdateDataSourceResponse() = default;
+UpdateDataSourceResponse::UpdateDataSourceResponse(const UpdateDataSourceResponse&) = default;
+UpdateDataSourceResponse& UpdateDataSourceResponse::operator=(const UpdateDataSourceResponse&) = default;
+UpdateDataSourceResponse::UpdateDataSourceResponse(UpdateDataSourceResponse&&) noexcept = default;
+UpdateDataSourceResponse& UpdateDataSourceResponse::operator=(UpdateDataSourceResponse&&) = default;
+
+bool UpdateDataSourceResponse::operator==(const UpdateDataSourceResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool UpdateDataSourceResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string UpdateDataSourceResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> UpdateDataSourceResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void UpdateDataSourceResponse::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+UpdateDataSourceRequest::UpdateDataSourceRequest() = default;
+UpdateDataSourceRequest::~UpdateDataSourceRequest() = default;
+UpdateDataSourceRequest::UpdateDataSourceRequest(const UpdateDataSourceRequest&) = default;
+UpdateDataSourceRequest& UpdateDataSourceRequest::operator=(const UpdateDataSourceRequest&) = default;
+UpdateDataSourceRequest::UpdateDataSourceRequest(UpdateDataSourceRequest&&) noexcept = default;
+UpdateDataSourceRequest& UpdateDataSourceRequest::operator=(UpdateDataSourceRequest&&) = default;
+
+bool UpdateDataSourceRequest::operator==(const UpdateDataSourceRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(data_source_descriptor_, other.data_source_descriptor_);
+}
+
+bool UpdateDataSourceRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* data_source_descriptor */:
+        (*data_source_descriptor_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string UpdateDataSourceRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> UpdateDataSourceRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void UpdateDataSourceRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: data_source_descriptor
+  if (_has_field_[1]) {
+    (*data_source_descriptor_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+RegisterDataSourceResponse::RegisterDataSourceResponse() = default;
+RegisterDataSourceResponse::~RegisterDataSourceResponse() = default;
+RegisterDataSourceResponse::RegisterDataSourceResponse(const RegisterDataSourceResponse&) = default;
+RegisterDataSourceResponse& RegisterDataSourceResponse::operator=(const RegisterDataSourceResponse&) = default;
+RegisterDataSourceResponse::RegisterDataSourceResponse(RegisterDataSourceResponse&&) noexcept = default;
+RegisterDataSourceResponse& RegisterDataSourceResponse::operator=(RegisterDataSourceResponse&&) = default;
+
+bool RegisterDataSourceResponse::operator==(const RegisterDataSourceResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(error_, other.error_);
+}
+
+bool RegisterDataSourceResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* error */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &error_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string RegisterDataSourceResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> RegisterDataSourceResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void RegisterDataSourceResponse::Serialize(::protozero::Message* msg) const {
+  // Field 1: error
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, error_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+RegisterDataSourceRequest::RegisterDataSourceRequest() = default;
+RegisterDataSourceRequest::~RegisterDataSourceRequest() = default;
+RegisterDataSourceRequest::RegisterDataSourceRequest(const RegisterDataSourceRequest&) = default;
+RegisterDataSourceRequest& RegisterDataSourceRequest::operator=(const RegisterDataSourceRequest&) = default;
+RegisterDataSourceRequest::RegisterDataSourceRequest(RegisterDataSourceRequest&&) noexcept = default;
+RegisterDataSourceRequest& RegisterDataSourceRequest::operator=(RegisterDataSourceRequest&&) = default;
+
+bool RegisterDataSourceRequest::operator==(const RegisterDataSourceRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(data_source_descriptor_, other.data_source_descriptor_);
+}
+
+bool RegisterDataSourceRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* data_source_descriptor */:
+        (*data_source_descriptor_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string RegisterDataSourceRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> RegisterDataSourceRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void RegisterDataSourceRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: data_source_descriptor
+  if (_has_field_[1]) {
+    (*data_source_descriptor_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+InitializeConnectionResponse::InitializeConnectionResponse() = default;
+InitializeConnectionResponse::~InitializeConnectionResponse() = default;
+InitializeConnectionResponse::InitializeConnectionResponse(const InitializeConnectionResponse&) = default;
+InitializeConnectionResponse& InitializeConnectionResponse::operator=(const InitializeConnectionResponse&) = default;
+InitializeConnectionResponse::InitializeConnectionResponse(InitializeConnectionResponse&&) noexcept = default;
+InitializeConnectionResponse& InitializeConnectionResponse::operator=(InitializeConnectionResponse&&) = default;
+
+bool InitializeConnectionResponse::operator==(const InitializeConnectionResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(using_shmem_provided_by_producer_, other.using_shmem_provided_by_producer_)
+   && ::protozero::internal::gen_helpers::EqualsField(direct_smb_patching_supported_, other.direct_smb_patching_supported_)
+   && ::protozero::internal::gen_helpers::EqualsField(use_shmem_emulation_, other.use_shmem_emulation_);
+}
+
+bool InitializeConnectionResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* using_shmem_provided_by_producer */:
+        field.get(&using_shmem_provided_by_producer_);
+        break;
+      case 2 /* direct_smb_patching_supported */:
+        field.get(&direct_smb_patching_supported_);
+        break;
+      case 3 /* use_shmem_emulation */:
+        field.get(&use_shmem_emulation_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string InitializeConnectionResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> InitializeConnectionResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void InitializeConnectionResponse::Serialize(::protozero::Message* msg) const {
+  // Field 1: using_shmem_provided_by_producer
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, using_shmem_provided_by_producer_, msg);
+  }
+
+  // Field 2: direct_smb_patching_supported
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, direct_smb_patching_supported_, msg);
+  }
+
+  // Field 3: use_shmem_emulation
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, use_shmem_emulation_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+InitializeConnectionRequest::InitializeConnectionRequest() = default;
+InitializeConnectionRequest::~InitializeConnectionRequest() = default;
+InitializeConnectionRequest::InitializeConnectionRequest(const InitializeConnectionRequest&) = default;
+InitializeConnectionRequest& InitializeConnectionRequest::operator=(const InitializeConnectionRequest&) = default;
+InitializeConnectionRequest::InitializeConnectionRequest(InitializeConnectionRequest&&) noexcept = default;
+InitializeConnectionRequest& InitializeConnectionRequest::operator=(InitializeConnectionRequest&&) = default;
+
+bool InitializeConnectionRequest::operator==(const InitializeConnectionRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(shared_memory_page_size_hint_bytes_, other.shared_memory_page_size_hint_bytes_)
+   && ::protozero::internal::gen_helpers::EqualsField(shared_memory_size_hint_bytes_, other.shared_memory_size_hint_bytes_)
+   && ::protozero::internal::gen_helpers::EqualsField(producer_name_, other.producer_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(smb_scraping_mode_, other.smb_scraping_mode_)
+   && ::protozero::internal::gen_helpers::EqualsField(producer_provided_shmem_, other.producer_provided_shmem_)
+   && ::protozero::internal::gen_helpers::EqualsField(sdk_version_, other.sdk_version_)
+   && ::protozero::internal::gen_helpers::EqualsField(shm_key_windows_, other.shm_key_windows_);
+}
+
+bool InitializeConnectionRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* shared_memory_page_size_hint_bytes */:
+        field.get(&shared_memory_page_size_hint_bytes_);
+        break;
+      case 2 /* shared_memory_size_hint_bytes */:
+        field.get(&shared_memory_size_hint_bytes_);
+        break;
+      case 3 /* producer_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &producer_name_);
+        break;
+      case 4 /* smb_scraping_mode */:
+        field.get(&smb_scraping_mode_);
+        break;
+      case 6 /* producer_provided_shmem */:
+        field.get(&producer_provided_shmem_);
+        break;
+      case 8 /* sdk_version */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &sdk_version_);
+        break;
+      case 7 /* shm_key_windows */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &shm_key_windows_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string InitializeConnectionRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> InitializeConnectionRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void InitializeConnectionRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: shared_memory_page_size_hint_bytes
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, shared_memory_page_size_hint_bytes_, msg);
+  }
+
+  // Field 2: shared_memory_size_hint_bytes
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, shared_memory_size_hint_bytes_, msg);
+  }
+
+  // Field 3: producer_name
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeString(3, producer_name_, msg);
+  }
+
+  // Field 4: smb_scraping_mode
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, smb_scraping_mode_, msg);
+  }
+
+  // Field 6: producer_provided_shmem
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(6, producer_provided_shmem_, msg);
+  }
+
+  // Field 8: sdk_version
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeString(8, sdk_version_, msg);
+  }
+
+  // Field 7: shm_key_windows
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeString(7, shm_key_windows_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/ipc/relay_port.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/ipc/relay_port.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+SyncClockResponse::SyncClockResponse() = default;
+SyncClockResponse::~SyncClockResponse() = default;
+SyncClockResponse::SyncClockResponse(const SyncClockResponse&) = default;
+SyncClockResponse& SyncClockResponse::operator=(const SyncClockResponse&) = default;
+SyncClockResponse::SyncClockResponse(SyncClockResponse&&) noexcept = default;
+SyncClockResponse& SyncClockResponse::operator=(SyncClockResponse&&) = default;
+
+bool SyncClockResponse::operator==(const SyncClockResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool SyncClockResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string SyncClockResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> SyncClockResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void SyncClockResponse::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+SyncClockRequest::SyncClockRequest() = default;
+SyncClockRequest::~SyncClockRequest() = default;
+SyncClockRequest::SyncClockRequest(const SyncClockRequest&) = default;
+SyncClockRequest& SyncClockRequest::operator=(const SyncClockRequest&) = default;
+SyncClockRequest::SyncClockRequest(SyncClockRequest&&) noexcept = default;
+SyncClockRequest& SyncClockRequest::operator=(SyncClockRequest&&) = default;
+
+bool SyncClockRequest::operator==(const SyncClockRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(phase_, other.phase_)
+   && ::protozero::internal::gen_helpers::EqualsField(clocks_, other.clocks_);
+}
+
+int SyncClockRequest::clocks_size() const { return static_cast<int>(clocks_.size()); }
+void SyncClockRequest::clear_clocks() { clocks_.clear(); }
+SyncClockRequest_Clock* SyncClockRequest::add_clocks() { clocks_.emplace_back(); return &clocks_.back(); }
+bool SyncClockRequest::ParseFromArray(const void* raw, size_t size) {
+  clocks_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* phase */:
+        field.get(&phase_);
+        break;
+      case 2 /* clocks */:
+        clocks_.emplace_back();
+        clocks_.back().ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string SyncClockRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> SyncClockRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void SyncClockRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: phase
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, phase_, msg);
+  }
+
+  // Field 2: clocks
+  for (auto& it : clocks_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+SyncClockRequest_Clock::SyncClockRequest_Clock() = default;
+SyncClockRequest_Clock::~SyncClockRequest_Clock() = default;
+SyncClockRequest_Clock::SyncClockRequest_Clock(const SyncClockRequest_Clock&) = default;
+SyncClockRequest_Clock& SyncClockRequest_Clock::operator=(const SyncClockRequest_Clock&) = default;
+SyncClockRequest_Clock::SyncClockRequest_Clock(SyncClockRequest_Clock&&) noexcept = default;
+SyncClockRequest_Clock& SyncClockRequest_Clock::operator=(SyncClockRequest_Clock&&) = default;
+
+bool SyncClockRequest_Clock::operator==(const SyncClockRequest_Clock& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(clock_id_, other.clock_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(timestamp_, other.timestamp_);
+}
+
+bool SyncClockRequest_Clock::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* clock_id */:
+        field.get(&clock_id_);
+        break;
+      case 2 /* timestamp */:
+        field.get(&timestamp_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string SyncClockRequest_Clock::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> SyncClockRequest_Clock::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void SyncClockRequest_Clock::Serialize(::protozero::Message* msg) const {
+  // Field 1: clock_id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, clock_id_, msg);
+  }
+
+  // Field 2: timestamp
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, timestamp_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/ipc/wire_protocol.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/ipc/wire_protocol.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+IPCFrame::IPCFrame() = default;
+IPCFrame::~IPCFrame() = default;
+IPCFrame::IPCFrame(const IPCFrame&) = default;
+IPCFrame& IPCFrame::operator=(const IPCFrame&) = default;
+IPCFrame::IPCFrame(IPCFrame&&) noexcept = default;
+IPCFrame& IPCFrame::operator=(IPCFrame&&) = default;
+
+bool IPCFrame::operator==(const IPCFrame& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(request_id_, other.request_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(msg_bind_service_, other.msg_bind_service_)
+   && ::protozero::internal::gen_helpers::EqualsField(msg_bind_service_reply_, other.msg_bind_service_reply_)
+   && ::protozero::internal::gen_helpers::EqualsField(msg_invoke_method_, other.msg_invoke_method_)
+   && ::protozero::internal::gen_helpers::EqualsField(msg_invoke_method_reply_, other.msg_invoke_method_reply_)
+   && ::protozero::internal::gen_helpers::EqualsField(msg_request_error_, other.msg_request_error_)
+   && ::protozero::internal::gen_helpers::EqualsField(set_peer_identity_, other.set_peer_identity_)
+   && ::protozero::internal::gen_helpers::EqualsField(data_for_testing_, other.data_for_testing_);
+}
+
+bool IPCFrame::ParseFromArray(const void* raw, size_t size) {
+  data_for_testing_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 2 /* request_id */:
+        field.get(&request_id_);
+        break;
+      case 3 /* msg_bind_service */:
+        (*msg_bind_service_).ParseFromArray(field.data(), field.size());
+        break;
+      case 4 /* msg_bind_service_reply */:
+        (*msg_bind_service_reply_).ParseFromArray(field.data(), field.size());
+        break;
+      case 5 /* msg_invoke_method */:
+        (*msg_invoke_method_).ParseFromArray(field.data(), field.size());
+        break;
+      case 6 /* msg_invoke_method_reply */:
+        (*msg_invoke_method_reply_).ParseFromArray(field.data(), field.size());
+        break;
+      case 7 /* msg_request_error */:
+        (*msg_request_error_).ParseFromArray(field.data(), field.size());
+        break;
+      case 8 /* set_peer_identity */:
+        (*set_peer_identity_).ParseFromArray(field.data(), field.size());
+        break;
+      case 1 /* data_for_testing */:
+        data_for_testing_.emplace_back();
+        field.get(&data_for_testing_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string IPCFrame::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> IPCFrame::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void IPCFrame::Serialize(::protozero::Message* msg) const {
+  // Field 2: request_id
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, request_id_, msg);
+  }
+
+  // Field 3: msg_bind_service
+  if (_has_field_[3]) {
+    (*msg_bind_service_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
+  }
+
+  // Field 4: msg_bind_service_reply
+  if (_has_field_[4]) {
+    (*msg_bind_service_reply_).Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
+  }
+
+  // Field 5: msg_invoke_method
+  if (_has_field_[5]) {
+    (*msg_invoke_method_).Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
+  }
+
+  // Field 6: msg_invoke_method_reply
+  if (_has_field_[6]) {
+    (*msg_invoke_method_reply_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
+  }
+
+  // Field 7: msg_request_error
+  if (_has_field_[7]) {
+    (*msg_request_error_).Serialize(msg->BeginNestedMessage<::protozero::Message>(7));
+  }
+
+  // Field 8: set_peer_identity
+  if (_has_field_[8]) {
+    (*set_peer_identity_).Serialize(msg->BeginNestedMessage<::protozero::Message>(8));
+  }
+
+  // Field 1: data_for_testing
+  for (auto& it : data_for_testing_) {
+    ::protozero::internal::gen_helpers::SerializeString(1, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+IPCFrame_SetPeerIdentity::IPCFrame_SetPeerIdentity() = default;
+IPCFrame_SetPeerIdentity::~IPCFrame_SetPeerIdentity() = default;
+IPCFrame_SetPeerIdentity::IPCFrame_SetPeerIdentity(const IPCFrame_SetPeerIdentity&) = default;
+IPCFrame_SetPeerIdentity& IPCFrame_SetPeerIdentity::operator=(const IPCFrame_SetPeerIdentity&) = default;
+IPCFrame_SetPeerIdentity::IPCFrame_SetPeerIdentity(IPCFrame_SetPeerIdentity&&) noexcept = default;
+IPCFrame_SetPeerIdentity& IPCFrame_SetPeerIdentity::operator=(IPCFrame_SetPeerIdentity&&) = default;
+
+bool IPCFrame_SetPeerIdentity::operator==(const IPCFrame_SetPeerIdentity& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(pid_, other.pid_)
+   && ::protozero::internal::gen_helpers::EqualsField(uid_, other.uid_)
+   && ::protozero::internal::gen_helpers::EqualsField(machine_id_hint_, other.machine_id_hint_);
+}
+
+bool IPCFrame_SetPeerIdentity::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* pid */:
+        field.get(&pid_);
+        break;
+      case 2 /* uid */:
+        field.get(&uid_);
+        break;
+      case 3 /* machine_id_hint */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &machine_id_hint_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string IPCFrame_SetPeerIdentity::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> IPCFrame_SetPeerIdentity::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void IPCFrame_SetPeerIdentity::Serialize(::protozero::Message* msg) const {
+  // Field 1: pid
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, pid_, msg);
+  }
+
+  // Field 2: uid
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, uid_, msg);
+  }
+
+  // Field 3: machine_id_hint
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeString(3, machine_id_hint_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+IPCFrame_RequestError::IPCFrame_RequestError() = default;
+IPCFrame_RequestError::~IPCFrame_RequestError() = default;
+IPCFrame_RequestError::IPCFrame_RequestError(const IPCFrame_RequestError&) = default;
+IPCFrame_RequestError& IPCFrame_RequestError::operator=(const IPCFrame_RequestError&) = default;
+IPCFrame_RequestError::IPCFrame_RequestError(IPCFrame_RequestError&&) noexcept = default;
+IPCFrame_RequestError& IPCFrame_RequestError::operator=(IPCFrame_RequestError&&) = default;
+
+bool IPCFrame_RequestError::operator==(const IPCFrame_RequestError& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(error_, other.error_);
+}
+
+bool IPCFrame_RequestError::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* error */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &error_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string IPCFrame_RequestError::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> IPCFrame_RequestError::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void IPCFrame_RequestError::Serialize(::protozero::Message* msg) const {
+  // Field 1: error
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, error_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+IPCFrame_InvokeMethodReply::IPCFrame_InvokeMethodReply() = default;
+IPCFrame_InvokeMethodReply::~IPCFrame_InvokeMethodReply() = default;
+IPCFrame_InvokeMethodReply::IPCFrame_InvokeMethodReply(const IPCFrame_InvokeMethodReply&) = default;
+IPCFrame_InvokeMethodReply& IPCFrame_InvokeMethodReply::operator=(const IPCFrame_InvokeMethodReply&) = default;
+IPCFrame_InvokeMethodReply::IPCFrame_InvokeMethodReply(IPCFrame_InvokeMethodReply&&) noexcept = default;
+IPCFrame_InvokeMethodReply& IPCFrame_InvokeMethodReply::operator=(IPCFrame_InvokeMethodReply&&) = default;
+
+bool IPCFrame_InvokeMethodReply::operator==(const IPCFrame_InvokeMethodReply& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(success_, other.success_)
+   && ::protozero::internal::gen_helpers::EqualsField(has_more_, other.has_more_)
+   && ::protozero::internal::gen_helpers::EqualsField(reply_proto_, other.reply_proto_);
+}
+
+bool IPCFrame_InvokeMethodReply::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* success */:
+        field.get(&success_);
+        break;
+      case 2 /* has_more */:
+        field.get(&has_more_);
+        break;
+      case 3 /* reply_proto */:
+        field.get(&reply_proto_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string IPCFrame_InvokeMethodReply::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> IPCFrame_InvokeMethodReply::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void IPCFrame_InvokeMethodReply::Serialize(::protozero::Message* msg) const {
+  // Field 1: success
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, success_, msg);
+  }
+
+  // Field 2: has_more
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, has_more_, msg);
+  }
+
+  // Field 3: reply_proto
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeString(3, reply_proto_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+IPCFrame_InvokeMethod::IPCFrame_InvokeMethod() = default;
+IPCFrame_InvokeMethod::~IPCFrame_InvokeMethod() = default;
+IPCFrame_InvokeMethod::IPCFrame_InvokeMethod(const IPCFrame_InvokeMethod&) = default;
+IPCFrame_InvokeMethod& IPCFrame_InvokeMethod::operator=(const IPCFrame_InvokeMethod&) = default;
+IPCFrame_InvokeMethod::IPCFrame_InvokeMethod(IPCFrame_InvokeMethod&&) noexcept = default;
+IPCFrame_InvokeMethod& IPCFrame_InvokeMethod::operator=(IPCFrame_InvokeMethod&&) = default;
+
+bool IPCFrame_InvokeMethod::operator==(const IPCFrame_InvokeMethod& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(service_id_, other.service_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(method_id_, other.method_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(args_proto_, other.args_proto_)
+   && ::protozero::internal::gen_helpers::EqualsField(drop_reply_, other.drop_reply_);
+}
+
+bool IPCFrame_InvokeMethod::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* service_id */:
+        field.get(&service_id_);
+        break;
+      case 2 /* method_id */:
+        field.get(&method_id_);
+        break;
+      case 3 /* args_proto */:
+        field.get(&args_proto_);
+        break;
+      case 4 /* drop_reply */:
+        field.get(&drop_reply_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string IPCFrame_InvokeMethod::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> IPCFrame_InvokeMethod::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void IPCFrame_InvokeMethod::Serialize(::protozero::Message* msg) const {
+  // Field 1: service_id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, service_id_, msg);
+  }
+
+  // Field 2: method_id
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, method_id_, msg);
+  }
+
+  // Field 3: args_proto
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeString(3, args_proto_, msg);
+  }
+
+  // Field 4: drop_reply
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, drop_reply_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+IPCFrame_BindServiceReply::IPCFrame_BindServiceReply() = default;
+IPCFrame_BindServiceReply::~IPCFrame_BindServiceReply() = default;
+IPCFrame_BindServiceReply::IPCFrame_BindServiceReply(const IPCFrame_BindServiceReply&) = default;
+IPCFrame_BindServiceReply& IPCFrame_BindServiceReply::operator=(const IPCFrame_BindServiceReply&) = default;
+IPCFrame_BindServiceReply::IPCFrame_BindServiceReply(IPCFrame_BindServiceReply&&) noexcept = default;
+IPCFrame_BindServiceReply& IPCFrame_BindServiceReply::operator=(IPCFrame_BindServiceReply&&) = default;
+
+bool IPCFrame_BindServiceReply::operator==(const IPCFrame_BindServiceReply& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(success_, other.success_)
+   && ::protozero::internal::gen_helpers::EqualsField(service_id_, other.service_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(methods_, other.methods_);
+}
+
+int IPCFrame_BindServiceReply::methods_size() const { return static_cast<int>(methods_.size()); }
+void IPCFrame_BindServiceReply::clear_methods() { methods_.clear(); }
+IPCFrame_BindServiceReply_MethodInfo* IPCFrame_BindServiceReply::add_methods() { methods_.emplace_back(); return &methods_.back(); }
+bool IPCFrame_BindServiceReply::ParseFromArray(const void* raw, size_t size) {
+  methods_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* success */:
+        field.get(&success_);
+        break;
+      case 2 /* service_id */:
+        field.get(&service_id_);
+        break;
+      case 3 /* methods */:
+        methods_.emplace_back();
+        methods_.back().ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string IPCFrame_BindServiceReply::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> IPCFrame_BindServiceReply::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void IPCFrame_BindServiceReply::Serialize(::protozero::Message* msg) const {
+  // Field 1: success
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, success_, msg);
+  }
+
+  // Field 2: service_id
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, service_id_, msg);
+  }
+
+  // Field 3: methods
+  for (auto& it : methods_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+IPCFrame_BindServiceReply_MethodInfo::IPCFrame_BindServiceReply_MethodInfo() = default;
+IPCFrame_BindServiceReply_MethodInfo::~IPCFrame_BindServiceReply_MethodInfo() = default;
+IPCFrame_BindServiceReply_MethodInfo::IPCFrame_BindServiceReply_MethodInfo(const IPCFrame_BindServiceReply_MethodInfo&) = default;
+IPCFrame_BindServiceReply_MethodInfo& IPCFrame_BindServiceReply_MethodInfo::operator=(const IPCFrame_BindServiceReply_MethodInfo&) = default;
+IPCFrame_BindServiceReply_MethodInfo::IPCFrame_BindServiceReply_MethodInfo(IPCFrame_BindServiceReply_MethodInfo&&) noexcept = default;
+IPCFrame_BindServiceReply_MethodInfo& IPCFrame_BindServiceReply_MethodInfo::operator=(IPCFrame_BindServiceReply_MethodInfo&&) = default;
+
+bool IPCFrame_BindServiceReply_MethodInfo::operator==(const IPCFrame_BindServiceReply_MethodInfo& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(id_, other.id_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_);
+}
+
+bool IPCFrame_BindServiceReply_MethodInfo::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* id */:
+        field.get(&id_);
+        break;
+      case 2 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string IPCFrame_BindServiceReply_MethodInfo::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> IPCFrame_BindServiceReply_MethodInfo::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void IPCFrame_BindServiceReply_MethodInfo::Serialize(::protozero::Message* msg) const {
+  // Field 1: id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, id_, msg);
+  }
+
+  // Field 2: name
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, name_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+IPCFrame_BindService::IPCFrame_BindService() = default;
+IPCFrame_BindService::~IPCFrame_BindService() = default;
+IPCFrame_BindService::IPCFrame_BindService(const IPCFrame_BindService&) = default;
+IPCFrame_BindService& IPCFrame_BindService::operator=(const IPCFrame_BindService&) = default;
+IPCFrame_BindService::IPCFrame_BindService(IPCFrame_BindService&&) noexcept = default;
+IPCFrame_BindService& IPCFrame_BindService::operator=(IPCFrame_BindService&&) = default;
+
+bool IPCFrame_BindService::operator==(const IPCFrame_BindService& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(service_name_, other.service_name_);
+}
+
+bool IPCFrame_BindService::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* service_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &service_name_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string IPCFrame_BindService::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> IPCFrame_BindService::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void IPCFrame_BindService::Serialize(::protozero::Message* msg) const {
+  // Field 1: service_name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, service_name_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: src/base/unix_socket.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/unix_socket.h
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_UNIX_SOCKET_H_
+#define INCLUDE_PERFETTO_EXT_BASE_UNIX_SOCKET_H_
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <memory>
+#include <string>
+#include <utility>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
+
+struct msghdr;
+
+namespace perfetto {
+namespace base {
+
+// Define the ScopedSocketHandle type.
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+int CloseSocket(SocketHandle);   // A wrapper around ::closesocket().
+using ScopedSocketHandle =
+    ScopedResource<SocketHandle, CloseSocket, static_cast<SocketHandle>(-1)>;
+#else
+using ScopedSocketHandle = ScopedFile;
+#endif
+
+class TaskRunner;
+
+// Use arbitrarily high values to avoid that some code accidentally ends up
+// assuming that these enum values match the sysroot's SOCK_xxx defines rather
+// than using MkSockType() / MkSockFamily().
+enum class SockType { kStream = 100, kDgram, kSeqPacket };
+enum class SockFamily { kUnspec = 0, kUnix = 200, kInet, kInet6, kVsock };
+
+// Controls the getsockopt(SO_PEERCRED) behavior, which allows to obtain the
+// peer credentials.
+enum class SockPeerCredMode {
+  // Obtain the peer credentials immediately after connection and cache them.
+  kReadOnConnect = 0,
+
+  // Don't read peer credentials at all. Calls to peer_uid()/peer_pid() will
+  // hit a DCHECK and return kInvalidUid/Pid in release builds.
+  kIgnore = 1,
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+  kDefault = kIgnore,
+#else
+  kDefault = kReadOnConnect,
+#endif
+};
+
+// Returns the socket family from the full addres that perfetto uses.
+// Addr can be:
+// - /path/to/socket : for linked AF_UNIX sockets.
+// - @abstract_name  : for abstract AF_UNIX sockets.
+// - 1.2.3.4:8080    : for Inet sockets.
+// - [::1]:8080      : for Inet6 sockets.
+// - vsock://-1:3000 : for VM sockets.
+SockFamily GetSockFamily(const char* addr);
+
+// Returns whether inter-process shared memory is supported for the socket.
+inline bool SockShmemSupported(SockFamily sock_family) {
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  return sock_family == SockFamily::kUnix;
+#else
+  base::ignore_result(sock_family);
+  // On Windows shm is negotiated by sharing an unguessable token
+  // over TCP sockets. In theory works on any socket type, in practice
+  // we need to tell the difference between a local and a remote
+  // connection. For now we assume everything is local.
+  // See comments on r.android.com/2951909 .
+  return true;
+#endif
+}
+inline bool SockShmemSupported(const char* addr) {
+  return SockShmemSupported(GetSockFamily(addr));
+}
+
+// UnixSocketRaw is a basic wrapper around sockets. It exposes wrapper
+// methods that take care of most common pitfalls (e.g., marking fd as
+// O_CLOEXEC, avoiding SIGPIPE, properly handling partial writes). It is used as
+// a building block for the more sophisticated UnixSocket class which depends
+// on base::TaskRunner.
+class UnixSocketRaw {
+ public:
+  // Creates a new unconnected unix socket.
+  static UnixSocketRaw CreateMayFail(SockFamily family, SockType type);
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  // Crates a pair of connected sockets.
+  static std::pair<UnixSocketRaw, UnixSocketRaw> CreatePairPosix(SockFamily,
+                                                                 SockType);
+#endif
+
+  // Creates an uninitialized unix socket.
+  UnixSocketRaw();
+
+  // Creates a unix socket adopting an existing file descriptor. This is
+  // typically used to inherit fds from init via environment variables.
+  UnixSocketRaw(ScopedSocketHandle, SockFamily, SockType);
+
+  ~UnixSocketRaw() = default;
+  UnixSocketRaw(UnixSocketRaw&&) noexcept = default;
+  UnixSocketRaw& operator=(UnixSocketRaw&&) = default;
+
+  bool Bind(const std::string& socket_name);
+  bool Listen();
+  bool Connect(const std::string& socket_name);
+  bool SetTxTimeout(uint32_t timeout_ms);
+  bool SetRxTimeout(uint32_t timeout_ms);
+  void Shutdown();
+  void SetBlocking(bool);
+  void DcheckIsBlocking(bool expected) const;  // No-op on release and Win.
+  void SetRetainOnExec(bool retain);
+  std::string GetSockAddr() const;
+  SockType type() const { return type_; }
+  SockFamily family() const { return family_; }
+  SocketHandle fd() const { return *fd_; }
+  explicit operator bool() const { return !!fd_; }
+
+  // This is the handle that passed to TaskRunner.AddFileDescriptorWatch().
+  // On UNIX this is just the socket FD. On Windows, we need to create a
+  // dedicated event object.
+  PlatformHandle watch_handle() const {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    return *event_handle_;
+#else
+    return *fd_;
+#endif
+  }
+
+  ScopedSocketHandle ReleaseFd() { return std::move(fd_); }
+
+  // |send_fds| and |num_fds| are ignored on Windows.
+  ssize_t Send(const void* msg,
+               size_t len,
+               const int* send_fds = nullptr,
+               size_t num_fds = 0);
+
+  ssize_t SendStr(const std::string& str) {
+    return Send(str.data(), str.size());
+  }
+
+  // |fd_vec| and |max_files| are ignored on Windows.
+  ssize_t Receive(void* msg,
+                  size_t len,
+                  ScopedFile* fd_vec = nullptr,
+                  size_t max_files = 0);
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  // UNIX-specific helpers to deal with SCM_RIGHTS.
+
+  // Re-enter sendmsg until all the data has been sent or an error occurs.
+  // TODO(fmayer): Figure out how to do timeouts here for heapprofd.
+  ssize_t SendMsgAllPosix(struct msghdr* msg);
+
+  // Exposed for testing only.
+  // Update msghdr so subsequent sendmsg will send data that remains after n
+  // bytes have already been sent.
+  static void ShiftMsgHdrPosix(size_t n, struct msghdr* msg);
+#endif
+
+ private:
+  UnixSocketRaw(SockFamily, SockType);
+
+  UnixSocketRaw(const UnixSocketRaw&) = delete;
+  UnixSocketRaw& operator=(const UnixSocketRaw&) = delete;
+
+  ScopedSocketHandle fd_;
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  ScopedPlatformHandle event_handle_;
+#endif
+  SockFamily family_ = SockFamily::kUnix;
+  SockType type_ = SockType::kStream;
+  uint32_t tx_timeout_ms_ = 0;
+};
+
+// A non-blocking UNIX domain socket. Allows also to transfer file descriptors.
+// None of the methods in this class are blocking.
+// The main design goal is making strong guarantees on the EventListener
+// callbacks, in order to avoid ending in some undefined state.
+// In case of any error it will aggressively just shut down the socket and
+// notify the failure with OnConnect(false) or OnDisconnect() depending on the
+// state of the socket (see below).
+// EventListener callbacks stop happening as soon as the instance is destroyed.
+//
+// Lifecycle of a client socket:
+//
+//                           Connect()
+//                               |
+//            +------------------+------------------+
+//            | (success)                           | (failure or Shutdown())
+//            V                                     V
+//     OnConnect(true)                         OnConnect(false)
+//            |
+//            V
+//    OnDataAvailable()
+//            |
+//            V
+//     OnDisconnect()  (failure or shutdown)
+//
+//
+// Lifecycle of a server socket:
+//
+//                          Listen()  --> returns false in case of errors.
+//                             |
+//                             V
+//              OnNewIncomingConnection(new_socket)
+//
+//          (|new_socket| inherits the same EventListener)
+//                             |
+//                             V
+//                     OnDataAvailable()
+//                             | (failure or Shutdown())
+//                             V
+//                       OnDisconnect()
+class PERFETTO_EXPORT_COMPONENT UnixSocket {
+ public:
+  class EventListener {
+   public:
+    EventListener() = default;
+    virtual ~EventListener();
+
+    EventListener(const EventListener&) = delete;
+    EventListener& operator=(const EventListener&) = delete;
+
+    EventListener(EventListener&&) noexcept = default;
+    EventListener& operator=(EventListener&&) noexcept = default;
+
+    // After Listen().
+    // |self| may be null if the connection was not accepted via a listen
+    // socket.
+    virtual void OnNewIncomingConnection(
+        UnixSocket* self,
+        std::unique_ptr<UnixSocket> new_connection);
+
+    // After Connect(), whether successful or not.
+    virtual void OnConnect(UnixSocket* self, bool connected);
+
+    // After a successful Connect() or OnNewIncomingConnection(). Either the
+    // other endpoint did disconnect or some other error happened.
+    virtual void OnDisconnect(UnixSocket* self);
+
+    // Whenever there is data available to Receive(). Note that spurious FD
+    // watch events are possible, so it is possible that Receive() soon after
+    // OnDataAvailable() returns 0 (just ignore those).
+    virtual void OnDataAvailable(UnixSocket* self);
+  };
+
+  enum class State {
+    kDisconnected = 0,  // Failed connection, peer disconnection or Shutdown().
+    kConnecting,  // Soon after Connect(), before it either succeeds or fails.
+    kConnected,   // After a successful Connect().
+    kListening    // After Listen(), until Shutdown().
+  };
+
+  // Creates a socket and starts listening. If SockFamily::kUnix and
+  // |socket_name| starts with a '@', an abstract UNIX dmoain socket will be
+  // created instead of a filesystem-linked UNIX socket (Linux/Android only).
+  // If SockFamily::kInet, |socket_name| is host:port (e.g., "1.2.3.4:8000").
+  // If SockFamily::kInet6, |socket_name| is [host]:port (e.g., "[::1]:8000").
+  // Returns nullptr if the socket creation or bind fails. If listening fails,
+  // (e.g. if another socket with the same name is already listening) the
+  // returned socket will have is_listening() == false.
+  static std::unique_ptr<UnixSocket> Listen(const std::string& socket_name,
+                                            EventListener*,
+                                            TaskRunner*,
+                                            SockFamily,
+                                            SockType);
+
+  // Attaches to a pre-existing socket. The socket must have been created in
+  // SOCK_STREAM mode and the caller must have called bind() on it.
+  static std::unique_ptr<UnixSocket> Listen(ScopedSocketHandle,
+                                            EventListener*,
+                                            TaskRunner*,
+                                            SockFamily,
+                                            SockType);
+
+  // Creates a Unix domain socket and connects to the listening endpoint.
+  // Returns always an instance. EventListener::OnConnect(bool success) will
+  // be called always, whether the connection succeeded or not.
+  static std::unique_ptr<UnixSocket> Connect(
+      const std::string& socket_name,
+      EventListener*,
+      TaskRunner*,
+      SockFamily,
+      SockType,
+      SockPeerCredMode = SockPeerCredMode::kDefault);
+
+  // Constructs a UnixSocket using the given connected socket.
+  static std::unique_ptr<UnixSocket> AdoptConnected(
+      ScopedSocketHandle,
+      EventListener*,
+      TaskRunner*,
+      SockFamily,
+      SockType,
+      SockPeerCredMode = SockPeerCredMode::kDefault);
+
+  UnixSocket(const UnixSocket&) = delete;
+  UnixSocket& operator=(const UnixSocket&) = delete;
+  // Cannot be easily moved because of tasks from the FileDescriptorWatch.
+  UnixSocket(UnixSocket&&) = delete;
+  UnixSocket& operator=(UnixSocket&&) = delete;
+
+  // This class gives the hard guarantee that no callback is called on the
+  // passed EventListener immediately after the object has been destroyed.
+  // Any queued callback will be silently dropped.
+  ~UnixSocket();
+
+  // Shuts down the current connection, if any. If the socket was Listen()-ing,
+  // stops listening. The socket goes back to kNotInitialized state, so it can
+  // be reused with Listen() or Connect().
+  void Shutdown(bool notify);
+
+  void SetTxTimeout(uint32_t timeout_ms) {
+    PERFETTO_CHECK(sock_raw_.SetTxTimeout(timeout_ms));
+  }
+  void SetRxTimeout(uint32_t timeout_ms) {
+    PERFETTO_CHECK(sock_raw_.SetRxTimeout(timeout_ms));
+  }
+
+  std::string GetSockAddr() const { return sock_raw_.GetSockAddr(); }
+
+  // Returns true is the message was queued, false if there was no space in the
+  // output buffer, in which case the client should retry or give up.
+  // If any other error happens the socket will be shutdown and
+  // EventListener::OnDisconnect() will be called.
+  // If the socket is not connected, Send() will just return false.
+  // Does not append a null string terminator to msg in any case.
+  bool Send(const void* msg, size_t len, const int* send_fds, size_t num_fds);
+
+  inline bool Send(const void* msg, size_t len, int send_fd = -1) {
+    if (send_fd != -1)
+      return Send(msg, len, &send_fd, 1);
+    return Send(msg, len, nullptr, 0);
+  }
+
+  inline bool SendStr(const std::string& msg) {
+    return Send(msg.data(), msg.size(), -1);
+  }
+
+  // Returns the number of bytes (<= |len|) written in |msg| or 0 if there
+  // is no data in the buffer to read or an error occurs (in which case a
+  // EventListener::OnDisconnect() will follow).
+  // If the ScopedFile pointer is not null and a FD is received, it moves the
+  // received FD into that. If a FD is received but the ScopedFile pointer is
+  // null, the FD will be automatically closed.
+  size_t Receive(void* msg, size_t len, ScopedFile*, size_t max_files = 1);
+
+  inline size_t Receive(void* msg, size_t len) {
+    return Receive(msg, len, nullptr, 0);
+  }
+
+  // Only for tests. This is slower than Receive() as it requires a heap
+  // allocation and a copy for the std::string. Guarantees that the returned
+  // string is null terminated even if the underlying message sent by the peer
+  // is not.
+  std::string ReceiveString(size_t max_length = 1024);
+
+  bool is_connected() const { return state_ == State::kConnected; }
+  bool is_listening() const { return state_ == State::kListening; }
+  SocketHandle fd() const { return sock_raw_.fd(); }
+  SockFamily family() const { return sock_raw_.family(); }
+
+  // User ID of the peer, as returned by the kernel. If the client disconnects
+  // and the socket goes into the kDisconnected state, it retains the uid of
+  // the last peer.
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
+    !PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+  uid_t peer_uid_posix(bool skip_check_for_testing = false) const {
+    PERFETTO_DCHECK((!is_listening() && peer_uid_ != kInvalidUid) ||
+                    skip_check_for_testing);
+
+    return peer_uid_;
+  }
+#endif
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  // Process ID of the peer, as returned by the kernel. If the client
+  // disconnects and the socket goes into the kDisconnected state, it
+  // retains the pid of the last peer.
+  //
+  // This is only available on Linux / Android.
+  pid_t peer_pid_linux(bool skip_check_for_testing = false) const {
+    PERFETTO_DCHECK((!is_listening() && peer_pid_ != kInvalidPid) ||
+                    skip_check_for_testing);
+    return peer_pid_;
+  }
+#endif
+
+  // This makes the UnixSocket unusable.
+  UnixSocketRaw ReleaseSocket();
+
+ private:
+  UnixSocket(EventListener*,
+             TaskRunner*,
+             SockFamily,
+             SockType,
+             SockPeerCredMode);
+  UnixSocket(EventListener*,
+             TaskRunner*,
+             ScopedSocketHandle,
+             State,
+             SockFamily,
+             SockType,
+             SockPeerCredMode);
+
+  // Called once by the corresponding public static factory methods.
+  void DoConnect(const std::string& socket_name);
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  void ReadPeerCredentialsPosix();
+#endif
+
+  void OnEvent();
+  void NotifyConnectionState(bool success);
+
+  UnixSocketRaw sock_raw_;
+  State state_ = State::kDisconnected;
+  SockPeerCredMode peer_cred_mode_ = SockPeerCredMode::kDefault;
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
+    !PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+  uid_t peer_uid_ = kInvalidUid;
+#endif
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  pid_t peer_pid_ = kInvalidPid;
+#endif
+  EventListener* const event_listener_;
+  TaskRunner* const task_runner_;
+  WeakPtrFactory<UnixSocket> weak_ptr_factory_;  // Keep last.
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_UNIX_SOCKET_H_
+// gen_amalgamated begin header: src/base/vm_sockets.h
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_BASE_VM_SOCKETS_H_
+#define SRC_BASE_VM_SOCKETS_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+
+#include <sys/socket.h>
+
+#ifdef AF_VSOCK
+// Use system vm_socket.h if avaialbe.
+#include <linux/vm_sockets.h>
+#else  // defined(AF_SOCK)
+// Fallback and use the stripped copy from the UAPI vm_sockets.h.
+
+#include <stdint.h>  // For uint8_t.
+
+#define AF_VSOCK 40
+
+struct sockaddr_vm {
+  sa_family_t svm_family;
+  unsigned short svm_reserved1;
+  unsigned int svm_port;
+  unsigned int svm_cid;
+  uint8_t svm_flags;
+  unsigned char svm_zero[sizeof(struct sockaddr) - sizeof(sa_family_t) -
+                         sizeof(unsigned short) - sizeof(unsigned int) -
+                         sizeof(unsigned int) - sizeof(uint8_t)];
+};
+
+#endif  // defined(AF_SOCK)
+
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||
+        // PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+
+#endif  // SRC_BASE_VM_SOCKETS_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+// The include order matters on these three Windows header groups.
+#include <Windows.h>
+
+#include <WS2tcpip.h>
+#include <WinSock2.h>
+
+#include <afunix.h>
+#else
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <poll.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#endif
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+#include <sys/ucred.h>
+#endif
+
+#include <algorithm>
+#include <memory>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+// Use a local stripped copy of vm_sockets.h from UAPI.
+// gen_amalgamated expanded: #include "src/base/vm_sockets.h"
+#endif
+
+namespace perfetto {
+namespace base {
+
+// The CMSG_* macros use NULL instead of nullptr.
+// Note: MSVC doesn't have #pragma GCC diagnostic, hence the if __GNUC__.
+#if defined(__GNUC__) && !PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
+#endif
+
+namespace {
+
+// Android takes an int instead of socklen_t for the control buffer size.
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+using CBufLenType = size_t;
+#else
+using CBufLenType = socklen_t;
+#endif
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+constexpr char kVsockNamePrefix[] = "vsock://";
+#endif
+
+// A wrapper around variable-size sockaddr structs.
+// This is solving the following problem: when calling connect() or bind(), the
+// caller needs to take care to allocate the right struct (sockaddr_un for
+// AF_UNIX, sockaddr_in for AF_INET).   Those structs have different sizes and,
+// more importantly, are bigger than the base struct sockaddr.
+struct SockaddrAny {
+  SockaddrAny() : size() {}
+  SockaddrAny(const void* addr, socklen_t sz)
+      : data(new char[static_cast<size_t>(sz)]), size(sz) {
+    memcpy(data.get(), addr, static_cast<size_t>(size));
+  }
+
+  const struct sockaddr* addr() const {
+    return reinterpret_cast<const struct sockaddr*>(data.get());
+  }
+
+  std::unique_ptr<char[]> data;
+  socklen_t size;
+};
+
+inline int MkSockFamily(SockFamily family) {
+  switch (family) {
+    case SockFamily::kUnix:
+      return AF_UNIX;
+    case SockFamily::kInet:
+      return AF_INET;
+    case SockFamily::kInet6:
+      return AF_INET6;
+    case SockFamily::kVsock:
+#ifdef AF_VSOCK
+      return AF_VSOCK;
+#else
+      return AF_UNSPEC;  // Return AF_UNSPEC on unsupported platforms.
+#endif
+    case SockFamily::kUnspec:
+      return AF_UNSPEC;
+  }
+  PERFETTO_CHECK(false);  // For GCC.
+}
+
+inline int MkSockType(SockType type) {
+#if defined(SOCK_CLOEXEC)
+  constexpr int kSockCloExec = SOCK_CLOEXEC;
+#else
+  constexpr int kSockCloExec = 0;
+#endif
+  switch (type) {
+    case SockType::kStream:
+      return SOCK_STREAM | kSockCloExec;
+    case SockType::kDgram:
+      return SOCK_DGRAM | kSockCloExec;
+    case SockType::kSeqPacket:
+      return SOCK_SEQPACKET | kSockCloExec;
+  }
+  PERFETTO_CHECK(false);  // For GCC.
+}
+
+SockaddrAny MakeSockAddr(SockFamily family, const std::string& socket_name) {
+  switch (family) {
+    case SockFamily::kUnix: {
+      struct sockaddr_un saddr {};
+      const size_t name_len = socket_name.size();
+      if (name_len + 1 /* for trailing \0 */ >= sizeof(saddr.sun_path)) {
+        errno = ENAMETOOLONG;
+        return SockaddrAny();
+      }
+      memcpy(saddr.sun_path, socket_name.data(), name_len);
+      if (saddr.sun_path[0] == '@') {
+        saddr.sun_path[0] = '\0';
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+        // The MSDN blog claims that abstract (non-filesystem based) AF_UNIX
+        // socket are supported, but that doesn't seem true.
+        PERFETTO_ELOG(
+            "Abstract AF_UNIX sockets are not supported on Windows, see "
+            "https://github.com/microsoft/WSL/issues/4240");
+        return SockaddrAny();
+#endif
+      }
+      saddr.sun_family = AF_UNIX;
+      auto size = static_cast<socklen_t>(
+          __builtin_offsetof(sockaddr_un, sun_path) + name_len + 1);
+
+      // Abstract sockets do NOT require a trailing null terminator (which is
+      // instad mandatory for filesystem sockets). Any byte up to `size`,
+      // including '\0' will become part of the socket name.
+      if (saddr.sun_path[0] == '\0')
+        --size;
+      PERFETTO_CHECK(static_cast<size_t>(size) <= sizeof(saddr));
+      return SockaddrAny(&saddr, size);
+    }
+    case SockFamily::kInet: {
+      auto parts = SplitString(socket_name, ":");
+      PERFETTO_CHECK(parts.size() == 2);
+      struct addrinfo* addr_info = nullptr;
+      struct addrinfo hints {};
+      hints.ai_family = AF_INET;
+      PERFETTO_CHECK(getaddrinfo(parts[0].c_str(), parts[1].c_str(), &hints,
+                                 &addr_info) == 0);
+      PERFETTO_CHECK(addr_info->ai_family == AF_INET);
+      SockaddrAny res(addr_info->ai_addr,
+                      static_cast<socklen_t>(addr_info->ai_addrlen));
+      freeaddrinfo(addr_info);
+      return res;
+    }
+    case SockFamily::kInet6: {
+      auto parts = SplitString(socket_name, "]");
+      PERFETTO_CHECK(parts.size() == 2);
+      auto address = SplitString(parts[0], "[");
+      PERFETTO_CHECK(address.size() == 1);
+      auto port = SplitString(parts[1], ":");
+      PERFETTO_CHECK(port.size() == 1);
+      struct addrinfo* addr_info = nullptr;
+      struct addrinfo hints {};
+      hints.ai_family = AF_INET6;
+      PERFETTO_CHECK(getaddrinfo(address[0].c_str(), port[0].c_str(), &hints,
+                                 &addr_info) == 0);
+      PERFETTO_CHECK(addr_info->ai_family == AF_INET6);
+      SockaddrAny res(addr_info->ai_addr,
+                      static_cast<socklen_t>(addr_info->ai_addrlen));
+      freeaddrinfo(addr_info);
+      return res;
+    }
+    case SockFamily::kVsock: {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+      PERFETTO_CHECK(StartsWith(socket_name, kVsockNamePrefix));
+      auto address_port = StripPrefix(socket_name, kVsockNamePrefix);
+      auto parts = SplitString(address_port, ":");
+      PERFETTO_CHECK(parts.size() == 2);
+      sockaddr_vm addr;
+      memset(&addr, 0, sizeof(addr));
+      addr.svm_family = AF_VSOCK;
+      addr.svm_cid = *base::StringToUInt32(parts[0]);
+      addr.svm_port = *base::StringToUInt32(parts[1]);
+      SockaddrAny res(&addr, sizeof(addr));
+      return res;
+#else
+      errno = ENOTSOCK;
+      return SockaddrAny();
+#endif
+    }
+    case SockFamily::kUnspec:
+      errno = ENOTSOCK;
+      return SockaddrAny();
+  }
+  PERFETTO_CHECK(false);  // For GCC.
+}
+
+ScopedSocketHandle CreateSocketHandle(SockFamily family, SockType type) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  static bool init_winsock_once = [] {
+    WSADATA ignored{};
+    return WSAStartup(MAKEWORD(2, 2), &ignored) == 0;
+  }();
+  PERFETTO_CHECK(init_winsock_once);
+#endif
+  return ScopedSocketHandle(socket(MkSockFamily(family), MkSockType(type), 0));
+}
+
+}  // namespace
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+int CloseSocket(SocketHandle s) {
+  return ::closesocket(s);
+}
+#endif
+
+SockFamily GetSockFamily(const char* addr) {
+  if (strlen(addr) == 0)
+    return SockFamily::kUnspec;
+
+  if (addr[0] == '@')
+    return SockFamily::kUnix;  // Abstract AF_UNIX sockets.
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  // Vsock address starts with vsock://.
+  if (strncmp(addr, kVsockNamePrefix, strlen(kVsockNamePrefix)) == 0)
+    return SockFamily::kVsock;
+#endif
+
+  // If `addr` ends in :NNNN it's either a kInet or kInet6 socket.
+  const char* col = strrchr(addr, ':');
+  if (col && CStringToInt32(col + 1).has_value()) {
+    return addr[0] == '[' ? SockFamily::kInet6 : SockFamily::kInet;
+  }
+
+  return SockFamily::kUnix;  // For anything else assume it's a linked AF_UNIX.
+}
+
+// +-----------------------+
+// | UnixSocketRaw methods |
+// +-----------------------+
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+// static
+void UnixSocketRaw::ShiftMsgHdrPosix(size_t n, struct msghdr* msg) {
+  using LenType = decltype(msg->msg_iovlen);  // Mac and Linux don't agree.
+  for (LenType i = 0; i < msg->msg_iovlen; ++i) {
+    struct iovec* vec = &msg->msg_iov[i];
+    if (n < vec->iov_len) {
+      // We sent a part of this iovec.
+      vec->iov_base = reinterpret_cast<char*>(vec->iov_base) + n;
+      vec->iov_len -= n;
+      msg->msg_iov = vec;
+      msg->msg_iovlen -= i;
+      return;
+    }
+    // We sent the whole iovec.
+    n -= vec->iov_len;
+  }
+  // We sent all the iovecs.
+  PERFETTO_CHECK(n == 0);
+  msg->msg_iovlen = 0;
+  msg->msg_iov = nullptr;
+}
+
+// static
+std::pair<UnixSocketRaw, UnixSocketRaw> UnixSocketRaw::CreatePairPosix(
+    SockFamily family,
+    SockType type) {
+  int fds[2];
+  if (socketpair(MkSockFamily(family), MkSockType(type), 0, fds) != 0) {
+    return std::make_pair(UnixSocketRaw(), UnixSocketRaw());
+  }
+  return std::make_pair(UnixSocketRaw(ScopedFile(fds[0]), family, type),
+                        UnixSocketRaw(ScopedFile(fds[1]), family, type));
+}
+#endif
+
+// static
+UnixSocketRaw UnixSocketRaw::CreateMayFail(SockFamily family, SockType type) {
+  auto fd = CreateSocketHandle(family, type);
+  if (!fd)
+    return UnixSocketRaw();
+  return UnixSocketRaw(std::move(fd), family, type);
+}
+
+UnixSocketRaw::UnixSocketRaw() = default;
+
+UnixSocketRaw::UnixSocketRaw(SockFamily family, SockType type)
+    : UnixSocketRaw(CreateSocketHandle(family, type), family, type) {}
+
+UnixSocketRaw::UnixSocketRaw(ScopedSocketHandle fd,
+                             SockFamily family,
+                             SockType type)
+    : fd_(std::move(fd)), family_(family), type_(type) {
+  PERFETTO_CHECK(fd_);
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+  const int no_sigpipe = 1;
+  setsockopt(*fd_, SOL_SOCKET, SO_NOSIGPIPE, &no_sigpipe, sizeof(no_sigpipe));
+#endif
+
+  if (family == SockFamily::kInet || family == SockFamily::kInet6 ||
+      family == SockFamily::kVsock) {
+    int flag = 1;
+    // The reinterpret_cast<const char*> is needed for Windows, where the 4th
+    // arg is a const char* (on other POSIX system is a const void*).
+    PERFETTO_CHECK(!setsockopt(*fd_, SOL_SOCKET, SO_REUSEADDR,
+                               reinterpret_cast<const char*>(&flag),
+                               sizeof(flag)));
+  }
+
+  if (family == SockFamily::kInet || family == SockFamily::kInet6) {
+    int flag = 1;
+    // Disable Nagle's algorithm, optimize for low-latency.
+    // See https://github.com/google/perfetto/issues/70.
+    setsockopt(*fd_, IPPROTO_TCP, TCP_NODELAY,
+               reinterpret_cast<const char*>(&flag), sizeof(flag));
+  }
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  // We use one event handle for all socket events, to stay consistent to what
+  // we do on UNIX with the base::TaskRunner's poll().
+  event_handle_.reset(WSACreateEvent());
+  PERFETTO_CHECK(event_handle_);
+#else
+  // There is no reason why a socket should outlive the process in case of
+  // exec() by default, this is just working around a broken unix design.
+  SetRetainOnExec(false);
+#endif
+}
+
+void UnixSocketRaw::SetBlocking(bool is_blocking) {
+  PERFETTO_DCHECK(fd_);
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  unsigned long flag = is_blocking ? 0 : 1;  // FIONBIO has reverse logic.
+  if (is_blocking) {
+    // When switching between non-blocking -> blocking mode, we need to reset
+    // the event handle registration, otherwise the call will fail.
+    PERFETTO_CHECK(WSAEventSelect(*fd_, *event_handle_, 0) == 0);
+  }
+  PERFETTO_CHECK(ioctlsocket(*fd_, static_cast<long>(FIONBIO), &flag) == 0);
+  if (!is_blocking) {
+    PERFETTO_CHECK(
+        WSAEventSelect(*fd_, *event_handle_,
+                       FD_ACCEPT | FD_CONNECT | FD_READ | FD_CLOSE) == 0);
+  }
+#else
+  int flags = fcntl(*fd_, F_GETFL, 0);
+  if (!is_blocking) {
+    flags |= O_NONBLOCK;
+  } else {
+    flags &= ~static_cast<int>(O_NONBLOCK);
+  }
+  int fcntl_res = fcntl(*fd_, F_SETFL, flags);
+  PERFETTO_CHECK(fcntl_res == 0);
+#endif
+}
+
+void UnixSocketRaw::SetRetainOnExec(bool retain) {
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
+    !PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+  PERFETTO_DCHECK(fd_);
+  int flags = fcntl(*fd_, F_GETFD, 0);
+  if (retain) {
+    flags &= ~static_cast<int>(FD_CLOEXEC);
+  } else {
+    flags |= FD_CLOEXEC;
+  }
+  int fcntl_res = fcntl(*fd_, F_SETFD, flags);
+  PERFETTO_CHECK(fcntl_res == 0);
+#else
+  ignore_result(retain);
+#endif
+}
+
+void UnixSocketRaw::DcheckIsBlocking(bool expected) const {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  ignore_result(expected);
+#else
+  PERFETTO_DCHECK(fd_);
+  bool is_blocking = (fcntl(*fd_, F_GETFL, 0) & O_NONBLOCK) == 0;
+  PERFETTO_DCHECK(is_blocking == expected);
+#endif
+}
+
+bool UnixSocketRaw::Bind(const std::string& socket_name) {
+  PERFETTO_DCHECK(fd_);
+  SockaddrAny addr = MakeSockAddr(family_, socket_name);
+  if (addr.size == 0)
+    return false;
+
+  if (bind(*fd_, addr.addr(), addr.size)) {
+    PERFETTO_DPLOG("bind(%s)", socket_name.c_str());
+    return false;
+  }
+
+  return true;
+}
+
+bool UnixSocketRaw::Listen() {
+  PERFETTO_DCHECK(fd_);
+  PERFETTO_DCHECK(type_ == SockType::kStream || type_ == SockType::kSeqPacket);
+  return listen(*fd_, SOMAXCONN) == 0;
+}
+
+bool UnixSocketRaw::Connect(const std::string& socket_name) {
+  PERFETTO_DCHECK(fd_);
+  SockaddrAny addr = MakeSockAddr(family_, socket_name);
+  if (addr.size == 0)
+    return false;
+
+  int res = PERFETTO_EINTR(connect(*fd_, addr.addr(), addr.size));
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  bool continue_async = WSAGetLastError() == WSAEWOULDBLOCK;
+#else
+  bool continue_async = errno == EINPROGRESS;
+#endif
+  if (res && !continue_async)
+    return false;
+
+  return true;
+}
+
+void UnixSocketRaw::Shutdown() {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  // Somebody felt very strongly about the naming of this constant.
+  shutdown(*fd_, SD_BOTH);
+#else
+  shutdown(*fd_, SHUT_RDWR);
+#endif
+  fd_.reset();
+}
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+ssize_t UnixSocketRaw::Send(const void* msg,
+                            size_t len,
+                            const int* /*send_fds*/,
+                            size_t num_fds) {
+  PERFETTO_DCHECK(num_fds == 0);
+  return sendto(*fd_, static_cast<const char*>(msg), static_cast<int>(len), 0,
+                nullptr, 0);
+}
+
+ssize_t UnixSocketRaw::Receive(void* msg,
+                               size_t len,
+                               ScopedFile* /*fd_vec*/,
+                               size_t /*max_files*/) {
+  return recv(*fd_, static_cast<char*>(msg), static_cast<int>(len), 0);
+}
+
+#else
+// For the interested reader, Linux kernel dive to verify this is not only a
+// theoretical possibility: sock_stream_sendmsg, if sock_alloc_send_pskb returns
+// NULL [1] (which it does when it gets interrupted [2]), returns early with the
+// amount of bytes already sent.
+//
+// [1]:
+// https://elixir.bootlin.com/linux/v4.18.10/source/net/unix/af_unix.c#L1872
+// [2]: https://elixir.bootlin.com/linux/v4.18.10/source/net/core/sock.c#L2101
+ssize_t UnixSocketRaw::SendMsgAllPosix(struct msghdr* msg) {
+  // This does not make sense on non-blocking sockets.
+  PERFETTO_DCHECK(fd_);
+
+  const bool is_blocking_with_timeout =
+      tx_timeout_ms_ > 0 && ((fcntl(*fd_, F_GETFL, 0) & O_NONBLOCK) == 0);
+  const int64_t start_ms = GetWallTimeMs().count();
+
+  // Waits until some space is available in the tx buffer.
+  // Returns true if some buffer space is available, false if times out.
+  auto poll_or_timeout = [&] {
+    PERFETTO_DCHECK(is_blocking_with_timeout);
+    const int64_t deadline = start_ms + tx_timeout_ms_;
+    const int64_t now_ms = GetWallTimeMs().count();
+    if (now_ms >= deadline)
+      return false;  // Timed out
+    const int timeout_ms = static_cast<int>(deadline - now_ms);
+    pollfd pfd{*fd_, POLLOUT, 0};
+    return PERFETTO_EINTR(poll(&pfd, 1, timeout_ms)) > 0;
+  };
+
+// We implement blocking sends that require a timeout as non-blocking + poll.
+// This is because SO_SNDTIMEO doesn't work as expected (b/193234818). On linux
+// we can just pass MSG_DONTWAIT to force the send to be non-blocking. On Mac,
+// instead we need to flip the O_NONBLOCK flag back and forth.
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+  // MSG_NOSIGNAL is not supported on Mac OS X, but in that case the socket is
+  // created with SO_NOSIGPIPE (See InitializeSocket()).
+  int send_flags = 0;
+
+  if (is_blocking_with_timeout)
+    SetBlocking(false);
+
+  auto reset_nonblock_on_exit = OnScopeExit([&] {
+    if (is_blocking_with_timeout)
+      SetBlocking(true);
+  });
+#else
+  int send_flags = MSG_NOSIGNAL | (is_blocking_with_timeout ? MSG_DONTWAIT : 0);
+#endif
+
+  ssize_t total_sent = 0;
+  while (msg->msg_iov) {
+    ssize_t send_res = PERFETTO_EINTR(sendmsg(*fd_, msg, send_flags));
+    if (send_res == -1 && IsAgain(errno)) {
+      if (is_blocking_with_timeout && poll_or_timeout()) {
+        continue;  // Tx buffer unblocked, repeat the loop.
+      }
+      return total_sent;
+    } else if (send_res <= 0) {
+      return send_res;  // An error occurred.
+    } else {
+      total_sent += send_res;
+      ShiftMsgHdrPosix(static_cast<size_t>(send_res), msg);
+      // Only send the ancillary data with the first sendmsg call.
+      msg->msg_control = nullptr;
+      msg->msg_controllen = 0;
+    }
+  }
+  return total_sent;
+}
+
+ssize_t UnixSocketRaw::Send(const void* msg,
+                            size_t len,
+                            const int* send_fds,
+                            size_t num_fds) {
+  PERFETTO_DCHECK(fd_);
+  msghdr msg_hdr = {};
+  iovec iov = {const_cast<void*>(msg), len};
+  msg_hdr.msg_iov = &iov;
+  msg_hdr.msg_iovlen = 1;
+  alignas(cmsghdr) char control_buf[256];
+
+  if (num_fds > 0) {
+    const auto raw_ctl_data_sz = num_fds * sizeof(int);
+    const CBufLenType control_buf_len =
+        static_cast<CBufLenType>(CMSG_SPACE(raw_ctl_data_sz));
+    PERFETTO_CHECK(control_buf_len <= sizeof(control_buf));
+    memset(control_buf, 0, sizeof(control_buf));
+    msg_hdr.msg_control = control_buf;
+    msg_hdr.msg_controllen = control_buf_len;  // used by CMSG_FIRSTHDR
+    struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg_hdr);
+    cmsg->cmsg_level = SOL_SOCKET;
+    cmsg->cmsg_type = SCM_RIGHTS;
+    cmsg->cmsg_len = static_cast<CBufLenType>(CMSG_LEN(raw_ctl_data_sz));
+    memcpy(CMSG_DATA(cmsg), send_fds, num_fds * sizeof(int));
+    // note: if we were to send multiple cmsghdr structures, then
+    // msg_hdr.msg_controllen would need to be adjusted, see "man 3 cmsg".
+  }
+
+  return SendMsgAllPosix(&msg_hdr);
+}
+
+ssize_t UnixSocketRaw::Receive(void* msg,
+                               size_t len,
+                               ScopedFile* fd_vec,
+                               size_t max_files) {
+  PERFETTO_DCHECK(fd_);
+  msghdr msg_hdr = {};
+  iovec iov = {msg, len};
+  msg_hdr.msg_iov = &iov;
+  msg_hdr.msg_iovlen = 1;
+  alignas(cmsghdr) char control_buf[256];
+
+  if (max_files > 0) {
+    msg_hdr.msg_control = control_buf;
+    msg_hdr.msg_controllen =
+        static_cast<CBufLenType>(CMSG_SPACE(max_files * sizeof(int)));
+    PERFETTO_CHECK(msg_hdr.msg_controllen <= sizeof(control_buf));
+  }
+  const ssize_t sz = PERFETTO_EINTR(recvmsg(*fd_, &msg_hdr, 0));
+  if (sz <= 0) {
+    return sz;
+  }
+  PERFETTO_CHECK(static_cast<size_t>(sz) <= len);
+
+  int* fds = nullptr;
+  uint32_t fds_len = 0;
+
+  if (max_files > 0) {
+    for (cmsghdr* cmsg = CMSG_FIRSTHDR(&msg_hdr); cmsg;
+         cmsg = CMSG_NXTHDR(&msg_hdr, cmsg)) {
+      const size_t payload_len = cmsg->cmsg_len - CMSG_LEN(0);
+      if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
+        PERFETTO_DCHECK(payload_len % sizeof(int) == 0u);
+        PERFETTO_CHECK(fds == nullptr);
+        fds = reinterpret_cast<int*>(CMSG_DATA(cmsg));
+        fds_len = static_cast<uint32_t>(payload_len / sizeof(int));
+      }
+    }
+  }
+
+  if (msg_hdr.msg_flags & MSG_TRUNC || msg_hdr.msg_flags & MSG_CTRUNC) {
+    for (size_t i = 0; fds && i < fds_len; ++i)
+      close(fds[i]);
+    PERFETTO_ELOG(
+        "Socket message truncated. This might be due to a SELinux denial on "
+        "fd:use.");
+    errno = EMSGSIZE;
+    return -1;
+  }
+
+  for (size_t i = 0; fds && i < fds_len; ++i) {
+    if (i < max_files)
+      fd_vec[i].reset(fds[i]);
+    else
+      close(fds[i]);
+  }
+
+  return sz;
+}
+#endif  // OS_WIN
+
+bool UnixSocketRaw::SetTxTimeout(uint32_t timeout_ms) {
+  PERFETTO_DCHECK(fd_);
+  // On Unix-based systems, SO_SNDTIMEO isn't used for Send() because it's
+  // unreliable (b/193234818). Instead we use non-blocking sendmsg() + poll().
+  // See SendMsgAllPosix(). We still make the setsockopt call because
+  // SO_SNDTIMEO also affects connect().
+  tx_timeout_ms_ = timeout_ms;
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  DWORD timeout = timeout_ms;
+  ignore_result(tx_timeout_ms_);
+#else
+  struct timeval timeout {};
+  uint32_t timeout_sec = timeout_ms / 1000;
+  timeout.tv_sec = static_cast<decltype(timeout.tv_sec)>(timeout_sec);
+  timeout.tv_usec = static_cast<decltype(timeout.tv_usec)>(
+      (timeout_ms - (timeout_sec * 1000)) * 1000);
+#endif
+  return setsockopt(*fd_, SOL_SOCKET, SO_SNDTIMEO,
+                    reinterpret_cast<const char*>(&timeout),
+                    sizeof(timeout)) == 0;
+}
+
+bool UnixSocketRaw::SetRxTimeout(uint32_t timeout_ms) {
+  PERFETTO_DCHECK(fd_);
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  DWORD timeout = timeout_ms;
+#else
+  struct timeval timeout {};
+  uint32_t timeout_sec = timeout_ms / 1000;
+  timeout.tv_sec = static_cast<decltype(timeout.tv_sec)>(timeout_sec);
+  timeout.tv_usec = static_cast<decltype(timeout.tv_usec)>(
+      (timeout_ms - (timeout_sec * 1000)) * 1000);
+#endif
+  return setsockopt(*fd_, SOL_SOCKET, SO_RCVTIMEO,
+                    reinterpret_cast<const char*>(&timeout),
+                    sizeof(timeout)) == 0;
+}
+
+std::string UnixSocketRaw::GetSockAddr() const {
+  struct sockaddr_storage stg {};
+  socklen_t slen = sizeof(stg);
+  PERFETTO_CHECK(
+      getsockname(*fd_, reinterpret_cast<struct sockaddr*>(&stg), &slen) == 0);
+  char addr[255]{};
+
+  if (stg.ss_family == AF_UNIX) {
+    auto* saddr = reinterpret_cast<struct sockaddr_un*>(&stg);
+    static_assert(sizeof(addr) >= sizeof(saddr->sun_path), "addr too small");
+    memcpy(addr, saddr->sun_path, sizeof(saddr->sun_path));
+    addr[0] = addr[0] == '\0' ? '@' : addr[0];
+    addr[sizeof(saddr->sun_path) - 1] = '\0';
+    return std::string(addr);
+  }
+
+  if (stg.ss_family == AF_INET) {
+    auto* saddr = reinterpret_cast<struct sockaddr_in*>(&stg);
+    PERFETTO_CHECK(inet_ntop(AF_INET, &saddr->sin_addr, addr, sizeof(addr)));
+    uint16_t port = ntohs(saddr->sin_port);
+    base::StackString<255> addr_and_port("%s:%" PRIu16, addr, port);
+    return addr_and_port.ToStdString();
+  }
+
+  if (stg.ss_family == AF_INET6) {
+    auto* saddr = reinterpret_cast<struct sockaddr_in6*>(&stg);
+    PERFETTO_CHECK(inet_ntop(AF_INET6, &saddr->sin6_addr, addr, sizeof(addr)));
+    auto port = ntohs(saddr->sin6_port);
+    base::StackString<255> addr_and_port("[%s]:%" PRIu16, addr, port);
+    return addr_and_port.ToStdString();
+  }
+
+#if defined(AF_VSOCK) && (PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+                          PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID))
+  if (stg.ss_family == AF_VSOCK) {
+    auto* saddr = reinterpret_cast<struct sockaddr_vm*>(&stg);
+    base::StackString<255> addr_and_port("%s%d:%d", kVsockNamePrefix,
+                                         saddr->svm_cid, saddr->svm_port);
+    return addr_and_port.ToStdString();
+  }
+#endif
+
+  PERFETTO_FATAL("GetSockAddr() unsupported on family %d", stg.ss_family);
+}
+
+#if defined(__GNUC__) && !PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+#pragma GCC diagnostic pop
+#endif
+
+// +--------------------+
+// | UnixSocket methods |
+// +--------------------+
+
+// TODO(primiano): Add ThreadChecker to methods of this class.
+
+// static
+std::unique_ptr<UnixSocket> UnixSocket::Listen(const std::string& socket_name,
+                                               EventListener* event_listener,
+                                               TaskRunner* task_runner,
+                                               SockFamily sock_family,
+                                               SockType sock_type) {
+  auto sock_raw = UnixSocketRaw::CreateMayFail(sock_family, sock_type);
+  if (!sock_raw || !sock_raw.Bind(socket_name))
+    return nullptr;
+
+  // Forward the call to the Listen() overload below.
+  return Listen(sock_raw.ReleaseFd(), event_listener, task_runner, sock_family,
+                sock_type);
+}
+
+// static
+std::unique_ptr<UnixSocket> UnixSocket::Listen(ScopedSocketHandle fd,
+                                               EventListener* event_listener,
+                                               TaskRunner* task_runner,
+                                               SockFamily sock_family,
+                                               SockType sock_type) {
+  return std::unique_ptr<UnixSocket>(new UnixSocket(
+      event_listener, task_runner, std::move(fd), State::kListening,
+      sock_family, sock_type, SockPeerCredMode::kDefault));
+}
+
+// static
+std::unique_ptr<UnixSocket> UnixSocket::Connect(
+    const std::string& socket_name,
+    EventListener* event_listener,
+    TaskRunner* task_runner,
+    SockFamily sock_family,
+    SockType sock_type,
+    SockPeerCredMode peer_cred_mode) {
+  std::unique_ptr<UnixSocket> sock(new UnixSocket(
+      event_listener, task_runner, sock_family, sock_type, peer_cred_mode));
+  sock->DoConnect(socket_name);
+  return sock;
+}
+
+// static
+std::unique_ptr<UnixSocket> UnixSocket::AdoptConnected(
+    ScopedSocketHandle fd,
+    EventListener* event_listener,
+    TaskRunner* task_runner,
+    SockFamily sock_family,
+    SockType sock_type,
+    SockPeerCredMode peer_cred_mode) {
+  return std::unique_ptr<UnixSocket>(new UnixSocket(
+      event_listener, task_runner, std::move(fd), State::kConnected,
+      sock_family, sock_type, peer_cred_mode));
+}
+
+UnixSocket::UnixSocket(EventListener* event_listener,
+                       TaskRunner* task_runner,
+                       SockFamily sock_family,
+                       SockType sock_type,
+                       SockPeerCredMode peer_cred_mode)
+    : UnixSocket(event_listener,
+                 task_runner,
+                 ScopedSocketHandle(),
+                 State::kDisconnected,
+                 sock_family,
+                 sock_type,
+                 peer_cred_mode) {}
+
+UnixSocket::UnixSocket(EventListener* event_listener,
+                       TaskRunner* task_runner,
+                       ScopedSocketHandle adopt_fd,
+                       State adopt_state,
+                       SockFamily sock_family,
+                       SockType sock_type,
+                       SockPeerCredMode peer_cred_mode)
+    : peer_cred_mode_(peer_cred_mode),
+      event_listener_(event_listener),
+      task_runner_(task_runner),
+      weak_ptr_factory_(this) {
+  state_ = State::kDisconnected;
+  if (adopt_state == State::kDisconnected) {
+    PERFETTO_DCHECK(!adopt_fd);
+    sock_raw_ = UnixSocketRaw::CreateMayFail(sock_family, sock_type);
+    if (!sock_raw_)
+      return;
+  } else if (adopt_state == State::kConnected) {
+    PERFETTO_DCHECK(adopt_fd);
+    sock_raw_ = UnixSocketRaw(std::move(adopt_fd), sock_family, sock_type);
+    state_ = State::kConnected;
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    if (peer_cred_mode_ == SockPeerCredMode::kReadOnConnect)
+      ReadPeerCredentialsPosix();
+#endif
+  } else if (adopt_state == State::kListening) {
+    // We get here from Listen().
+
+    // |adopt_fd| might genuinely be invalid if the bind() failed.
+    if (!adopt_fd)
+      return;
+
+    sock_raw_ = UnixSocketRaw(std::move(adopt_fd), sock_family, sock_type);
+    if (!sock_raw_.Listen()) {
+      PERFETTO_DPLOG("listen() failed");
+      return;
+    }
+    state_ = State::kListening;
+  } else {
+    PERFETTO_FATAL("Unexpected adopt_state");  // Unfeasible.
+  }
+
+  PERFETTO_CHECK(sock_raw_);
+
+  sock_raw_.SetBlocking(false);
+
+  WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
+
+  task_runner_->AddFileDescriptorWatch(sock_raw_.watch_handle(), [weak_ptr] {
+    if (weak_ptr)
+      weak_ptr->OnEvent();
+  });
+}
+
+UnixSocket::~UnixSocket() {
+  // The implicit dtor of |weak_ptr_factory_| will no-op pending callbacks.
+  Shutdown(true);
+}
+
+UnixSocketRaw UnixSocket::ReleaseSocket() {
+  // This will invalidate any pending calls to OnEvent.
+  state_ = State::kDisconnected;
+  if (sock_raw_)
+    task_runner_->RemoveFileDescriptorWatch(sock_raw_.watch_handle());
+
+  return std::move(sock_raw_);
+}
+
+// Called only by the Connect() static constructor.
+void UnixSocket::DoConnect(const std::string& socket_name) {
+  PERFETTO_DCHECK(state_ == State::kDisconnected);
+
+  // This is the only thing that can gracefully fail in the ctor.
+  if (!sock_raw_)
+    return NotifyConnectionState(false);
+
+  if (!sock_raw_.Connect(socket_name))
+    return NotifyConnectionState(false);
+
+  // At this point either connect() succeeded or started asynchronously
+  // (errno = EINPROGRESS).
+  state_ = State::kConnecting;
+
+  // Even if the socket is non-blocking, connecting to a UNIX socket can be
+  // acknowledged straight away rather than returning EINPROGRESS.
+  // The decision here is to deal with the two cases uniformly, at the cost of
+  // delaying the straight-away-connect() case by one task, to avoid depending
+  // on implementation details of UNIX socket on the various OSes.
+  // Posting the OnEvent() below emulates a wakeup of the FD watch. OnEvent(),
+  // which knows how to deal with spurious wakeups, will poll the SO_ERROR and
+  // evolve, if necessary, the state into either kConnected or kDisconnected.
+  WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostTask([weak_ptr] {
+    if (weak_ptr)
+      weak_ptr->OnEvent();
+  });
+}
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+void UnixSocket::ReadPeerCredentialsPosix() {
+  // Peer credentials are supported only on AF_UNIX sockets.
+  if (sock_raw_.family() != SockFamily::kUnix)
+    return;
+  PERFETTO_CHECK(peer_cred_mode_ != SockPeerCredMode::kIgnore);
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  struct ucred user_cred;
+  socklen_t len = sizeof(user_cred);
+  int fd = sock_raw_.fd();
+  int res = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &user_cred, &len);
+  PERFETTO_CHECK(res == 0);
+  peer_uid_ = user_cred.uid;
+  peer_pid_ = user_cred.pid;
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+  struct xucred user_cred;
+  socklen_t len = sizeof(user_cred);
+  int res = getsockopt(sock_raw_.fd(), 0, LOCAL_PEERCRED, &user_cred, &len);
+  PERFETTO_CHECK(res == 0 && user_cred.cr_version == XUCRED_VERSION);
+  peer_uid_ = static_cast<uid_t>(user_cred.cr_uid);
+  // There is no pid in the LOCAL_PEERCREDS for MacOS / FreeBSD.
+#endif
+}
+#endif  // !OS_WIN
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+void UnixSocket::OnEvent() {
+  WSANETWORKEVENTS evts{};
+  PERFETTO_CHECK(WSAEnumNetworkEvents(sock_raw_.fd(), sock_raw_.watch_handle(),
+                                      &evts) == 0);
+  if (state_ == State::kDisconnected)
+    return;  // Some spurious event, typically queued just before Shutdown().
+
+  if (state_ == State::kConnecting && (evts.lNetworkEvents & FD_CONNECT)) {
+    PERFETTO_DCHECK(sock_raw_);
+    int err = evts.iErrorCode[FD_CONNECT_BIT];
+    if (err) {
+      PERFETTO_DPLOG("Connection error: %d", err);
+      Shutdown(false);
+      event_listener_->OnConnect(this, false /* connected */);
+      return;
+    }
+
+    // kReadOnConnect is not supported on Windows.
+    PERFETTO_DCHECK(peer_cred_mode_ != SockPeerCredMode::kReadOnConnect);
+    state_ = State::kConnected;
+    event_listener_->OnConnect(this, true /* connected */);
+  }
+
+  // This is deliberately NOT an else-if. When a client socket connects and
+  // there is already data queued, the following will happen within the same
+  // OnEvent() call:
+  // 1. The block above will transition kConnecting -> kConnected.
+  // 2. This block will cause an OnDataAvailable() call.
+  // Unlike UNIX, where poll() keeps signalling the event until the client
+  // does a recv(), Windows is more picky and stops signalling the event until
+  // the next call to recv() is made. In other words, in Windows we cannot
+  // miss an OnDataAvailable() call or the event pump will stop.
+  if (state_ == State::kConnected) {
+    if (evts.lNetworkEvents & FD_READ) {
+      event_listener_->OnDataAvailable(this);
+      // TODO(primiano): I am very conflicted here. Because of the behavior
+      // described above, if the event listener doesn't do a Recv() call in
+      // the OnDataAvailable() callback, WinSock won't notify the event ever
+      // again. On one side, I don't see any reason why a client should decide
+      // to not do a Recv() in OnDataAvailable. On the other side, the
+      // behavior here diverges from UNIX, where OnDataAvailable() would be
+      // re-posted immediately. In both cases, not doing a Recv() in
+      // OnDataAvailable, leads to something bad (getting stuck on Windows,
+      // getting in a hot loop on Linux), so doesn't feel we should worry too
+      // much about this. If we wanted to keep the behavrior consistent, here
+      // we should do something like: `if (sock_raw_)
+      // sock_raw_.SetBlocking(false)` (Note that the socket might be closed
+      // by the time we come back here, hence the if part).
+      return;
+    }
+    // Could read EOF and disconnect here.
+    if (evts.lNetworkEvents & FD_CLOSE) {
+      Shutdown(true);
+      return;
+    }
+  }
+
+  // New incoming connection.
+  if (state_ == State::kListening && (evts.lNetworkEvents & FD_ACCEPT)) {
+    // There could be more than one incoming connection behind each FD watch
+    // notification. Drain'em all.
+    for (;;) {
+      // Note: right now we don't need the remote endpoint, hence we pass
+      // nullptr to |addr| and |addrlen|. If we ever need to do so, be
+      // extremely careful. Windows' WinSock API will happily write more than
+      // |addrlen| (hence corrupt the stack) if the |addr| argument passed is
+      // not big enough (e.g. passing a struct sockaddr_in to a AF_UNIX
+      // socket, where sizeof(sockaddr_un) is >> sizef(sockaddr_in)). It seems
+      // a Windows / CRT bug in the AF_UNIX implementation.
+      ScopedSocketHandle new_fd(accept(sock_raw_.fd(), nullptr, nullptr));
+      if (!new_fd)
+        return;
+      std::unique_ptr<UnixSocket> new_sock(new UnixSocket(
+          event_listener_, task_runner_, std::move(new_fd), State::kConnected,
+          sock_raw_.family(), sock_raw_.type(), peer_cred_mode_));
+      event_listener_->OnNewIncomingConnection(this, std::move(new_sock));
+    }
+  }
+}
+#else
+void UnixSocket::OnEvent() {
+  if (state_ == State::kDisconnected)
+    return;  // Some spurious event, typically queued just before Shutdown().
+
+  if (state_ == State::kConnected)
+    return event_listener_->OnDataAvailable(this);
+
+  if (state_ == State::kConnecting) {
+    PERFETTO_DCHECK(sock_raw_);
+    int sock_err = EINVAL;
+    socklen_t err_len = sizeof(sock_err);
+    int res =
+        getsockopt(sock_raw_.fd(), SOL_SOCKET, SO_ERROR, &sock_err, &err_len);
+
+    if (res == 0 && sock_err == EINPROGRESS)
+      return;  // Not connected yet, just a spurious FD watch wakeup.
+    if (res == 0 && sock_err == 0) {
+      if (peer_cred_mode_ == SockPeerCredMode::kReadOnConnect)
+        ReadPeerCredentialsPosix();
+      state_ = State::kConnected;
+      return event_listener_->OnConnect(this, true /* connected */);
+    }
+    PERFETTO_DLOG("Connection error: %s", strerror(sock_err));
+    Shutdown(false);
+    return event_listener_->OnConnect(this, false /* connected */);
+  }
+
+  // New incoming connection.
+  if (state_ == State::kListening) {
+    // There could be more than one incoming connection behind each FD watch
+    // notification. Drain'em all.
+    for (;;) {
+      ScopedFile new_fd(
+          PERFETTO_EINTR(accept(sock_raw_.fd(), nullptr, nullptr)));
+      if (!new_fd)
+        return;
+      std::unique_ptr<UnixSocket> new_sock(new UnixSocket(
+          event_listener_, task_runner_, std::move(new_fd), State::kConnected,
+          sock_raw_.family(), sock_raw_.type(), peer_cred_mode_));
+      event_listener_->OnNewIncomingConnection(this, std::move(new_sock));
+    }
+  }
+}
+#endif
+
+bool UnixSocket::Send(const void* msg,
+                      size_t len,
+                      const int* send_fds,
+                      size_t num_fds) {
+  if (state_ != State::kConnected) {
+    errno = ENOTCONN;
+    return false;
+  }
+
+  sock_raw_.SetBlocking(true);
+  const ssize_t sz = sock_raw_.Send(msg, len, send_fds, num_fds);
+  sock_raw_.SetBlocking(false);
+
+  if (sz == static_cast<ssize_t>(len)) {
+    return true;
+  }
+
+  // If we ever decide to support non-blocking sends again, here we should
+  // watch for both EAGAIN and EWOULDBLOCK (see base::IsAgain()).
+
+  // If sendmsg() succeeds but the returned size is >= 0 and < |len| it means
+  // that the endpoint disconnected in the middle of the read, and we managed
+  // to send only a portion of the buffer.
+  // If sz < 0, either the other endpoint disconnected (ECONNRESET) or some
+  // other error happened. In both cases we should just give up.
+  PERFETTO_DPLOG("sendmsg() failed");
+  Shutdown(true);
+  return false;
+}
+
+void UnixSocket::Shutdown(bool notify) {
+  WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
+  if (notify) {
+    if (state_ == State::kConnected) {
+      task_runner_->PostTask([weak_ptr] {
+        if (weak_ptr)
+          weak_ptr->event_listener_->OnDisconnect(weak_ptr.get());
+      });
+    } else if (state_ == State::kConnecting) {
+      task_runner_->PostTask([weak_ptr] {
+        if (weak_ptr)
+          weak_ptr->event_listener_->OnConnect(weak_ptr.get(), false);
+      });
+    }
+  }
+
+  if (sock_raw_) {
+    task_runner_->RemoveFileDescriptorWatch(sock_raw_.watch_handle());
+    sock_raw_.Shutdown();
+  }
+  state_ = State::kDisconnected;
+}
+
+size_t UnixSocket::Receive(void* msg,
+                           size_t len,
+                           ScopedFile* fd_vec,
+                           size_t max_files) {
+  if (state_ != State::kConnected)
+    return 0;
+
+  const ssize_t sz = sock_raw_.Receive(msg, len, fd_vec, max_files);
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  bool async_would_block = WSAGetLastError() == WSAEWOULDBLOCK;
+#else
+  bool async_would_block = IsAgain(errno);
+#endif
+  if (sz < 0 && async_would_block)
+    return 0;
+
+  if (sz <= 0) {
+    Shutdown(true);
+    return 0;
+  }
+  PERFETTO_CHECK(static_cast<size_t>(sz) <= len);
+  return static_cast<size_t>(sz);
+}
+
+std::string UnixSocket::ReceiveString(size_t max_length) {
+  std::unique_ptr<char[]> buf(new char[max_length + 1]);
+  size_t rsize = Receive(buf.get(), max_length);
+  PERFETTO_CHECK(rsize <= max_length);
+  buf[rsize] = '\0';
+  return std::string(buf.get());
+}
+
+void UnixSocket::NotifyConnectionState(bool success) {
+  if (!success)
+    Shutdown(false);
+
+  WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostTask([weak_ptr, success] {
+    if (weak_ptr)
+      weak_ptr->event_listener_->OnConnect(weak_ptr.get(), success);
+  });
+}
+
+UnixSocket::EventListener::~EventListener() {}
+void UnixSocket::EventListener::OnNewIncomingConnection(
+    UnixSocket*,
+    std::unique_ptr<UnixSocket>) {}
+void UnixSocket::EventListener::OnConnect(UnixSocket*, bool) {}
+void UnixSocket::EventListener::OnDisconnect(UnixSocket*) {}
+void UnixSocket::EventListener::OnDataAvailable(UnixSocket*) {}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/ipc/buffered_frame_deserializer.cc
+// gen_amalgamated begin header: src/ipc/buffered_frame_deserializer.h
+// gen_amalgamated begin header: include/perfetto/ext/ipc/basic_types.h
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_IPC_BASIC_TYPES_H_
+#define INCLUDE_PERFETTO_EXT_IPC_BASIC_TYPES_H_
+
+#include <stddef.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+
+namespace perfetto {
+namespace ipc {
+
+using ProtoMessage = ::protozero::CppMessageObj;
+using ServiceID = uint32_t;
+using MethodID = uint32_t;
+using ClientID = uint64_t;
+using RequestID = uint64_t;
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+// AF_UNIX on Windows is supported only on Windows 10 from build 17063.
+// Also it doesn't bring major advantages compared to a TCP socket.
+// See go/perfetto-win .
+constexpr bool kUseTCPSocket = true;
+#else
+// Android, Linux, Mac, Fuchsia use local sockets.
+constexpr bool kUseTCPSocket = false;
+#endif
+
+// This determines the maximum size allowed for an IPC message. Trying to send
+// or receive a larger message will hit DCHECK(s) and auto-disconnect.
+constexpr size_t kIPCBufferSize = 128 * 1024;
+
+constexpr uid_t kInvalidUid = static_cast<uid_t>(-1);
+
+}  // namespace ipc
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_IPC_BASIC_TYPES_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_IPC_BUFFERED_FRAME_DESERIALIZER_H_
+#define SRC_IPC_BUFFERED_FRAME_DESERIALIZER_H_
+
+#include <stddef.h>
+
+#include <list>
+#include <memory>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/paged_memory.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
+
+namespace perfetto {
+
+namespace protos {
+namespace gen {
+class IPCFrame;
+}  // namespace gen
+}  // namespace protos
+
+namespace ipc {
+
+using Frame = ::perfetto::protos::gen::IPCFrame;
+
+// Deserializes incoming frames, taking care of buffering and tokenization.
+// Used by both host and client to decode incoming frames.
+//
+// Which problem does it solve?
+// ----------------------------
+// The wire protocol is as follows:
+// [32-bit frame size][proto-encoded Frame], e.g:
+// [06 00 00 00][00 11 22 33 44 55 66]
+// [02 00 00 00][AA BB]
+// [04 00 00 00][CC DD EE FF]
+// However, given that the socket works in SOCK_STREAM mode, the recv() calls
+// might see the following:
+// 06 00 00
+// 00 00 11 22 33 44 55
+// 66 02 00 00 00 ...
+// This class takes care of buffering efficiently the data received, without
+// making any assumption on how the incoming data will be chunked by the socket.
+// For instance, it is possible that a recv() doesn't produce any frame (because
+// it received only a part of the frame) or produces more than one frame.
+//
+// Usage
+// -----
+// Both host and client use this as follows:
+//
+// auto buf = rpc_frame_decoder.BeginReceive();
+// size_t rsize = socket.recv(buf.first, buf.second);
+// rpc_frame_decoder.EndReceive(rsize);
+// while (Frame frame = rpc_frame_decoder.PopNextFrame()) {
+//   ... process |frame|
+// }
+//
+// Design goals:
+// -------------
+// - Optimize for the realistic case of each recv() receiving one or more
+//   whole frames. In this case no memmove is performed.
+// - Guarantee that frames lay in a virtually contiguous memory area.
+//   This allows to use the protobuf-lite deserialization API (scattered
+//   deserialization is supported only by libprotobuf-full).
+// - Put a hard boundary to the size of the incoming buffer. This is to prevent
+//   that a malicious sends an abnormally large frame and OOMs us.
+// - Simplicity: just use a linear mmap region. No reallocations or scattering.
+//   Takes care of madvise()-ing unused memory.
+
+class BufferedFrameDeserializer {
+ public:
+  struct ReceiveBuffer {
+    char* data;
+    size_t size;
+  };
+
+  // |max_capacity| is overridable only for tests.
+  explicit BufferedFrameDeserializer(size_t max_capacity = kIPCBufferSize);
+  ~BufferedFrameDeserializer();
+
+  // This function doesn't really belong here as it does Serialization, unlike
+  // the rest of this class. However it is so small and has so many dependencies
+  // in common that doesn't justify having its own class.
+  static std::string Serialize(const Frame&);
+
+  // Returns a buffer that can be passed to recv(). The buffer is deliberately
+  // not initialized.
+  ReceiveBuffer BeginReceive();
+
+  // Must be called soon after BeginReceive().
+  // |recv_size| is the number of valid bytes that have been written into the
+  // buffer previously returned by BeginReceive() (the return value of recv()).
+  // Returns false if a header > |max_capacity| is received, in which case the
+  // caller is expected to shutdown the socket and terminate the ipc.
+  bool EndReceive(size_t recv_size) PERFETTO_WARN_UNUSED_RESULT;
+
+  // Decodes and returns the next decoded frame in the buffer if any, nullptr
+  // if no further frames have been decoded.
+  std::unique_ptr<Frame> PopNextFrame();
+
+  size_t capacity() const { return capacity_; }
+  size_t size() const { return size_; }
+
+ private:
+  BufferedFrameDeserializer(const BufferedFrameDeserializer&) = delete;
+  BufferedFrameDeserializer& operator=(const BufferedFrameDeserializer&) =
+      delete;
+
+  // If a valid frame is decoded it is added to |decoded_frames_|.
+  void DecodeFrame(const char*, size_t);
+
+  char* buf() { return reinterpret_cast<char*>(buf_.Get()); }
+
+  base::PagedMemory buf_;
+  const size_t capacity_ = 0;  // sizeof(|buf_|).
+
+  // THe number of bytes in |buf_| that contain valid data (as a result of
+  // EndReceive()). This is always <= |capacity_|.
+  size_t size_ = 0;
+
+  std::list<std::unique_ptr<Frame>> decoded_frames_;
+};
+
+}  // namespace ipc
+}  // namespace perfetto
+
+#endif  // SRC_IPC_BUFFERED_FRAME_DESERIALIZER_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "src/ipc/buffered_frame_deserializer.h"
+
+#include <algorithm>
+#include <cinttypes>
+#include <type_traits>
+#include <utility>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/ipc/wire_protocol.gen.h"
+
+namespace perfetto {
+namespace ipc {
+
+namespace {
+
+// The header is just the number of bytes of the Frame protobuf message.
+constexpr size_t kHeaderSize = sizeof(uint32_t);
+}  // namespace
+
+BufferedFrameDeserializer::BufferedFrameDeserializer(size_t max_capacity)
+    : capacity_(max_capacity) {
+  PERFETTO_CHECK(max_capacity % base::GetSysPageSize() == 0);
+  PERFETTO_CHECK(max_capacity >= base::GetSysPageSize());
+}
+
+BufferedFrameDeserializer::~BufferedFrameDeserializer() = default;
+
+BufferedFrameDeserializer::ReceiveBuffer
+BufferedFrameDeserializer::BeginReceive() {
+  // Upon the first recv initialize the buffer to the max message size but
+  // release the physical memory for all but the first page. The kernel will
+  // automatically give us physical pages back as soon as we page-fault on them.
+  if (!buf_.IsValid()) {
+    PERFETTO_DCHECK(size_ == 0);
+    // TODO(eseckler): Don't commit all of the buffer at once on Windows.
+    buf_ = base::PagedMemory::Allocate(capacity_);
+
+    // Surely we are going to use at least the first page, but we may not need
+    // the rest for a bit.
+    const auto page_size = base::GetSysPageSize();
+    buf_.AdviseDontNeed(buf() + page_size, capacity_ - page_size);
+  }
+
+  PERFETTO_CHECK(capacity_ > size_);
+  return ReceiveBuffer{buf() + size_, capacity_ - size_};
+}
+
+bool BufferedFrameDeserializer::EndReceive(size_t recv_size) {
+  const auto page_size = base::GetSysPageSize();
+  PERFETTO_CHECK(recv_size + size_ <= capacity_);
+  size_ += recv_size;
+
+  // At this point the contents buf_ can contain:
+  // A) Only a fragment of the header (the size of the frame). E.g.,
+  //    03 00 00 (the header is 4 bytes, one is missing).
+  //
+  // B) A header and a part of the frame. E.g.,
+  //     05 00 00 00         11 22 33
+  //    [ header, size=5 ]  [ Partial frame ]
+  //
+  // C) One or more complete header+frame. E.g.,
+  //     05 00 00 00         11 22 33 44 55   03 00 00 00        AA BB CC
+  //    [ header, size=5 ]  [ Whole frame ]  [ header, size=3 ] [ Whole frame ]
+  //
+  // D) Some complete header+frame(s) and a partial header or frame (C + A/B).
+  //
+  // C Is the more likely case and the one we are optimizing for. A, B, D can
+  // happen because of the streaming nature of the socket.
+  // The invariant of this function is that, when it returns, buf_ is either
+  // empty (we drained all the complete frames) or starts with the header of the
+  // next, still incomplete, frame.
+
+  size_t consumed_size = 0;
+  for (;;) {
+    if (size_ < consumed_size + kHeaderSize)
+      break;  // Case A, not enough data to read even the header.
+
+    // Read the header into |payload_size|.
+    uint32_t payload_size = 0;
+    const char* rd_ptr = buf() + consumed_size;
+    memcpy(base::AssumeLittleEndian(&payload_size), rd_ptr, kHeaderSize);
+
+    // Saturate the |payload_size| to prevent overflows. The > capacity_ check
+    // below will abort the parsing.
+    size_t next_frame_size =
+        std::min(static_cast<size_t>(payload_size), capacity_);
+    next_frame_size += kHeaderSize;
+    rd_ptr += kHeaderSize;
+
+    if (size_ < consumed_size + next_frame_size) {
+      // Case B. We got the header but not the whole frame.
+      if (next_frame_size > capacity_) {
+        // The caller is expected to shut down the socket and give up at this
+        // point. If it doesn't do that and insists going on at some point it
+        // will hit the capacity check in BeginReceive().
+        PERFETTO_LOG("IPC Frame too large (size %zu)", next_frame_size);
+        return false;
+      }
+      break;
+    }
+
+    // Case C. We got at least one header and whole frame.
+    DecodeFrame(rd_ptr, payload_size);
+    consumed_size += next_frame_size;
+  }
+
+  PERFETTO_DCHECK(consumed_size <= size_);
+  if (consumed_size > 0) {
+    // Shift out the consumed data from the buffer. In the typical case (C)
+    // there is nothing to shift really, just setting size_ = 0 is enough.
+    // Shifting is only for the (unlikely) case D.
+    size_ -= consumed_size;
+    if (size_ > 0) {
+      // Case D. We consumed some frames but there is a leftover at the end of
+      // the buffer. Shift out the consumed bytes, so that on the next round
+      // |buf_| starts with the header of the next unconsumed frame.
+      const char* move_begin = buf() + consumed_size;
+      PERFETTO_CHECK(move_begin > buf());
+      PERFETTO_CHECK(move_begin + size_ <= buf() + capacity_);
+      memmove(buf(), move_begin, size_);
+    }
+    // If we just finished decoding a large frame that used more than one page,
+    // release the extra memory in the buffer. Large frames should be quite
+    // rare.
+    if (consumed_size > page_size) {
+      size_t size_rounded_up = (size_ / page_size + 1) * page_size;
+      if (size_rounded_up < capacity_) {
+        char* madvise_begin = buf() + size_rounded_up;
+        const size_t madvise_size = capacity_ - size_rounded_up;
+        PERFETTO_CHECK(madvise_begin > buf() + size_);
+        PERFETTO_CHECK(madvise_begin + madvise_size <= buf() + capacity_);
+        buf_.AdviseDontNeed(madvise_begin, madvise_size);
+      }
+    }
+  }
+  // At this point |size_| == 0 for case C, > 0 for cases A, B, D.
+  return true;
+}
+
+std::unique_ptr<Frame> BufferedFrameDeserializer::PopNextFrame() {
+  if (decoded_frames_.empty())
+    return nullptr;
+  std::unique_ptr<Frame> frame = std::move(decoded_frames_.front());
+  decoded_frames_.pop_front();
+  return frame;
+}
+
+void BufferedFrameDeserializer::DecodeFrame(const char* data, size_t size) {
+  if (size == 0)
+    return;
+  std::unique_ptr<Frame> frame(new Frame);
+  if (frame->ParseFromArray(data, size))
+    decoded_frames_.push_back(std::move(frame));
+}
+
+// static
+std::string BufferedFrameDeserializer::Serialize(const Frame& frame) {
+  std::vector<uint8_t> payload = frame.SerializeAsArray();
+  const uint32_t payload_size = static_cast<uint32_t>(payload.size());
+  std::string buf;
+  buf.resize(kHeaderSize + payload_size);
+  memcpy(&buf[0], base::AssumeLittleEndian(&payload_size), kHeaderSize);
+  memcpy(&buf[kHeaderSize], payload.data(), payload.size());
+  return buf;
+}
+
+}  // namespace ipc
+}  // namespace perfetto
+// gen_amalgamated begin source: src/ipc/deferred.cc
+// gen_amalgamated begin header: include/perfetto/ext/ipc/deferred.h
+// gen_amalgamated begin header: include/perfetto/ext/ipc/async_result.h
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_IPC_ASYNC_RESULT_H_
+#define INCLUDE_PERFETTO_EXT_IPC_ASYNC_RESULT_H_
+
+#include <memory>
+#include <type_traits>
+#include <utility>
+
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
+
+namespace perfetto {
+namespace ipc {
+
+// Wraps the result of an asynchronous invocation. This is the equivalent of a
+// std::pair<unique_ptr<T>, bool> with syntactic sugar. It is used as callback
+// argument by Deferred<T>. T is a ProtoMessage subclass (i.e. generated .pb.h).
+template <typename T>
+class AsyncResult {
+ public:
+  static AsyncResult Create() {
+    return AsyncResult(std::unique_ptr<T>(new T()));
+  }
+
+  AsyncResult(std::unique_ptr<T> msg = nullptr,
+              bool has_more = false,
+              int fd = -1)
+      : msg_(std::move(msg)), has_more_(has_more), fd_(fd) {
+    static_assert(std::is_base_of<ProtoMessage, T>::value, "T->ProtoMessage");
+  }
+  AsyncResult(AsyncResult&&) noexcept = default;
+  AsyncResult& operator=(AsyncResult&&) = default;
+
+  bool success() const { return !!msg_; }
+  explicit operator bool() const { return success(); }
+
+  bool has_more() const { return has_more_; }
+  void set_has_more(bool has_more) { has_more_ = has_more; }
+
+  void set_msg(std::unique_ptr<T> msg) { msg_ = std::move(msg); }
+  T* release_msg() { return msg_.release(); }
+  T* operator->() { return msg_.get(); }
+  T& operator*() { return *msg_; }
+
+  void set_fd(int fd) { fd_ = fd; }
+  int fd() const { return fd_; }
+
+ private:
+  std::unique_ptr<T> msg_;
+  bool has_more_ = false;
+
+  // Optional. Only for messages that convey a file descriptor, for sharing
+  // memory across processes.
+  int fd_ = -1;
+};
+
+}  // namespace ipc
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_IPC_ASYNC_RESULT_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_IPC_DEFERRED_H_
+#define INCLUDE_PERFETTO_EXT_IPC_DEFERRED_H_
+
+#include <functional>
+#include <memory>
+#include <utility>
+
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/async_result.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
+
+namespace perfetto {
+namespace ipc {
+
+// This class is a wrapper for a callback handling async results.
+// The problem this is solving is the following: For each result argument of the
+// methods generated from the .proto file:
+// - The client wants to see something on which it can Bind() a callback, which
+//   is invoked asynchronously once reply is received from the host.
+// - The host wants to expose something to user code that implements the IPC
+//   methods to allow them to provide an asynchronous reply back to the client.
+//   Eventually even more than once, for the case streaming replies.
+//
+// In both cases we want to make sure that callbacks don't get lost along the
+// way. To address this, this class will automatically reject the callbacks
+// if they are not resolved at destructor time (or the object is std::move()'d).
+//
+// The client is supposed to use this class as follows:
+//   class GreeterProxy {
+//      void SayHello(const HelloRequest&, Deferred<HelloReply> reply)
+//   }
+//  ...
+//  Deferred<HelloReply> reply;
+//  reply.Bind([] (AsyncResult<HelloReply> reply) {
+//    std::cout << reply.success() ? reply->message : "failure";
+//  });
+//  host_proxy_instance.SayHello(req, std::move(reply));
+//
+// The host instead is supposed to use this as follows:
+//   class GreeterImpl : public Greeter {
+//     void SayHello(const HelloRequest& req, Deferred<HelloReply> reply) {
+//        AsyncResult<HelloReply> reply = AsyncResult<HelloReply>::Create();
+//        reply->set_greeting("Hello " + req.name)
+//        reply.Resolve(std::move(reply));
+//     }
+//   }
+// Or for more complex cases, the deferred object can be std::move()'d outside
+// and the reply can continue asynchronously later.
+
+template <typename T>
+class Deferred;
+
+class DeferredBase {
+ public:
+  explicit DeferredBase(
+      std::function<void(AsyncResult<ProtoMessage>)> callback = nullptr);
+
+  ~DeferredBase();
+  DeferredBase(DeferredBase&&) noexcept;
+  DeferredBase& operator=(DeferredBase&&);
+  void Bind(std::function<void(AsyncResult<ProtoMessage>)> callback);
+  bool IsBound() const;
+  void Resolve(AsyncResult<ProtoMessage>);
+  void Reject();
+
+ protected:
+  template <typename T>
+  friend class Deferred;
+  void Move(DeferredBase&);
+
+  std::function<void(AsyncResult<ProtoMessage>)> callback_;
+};
+
+template <typename T>  // T : ProtoMessage subclass
+class Deferred : public DeferredBase {
+ public:
+  explicit Deferred(std::function<void(AsyncResult<T>)> callback = nullptr) {
+    Bind(std::move(callback));
+  }
+
+  // This move constructor (and the similar one in DeferredBase) is meant to be
+  // called only by the autogenerated code. The caller has to guarantee that the
+  // moved-from and moved-to types match. The behavior is otherwise undefined.
+  explicit Deferred(DeferredBase&& other) {
+    callback_ = std::move(other.callback_);
+    other.callback_ = nullptr;
+  }
+
+  void Bind(std::function<void(AsyncResult<T>)> callback) {
+    if (!callback)
+      return;
+
+    // Here we need a callback adapter to downcast the callback to a generic
+    // callback that takes an AsyncResult<ProtoMessage>, so that it can be
+    // stored in the base class |callback_|.
+    auto callback_adapter = [callback](
+                                AsyncResult<ProtoMessage> async_result_base) {
+      // Upcast the async_result from <ProtoMessage> -> <T : ProtoMessage>.
+      static_assert(std::is_base_of<ProtoMessage, T>::value, "T:ProtoMessage");
+      AsyncResult<T> async_result(
+          std::unique_ptr<T>(static_cast<T*>(async_result_base.release_msg())),
+          async_result_base.has_more(), async_result_base.fd());
+      callback(std::move(async_result));
+    };
+    DeferredBase::Bind(callback_adapter);
+  }
+
+  // If no more messages are expected, |callback_| is released.
+  void Resolve(AsyncResult<T> async_result) {
+    // Convert the |async_result| to the generic base one (T -> ProtoMessage).
+    AsyncResult<ProtoMessage> async_result_base(
+        std::unique_ptr<ProtoMessage>(async_result.release_msg()),
+        async_result.has_more(), async_result.fd());
+    DeferredBase::Resolve(std::move(async_result_base));
+  }
+};
+
+}  // namespace ipc
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_IPC_DEFERRED_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+
+namespace perfetto {
+namespace ipc {
+
+DeferredBase::DeferredBase(
+    std::function<void(AsyncResult<ProtoMessage>)> callback)
+    : callback_(std::move(callback)) {}
+
+DeferredBase::~DeferredBase() {
+  if (callback_)
+    Reject();
+}
+
+// Can't just use "= default" here because the default move operator for
+// std::function doesn't necessarily swap and hence can leave a copy of the
+// bind state around, which is undesirable.
+DeferredBase::DeferredBase(DeferredBase&& other) noexcept {
+  Move(other);
+}
+
+DeferredBase& DeferredBase::operator=(DeferredBase&& other) {
+  if (callback_)
+    Reject();
+  Move(other);
+  return *this;
+}
+
+void DeferredBase::Move(DeferredBase& other) {
+  callback_ = std::move(other.callback_);
+  other.callback_ = nullptr;
+}
+
+void DeferredBase::Bind(
+    std::function<void(AsyncResult<ProtoMessage>)> callback) {
+  callback_ = std::move(callback);
+}
+
+bool DeferredBase::IsBound() const {
+  return !!callback_;
+}
+
+void DeferredBase::Resolve(AsyncResult<ProtoMessage> async_result) {
+  if (!callback_) {
+    PERFETTO_DFATAL("No callback set.");
+    return;
+  }
+  bool has_more = async_result.has_more();
+  callback_(std::move(async_result));
+  if (!has_more)
+    callback_ = nullptr;
+}
+
+// Resolves with a nullptr |msg_|, signalling failure to |callback_|.
+void DeferredBase::Reject() {
+  Resolve(AsyncResult<ProtoMessage>());
+}
+
+}  // namespace ipc
+}  // namespace perfetto
+// gen_amalgamated begin source: src/ipc/virtual_destructors.cc
+// gen_amalgamated begin header: include/perfetto/ext/ipc/client.h
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_IPC_CLIENT_H_
+#define INCLUDE_PERFETTO_EXT_IPC_CLIENT_H_
+
+#include <functional>
+#include <memory>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
+
+namespace perfetto {
+
+namespace base {
+class TaskRunner;
+}  // namespace base
+
+namespace ipc {
+class ServiceProxy;
+
+// The client-side class that talks to the host over the socket and multiplexes
+// requests coming from the various autogenerated ServiceProxy stubs.
+// This is meant to be used by the user code as follows:
+// auto client = Client::CreateInstance("socket_name", task_runner);
+// std::unique_ptr<GreeterService> svc(new GreeterService());
+// client.BindService(svc);
+// svc.OnConnect([] () {
+//    svc.SayHello(..., ...);
+// });
+class Client {
+ public:
+  // struct ConnArgs is used for creating a client in 2 connection modes:
+  // 1. Connect using a socket name with the option to retry the connection on
+  //    connection failure.
+  // 2. Adopt a connected socket.
+  struct ConnArgs {
+    ConnArgs(const char* sock_name, bool sock_retry)
+        : socket_name(sock_name), retry(sock_retry) {}
+    explicit ConnArgs(base::ScopedSocketHandle sock_fd)
+        : socket_fd(std::move(sock_fd)) {}
+
+    // Disallow copy. Only supports move.
+    ConnArgs(const ConnArgs& other) = delete;
+    ConnArgs(ConnArgs&& other) = default;
+
+    base::ScopedSocketHandle socket_fd;
+    const char* socket_name = nullptr;
+    bool retry = false;  // Only for connecting with |socket_name|.
+    std::function<int(void)> receive_shmem_fd_cb_fuchsia;
+  };
+
+  static std::unique_ptr<Client> CreateInstance(ConnArgs, base::TaskRunner*);
+  virtual ~Client();
+
+  virtual void BindService(base::WeakPtr<ServiceProxy>) = 0;
+
+  // There is no need to call this method explicitly. Destroying the
+  // ServiceProxy instance is sufficient and will automatically unbind it. This
+  // method is exposed only for the ServiceProxy destructor.
+  virtual void UnbindService(ServiceID) = 0;
+
+  // Returns (with move semantics) the last file descriptor received on the IPC
+  // channel. No buffering is performed: if a service sends two file descriptors
+  // and the caller doesn't read them immediately, the first one will be
+  // automatically closed when the second is received (and will hit a DCHECK in
+  // debug builds).
+  virtual base::ScopedFile TakeReceivedFD() = 0;
+};
+
+}  // namespace ipc
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_IPC_CLIENT_H_
+// gen_amalgamated begin header: include/perfetto/ext/ipc/host.h
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_IPC_HOST_H_
+#define INCLUDE_PERFETTO_EXT_IPC_HOST_H_
+
+#include <memory>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
+
+namespace perfetto {
+
+namespace base {
+class TaskRunner;
+}  // namespace base
+
+namespace ipc {
+
+class Service;
+
+// The host-side of the IPC layer. This class acts as a registry and request
+// dispatcher. It listen on the UnixSocket |socket_name| for incoming requests
+// (coming Client instances) and dispatches their requests to the various
+// Services exposed.
+class Host {
+ public:
+  // Creates an instance and starts listening on the given |socket_name|.
+  // Returns nullptr if listening on the socket fails.
+  static std::unique_ptr<Host> CreateInstance(const char* socket_name,
+                                              base::TaskRunner*);
+
+  // Like the above but takes a file descriptor to a pre-bound unix socket.
+  // Returns nullptr if listening on the socket fails.
+  static std::unique_ptr<Host> CreateInstance(base::ScopedSocketHandle,
+                                              base::TaskRunner*);
+
+  // Creates a Host which is not backed by a POSIX listening socket.
+  // Instead, it accepts sockets passed in via AdoptConnectedSocket_Fuchsia().
+  // See go/fuchsetto for more details.
+  static std::unique_ptr<Host> CreateInstance_Fuchsia(base::TaskRunner*);
+
+  virtual ~Host();
+
+  // Registers a new service and makes it available to remote IPC peers.
+  // All the exposed Service instances will be destroyed when destroying the
+  // Host instance if ExposeService succeeds and returns true, or immediately
+  // after the call in case of failure.
+  // Returns true if the register has been successfully registered, false in
+  // case of errors (e.g., another service with the same name is already
+  // registered).
+  virtual bool ExposeService(std::unique_ptr<Service>) = 0;
+
+  // Accepts a pre-connected socket handle and a callback used to send a
+  // shared memory FD to the remote client.
+  // The callback returns false if the FD could not be sent.
+  // Should only be used in conjunction with CreateInstance_Fuchsia().
+  virtual void AdoptConnectedSocket_Fuchsia(
+      base::ScopedSocketHandle,
+      std::function<bool(int)> send_fd_cb) = 0;
+
+  // Overrides the default send timeout for the per-connection sockets.
+  virtual void SetSocketSendTimeoutMs(uint32_t timeout_ms) = 0;
+};
+
+}  // namespace ipc
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_IPC_HOST_H_
+// gen_amalgamated begin header: include/perfetto/ext/ipc/service.h
+// gen_amalgamated begin header: include/perfetto/ext/ipc/client_info.h
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_IPC_CLIENT_INFO_H_
+#define INCLUDE_PERFETTO_EXT_IPC_CLIENT_INFO_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/sys_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
+
+namespace perfetto {
+namespace ipc {
+
+// Passed to Service(s) to identify remote clients.
+class ClientInfo {
+ public:
+  ClientInfo() = default;
+  ClientInfo(ClientID client_id,
+             uid_t uid,
+             pid_t pid,
+             base::MachineID machine_id)
+      : client_id_(client_id), uid_(uid), pid_(pid), machine_id_(machine_id) {}
+
+  bool operator==(const ClientInfo& other) const {
+    return std::tie(client_id_, uid_, pid_, machine_id_) ==
+           std::tie(other.client_id_, other.uid_, other.pid_,
+                    other.machine_id_);
+  }
+  bool operator!=(const ClientInfo& other) const { return !(*this == other); }
+
+  // For map<> and other sorted containers.
+  bool operator<(const ClientInfo& other) const {
+    PERFETTO_DCHECK(client_id_ != other.client_id_ || *this == other);
+    return client_id_ < other.client_id_;
+  }
+
+  bool is_valid() const { return client_id_ != 0; }
+
+  // A monotonic counter.
+  ClientID client_id() const { return client_id_; }
+
+  // Posix User ID. Comes from the kernel, can be trusted.
+  uid_t uid() const { return uid_; }
+
+  // Posix process ID. Comes from the kernel and can be trusted.
+  int32_t pid() const { return pid_; }
+
+  // An integral ID that identifies the machine the client is on.
+  base::MachineID machine_id() const { return machine_id_; }
+
+ private:
+  ClientID client_id_ = 0;
+  // The following fields are emitted to trace packets and should be kept in
+  // sync with perfetto::ClientIdentity.
+  uid_t uid_ = kInvalidUid;
+  pid_t pid_ = base::kInvalidPid;
+  base::MachineID machine_id_ = base::kDefaultMachineID;
+};
+
+}  // namespace ipc
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_IPC_CLIENT_INFO_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_IPC_SERVICE_H_
+#define INCLUDE_PERFETTO_EXT_IPC_SERVICE_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/client_info.h"
+
+namespace perfetto {
+namespace ipc {
+
+class ServiceDescriptor;
+
+// The base class for all the autogenerated host-side service interfaces.
+class Service {
+ public:
+  virtual ~Service();
+
+  // Overridden by the auto-generated class. Provides the list of methods and
+  // the protobuf (de)serialization functions for their arguments.
+  virtual const ServiceDescriptor& GetDescriptor() = 0;
+
+  // Invoked when a remote client disconnects. Use client_info() to obtain
+  // details about the client that disconnected.
+  virtual void OnClientDisconnected() {}
+
+  // Returns the ClientInfo for the current IPC request. Returns an invalid
+  // ClientInfo if called outside the scope of an IPC method.
+  const ClientInfo& client_info() {
+    PERFETTO_DCHECK(client_info_.is_valid());
+    return client_info_;
+  }
+
+  base::ScopedFile TakeReceivedFD() {
+    if (received_fd_)
+      return std::move(*received_fd_);
+    return base::ScopedFile();
+  }
+
+  bool use_shmem_emulation() { return use_shmem_emulation_; }
+
+ private:
+  friend class HostImpl;
+  ClientInfo client_info_;
+  // This is a pointer because the received fd needs to remain owned by the
+  // ClientConnection, as we will provide it to all method invocations
+  // for that client until one of them calls Service::TakeReceivedFD.
+  //
+  // Different clients might have sent different FDs so this cannot be owned
+  // here.
+  //
+  // Note that this means that there can always only be one outstanding
+  // invocation per client that supplies an FD and the client needs to
+  // wait for this one to return before calling another one.
+  base::ScopedFile* received_fd_;
+
+  // Whether the socket needs to emulate shared memory buffer. Set by HostImpl
+  // when the service is exposed.
+  bool use_shmem_emulation_ = false;
+};
+
+}  // namespace ipc
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_IPC_SERVICE_H_
+// gen_amalgamated begin header: include/perfetto/ext/ipc/service_proxy.h
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_IPC_SERVICE_PROXY_H_
+#define INCLUDE_PERFETTO_EXT_IPC_SERVICE_PROXY_H_
+
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
+
+#include <assert.h>
+
+#include <functional>
+#include <map>
+#include <memory>
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
+
+namespace perfetto {
+namespace ipc {
+
+class Client;
+class ServiceDescriptor;
+
+// The base class for the client-side autogenerated stubs that forward method
+// invocations to the host. All the methods of this class are meant to be called
+// only by the autogenerated code.
+class PERFETTO_EXPORT_COMPONENT ServiceProxy {
+ public:
+  class EventListener {
+   public:
+    virtual ~EventListener();
+
+    // Called once after Client::BindService() if the ServiceProxy has been
+    // successfully bound to the host. It is possible to start sending IPC
+    // requests soon after this.
+    virtual void OnConnect() {}
+
+    // Called if the connection fails to be established or drops after having
+    // been established.
+    virtual void OnDisconnect() {}
+  };
+
+  // Guarantees that no callback will happen after this object has been
+  // destroyed. The caller has to guarantee that the |event_listener| stays
+  // alive at least as long as the ServiceProxy instance.
+  explicit ServiceProxy(EventListener*);
+  virtual ~ServiceProxy();
+
+  void InitializeBinding(base::WeakPtr<Client>,
+                         ServiceID,
+                         std::map<std::string, MethodID>);
+
+  // Called by the IPC methods in the autogenerated classes.
+  void BeginInvoke(const std::string& method_name,
+                   const ProtoMessage& request,
+                   DeferredBase reply,
+                   int fd = -1);
+
+  // Called by ClientImpl.
+  // |reply_args| == nullptr means request failure.
+  void EndInvoke(RequestID,
+                 std::unique_ptr<ProtoMessage> reply_arg,
+                 bool has_more);
+
+  // Called by ClientImpl.
+  void OnConnect(bool success);
+  void OnDisconnect();
+  bool connected() const { return service_id_ != 0; }
+
+  base::WeakPtr<ServiceProxy> GetWeakPtr() const;
+
+  // Implemented by the autogenerated class.
+  virtual const ServiceDescriptor& GetDescriptor() = 0;
+
+ private:
+  base::WeakPtr<Client> client_;
+  ServiceID service_id_ = 0;
+  std::map<std::string, MethodID> remote_method_ids_;
+  std::map<RequestID, DeferredBase> pending_callbacks_;
+  EventListener* const event_listener_;
+  base::WeakPtrFactory<ServiceProxy> weak_ptr_factory_;  // Keep last.
+};
+
+}  // namespace ipc
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_IPC_SERVICE_PROXY_H_
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/client.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/host.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
+
+// This translation unit contains the definitions for the destructor of pure
+// virtual interfaces for the current build target. The alternative would be
+// introducing a one-liner .cc file for each pure virtual interface, which is
+// overkill. This is for compliance with -Wweak-vtables.
+
+namespace perfetto {
+namespace ipc {
+
+Client::~Client() = default;
+Host::~Host() = default;
+Service::~Service() = default;
+ServiceProxy::EventListener::~EventListener() = default;
+
+}  // namespace ipc
+}  // namespace perfetto
+// gen_amalgamated begin source: src/ipc/client_impl.cc
+// gen_amalgamated begin header: src/ipc/client_impl.h
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_IPC_CLIENT_IMPL_H_
+#define SRC_IPC_CLIENT_IMPL_H_
+
+#include <list>
+#include <map>
+#include <memory>
+
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/client.h"
+// gen_amalgamated expanded: #include "src/ipc/buffered_frame_deserializer.h"
+
+namespace perfetto {
+
+namespace protos {
+namespace gen {
+class IPCFrame_BindServiceReply;
+class IPCFrame_InvokeMethodReply;
+}  // namespace gen
+}  // namespace protos
+
+namespace base {
+class TaskRunner;
+}  // namespace base
+
+namespace ipc {
+
+class ServiceDescriptor;
+
+class ClientImpl : public Client, public base::UnixSocket::EventListener {
+ public:
+  ClientImpl(ConnArgs, base::TaskRunner*);
+  ~ClientImpl() override;
+
+  // Client implementation.
+  void BindService(base::WeakPtr<ServiceProxy>) override;
+  void UnbindService(ServiceID) override;
+  base::ScopedFile TakeReceivedFD() override;
+
+  // base::UnixSocket::EventListener implementation.
+  void OnConnect(base::UnixSocket*, bool connected) override;
+  void OnDisconnect(base::UnixSocket*) override;
+  void OnDataAvailable(base::UnixSocket*) override;
+
+  RequestID BeginInvoke(ServiceID,
+                        const std::string& method_name,
+                        MethodID remote_method_id,
+                        const ProtoMessage& method_args,
+                        bool drop_reply,
+                        base::WeakPtr<ServiceProxy>,
+                        int fd = -1);
+
+  base::UnixSocket* GetUnixSocketForTesting() { return sock_.get(); }
+
+ private:
+  struct QueuedRequest {
+    QueuedRequest();
+    int type = 0;  // From Frame::msg_case(), see wire_protocol.proto.
+    RequestID request_id = 0;
+    base::WeakPtr<ServiceProxy> service_proxy;
+
+    // Only for type == kMsgInvokeMethod.
+    std::string method_name;
+  };
+
+  ClientImpl(const ClientImpl&) = delete;
+  ClientImpl& operator=(const ClientImpl&) = delete;
+
+  void TryConnect();
+  bool SendFrame(const Frame&, int fd = -1);
+  void OnFrameReceived(const Frame&);
+  void OnBindServiceReply(QueuedRequest,
+                          const protos::gen::IPCFrame_BindServiceReply&);
+  void OnInvokeMethodReply(QueuedRequest,
+                           const protos::gen::IPCFrame_InvokeMethodReply&);
+
+  bool invoking_method_reply_ = false;
+  const char* socket_name_ = nullptr;
+  bool socket_retry_ = false;
+  uint32_t socket_backoff_ms_ = 0;
+  std::unique_ptr<base::UnixSocket> sock_;
+  base::TaskRunner* const task_runner_;
+  RequestID last_request_id_ = 0;
+  BufferedFrameDeserializer frame_deserializer_;
+  base::ScopedFile received_fd_;
+  std::map<RequestID, QueuedRequest> queued_requests_;
+  std::map<ServiceID, base::WeakPtr<ServiceProxy>> service_bindings_;
+
+  // Queue of calls to BindService() that happened before the socket connected.
+  std::list<base::WeakPtr<ServiceProxy>> queued_bindings_;
+
+  base::WeakPtrFactory<Client> weak_ptr_factory_;  // Keep last.
+};
+
+}  // namespace ipc
+}  // namespace perfetto
+
+#endif  // SRC_IPC_CLIENT_IMPL_H_
+// gen_amalgamated begin header: include/perfetto/ext/ipc/service_descriptor.h
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_IPC_SERVICE_DESCRIPTOR_H_
+#define INCLUDE_PERFETTO_EXT_IPC_SERVICE_DESCRIPTOR_H_
+
+#include <functional>
+#include <string>
+#include <utility>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
+
+namespace perfetto {
+namespace ipc {
+
+class Service;
+
+// This is a pure data structure which holds factory methods and strings for the
+// services and their methods that get generated in the .h/.cc files.
+// Each autogenerated class has a GetDescriptor() method that returns one
+// instance of these and allows both client and hosts to map service and method
+// names to IDs and provide function pointers to the protobuf decoder fuctions.
+class ServiceDescriptor {
+ public:
+  struct Method {
+    const char* name;
+
+    // DecoderFunc is pointer to a function that takes a string in input
+    // containing protobuf encoded data and returns a decoded protobuf message.
+    using DecoderFunc = std::unique_ptr<ProtoMessage> (*)(const std::string&);
+
+    // Function pointer to decode the request argument of the method.
+    DecoderFunc request_proto_decoder;
+
+    // Function pointer to decoded the reply argument of the method.
+    DecoderFunc reply_proto_decoder;
+
+    // Function pointer that dispatches the generic request to the corresponding
+    // method implementation.
+    using InvokerFunc = void (*)(Service*,
+                                 const ProtoMessage& /* request_args */,
+                                 DeferredBase /* deferred_reply */);
+    InvokerFunc invoker;
+  };
+
+  const char* service_name = nullptr;
+
+  // Note that methods order is not stable. Client and Host might have different
+  // method indexes, depending on their versions. The Client can't just rely
+  // on the indexes and has to keep a [string -> remote index] translation map.
+  std::vector<Method> methods;
+};
+
+}  // namespace ipc
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_IPC_SERVICE_DESCRIPTOR_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "src/ipc/client_impl.h"
+
+#include <fcntl.h>
+
+#include <cinttypes>
+#include <utility>
+
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_descriptor.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/ipc/wire_protocol.gen.h"
+
+// TODO(primiano): Add ThreadChecker everywhere.
+
+// TODO(primiano): Add timeouts.
+
+namespace perfetto {
+namespace ipc {
+
+namespace {
+constexpr base::SockFamily kClientSockFamily =
+    kUseTCPSocket ? base::SockFamily::kInet : base::SockFamily::kUnix;
+}  // namespace
+
+// static
+std::unique_ptr<Client> Client::CreateInstance(ConnArgs conn_args,
+                                               base::TaskRunner* task_runner) {
+  std::unique_ptr<Client> client(
+      new ClientImpl(std::move(conn_args), task_runner));
+  return client;
+}
+
+ClientImpl::ClientImpl(ConnArgs conn_args, base::TaskRunner* task_runner)
+    : socket_name_(conn_args.socket_name),
+      socket_retry_(conn_args.retry),
+      task_runner_(task_runner),
+      weak_ptr_factory_(this) {
+  if (conn_args.socket_fd) {
+    // Create the client using a connected socket. This code path will never hit
+    // OnConnect().
+    sock_ = base::UnixSocket::AdoptConnected(
+        std::move(conn_args.socket_fd), this, task_runner_, kClientSockFamily,
+        base::SockType::kStream, base::SockPeerCredMode::kIgnore);
+  } else {
+    // Connect using the socket name.
+    TryConnect();
+  }
+}
+
+ClientImpl::~ClientImpl() {
+  // Ensure we are not destroyed in the middle of invoking a reply.
+  PERFETTO_DCHECK(!invoking_method_reply_);
+  OnDisconnect(
+      nullptr);  // The base::UnixSocket* ptr is not used in OnDisconnect().
+}
+
+void ClientImpl::TryConnect() {
+  PERFETTO_DCHECK(socket_name_);
+  sock_ = base::UnixSocket::Connect(
+      socket_name_, this, task_runner_, base::GetSockFamily(socket_name_),
+      base::SockType::kStream, base::SockPeerCredMode::kIgnore);
+}
+
+void ClientImpl::BindService(base::WeakPtr<ServiceProxy> service_proxy) {
+  if (!service_proxy)
+    return;
+  if (!sock_->is_connected()) {
+    queued_bindings_.emplace_back(service_proxy);
+    return;
+  }
+  RequestID request_id = ++last_request_id_;
+  Frame frame;
+  frame.set_request_id(request_id);
+  Frame::BindService* req = frame.mutable_msg_bind_service();
+  const char* const service_name = service_proxy->GetDescriptor().service_name;
+  req->set_service_name(service_name);
+  if (!SendFrame(frame)) {
+    PERFETTO_DLOG("BindService(%s) failed", service_name);
+    return service_proxy->OnConnect(false /* success */);
+  }
+  QueuedRequest qr;
+  qr.type = Frame::kMsgBindServiceFieldNumber;
+  qr.request_id = request_id;
+  qr.service_proxy = service_proxy;
+  queued_requests_.emplace(request_id, std::move(qr));
+}
+
+void ClientImpl::UnbindService(ServiceID service_id) {
+  service_bindings_.erase(service_id);
+}
+
+RequestID ClientImpl::BeginInvoke(ServiceID service_id,
+                                  const std::string& method_name,
+                                  MethodID remote_method_id,
+                                  const ProtoMessage& method_args,
+                                  bool drop_reply,
+                                  base::WeakPtr<ServiceProxy> service_proxy,
+                                  int fd) {
+  RequestID request_id = ++last_request_id_;
+  Frame frame;
+  frame.set_request_id(request_id);
+  Frame::InvokeMethod* req = frame.mutable_msg_invoke_method();
+  req->set_service_id(service_id);
+  req->set_method_id(remote_method_id);
+  req->set_drop_reply(drop_reply);
+  req->set_args_proto(method_args.SerializeAsString());
+  if (!SendFrame(frame, fd)) {
+    PERFETTO_DLOG("BeginInvoke() failed while sending the frame");
+    return 0;
+  }
+  if (drop_reply)
+    return 0;
+  QueuedRequest qr;
+  qr.type = Frame::kMsgInvokeMethodFieldNumber;
+  qr.request_id = request_id;
+  qr.method_name = method_name;
+  qr.service_proxy = std::move(service_proxy);
+  queued_requests_.emplace(request_id, std::move(qr));
+  return request_id;
+}
+
+bool ClientImpl::SendFrame(const Frame& frame, int fd) {
+  // Serialize the frame into protobuf, add the size header, and send it.
+  std::string buf = BufferedFrameDeserializer::Serialize(frame);
+
+  // TODO(primiano): this should do non-blocking I/O. But then what if the
+  // socket buffer is full? We might want to either drop the request or throttle
+  // the send and PostTask the reply later? Right now we are making Send()
+  // blocking as a workaround. Propagate bakpressure to the caller instead.
+  bool res = sock_->Send(buf.data(), buf.size(), fd);
+  PERFETTO_CHECK(res || !sock_->is_connected());
+  return res;
+}
+
+void ClientImpl::OnConnect(base::UnixSocket*, bool connected) {
+  if (!connected && socket_retry_) {
+    socket_backoff_ms_ =
+        (socket_backoff_ms_ < 10000) ? socket_backoff_ms_ + 1000 : 30000;
+    PERFETTO_DLOG(
+        "Connection to traced's UNIX socket failed, retrying in %u seconds",
+        socket_backoff_ms_ / 1000);
+    auto weak_this = weak_ptr_factory_.GetWeakPtr();
+    task_runner_->PostDelayedTask(
+        [weak_this] {
+          if (weak_this)
+            static_cast<ClientImpl&>(*weak_this).TryConnect();
+        },
+        socket_backoff_ms_);
+    return;
+  }
+
+  // Drain the BindService() calls that were queued before establishing the
+  // connection with the host. Note that if we got disconnected, the call to
+  // OnConnect below might delete |this|, so move everything on the stack first.
+  auto queued_bindings = std::move(queued_bindings_);
+  queued_bindings_.clear();
+  for (base::WeakPtr<ServiceProxy>& service_proxy : queued_bindings) {
+    if (connected) {
+      BindService(service_proxy);
+    } else if (service_proxy) {
+      service_proxy->OnConnect(false /* success */);
+    }
+  }
+  // Don't access |this| below here.
+}
+
+void ClientImpl::OnDisconnect(base::UnixSocket*) {
+  for (const auto& it : service_bindings_) {
+    base::WeakPtr<ServiceProxy> service_proxy = it.second;
+    task_runner_->PostTask([service_proxy] {
+      if (service_proxy)
+        service_proxy->OnDisconnect();
+    });
+  }
+  for (const auto& it : queued_requests_) {
+    const QueuedRequest& queued_request = it.second;
+    if (queued_request.type != Frame::kMsgBindServiceFieldNumber) {
+      continue;
+    }
+    base::WeakPtr<ServiceProxy> service_proxy = queued_request.service_proxy;
+    task_runner_->PostTask([service_proxy] {
+      if (service_proxy)
+        service_proxy->OnConnect(false);
+    });
+  }
+  service_bindings_.clear();
+  queued_bindings_.clear();
+}
+
+void ClientImpl::OnDataAvailable(base::UnixSocket*) {
+  size_t rsize;
+  do {
+    auto buf = frame_deserializer_.BeginReceive();
+    base::ScopedFile fd;
+    rsize = sock_->Receive(buf.data, buf.size, &fd);
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    PERFETTO_DCHECK(!fd);
+#else
+    if (fd) {
+      PERFETTO_DCHECK(!received_fd_);
+      int res = fcntl(*fd, F_SETFD, FD_CLOEXEC);
+      PERFETTO_DCHECK(res == 0);
+      received_fd_ = std::move(fd);
+    }
+#endif
+    if (!frame_deserializer_.EndReceive(rsize)) {
+      // The endpoint tried to send a frame that is way too large.
+      return sock_->Shutdown(true);  // In turn will trigger an OnDisconnect().
+      // TODO(fmayer): check this.
+    }
+  } while (rsize > 0);
+
+  while (std::unique_ptr<Frame> frame = frame_deserializer_.PopNextFrame())
+    OnFrameReceived(*frame);
+}
+
+void ClientImpl::OnFrameReceived(const Frame& frame) {
+  auto queued_requests_it = queued_requests_.find(frame.request_id());
+  if (queued_requests_it == queued_requests_.end()) {
+    PERFETTO_DLOG("OnFrameReceived(): got invalid request_id=%" PRIu64,
+                  static_cast<uint64_t>(frame.request_id()));
+    return;
+  }
+  QueuedRequest req = std::move(queued_requests_it->second);
+  queued_requests_.erase(queued_requests_it);
+
+  if (req.type == Frame::kMsgBindServiceFieldNumber &&
+      frame.has_msg_bind_service_reply()) {
+    return OnBindServiceReply(std::move(req), frame.msg_bind_service_reply());
+  }
+  if (req.type == Frame::kMsgInvokeMethodFieldNumber &&
+      frame.has_msg_invoke_method_reply()) {
+    return OnInvokeMethodReply(std::move(req), frame.msg_invoke_method_reply());
+  }
+  if (frame.has_msg_request_error()) {
+    PERFETTO_DLOG("Host error: %s", frame.msg_request_error().error().c_str());
+    return;
+  }
+
+  PERFETTO_DLOG(
+      "OnFrameReceived() request type=%d, received unknown frame in reply to "
+      "request_id=%" PRIu64,
+      req.type, static_cast<uint64_t>(frame.request_id()));
+}
+
+void ClientImpl::OnBindServiceReply(QueuedRequest req,
+                                    const Frame::BindServiceReply& reply) {
+  base::WeakPtr<ServiceProxy>& service_proxy = req.service_proxy;
+  if (!service_proxy)
+    return;
+  const char* svc_name = service_proxy->GetDescriptor().service_name;
+  if (!reply.success()) {
+    PERFETTO_DLOG("BindService(): unknown service_name=\"%s\"", svc_name);
+    return service_proxy->OnConnect(false /* success */);
+  }
+
+  auto prev_service = service_bindings_.find(reply.service_id());
+  if (prev_service != service_bindings_.end() && prev_service->second.get()) {
+    PERFETTO_DLOG(
+        "BindService(): Trying to bind service \"%s\" but another service "
+        "named \"%s\" is already bound with the same ID.",
+        svc_name, prev_service->second->GetDescriptor().service_name);
+    return service_proxy->OnConnect(false /* success */);
+  }
+
+  // Build the method [name] -> [remote_id] map.
+  std::map<std::string, MethodID> methods;
+  for (const auto& method : reply.methods()) {
+    if (method.name().empty() || method.id() <= 0) {
+      PERFETTO_DLOG("OnBindServiceReply(): invalid method \"%s\" -> %" PRIu64,
+                    method.name().c_str(), static_cast<uint64_t>(method.id()));
+      continue;
+    }
+    methods[method.name()] = method.id();
+  }
+  service_proxy->InitializeBinding(weak_ptr_factory_.GetWeakPtr(),
+                                   reply.service_id(), std::move(methods));
+  service_bindings_[reply.service_id()] = service_proxy;
+  service_proxy->OnConnect(true /* success */);
+}
+
+void ClientImpl::OnInvokeMethodReply(QueuedRequest req,
+                                     const Frame::InvokeMethodReply& reply) {
+  base::WeakPtr<ServiceProxy> service_proxy = req.service_proxy;
+  if (!service_proxy)
+    return;
+  std::unique_ptr<ProtoMessage> decoded_reply;
+  if (reply.success()) {
+    // If this becomes a hotspot, optimize by maintaining a dedicated hashtable.
+    for (const auto& method : service_proxy->GetDescriptor().methods) {
+      if (req.method_name == method.name) {
+        decoded_reply = method.reply_proto_decoder(reply.reply_proto());
+        break;
+      }
+    }
+  }
+  const RequestID request_id = req.request_id;
+  invoking_method_reply_ = true;
+  service_proxy->EndInvoke(request_id, std::move(decoded_reply),
+                           reply.has_more());
+  invoking_method_reply_ = false;
+
+  // If this is a streaming method and future replies will be resolved, put back
+  // the |req| with the callback into the set of active requests.
+  if (reply.has_more())
+    queued_requests_.emplace(request_id, std::move(req));
+}
+
+ClientImpl::QueuedRequest::QueuedRequest() = default;
+
+base::ScopedFile ClientImpl::TakeReceivedFD() {
+  return std::move(received_fd_);
+}
+
+}  // namespace ipc
+}  // namespace perfetto
+// gen_amalgamated begin source: src/ipc/service_proxy.cc
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
+
+#include <utility>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_descriptor.h"
+// gen_amalgamated expanded: #include "src/ipc/client_impl.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/ipc/wire_protocol.gen.h"
+
+namespace perfetto {
+namespace ipc {
+
+ServiceProxy::ServiceProxy(EventListener* event_listener)
+    : event_listener_(event_listener), weak_ptr_factory_(this) {}
+
+ServiceProxy::~ServiceProxy() {
+  if (client_ && connected())
+    client_->UnbindService(service_id_);
+}
+
+void ServiceProxy::InitializeBinding(
+    base::WeakPtr<Client> client,
+    ServiceID service_id,
+    std::map<std::string, MethodID> remote_method_ids) {
+  client_ = std::move(client);
+  service_id_ = service_id;
+  remote_method_ids_ = std::move(remote_method_ids);
+}
+
+void ServiceProxy::BeginInvoke(const std::string& method_name,
+                               const ProtoMessage& request,
+                               DeferredBase reply,
+                               int fd) {
+  // |reply| will auto-resolve if it gets out of scope early.
+  if (!connected()) {
+    PERFETTO_DFATAL("Not connected.");
+    return;
+  }
+  if (!client_)
+    return;  // The Client object has been destroyed in the meantime.
+
+  auto remote_method_it = remote_method_ids_.find(method_name);
+  RequestID request_id = 0;
+  const bool drop_reply = !reply.IsBound();
+  if (remote_method_it != remote_method_ids_.end()) {
+    request_id =
+        static_cast<ClientImpl*>(client_.get())
+            ->BeginInvoke(service_id_, method_name, remote_method_it->second,
+                          request, drop_reply, weak_ptr_factory_.GetWeakPtr(),
+                          fd);
+  } else {
+    PERFETTO_DLOG("Cannot find method \"%s\" on the host", method_name.c_str());
+  }
+
+  // When passing |drop_reply| == true, the returned |request_id| should be 0.
+  PERFETTO_DCHECK(!drop_reply || !request_id);
+
+  if (!request_id)
+    return;
+  PERFETTO_DCHECK(pending_callbacks_.count(request_id) == 0);
+  pending_callbacks_.emplace(request_id, std::move(reply));
+}
+
+void ServiceProxy::EndInvoke(RequestID request_id,
+                             std::unique_ptr<ProtoMessage> result,
+                             bool has_more) {
+  auto callback_it = pending_callbacks_.find(request_id);
+  if (callback_it == pending_callbacks_.end()) {
+    // Either we are getting a reply for a method we never invoked, or we are
+    // getting a reply to a method marked drop_reply (that has been invoked
+    // without binding any callback in the Defererd response object).
+    PERFETTO_DFATAL("Unexpected reply received.");
+    return;
+  }
+  DeferredBase& reply_callback = callback_it->second;
+  AsyncResult<ProtoMessage> reply(std::move(result), has_more);
+  reply_callback.Resolve(std::move(reply));
+  if (!has_more)
+    pending_callbacks_.erase(callback_it);
+}
+
+void ServiceProxy::OnConnect(bool success) {
+  if (success) {
+    PERFETTO_DCHECK(service_id_);
+    return event_listener_->OnConnect();
+  }
+  return event_listener_->OnDisconnect();
+}
+
+void ServiceProxy::OnDisconnect() {
+  pending_callbacks_.clear();  // Will Reject() all the pending callbacks.
+  event_listener_->OnDisconnect();
+}
+
+base::WeakPtr<ServiceProxy> ServiceProxy::GetWeakPtr() const {
+  return weak_ptr_factory_.GetWeakPtr();
+}
+
+}  // namespace ipc
+}  // namespace perfetto
+// gen_amalgamated begin source: src/ipc/host_impl.cc
+// gen_amalgamated begin header: src/ipc/host_impl.h
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_IPC_HOST_IMPL_H_
+#define SRC_IPC_HOST_IMPL_H_
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/sys_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/host.h"
+// gen_amalgamated expanded: #include "src/ipc/buffered_frame_deserializer.h"
+
+namespace perfetto {
+namespace ipc {
+
+constexpr uint32_t kDefaultIpcTxTimeoutMs = 10000;
+
+class HostImpl : public Host, public base::UnixSocket::EventListener {
+ public:
+  HostImpl(const char* socket_name, base::TaskRunner*);
+  HostImpl(base::ScopedSocketHandle, base::TaskRunner*);
+  HostImpl(base::TaskRunner* task_runner);
+  ~HostImpl() override;
+
+  // Host implementation.
+  bool ExposeService(std::unique_ptr<Service>) override;
+  void AdoptConnectedSocket_Fuchsia(
+      base::ScopedSocketHandle,
+      std::function<bool(int)> send_fd_cb) override;
+  void SetSocketSendTimeoutMs(uint32_t timeout_ms) override;
+
+  // base::UnixSocket::EventListener implementation.
+  void OnNewIncomingConnection(base::UnixSocket*,
+                               std::unique_ptr<base::UnixSocket>) override;
+  void OnDisconnect(base::UnixSocket*) override;
+  void OnDataAvailable(base::UnixSocket*) override;
+
+  const base::UnixSocket* sock() const { return sock_.get(); }
+
+ private:
+  // Owns the per-client receive buffer (BufferedFrameDeserializer).
+  struct ClientConnection {
+    ~ClientConnection();
+    ClientID id;
+    std::unique_ptr<base::UnixSocket> sock;
+    BufferedFrameDeserializer frame_deserializer;
+    base::ScopedFile received_fd;
+    std::function<bool(int)> send_fd_cb_fuchsia;
+    // Peer identity set using IPCFrame sent by the client. These 3 fields
+    // should be used only for non-AF_UNIX connections AF_UNIX connections
+    // should only rely on the peer identity obtained from the socket.
+    uid_t uid_override = base::kInvalidUid;
+    pid_t pid_override = base::kInvalidPid;
+
+    // |machine_id| is mapped from machine_id_hint (or socket hostname if
+    // |the client doesn't support machine_id_hint).
+    base::MachineID machine_id = base::kDefaultMachineID;
+
+    pid_t GetLinuxPeerPid() const;
+    uid_t GetPosixPeerUid() const;
+    base::MachineID GetMachineID() const { return machine_id; }
+  };
+  struct ExposedService {
+    ExposedService(ServiceID, const std::string&, std::unique_ptr<Service>);
+    ~ExposedService();
+    ExposedService(ExposedService&&) noexcept;
+    ExposedService& operator=(ExposedService&&);
+
+    ServiceID id;
+    std::string name;
+    std::unique_ptr<Service> instance;
+  };
+
+  HostImpl(const HostImpl&) = delete;
+  HostImpl& operator=(const HostImpl&) = delete;
+
+  bool Initialize(const char* socket_name);
+  void OnReceivedFrame(ClientConnection*, const Frame&);
+  void OnBindService(ClientConnection*, const Frame&);
+  void OnInvokeMethod(ClientConnection*, const Frame&);
+  void OnSetPeerIdentity(ClientConnection*, const Frame&);
+
+  void ReplyToMethodInvocation(ClientID, RequestID, AsyncResult<ProtoMessage>);
+  const ExposedService* GetServiceByName(const std::string&);
+
+  static void SendFrame(ClientConnection*, const Frame&, int fd = -1);
+
+  base::TaskRunner* const task_runner_;
+  std::map<ServiceID, ExposedService> services_;
+  std::unique_ptr<base::UnixSocket> sock_;  // The listening socket.
+  std::map<ClientID, std::unique_ptr<ClientConnection>> clients_;
+  std::map<base::UnixSocket*, ClientConnection*> clients_by_socket_;
+  ServiceID last_service_id_ = 0;
+  ClientID last_client_id_ = 0;
+  uint32_t socket_tx_timeout_ms_ = kDefaultIpcTxTimeoutMs;
+  PERFETTO_THREAD_CHECKER(thread_checker_)
+  base::WeakPtrFactory<HostImpl> weak_ptr_factory_;  // Keep last.
+};
+
+}  // namespace ipc
+}  // namespace perfetto
+
+#endif  // SRC_IPC_HOST_IMPL_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "src/ipc/host_impl.h"
+
+#include <algorithm>
+#include <cinttypes>
+#include <utility>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/crash_keys.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/sys_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_descriptor.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/ipc/wire_protocol.gen.h"
+
+// TODO(primiano): put limits on #connections/uid and req. queue (b/69093705).
+
+namespace perfetto {
+namespace ipc {
+
+namespace {
+
+constexpr base::SockFamily kHostSockFamily =
+    kUseTCPSocket ? base::SockFamily::kInet : base::SockFamily::kUnix;
+
+base::CrashKey g_crash_key_uid("ipc_uid");
+
+base::MachineID GenerateMachineID(base::UnixSocket* sock,
+                                  const std::string& machine_id_hint) {
+  // The special value of base::kDefaultMachineID is reserved for local
+  // producers.
+  if (!sock->is_connected() || sock->family() == base::SockFamily::kUnix)
+    return base::kDefaultMachineID;
+
+  base::Hasher hasher;
+  // Use the hint from the client, or fallback to hostname if the client
+  // doesn't provide a hint.
+  if (!machine_id_hint.empty()) {
+    hasher.Update(machine_id_hint);
+  } else {
+    // Use the socket address without the port number part as the hint.
+    auto host_id = sock->GetSockAddr();
+    auto pos = std::string::npos;
+    switch (sock->family()) {
+      case base::SockFamily::kInet:
+        PERFETTO_FALLTHROUGH;
+      case base::SockFamily::kInet6:
+        PERFETTO_FALLTHROUGH;
+      case base::SockFamily::kVsock:
+        pos = host_id.rfind(":");
+        if (pos != std::string::npos)
+          host_id.resize(pos);
+        break;
+      case base::SockFamily::kUnspec:
+        PERFETTO_FALLTHROUGH;
+      case base::SockFamily::kUnix:
+        PERFETTO_DFATAL("Should be unreachable.");
+        return base::kDefaultMachineID;
+    }
+    hasher.Update(host_id);
+  }
+
+  // Take the lower 32-bit from the hash.
+  uint32_t digest = static_cast<uint32_t>(hasher.digest());
+  // Avoid the extremely unlikely case that the hasher digest happens to be 0.
+  return digest == base::kDefaultMachineID ? 1 : digest;
+}
+}  // namespace
+
+uid_t HostImpl::ClientConnection::GetPosixPeerUid() const {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+  if (sock->family() == base::SockFamily::kUnix)
+    return sock->peer_uid_posix();
+#endif
+
+  // For non-unix sockets, check if the UID is set in OnSetPeerIdentity().
+  if (uid_override != base::kInvalidUid)
+    return uid_override;
+  // Must be != kInvalidUid or the PacketValidator will fail.
+  return 0;
+}
+
+pid_t HostImpl::ClientConnection::GetLinuxPeerPid() const {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  if (sock->family() == base::SockFamily::kUnix)
+    return sock->peer_pid_linux();
+#endif
+
+  // For non-unix sockets, return the PID set in OnSetPeerIdentity().
+  return pid_override;
+}
+
+// static
+std::unique_ptr<Host> Host::CreateInstance(const char* socket_name,
+                                           base::TaskRunner* task_runner) {
+  std::unique_ptr<HostImpl> host(new HostImpl(socket_name, task_runner));
+  if (!host->sock() || !host->sock()->is_listening())
+    return nullptr;
+  return std::unique_ptr<Host>(std::move(host));
+}
+
+// static
+std::unique_ptr<Host> Host::CreateInstance(base::ScopedSocketHandle socket_fd,
+                                           base::TaskRunner* task_runner) {
+  std::unique_ptr<HostImpl> host(
+      new HostImpl(std::move(socket_fd), task_runner));
+  if (!host->sock() || !host->sock()->is_listening())
+    return nullptr;
+  return std::unique_ptr<Host>(std::move(host));
+}
+
+// static
+std::unique_ptr<Host> Host::CreateInstance_Fuchsia(
+    base::TaskRunner* task_runner) {
+  return std::unique_ptr<HostImpl>(new HostImpl(task_runner));
+}
+
+HostImpl::HostImpl(base::ScopedSocketHandle socket_fd,
+                   base::TaskRunner* task_runner)
+    : task_runner_(task_runner), weak_ptr_factory_(this) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  sock_ = base::UnixSocket::Listen(std::move(socket_fd), this, task_runner_,
+                                   kHostSockFamily, base::SockType::kStream);
+}
+
+HostImpl::HostImpl(const char* socket_name, base::TaskRunner* task_runner)
+    : task_runner_(task_runner), weak_ptr_factory_(this) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  sock_ = base::UnixSocket::Listen(socket_name, this, task_runner_,
+                                   base::GetSockFamily(socket_name),
+                                   base::SockType::kStream);
+  if (!sock_) {
+    PERFETTO_PLOG("Failed to create %s", socket_name);
+  }
+}
+
+HostImpl::HostImpl(base::TaskRunner* task_runner)
+    : task_runner_(task_runner), weak_ptr_factory_(this) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+}
+
+HostImpl::~HostImpl() = default;
+
+bool HostImpl::ExposeService(std::unique_ptr<Service> service) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  const std::string& service_name = service->GetDescriptor().service_name;
+  if (GetServiceByName(service_name)) {
+    PERFETTO_DLOG("Duplicate ExposeService(): %s", service_name.c_str());
+    return false;
+  }
+  service->use_shmem_emulation_ =
+      sock() && !base::SockShmemSupported(sock()->family());
+  ServiceID sid = ++last_service_id_;
+  ExposedService exposed_service(sid, service_name, std::move(service));
+  services_.emplace(sid, std::move(exposed_service));
+  return true;
+}
+
+void HostImpl::AdoptConnectedSocket_Fuchsia(
+    base::ScopedSocketHandle connected_socket,
+    std::function<bool(int)> send_fd_cb) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DCHECK(connected_socket);
+  // Should not be used in conjunction with listen sockets.
+  PERFETTO_DCHECK(!sock_);
+
+  auto unix_socket = base::UnixSocket::AdoptConnected(
+      std::move(connected_socket), this, task_runner_, kHostSockFamily,
+      base::SockType::kStream);
+
+  auto* unix_socket_ptr = unix_socket.get();
+  OnNewIncomingConnection(nullptr, std::move(unix_socket));
+  ClientConnection* client_connection = clients_by_socket_[unix_socket_ptr];
+  client_connection->send_fd_cb_fuchsia = std::move(send_fd_cb);
+  PERFETTO_DCHECK(client_connection->send_fd_cb_fuchsia);
+}
+
+void HostImpl::SetSocketSendTimeoutMs(uint32_t timeout_ms) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  // Should be less than the watchdog period (30s).
+  socket_tx_timeout_ms_ = timeout_ms;
+}
+
+void HostImpl::OnNewIncomingConnection(
+    base::UnixSocket*,
+    std::unique_ptr<base::UnixSocket> new_conn) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  std::unique_ptr<ClientConnection> client(new ClientConnection());
+  ClientID client_id = ++last_client_id_;
+  clients_by_socket_[new_conn.get()] = client.get();
+  client->id = client_id;
+  client->sock = std::move(new_conn);
+  client->sock->SetTxTimeout(socket_tx_timeout_ms_);
+  clients_[client_id] = std::move(client);
+}
+
+void HostImpl::OnDataAvailable(base::UnixSocket* sock) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto it = clients_by_socket_.find(sock);
+  if (it == clients_by_socket_.end())
+    return;
+  ClientConnection* client = it->second;
+  BufferedFrameDeserializer& frame_deserializer = client->frame_deserializer;
+
+  auto peer_uid = client->GetPosixPeerUid();
+  auto scoped_key = g_crash_key_uid.SetScoped(static_cast<int64_t>(peer_uid));
+
+  size_t rsize;
+  do {
+    auto buf = frame_deserializer.BeginReceive();
+    base::ScopedFile fd;
+    rsize = client->sock->Receive(buf.data, buf.size, &fd);
+    if (fd) {
+      PERFETTO_DCHECK(!client->received_fd);
+      client->received_fd = std::move(fd);
+    }
+    if (!frame_deserializer.EndReceive(rsize))
+      return OnDisconnect(client->sock.get());
+  } while (rsize > 0);
+
+  for (;;) {
+    std::unique_ptr<Frame> frame = frame_deserializer.PopNextFrame();
+    if (!frame)
+      break;
+    OnReceivedFrame(client, *frame);
+  }
+}
+
+void HostImpl::OnReceivedFrame(ClientConnection* client,
+                               const Frame& req_frame) {
+  if (req_frame.has_msg_bind_service())
+    return OnBindService(client, req_frame);
+  if (req_frame.has_msg_invoke_method())
+    return OnInvokeMethod(client, req_frame);
+  if (req_frame.has_set_peer_identity())
+    return OnSetPeerIdentity(client, req_frame);
+
+  PERFETTO_DLOG("Received invalid RPC frame from client %" PRIu64, client->id);
+  Frame reply_frame;
+  reply_frame.set_request_id(req_frame.request_id());
+  reply_frame.mutable_msg_request_error()->set_error("unknown request");
+  SendFrame(client, reply_frame);
+}
+
+void HostImpl::OnBindService(ClientConnection* client, const Frame& req_frame) {
+  // Binding a service doesn't do anything major. It just returns back the
+  // service id and its method map.
+  const Frame::BindService& req = req_frame.msg_bind_service();
+  Frame reply_frame;
+  reply_frame.set_request_id(req_frame.request_id());
+  auto* reply = reply_frame.mutable_msg_bind_service_reply();
+  const ExposedService* service = GetServiceByName(req.service_name());
+  if (service) {
+    reply->set_success(true);
+    reply->set_service_id(service->id);
+    uint32_t method_id = 1;  // method ids start at index 1.
+    for (const auto& desc_method : service->instance->GetDescriptor().methods) {
+      Frame::BindServiceReply::MethodInfo* method_info = reply->add_methods();
+      method_info->set_name(desc_method.name);
+      method_info->set_id(method_id++);
+    }
+  }
+  SendFrame(client, reply_frame);
+}
+
+void HostImpl::OnInvokeMethod(ClientConnection* client,
+                              const Frame& req_frame) {
+  const Frame::InvokeMethod& req = req_frame.msg_invoke_method();
+  Frame reply_frame;
+  RequestID request_id = req_frame.request_id();
+  reply_frame.set_request_id(request_id);
+  reply_frame.mutable_msg_invoke_method_reply()->set_success(false);
+  auto svc_it = services_.find(req.service_id());
+  if (svc_it == services_.end())
+    return SendFrame(client, reply_frame);  // |success| == false by default.
+
+  Service* service = svc_it->second.instance.get();
+  const ServiceDescriptor& svc = service->GetDescriptor();
+  const auto& methods = svc.methods;
+  const uint32_t method_id = req.method_id();
+  if (method_id == 0 || method_id > methods.size())
+    return SendFrame(client, reply_frame);
+
+  const ServiceDescriptor::Method& method = methods[method_id - 1];
+  std::unique_ptr<ProtoMessage> decoded_req_args(
+      method.request_proto_decoder(req.args_proto()));
+  if (!decoded_req_args)
+    return SendFrame(client, reply_frame);
+
+  Deferred<ProtoMessage> deferred_reply;
+  base::WeakPtr<HostImpl> host_weak_ptr = weak_ptr_factory_.GetWeakPtr();
+  ClientID client_id = client->id;
+
+  if (!req.drop_reply()) {
+    deferred_reply.Bind([host_weak_ptr, client_id,
+                         request_id](AsyncResult<ProtoMessage> reply) {
+      if (!host_weak_ptr)
+        return;  // The reply came too late, the HostImpl has gone.
+      host_weak_ptr->ReplyToMethodInvocation(client_id, request_id,
+                                             std::move(reply));
+    });
+  }
+
+  auto peer_uid = client->GetPosixPeerUid();
+  auto scoped_key = g_crash_key_uid.SetScoped(static_cast<int64_t>(peer_uid));
+  service->client_info_ = ClientInfo(
+      client->id, peer_uid, client->GetLinuxPeerPid(), client->GetMachineID());
+  service->received_fd_ = &client->received_fd;
+  method.invoker(service, *decoded_req_args, std::move(deferred_reply));
+  service->received_fd_ = nullptr;
+  service->client_info_ = ClientInfo();
+}
+
+void HostImpl::OnSetPeerIdentity(ClientConnection* client,
+                                 const Frame& req_frame) {
+  if (client->sock->family() == base::SockFamily::kUnix) {
+    PERFETTO_DLOG("SetPeerIdentity is ignored for unix socket connections.");
+    return;
+  }
+
+  // This is can only be set once by the relay service.
+  if (client->pid_override != base::kInvalidPid ||
+      client->uid_override != base::kInvalidUid) {
+    PERFETTO_DLOG("Already received SetPeerIdentity.");
+    return;
+  }
+
+  const auto& set_peer_identity = req_frame.set_peer_identity();
+  client->pid_override = set_peer_identity.pid();
+  client->uid_override = static_cast<uid_t>(set_peer_identity.uid());
+
+  client->machine_id = GenerateMachineID(client->sock.get(),
+                                         set_peer_identity.machine_id_hint());
+}
+
+void HostImpl::ReplyToMethodInvocation(ClientID client_id,
+                                       RequestID request_id,
+                                       AsyncResult<ProtoMessage> reply) {
+  auto client_iter = clients_.find(client_id);
+  if (client_iter == clients_.end())
+    return;  // client has disconnected by the time we got the async reply.
+
+  ClientConnection* client = client_iter->second.get();
+  Frame reply_frame;
+  reply_frame.set_request_id(request_id);
+
+  // TODO(fmayer): add a test to guarantee that the reply is consumed within the
+  // same call stack and not kept around. ConsumerIPCService::OnTraceData()
+  // relies on this behavior.
+  auto* reply_frame_data = reply_frame.mutable_msg_invoke_method_reply();
+  reply_frame_data->set_has_more(reply.has_more());
+  if (reply.success()) {
+    std::string reply_proto = reply->SerializeAsString();
+    reply_frame_data->set_reply_proto(reply_proto);
+    reply_frame_data->set_success(true);
+  }
+  SendFrame(client, reply_frame, reply.fd());
+}
+
+// static
+void HostImpl::SendFrame(ClientConnection* client, const Frame& frame, int fd) {
+  auto peer_uid = client->GetPosixPeerUid();
+  auto scoped_key = g_crash_key_uid.SetScoped(static_cast<int64_t>(peer_uid));
+
+  std::string buf = BufferedFrameDeserializer::Serialize(frame);
+
+  // On Fuchsia, |send_fd_cb_fuchsia_| is used to send the FD to the client
+  // and therefore must be set.
+  PERFETTO_DCHECK(!PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA) ||
+                  client->send_fd_cb_fuchsia);
+  if (client->send_fd_cb_fuchsia && fd != base::ScopedFile::kInvalid) {
+    if (!client->send_fd_cb_fuchsia(fd)) {
+      client->sock->Shutdown(true);
+      return;
+    }
+    fd = base::ScopedFile::kInvalid;
+  }
+
+  // When a new Client connects in OnNewClientConnection we set a timeout on
+  // Send (see call to SetTxTimeout).
+  //
+  // The old behaviour was to do a blocking I/O call, which caused crashes from
+  // misbehaving producers (see b/169051440).
+  bool res = client->sock->Send(buf.data(), buf.size(), fd);
+  // If we timeout |res| will be false, but the UnixSocket will have called
+  // UnixSocket::ShutDown() and thus |is_connected()| is false.
+  PERFETTO_CHECK(res || !client->sock->is_connected());
+}
+
+void HostImpl::OnDisconnect(base::UnixSocket* sock) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto it = clients_by_socket_.find(sock);
+  if (it == clients_by_socket_.end())
+    return;
+  auto* client = it->second;
+  ClientID client_id = client->id;
+
+  ClientInfo client_info(client_id, client->GetPosixPeerUid(),
+                         client->GetLinuxPeerPid(), client->GetMachineID());
+
+  clients_by_socket_.erase(it);
+  PERFETTO_DCHECK(clients_.count(client_id));
+  clients_.erase(client_id);
+
+  for (const auto& service_it : services_) {
+    Service& service = *service_it.second.instance;
+    service.client_info_ = client_info;
+    service.OnClientDisconnected();
+    service.client_info_ = ClientInfo();
+  }
+}
+
+const HostImpl::ExposedService* HostImpl::GetServiceByName(
+    const std::string& name) {
+  // This could be optimized by using another map<name,ServiceID>. However this
+  // is used only by Bind/ExposeService that are quite rare (once per client
+  // connection and once per service instance), not worth it.
+  for (const auto& it : services_) {
+    if (it.second.name == name)
+      return &it.second;
+  }
+  return nullptr;
+}
+
+HostImpl::ExposedService::ExposedService(ServiceID id_,
+                                         const std::string& name_,
+                                         std::unique_ptr<Service> instance_)
+    : id(id_), name(name_), instance(std::move(instance_)) {}
+
+HostImpl::ExposedService::ExposedService(ExposedService&&) noexcept = default;
+HostImpl::ExposedService& HostImpl::ExposedService::operator=(
+    HostImpl::ExposedService&&) = default;
+HostImpl::ExposedService::~ExposedService() = default;
+
+HostImpl::ClientConnection::~ClientConnection() = default;
+
+}  // namespace ipc
+}  // namespace perfetto
+// gen_amalgamated begin source: gen/protos/perfetto/ipc/consumer_port.ipc.cc
+// gen_amalgamated begin header: gen/protos/perfetto/ipc/consumer_port.ipc.h
+// DO NOT EDIT. Autogenerated by Perfetto IPC
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_CONSUMER_PORT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_CONSUMER_PORT_PROTO_H_
+
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_descriptor.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/ipc/consumer_port.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/observable_events.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_state.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_capabilities.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/trace_stats.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/trace_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class ConsumerPort : public ::perfetto::ipc::Service {
+ private:
+  static ::perfetto::ipc::ServiceDescriptor* NewDescriptor();
+
+ public:
+  ~ConsumerPort() override;
+
+  static const ::perfetto::ipc::ServiceDescriptor& GetDescriptorStatic();
+
+  // Service implementation.
+  const ::perfetto::ipc::ServiceDescriptor& GetDescriptor() override;
+
+  // Methods from the .proto file
+  using DeferredEnableTracingResponse = ::perfetto::ipc::Deferred<EnableTracingResponse>;
+  virtual void EnableTracing(const EnableTracingRequest&, DeferredEnableTracingResponse) = 0;
+
+  using DeferredDisableTracingResponse = ::perfetto::ipc::Deferred<DisableTracingResponse>;
+  virtual void DisableTracing(const DisableTracingRequest&, DeferredDisableTracingResponse) = 0;
+
+  using DeferredReadBuffersResponse = ::perfetto::ipc::Deferred<ReadBuffersResponse>;
+  virtual void ReadBuffers(const ReadBuffersRequest&, DeferredReadBuffersResponse) = 0;
+
+  using DeferredFreeBuffersResponse = ::perfetto::ipc::Deferred<FreeBuffersResponse>;
+  virtual void FreeBuffers(const FreeBuffersRequest&, DeferredFreeBuffersResponse) = 0;
+
+  using DeferredFlushResponse = ::perfetto::ipc::Deferred<FlushResponse>;
+  virtual void Flush(const FlushRequest&, DeferredFlushResponse) = 0;
+
+  using DeferredStartTracingResponse = ::perfetto::ipc::Deferred<StartTracingResponse>;
+  virtual void StartTracing(const StartTracingRequest&, DeferredStartTracingResponse) = 0;
+
+  using DeferredChangeTraceConfigResponse = ::perfetto::ipc::Deferred<ChangeTraceConfigResponse>;
+  virtual void ChangeTraceConfig(const ChangeTraceConfigRequest&, DeferredChangeTraceConfigResponse) = 0;
+
+  using DeferredDetachResponse = ::perfetto::ipc::Deferred<DetachResponse>;
+  virtual void Detach(const DetachRequest&, DeferredDetachResponse) = 0;
+
+  using DeferredAttachResponse = ::perfetto::ipc::Deferred<AttachResponse>;
+  virtual void Attach(const AttachRequest&, DeferredAttachResponse) = 0;
+
+  using DeferredGetTraceStatsResponse = ::perfetto::ipc::Deferred<GetTraceStatsResponse>;
+  virtual void GetTraceStats(const GetTraceStatsRequest&, DeferredGetTraceStatsResponse) = 0;
+
+  using DeferredObserveEventsResponse = ::perfetto::ipc::Deferred<ObserveEventsResponse>;
+  virtual void ObserveEvents(const ObserveEventsRequest&, DeferredObserveEventsResponse) = 0;
+
+  using DeferredQueryServiceStateResponse = ::perfetto::ipc::Deferred<QueryServiceStateResponse>;
+  virtual void QueryServiceState(const QueryServiceStateRequest&, DeferredQueryServiceStateResponse) = 0;
+
+  using DeferredQueryCapabilitiesResponse = ::perfetto::ipc::Deferred<QueryCapabilitiesResponse>;
+  virtual void QueryCapabilities(const QueryCapabilitiesRequest&, DeferredQueryCapabilitiesResponse) = 0;
+
+  using DeferredSaveTraceForBugreportResponse = ::perfetto::ipc::Deferred<SaveTraceForBugreportResponse>;
+  virtual void SaveTraceForBugreport(const SaveTraceForBugreportRequest&, DeferredSaveTraceForBugreportResponse) = 0;
+
+  using DeferredCloneSessionResponse = ::perfetto::ipc::Deferred<CloneSessionResponse>;
+  virtual void CloneSession(const CloneSessionRequest&, DeferredCloneSessionResponse) = 0;
+
+};
+
+
+class ConsumerPortProxy : public ::perfetto::ipc::ServiceProxy {
+ public:
+   explicit ConsumerPortProxy(::perfetto::ipc::ServiceProxy::EventListener*);
+   ~ConsumerPortProxy() override;
+
+  // ServiceProxy implementation.
+  const ::perfetto::ipc::ServiceDescriptor& GetDescriptor() override;
+
+  // Methods from the .proto file
+  using DeferredEnableTracingResponse = ::perfetto::ipc::Deferred<EnableTracingResponse>;
+  void EnableTracing(const EnableTracingRequest&, DeferredEnableTracingResponse, int fd = -1);
+
+  using DeferredDisableTracingResponse = ::perfetto::ipc::Deferred<DisableTracingResponse>;
+  void DisableTracing(const DisableTracingRequest&, DeferredDisableTracingResponse, int fd = -1);
+
+  using DeferredReadBuffersResponse = ::perfetto::ipc::Deferred<ReadBuffersResponse>;
+  void ReadBuffers(const ReadBuffersRequest&, DeferredReadBuffersResponse, int fd = -1);
+
+  using DeferredFreeBuffersResponse = ::perfetto::ipc::Deferred<FreeBuffersResponse>;
+  void FreeBuffers(const FreeBuffersRequest&, DeferredFreeBuffersResponse, int fd = -1);
+
+  using DeferredFlushResponse = ::perfetto::ipc::Deferred<FlushResponse>;
+  void Flush(const FlushRequest&, DeferredFlushResponse, int fd = -1);
+
+  using DeferredStartTracingResponse = ::perfetto::ipc::Deferred<StartTracingResponse>;
+  void StartTracing(const StartTracingRequest&, DeferredStartTracingResponse, int fd = -1);
+
+  using DeferredChangeTraceConfigResponse = ::perfetto::ipc::Deferred<ChangeTraceConfigResponse>;
+  void ChangeTraceConfig(const ChangeTraceConfigRequest&, DeferredChangeTraceConfigResponse, int fd = -1);
+
+  using DeferredDetachResponse = ::perfetto::ipc::Deferred<DetachResponse>;
+  void Detach(const DetachRequest&, DeferredDetachResponse, int fd = -1);
+
+  using DeferredAttachResponse = ::perfetto::ipc::Deferred<AttachResponse>;
+  void Attach(const AttachRequest&, DeferredAttachResponse, int fd = -1);
+
+  using DeferredGetTraceStatsResponse = ::perfetto::ipc::Deferred<GetTraceStatsResponse>;
+  void GetTraceStats(const GetTraceStatsRequest&, DeferredGetTraceStatsResponse, int fd = -1);
+
+  using DeferredObserveEventsResponse = ::perfetto::ipc::Deferred<ObserveEventsResponse>;
+  void ObserveEvents(const ObserveEventsRequest&, DeferredObserveEventsResponse, int fd = -1);
+
+  using DeferredQueryServiceStateResponse = ::perfetto::ipc::Deferred<QueryServiceStateResponse>;
+  void QueryServiceState(const QueryServiceStateRequest&, DeferredQueryServiceStateResponse, int fd = -1);
+
+  using DeferredQueryCapabilitiesResponse = ::perfetto::ipc::Deferred<QueryCapabilitiesResponse>;
+  void QueryCapabilities(const QueryCapabilitiesRequest&, DeferredQueryCapabilitiesResponse, int fd = -1);
+
+  using DeferredSaveTraceForBugreportResponse = ::perfetto::ipc::Deferred<SaveTraceForBugreportResponse>;
+  void SaveTraceForBugreport(const SaveTraceForBugreportRequest&, DeferredSaveTraceForBugreportResponse, int fd = -1);
+
+  using DeferredCloneSessionResponse = ::perfetto::ipc::Deferred<CloneSessionResponse>;
+  void CloneSession(const CloneSessionRequest&, DeferredCloneSessionResponse, int fd = -1);
+
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_CONSUMER_PORT_PROTO_H_
+// gen_amalgamated begin header: include/perfetto/ext/ipc/codegen_helpers.h
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// This file is only meant to be included in autogenerated .cc files.
+
+#ifndef INCLUDE_PERFETTO_EXT_IPC_CODEGEN_HELPERS_H_
+#define INCLUDE_PERFETTO_EXT_IPC_CODEGEN_HELPERS_H_
+
+#include <memory>
+
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
+
+// A templated protobuf message decoder. Returns nullptr in case of failure.
+template <typename T>
+::std::unique_ptr<::perfetto::ipc::ProtoMessage> _IPC_Decoder(
+    const std::string& proto_data) {
+  ::std::unique_ptr<::perfetto::ipc::ProtoMessage> msg(new T());
+  if (msg->ParseFromString(proto_data))
+    return msg;
+  return nullptr;
+}
+
+// Templated method dispatcher. Used to obtain a function pointer to a given
+// IPC method (Method) of a given service (TSvc) that can be invoked by the
+// host-side machinery starting from a generic Service pointer and a generic
+// ProtoMessage request argument.
+template <typename TSvc,    // Type of the actual Service subclass.
+          typename TReq,    // Type of the request argument.
+          typename TReply,  // Type of the reply argument.
+          void (TSvc::*Method)(const TReq&, ::perfetto::ipc::Deferred<TReply>)>
+void _IPC_Invoker(::perfetto::ipc::Service* s,
+                  const ::perfetto::ipc::ProtoMessage& req,
+                  ::perfetto::ipc::DeferredBase reply) {
+  (*static_cast<TSvc*>(s).*Method)(
+      static_cast<const TReq&>(req),
+      ::perfetto::ipc::Deferred<TReply>(::std::move(reply)));
+}
+
+#endif  // INCLUDE_PERFETTO_EXT_IPC_CODEGEN_HELPERS_H_
+// DO NOT EDIT. Autogenerated by Perfetto IPC
+// gen_amalgamated expanded: #include "protos/perfetto/ipc/consumer_port.ipc.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/codegen_helpers.h"
+
+#include <memory>
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+::perfetto::ipc::ServiceDescriptor* ConsumerPort::NewDescriptor() {
+  auto* desc = new ::perfetto::ipc::ServiceDescriptor();
+  desc->service_name = "ConsumerPort";
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "EnableTracing",
+     &_IPC_Decoder<EnableTracingRequest>,
+     &_IPC_Decoder<EnableTracingResponse>,
+     &_IPC_Invoker<ConsumerPort, EnableTracingRequest, EnableTracingResponse, &ConsumerPort::EnableTracing>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "DisableTracing",
+     &_IPC_Decoder<DisableTracingRequest>,
+     &_IPC_Decoder<DisableTracingResponse>,
+     &_IPC_Invoker<ConsumerPort, DisableTracingRequest, DisableTracingResponse, &ConsumerPort::DisableTracing>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "ReadBuffers",
+     &_IPC_Decoder<ReadBuffersRequest>,
+     &_IPC_Decoder<ReadBuffersResponse>,
+     &_IPC_Invoker<ConsumerPort, ReadBuffersRequest, ReadBuffersResponse, &ConsumerPort::ReadBuffers>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "FreeBuffers",
+     &_IPC_Decoder<FreeBuffersRequest>,
+     &_IPC_Decoder<FreeBuffersResponse>,
+     &_IPC_Invoker<ConsumerPort, FreeBuffersRequest, FreeBuffersResponse, &ConsumerPort::FreeBuffers>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "Flush",
+     &_IPC_Decoder<FlushRequest>,
+     &_IPC_Decoder<FlushResponse>,
+     &_IPC_Invoker<ConsumerPort, FlushRequest, FlushResponse, &ConsumerPort::Flush>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "StartTracing",
+     &_IPC_Decoder<StartTracingRequest>,
+     &_IPC_Decoder<StartTracingResponse>,
+     &_IPC_Invoker<ConsumerPort, StartTracingRequest, StartTracingResponse, &ConsumerPort::StartTracing>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "ChangeTraceConfig",
+     &_IPC_Decoder<ChangeTraceConfigRequest>,
+     &_IPC_Decoder<ChangeTraceConfigResponse>,
+     &_IPC_Invoker<ConsumerPort, ChangeTraceConfigRequest, ChangeTraceConfigResponse, &ConsumerPort::ChangeTraceConfig>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "Detach",
+     &_IPC_Decoder<DetachRequest>,
+     &_IPC_Decoder<DetachResponse>,
+     &_IPC_Invoker<ConsumerPort, DetachRequest, DetachResponse, &ConsumerPort::Detach>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "Attach",
+     &_IPC_Decoder<AttachRequest>,
+     &_IPC_Decoder<AttachResponse>,
+     &_IPC_Invoker<ConsumerPort, AttachRequest, AttachResponse, &ConsumerPort::Attach>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "GetTraceStats",
+     &_IPC_Decoder<GetTraceStatsRequest>,
+     &_IPC_Decoder<GetTraceStatsResponse>,
+     &_IPC_Invoker<ConsumerPort, GetTraceStatsRequest, GetTraceStatsResponse, &ConsumerPort::GetTraceStats>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "ObserveEvents",
+     &_IPC_Decoder<ObserveEventsRequest>,
+     &_IPC_Decoder<ObserveEventsResponse>,
+     &_IPC_Invoker<ConsumerPort, ObserveEventsRequest, ObserveEventsResponse, &ConsumerPort::ObserveEvents>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "QueryServiceState",
+     &_IPC_Decoder<QueryServiceStateRequest>,
+     &_IPC_Decoder<QueryServiceStateResponse>,
+     &_IPC_Invoker<ConsumerPort, QueryServiceStateRequest, QueryServiceStateResponse, &ConsumerPort::QueryServiceState>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "QueryCapabilities",
+     &_IPC_Decoder<QueryCapabilitiesRequest>,
+     &_IPC_Decoder<QueryCapabilitiesResponse>,
+     &_IPC_Invoker<ConsumerPort, QueryCapabilitiesRequest, QueryCapabilitiesResponse, &ConsumerPort::QueryCapabilities>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "SaveTraceForBugreport",
+     &_IPC_Decoder<SaveTraceForBugreportRequest>,
+     &_IPC_Decoder<SaveTraceForBugreportResponse>,
+     &_IPC_Invoker<ConsumerPort, SaveTraceForBugreportRequest, SaveTraceForBugreportResponse, &ConsumerPort::SaveTraceForBugreport>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "CloneSession",
+     &_IPC_Decoder<CloneSessionRequest>,
+     &_IPC_Decoder<CloneSessionResponse>,
+     &_IPC_Invoker<ConsumerPort, CloneSessionRequest, CloneSessionResponse, &ConsumerPort::CloneSession>});
+  desc->methods.shrink_to_fit();
+  return desc;
+}
+
+
+const ::perfetto::ipc::ServiceDescriptor& ConsumerPort::GetDescriptorStatic() {
+  static auto* instance = NewDescriptor();
+  return *instance;
+}
+
+// Host-side definitions.
+ConsumerPort::~ConsumerPort() = default;
+
+const ::perfetto::ipc::ServiceDescriptor& ConsumerPort::GetDescriptor() {
+  return GetDescriptorStatic();
+}
+
+// Client-side definitions.
+ConsumerPortProxy::ConsumerPortProxy(::perfetto::ipc::ServiceProxy::EventListener* event_listener)
+    : ::perfetto::ipc::ServiceProxy(event_listener) {}
+
+ConsumerPortProxy::~ConsumerPortProxy() = default;
+
+const ::perfetto::ipc::ServiceDescriptor& ConsumerPortProxy::GetDescriptor() {
+  return ConsumerPort::GetDescriptorStatic();
+}
+
+void ConsumerPortProxy::EnableTracing(const EnableTracingRequest& request, DeferredEnableTracingResponse reply, int fd) {
+  BeginInvoke("EnableTracing", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ConsumerPortProxy::DisableTracing(const DisableTracingRequest& request, DeferredDisableTracingResponse reply, int fd) {
+  BeginInvoke("DisableTracing", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ConsumerPortProxy::ReadBuffers(const ReadBuffersRequest& request, DeferredReadBuffersResponse reply, int fd) {
+  BeginInvoke("ReadBuffers", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ConsumerPortProxy::FreeBuffers(const FreeBuffersRequest& request, DeferredFreeBuffersResponse reply, int fd) {
+  BeginInvoke("FreeBuffers", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ConsumerPortProxy::Flush(const FlushRequest& request, DeferredFlushResponse reply, int fd) {
+  BeginInvoke("Flush", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ConsumerPortProxy::StartTracing(const StartTracingRequest& request, DeferredStartTracingResponse reply, int fd) {
+  BeginInvoke("StartTracing", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ConsumerPortProxy::ChangeTraceConfig(const ChangeTraceConfigRequest& request, DeferredChangeTraceConfigResponse reply, int fd) {
+  BeginInvoke("ChangeTraceConfig", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ConsumerPortProxy::Detach(const DetachRequest& request, DeferredDetachResponse reply, int fd) {
+  BeginInvoke("Detach", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ConsumerPortProxy::Attach(const AttachRequest& request, DeferredAttachResponse reply, int fd) {
+  BeginInvoke("Attach", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ConsumerPortProxy::GetTraceStats(const GetTraceStatsRequest& request, DeferredGetTraceStatsResponse reply, int fd) {
+  BeginInvoke("GetTraceStats", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ConsumerPortProxy::ObserveEvents(const ObserveEventsRequest& request, DeferredObserveEventsResponse reply, int fd) {
+  BeginInvoke("ObserveEvents", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ConsumerPortProxy::QueryServiceState(const QueryServiceStateRequest& request, DeferredQueryServiceStateResponse reply, int fd) {
+  BeginInvoke("QueryServiceState", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ConsumerPortProxy::QueryCapabilities(const QueryCapabilitiesRequest& request, DeferredQueryCapabilitiesResponse reply, int fd) {
+  BeginInvoke("QueryCapabilities", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ConsumerPortProxy::SaveTraceForBugreport(const SaveTraceForBugreportRequest& request, DeferredSaveTraceForBugreportResponse reply, int fd) {
+  BeginInvoke("SaveTraceForBugreport", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ConsumerPortProxy::CloneSession(const CloneSessionRequest& request, DeferredCloneSessionResponse reply, int fd) {
+  BeginInvoke("CloneSession", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+// gen_amalgamated begin source: gen/protos/perfetto/ipc/producer_port.ipc.cc
+// gen_amalgamated begin header: gen/protos/perfetto/ipc/producer_port.ipc.h
+// DO NOT EDIT. Autogenerated by Perfetto IPC
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_PRODUCER_PORT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_PRODUCER_PORT_PROTO_H_
+
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_descriptor.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/ipc/producer_port.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/commit_data_request.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class ProducerPort : public ::perfetto::ipc::Service {
+ private:
+  static ::perfetto::ipc::ServiceDescriptor* NewDescriptor();
+
+ public:
+  ~ProducerPort() override;
+
+  static const ::perfetto::ipc::ServiceDescriptor& GetDescriptorStatic();
+
+  // Service implementation.
+  const ::perfetto::ipc::ServiceDescriptor& GetDescriptor() override;
+
+  // Methods from the .proto file
+  using DeferredInitializeConnectionResponse = ::perfetto::ipc::Deferred<InitializeConnectionResponse>;
+  virtual void InitializeConnection(const InitializeConnectionRequest&, DeferredInitializeConnectionResponse) = 0;
+
+  using DeferredRegisterDataSourceResponse = ::perfetto::ipc::Deferred<RegisterDataSourceResponse>;
+  virtual void RegisterDataSource(const RegisterDataSourceRequest&, DeferredRegisterDataSourceResponse) = 0;
+
+  using DeferredUnregisterDataSourceResponse = ::perfetto::ipc::Deferred<UnregisterDataSourceResponse>;
+  virtual void UnregisterDataSource(const UnregisterDataSourceRequest&, DeferredUnregisterDataSourceResponse) = 0;
+
+  using DeferredCommitDataResponse = ::perfetto::ipc::Deferred<CommitDataResponse>;
+  virtual void CommitData(const CommitDataRequest&, DeferredCommitDataResponse) = 0;
+
+  using DeferredGetAsyncCommandResponse = ::perfetto::ipc::Deferred<GetAsyncCommandResponse>;
+  virtual void GetAsyncCommand(const GetAsyncCommandRequest&, DeferredGetAsyncCommandResponse) = 0;
+
+  using DeferredRegisterTraceWriterResponse = ::perfetto::ipc::Deferred<RegisterTraceWriterResponse>;
+  virtual void RegisterTraceWriter(const RegisterTraceWriterRequest&, DeferredRegisterTraceWriterResponse) = 0;
+
+  using DeferredUnregisterTraceWriterResponse = ::perfetto::ipc::Deferred<UnregisterTraceWriterResponse>;
+  virtual void UnregisterTraceWriter(const UnregisterTraceWriterRequest&, DeferredUnregisterTraceWriterResponse) = 0;
+
+  using DeferredNotifyDataSourceStartedResponse = ::perfetto::ipc::Deferred<NotifyDataSourceStartedResponse>;
+  virtual void NotifyDataSourceStarted(const NotifyDataSourceStartedRequest&, DeferredNotifyDataSourceStartedResponse) = 0;
+
+  using DeferredNotifyDataSourceStoppedResponse = ::perfetto::ipc::Deferred<NotifyDataSourceStoppedResponse>;
+  virtual void NotifyDataSourceStopped(const NotifyDataSourceStoppedRequest&, DeferredNotifyDataSourceStoppedResponse) = 0;
+
+  using DeferredActivateTriggersResponse = ::perfetto::ipc::Deferred<ActivateTriggersResponse>;
+  virtual void ActivateTriggers(const ActivateTriggersRequest&, DeferredActivateTriggersResponse) = 0;
+
+  using DeferredSyncResponse = ::perfetto::ipc::Deferred<SyncResponse>;
+  virtual void Sync(const SyncRequest&, DeferredSyncResponse) = 0;
+
+  using DeferredUpdateDataSourceResponse = ::perfetto::ipc::Deferred<UpdateDataSourceResponse>;
+  virtual void UpdateDataSource(const UpdateDataSourceRequest&, DeferredUpdateDataSourceResponse) = 0;
+
+};
+
+
+class ProducerPortProxy : public ::perfetto::ipc::ServiceProxy {
+ public:
+   explicit ProducerPortProxy(::perfetto::ipc::ServiceProxy::EventListener*);
+   ~ProducerPortProxy() override;
+
+  // ServiceProxy implementation.
+  const ::perfetto::ipc::ServiceDescriptor& GetDescriptor() override;
+
+  // Methods from the .proto file
+  using DeferredInitializeConnectionResponse = ::perfetto::ipc::Deferred<InitializeConnectionResponse>;
+  void InitializeConnection(const InitializeConnectionRequest&, DeferredInitializeConnectionResponse, int fd = -1);
+
+  using DeferredRegisterDataSourceResponse = ::perfetto::ipc::Deferred<RegisterDataSourceResponse>;
+  void RegisterDataSource(const RegisterDataSourceRequest&, DeferredRegisterDataSourceResponse, int fd = -1);
+
+  using DeferredUnregisterDataSourceResponse = ::perfetto::ipc::Deferred<UnregisterDataSourceResponse>;
+  void UnregisterDataSource(const UnregisterDataSourceRequest&, DeferredUnregisterDataSourceResponse, int fd = -1);
+
+  using DeferredCommitDataResponse = ::perfetto::ipc::Deferred<CommitDataResponse>;
+  void CommitData(const CommitDataRequest&, DeferredCommitDataResponse, int fd = -1);
+
+  using DeferredGetAsyncCommandResponse = ::perfetto::ipc::Deferred<GetAsyncCommandResponse>;
+  void GetAsyncCommand(const GetAsyncCommandRequest&, DeferredGetAsyncCommandResponse, int fd = -1);
+
+  using DeferredRegisterTraceWriterResponse = ::perfetto::ipc::Deferred<RegisterTraceWriterResponse>;
+  void RegisterTraceWriter(const RegisterTraceWriterRequest&, DeferredRegisterTraceWriterResponse, int fd = -1);
+
+  using DeferredUnregisterTraceWriterResponse = ::perfetto::ipc::Deferred<UnregisterTraceWriterResponse>;
+  void UnregisterTraceWriter(const UnregisterTraceWriterRequest&, DeferredUnregisterTraceWriterResponse, int fd = -1);
+
+  using DeferredNotifyDataSourceStartedResponse = ::perfetto::ipc::Deferred<NotifyDataSourceStartedResponse>;
+  void NotifyDataSourceStarted(const NotifyDataSourceStartedRequest&, DeferredNotifyDataSourceStartedResponse, int fd = -1);
+
+  using DeferredNotifyDataSourceStoppedResponse = ::perfetto::ipc::Deferred<NotifyDataSourceStoppedResponse>;
+  void NotifyDataSourceStopped(const NotifyDataSourceStoppedRequest&, DeferredNotifyDataSourceStoppedResponse, int fd = -1);
+
+  using DeferredActivateTriggersResponse = ::perfetto::ipc::Deferred<ActivateTriggersResponse>;
+  void ActivateTriggers(const ActivateTriggersRequest&, DeferredActivateTriggersResponse, int fd = -1);
+
+  using DeferredSyncResponse = ::perfetto::ipc::Deferred<SyncResponse>;
+  void Sync(const SyncRequest&, DeferredSyncResponse, int fd = -1);
+
+  using DeferredUpdateDataSourceResponse = ::perfetto::ipc::Deferred<UpdateDataSourceResponse>;
+  void UpdateDataSource(const UpdateDataSourceRequest&, DeferredUpdateDataSourceResponse, int fd = -1);
+
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_PRODUCER_PORT_PROTO_H_
+// DO NOT EDIT. Autogenerated by Perfetto IPC
+// gen_amalgamated expanded: #include "protos/perfetto/ipc/producer_port.ipc.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/codegen_helpers.h"
+
+#include <memory>
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+::perfetto::ipc::ServiceDescriptor* ProducerPort::NewDescriptor() {
+  auto* desc = new ::perfetto::ipc::ServiceDescriptor();
+  desc->service_name = "ProducerPort";
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "InitializeConnection",
+     &_IPC_Decoder<InitializeConnectionRequest>,
+     &_IPC_Decoder<InitializeConnectionResponse>,
+     &_IPC_Invoker<ProducerPort, InitializeConnectionRequest, InitializeConnectionResponse, &ProducerPort::InitializeConnection>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "RegisterDataSource",
+     &_IPC_Decoder<RegisterDataSourceRequest>,
+     &_IPC_Decoder<RegisterDataSourceResponse>,
+     &_IPC_Invoker<ProducerPort, RegisterDataSourceRequest, RegisterDataSourceResponse, &ProducerPort::RegisterDataSource>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "UnregisterDataSource",
+     &_IPC_Decoder<UnregisterDataSourceRequest>,
+     &_IPC_Decoder<UnregisterDataSourceResponse>,
+     &_IPC_Invoker<ProducerPort, UnregisterDataSourceRequest, UnregisterDataSourceResponse, &ProducerPort::UnregisterDataSource>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "CommitData",
+     &_IPC_Decoder<CommitDataRequest>,
+     &_IPC_Decoder<CommitDataResponse>,
+     &_IPC_Invoker<ProducerPort, CommitDataRequest, CommitDataResponse, &ProducerPort::CommitData>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "GetAsyncCommand",
+     &_IPC_Decoder<GetAsyncCommandRequest>,
+     &_IPC_Decoder<GetAsyncCommandResponse>,
+     &_IPC_Invoker<ProducerPort, GetAsyncCommandRequest, GetAsyncCommandResponse, &ProducerPort::GetAsyncCommand>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "RegisterTraceWriter",
+     &_IPC_Decoder<RegisterTraceWriterRequest>,
+     &_IPC_Decoder<RegisterTraceWriterResponse>,
+     &_IPC_Invoker<ProducerPort, RegisterTraceWriterRequest, RegisterTraceWriterResponse, &ProducerPort::RegisterTraceWriter>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "UnregisterTraceWriter",
+     &_IPC_Decoder<UnregisterTraceWriterRequest>,
+     &_IPC_Decoder<UnregisterTraceWriterResponse>,
+     &_IPC_Invoker<ProducerPort, UnregisterTraceWriterRequest, UnregisterTraceWriterResponse, &ProducerPort::UnregisterTraceWriter>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "NotifyDataSourceStarted",
+     &_IPC_Decoder<NotifyDataSourceStartedRequest>,
+     &_IPC_Decoder<NotifyDataSourceStartedResponse>,
+     &_IPC_Invoker<ProducerPort, NotifyDataSourceStartedRequest, NotifyDataSourceStartedResponse, &ProducerPort::NotifyDataSourceStarted>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "NotifyDataSourceStopped",
+     &_IPC_Decoder<NotifyDataSourceStoppedRequest>,
+     &_IPC_Decoder<NotifyDataSourceStoppedResponse>,
+     &_IPC_Invoker<ProducerPort, NotifyDataSourceStoppedRequest, NotifyDataSourceStoppedResponse, &ProducerPort::NotifyDataSourceStopped>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "ActivateTriggers",
+     &_IPC_Decoder<ActivateTriggersRequest>,
+     &_IPC_Decoder<ActivateTriggersResponse>,
+     &_IPC_Invoker<ProducerPort, ActivateTriggersRequest, ActivateTriggersResponse, &ProducerPort::ActivateTriggers>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "Sync",
+     &_IPC_Decoder<SyncRequest>,
+     &_IPC_Decoder<SyncResponse>,
+     &_IPC_Invoker<ProducerPort, SyncRequest, SyncResponse, &ProducerPort::Sync>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "UpdateDataSource",
+     &_IPC_Decoder<UpdateDataSourceRequest>,
+     &_IPC_Decoder<UpdateDataSourceResponse>,
+     &_IPC_Invoker<ProducerPort, UpdateDataSourceRequest, UpdateDataSourceResponse, &ProducerPort::UpdateDataSource>});
+  desc->methods.shrink_to_fit();
+  return desc;
+}
+
+
+const ::perfetto::ipc::ServiceDescriptor& ProducerPort::GetDescriptorStatic() {
+  static auto* instance = NewDescriptor();
+  return *instance;
+}
+
+// Host-side definitions.
+ProducerPort::~ProducerPort() = default;
+
+const ::perfetto::ipc::ServiceDescriptor& ProducerPort::GetDescriptor() {
+  return GetDescriptorStatic();
+}
+
+// Client-side definitions.
+ProducerPortProxy::ProducerPortProxy(::perfetto::ipc::ServiceProxy::EventListener* event_listener)
+    : ::perfetto::ipc::ServiceProxy(event_listener) {}
+
+ProducerPortProxy::~ProducerPortProxy() = default;
+
+const ::perfetto::ipc::ServiceDescriptor& ProducerPortProxy::GetDescriptor() {
+  return ProducerPort::GetDescriptorStatic();
+}
+
+void ProducerPortProxy::InitializeConnection(const InitializeConnectionRequest& request, DeferredInitializeConnectionResponse reply, int fd) {
+  BeginInvoke("InitializeConnection", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ProducerPortProxy::RegisterDataSource(const RegisterDataSourceRequest& request, DeferredRegisterDataSourceResponse reply, int fd) {
+  BeginInvoke("RegisterDataSource", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ProducerPortProxy::UnregisterDataSource(const UnregisterDataSourceRequest& request, DeferredUnregisterDataSourceResponse reply, int fd) {
+  BeginInvoke("UnregisterDataSource", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ProducerPortProxy::CommitData(const CommitDataRequest& request, DeferredCommitDataResponse reply, int fd) {
+  BeginInvoke("CommitData", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ProducerPortProxy::GetAsyncCommand(const GetAsyncCommandRequest& request, DeferredGetAsyncCommandResponse reply, int fd) {
+  BeginInvoke("GetAsyncCommand", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ProducerPortProxy::RegisterTraceWriter(const RegisterTraceWriterRequest& request, DeferredRegisterTraceWriterResponse reply, int fd) {
+  BeginInvoke("RegisterTraceWriter", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ProducerPortProxy::UnregisterTraceWriter(const UnregisterTraceWriterRequest& request, DeferredUnregisterTraceWriterResponse reply, int fd) {
+  BeginInvoke("UnregisterTraceWriter", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ProducerPortProxy::NotifyDataSourceStarted(const NotifyDataSourceStartedRequest& request, DeferredNotifyDataSourceStartedResponse reply, int fd) {
+  BeginInvoke("NotifyDataSourceStarted", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ProducerPortProxy::NotifyDataSourceStopped(const NotifyDataSourceStoppedRequest& request, DeferredNotifyDataSourceStoppedResponse reply, int fd) {
+  BeginInvoke("NotifyDataSourceStopped", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ProducerPortProxy::ActivateTriggers(const ActivateTriggersRequest& request, DeferredActivateTriggersResponse reply, int fd) {
+  BeginInvoke("ActivateTriggers", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ProducerPortProxy::Sync(const SyncRequest& request, DeferredSyncResponse reply, int fd) {
+  BeginInvoke("Sync", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ProducerPortProxy::UpdateDataSource(const UpdateDataSourceRequest& request, DeferredUpdateDataSourceResponse reply, int fd) {
+  BeginInvoke("UpdateDataSource", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+// gen_amalgamated begin source: gen/protos/perfetto/ipc/relay_port.ipc.cc
+// gen_amalgamated begin header: gen/protos/perfetto/ipc/relay_port.ipc.h
+// DO NOT EDIT. Autogenerated by Perfetto IPC
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_RELAY_PORT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_RELAY_PORT_PROTO_H_
+
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_descriptor.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/ipc/relay_port.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class RelayPort : public ::perfetto::ipc::Service {
+ private:
+  static ::perfetto::ipc::ServiceDescriptor* NewDescriptor();
+
+ public:
+  ~RelayPort() override;
+
+  static const ::perfetto::ipc::ServiceDescriptor& GetDescriptorStatic();
+
+  // Service implementation.
+  const ::perfetto::ipc::ServiceDescriptor& GetDescriptor() override;
+
+  // Methods from the .proto file
+  using DeferredSyncClockResponse = ::perfetto::ipc::Deferred<SyncClockResponse>;
+  virtual void SyncClock(const SyncClockRequest&, DeferredSyncClockResponse) = 0;
+
+};
+
+
+class RelayPortProxy : public ::perfetto::ipc::ServiceProxy {
+ public:
+   explicit RelayPortProxy(::perfetto::ipc::ServiceProxy::EventListener*);
+   ~RelayPortProxy() override;
+
+  // ServiceProxy implementation.
+  const ::perfetto::ipc::ServiceDescriptor& GetDescriptor() override;
+
+  // Methods from the .proto file
+  using DeferredSyncClockResponse = ::perfetto::ipc::Deferred<SyncClockResponse>;
+  void SyncClock(const SyncClockRequest&, DeferredSyncClockResponse, int fd = -1);
+
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_RELAY_PORT_PROTO_H_
+// DO NOT EDIT. Autogenerated by Perfetto IPC
+// gen_amalgamated expanded: #include "protos/perfetto/ipc/relay_port.ipc.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/codegen_helpers.h"
+
+#include <memory>
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+::perfetto::ipc::ServiceDescriptor* RelayPort::NewDescriptor() {
+  auto* desc = new ::perfetto::ipc::ServiceDescriptor();
+  desc->service_name = "RelayPort";
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "SyncClock",
+     &_IPC_Decoder<SyncClockRequest>,
+     &_IPC_Decoder<SyncClockResponse>,
+     &_IPC_Invoker<RelayPort, SyncClockRequest, SyncClockResponse, &RelayPort::SyncClock>});
+  desc->methods.shrink_to_fit();
+  return desc;
+}
+
+
+const ::perfetto::ipc::ServiceDescriptor& RelayPort::GetDescriptorStatic() {
+  static auto* instance = NewDescriptor();
+  return *instance;
+}
+
+// Host-side definitions.
+RelayPort::~RelayPort() = default;
+
+const ::perfetto::ipc::ServiceDescriptor& RelayPort::GetDescriptor() {
+  return GetDescriptorStatic();
+}
+
+// Client-side definitions.
+RelayPortProxy::RelayPortProxy(::perfetto::ipc::ServiceProxy::EventListener* event_listener)
+    : ::perfetto::ipc::ServiceProxy(event_listener) {}
+
+RelayPortProxy::~RelayPortProxy() = default;
+
+const ::perfetto::ipc::ServiceDescriptor& RelayPortProxy::GetDescriptor() {
+  return RelayPort::GetDescriptorStatic();
+}
+
+void RelayPortProxy::SyncClock(const SyncClockRequest& request, DeferredSyncClockResponse reply, int fd) {
+  BeginInvoke("SyncClock", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+// gen_amalgamated begin source: src/tracing/ipc/default_socket.cc
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/default_socket.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
+
+#include <stdlib.h>
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+#include <unistd.h>
+#endif
+
+namespace perfetto {
+namespace {
+
+const char* kRunPerfettoBaseDir = "/run/perfetto/";
+
+// On Linux and CrOS, check /run/perfetto/ before using /tmp/ as the socket
+// base directory.
+bool UseRunPerfettoBaseDir() {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX)
+  // Note that the trailing / in |kRunPerfettoBaseDir| ensures we are checking
+  // against a directory, not a file.
+  int res = PERFETTO_EINTR(access(kRunPerfettoBaseDir, X_OK));
+  if (!res)
+    return true;
+
+  // If the path doesn't exist (ENOENT), fail silently to the caller. Otherwise,
+  // fail with an explicit error message.
+  if (errno != ENOENT
+#if PERFETTO_BUILDFLAG(PERFETTO_CHROMIUM_BUILD)
+      // access(2) won't return EPERM, but Chromium sandbox returns EPERM if the
+      // sandbox doesn't allow the call (e.g. in the child processes).
+      && errno != EPERM
+#endif
+  ) {
+    PERFETTO_PLOG("%s exists but cannot be accessed. Falling back on /tmp/ ",
+                  kRunPerfettoBaseDir);
+  }
+  return false;
+#else
+  base::ignore_result(kRunPerfettoBaseDir);
+  return false;
+#endif
+}
+
+}  // anonymous namespace
+
+const char* GetProducerSocket() {
+  const char* name = getenv("PERFETTO_PRODUCER_SOCK_NAME");
+  if (name == nullptr) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    name = "127.0.0.1:32278";
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+    name = "/dev/socket/traced_producer";
+#else
+    // Use /run/perfetto if it exists. Then fallback to /tmp.
+    static const char* producer_socket =
+        UseRunPerfettoBaseDir() ? "/run/perfetto/traced-producer.sock"
+                                : "/tmp/perfetto-producer";
+    name = producer_socket;
+#endif
+  }
+  base::ignore_result(UseRunPerfettoBaseDir);  // Silence unused func warnings.
+  return name;
+}
+
+const char* GetRelaySocket() {
+  // The relay socket is optional and is connected only when the env var is set.
+  return getenv("PERFETTO_RELAY_SOCK_NAME");
+}
+
+std::vector<std::string> TokenizeProducerSockets(
+    const char* producer_socket_names) {
+  return base::SplitString(producer_socket_names, ",");
+}
+
+const char* GetConsumerSocket() {
+  const char* name = getenv("PERFETTO_CONSUMER_SOCK_NAME");
+  if (name == nullptr) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    name = "127.0.0.1:32279";
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+    name = "/dev/socket/traced_consumer";
+#else
+    // Use /run/perfetto if it exists. Then fallback to /tmp.
+    static const char* consumer_socket =
+        UseRunPerfettoBaseDir() ? "/run/perfetto/traced-consumer.sock"
+                                : "/tmp/perfetto-consumer";
+    name = consumer_socket;
+#endif
+  }
+  return name;
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/ipc/memfd.cc
+// gen_amalgamated begin header: src/tracing/ipc/memfd.h
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACING_IPC_MEMFD_H_
+#define SRC_TRACING_IPC_MEMFD_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+
+// Some android build bots use a sysroot that doesn't support memfd when
+// compiling for the host, so we define the flags we need ourselves.
+
+// from memfd.h
+#ifndef MFD_CLOEXEC
+#define MFD_CLOEXEC 0x0001U
+#define MFD_ALLOW_SEALING 0x0002U
+#endif
+
+// from fcntl.h
+#ifndef F_ADD_SEALS
+#define F_ADD_SEALS 1033
+#define F_GET_SEALS 1034
+#define F_SEAL_SEAL 0x0001
+#define F_SEAL_SHRINK 0x0002
+#define F_SEAL_GROW 0x0004
+#define F_SEAL_WRITE 0x0008
+#endif
+
+namespace perfetto {
+
+// Whether the operating system supports memfd.
+bool HasMemfdSupport();
+
+// Call memfd(2) if available on platform and return the fd as result. This call
+// also makes a kernel version check for safety on older kernels (b/116769556).
+// Returns an invalid ScopedFile on failure.
+base::ScopedFile CreateMemfd(const char* name, unsigned int flags);
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_IPC_MEMFD_H_
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/ipc/memfd.h"
+
+#include <errno.h>
+
+#define PERFETTO_MEMFD_ENABLED()             \
+  PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+      PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX)
+
+#if PERFETTO_MEMFD_ENABLED()
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/syscall.h>
+#include <sys/utsname.h>
+#include <unistd.h>
+
+// Some android build bots use a sysroot that doesn't support memfd when
+// compiling for the host, so we redefine it if necessary.
+#if !defined(__NR_memfd_create)
+#if defined(__x86_64__)
+#define __NR_memfd_create 319
+#elif defined(__i386__)
+#define __NR_memfd_create 356
+#elif defined(__aarch64__)
+#define __NR_memfd_create 279
+#elif defined(__arm__)
+#define __NR_memfd_create 385
+#else
+#error "unsupported sysroot without memfd support"
+#endif
+#endif  // !defined(__NR_memfd_create)
+
+namespace perfetto {
+bool HasMemfdSupport() {
+  static bool kSupportsMemfd = [] {
+    // Check kernel version supports memfd_create(). Some older kernels segfault
+    // executing memfd_create() rather than returning ENOSYS (b/116769556).
+    static constexpr int kRequiredMajor = 3;
+    static constexpr int kRequiredMinor = 17;
+    struct utsname uts;
+    int major, minor;
+    if (uname(&uts) == 0 && strcmp(uts.sysname, "Linux") == 0 &&
+        sscanf(uts.release, "%d.%d", &major, &minor) == 2 &&
+        ((major < kRequiredMajor ||
+          (major == kRequiredMajor && minor < kRequiredMinor)))) {
+      return false;
+    }
+
+    base::ScopedFile fd;
+    fd.reset(static_cast<int>(syscall(__NR_memfd_create, "perfetto_shmem",
+                                      MFD_CLOEXEC | MFD_ALLOW_SEALING)));
+    return !!fd;
+  }();
+  return kSupportsMemfd;
+}
+
+base::ScopedFile CreateMemfd(const char* name, unsigned int flags) {
+  if (!HasMemfdSupport()) {
+    errno = ENOSYS;
+    return base::ScopedFile();
+  }
+  return base::ScopedFile(
+      static_cast<int>(syscall(__NR_memfd_create, name, flags)));
+}
+}  // namespace perfetto
+
+#else  // PERFETTO_MEMFD_ENABLED()
+
+namespace perfetto {
+bool HasMemfdSupport() {
+  return false;
+}
+base::ScopedFile CreateMemfd(const char*, unsigned int) {
+  errno = ENOSYS;
+  return base::ScopedFile();
+}
+}  // namespace perfetto
+
+#endif  // PERFETTO_MEMFD_ENABLED()
+// gen_amalgamated begin source: src/tracing/ipc/posix_shared_memory.cc
+// gen_amalgamated begin header: src/tracing/ipc/posix_shared_memory.h
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACING_IPC_POSIX_SHARED_MEMORY_H_
+#define SRC_TRACING_IPC_POSIX_SHARED_MEMORY_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_WASM)
+
+#include <stddef.h>
+
+#include <memory>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
+
+namespace perfetto {
+
+// Implements the SharedMemory and its factory for the posix-based transport.
+class PosixSharedMemory : public SharedMemory {
+ public:
+  class Factory : public SharedMemory::Factory {
+   public:
+    ~Factory() override;
+    std::unique_ptr<SharedMemory> CreateSharedMemory(size_t) override;
+  };
+
+  // Create a brand new SHM region.
+  static std::unique_ptr<PosixSharedMemory> Create(size_t size);
+
+  // Mmaps a file descriptor to an existing SHM region. If
+  // |require_seals_if_supported| is true and the system supports
+  // memfd_create(), the FD is required to be a sealed memfd with F_SEAL_SEAL,
+  // F_SEAL_GROW, and F_SEAL_SHRINK seals set (otherwise, nullptr is returned).
+  // May also return nullptr if mapping fails for another reason (e.g. OOM).
+  static std::unique_ptr<PosixSharedMemory> AttachToFd(
+      base::ScopedFile,
+      bool require_seals_if_supported = true);
+
+  ~PosixSharedMemory() override;
+
+  int fd() const { return fd_.get(); }
+
+  // SharedMemory implementation.
+  void* start() const override { return start_; }
+  size_t size() const override { return size_; }
+
+ private:
+  static std::unique_ptr<PosixSharedMemory> MapFD(base::ScopedFile, size_t);
+
+  PosixSharedMemory(void* start, size_t size, base::ScopedFile);
+  PosixSharedMemory(const PosixSharedMemory&) = delete;
+  PosixSharedMemory& operator=(const PosixSharedMemory&) = delete;
+
+  void* const start_;
+  const size_t size_;
+  base::ScopedFile fd_;
+};
+
+}  // namespace perfetto
+
+#endif  // OS_LINUX || OS_ANDROID || OS_APPLE
+#endif  // SRC_TRACING_IPC_POSIX_SHARED_MEMORY_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/ipc/posix_shared_memory.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_WASM)
+
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <memory>
+#include <utility>
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/temp_file.h"
+// gen_amalgamated expanded: #include "src/tracing/ipc/memfd.h"
+
+namespace perfetto {
+
+namespace {
+int kFileSeals = F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_SEAL;
+}  // namespace
+
+// static
+std::unique_ptr<PosixSharedMemory> PosixSharedMemory::Create(size_t size) {
+  base::ScopedFile fd =
+      CreateMemfd("perfetto_shmem", MFD_CLOEXEC | MFD_ALLOW_SEALING);
+  bool is_memfd = !!fd;
+
+  // In-tree builds only allow mem_fd, so we can inspect the seals to verify the
+  // fd is appropriately sealed. We'll crash in the PERFETTO_CHECK(fd) below if
+  // memfd_create failed.
+#if !PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
+  if (!fd) {
+    // TODO: if this fails on Android we should fall back on ashmem.
+    PERFETTO_DPLOG("memfd_create() failed");
+    fd = base::TempFile::CreateUnlinked().ReleaseFD();
+  }
+#endif
+
+  PERFETTO_CHECK(fd);
+  int res = ftruncate(fd.get(), static_cast<off_t>(size));
+  PERFETTO_CHECK(res == 0);
+
+  if (is_memfd) {
+    // When memfd is supported, file seals should be, too.
+    res = fcntl(*fd, F_ADD_SEALS, kFileSeals);
+    PERFETTO_DCHECK(res == 0);
+  }
+
+  return MapFD(std::move(fd), size);
+}
+
+// static
+std::unique_ptr<PosixSharedMemory> PosixSharedMemory::AttachToFd(
+    base::ScopedFile fd,
+    bool require_seals_if_supported) {
+  bool requires_seals = require_seals_if_supported;
+
+#if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
+  // In-tree kernels all support memfd.
+  PERFETTO_CHECK(HasMemfdSupport());
+#else
+  // In out-of-tree builds, we only require seals if the kernel supports memfd.
+  if (requires_seals)
+    requires_seals = HasMemfdSupport();
+#endif
+
+  if (requires_seals) {
+    // If the system supports memfd, we require a sealed memfd.
+    int res = fcntl(*fd, F_GET_SEALS);
+    if (res == -1 || (res & kFileSeals) != kFileSeals) {
+      PERFETTO_PLOG("Couldn't verify file seals on shmem FD");
+      return nullptr;
+    }
+  }
+
+  struct stat stat_buf = {};
+  int res = fstat(fd.get(), &stat_buf);
+  PERFETTO_CHECK(res == 0 && stat_buf.st_size > 0);
+  return MapFD(std::move(fd), static_cast<size_t>(stat_buf.st_size));
+}
+
+// static
+std::unique_ptr<PosixSharedMemory> PosixSharedMemory::MapFD(base::ScopedFile fd,
+                                                            size_t size) {
+  PERFETTO_DCHECK(fd);
+  PERFETTO_DCHECK(size > 0);
+  void* start =
+      mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd.get(), 0);
+  PERFETTO_CHECK(start != MAP_FAILED);
+  return std::unique_ptr<PosixSharedMemory>(
+      new PosixSharedMemory(start, size, std::move(fd)));
+}
+
+PosixSharedMemory::PosixSharedMemory(void* start,
+                                     size_t size,
+                                     base::ScopedFile fd)
+    : start_(start), size_(size), fd_(std::move(fd)) {}
+
+PosixSharedMemory::~PosixSharedMemory() {
+  munmap(start(), size());
+}
+
+PosixSharedMemory::Factory::~Factory() {}
+
+std::unique_ptr<SharedMemory> PosixSharedMemory::Factory::CreateSharedMemory(
+    size_t size) {
+  return PosixSharedMemory::Create(size);
+}
+
+}  // namespace perfetto
+
+#endif  // OS_LINUX || OS_ANDROID || OS_APPLE
+// gen_amalgamated begin source: src/tracing/ipc/shared_memory_windows.cc
+// gen_amalgamated begin header: src/tracing/ipc/shared_memory_windows.h
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACING_IPC_SHARED_MEMORY_WINDOWS_H_
+#define SRC_TRACING_IPC_SHARED_MEMORY_WINDOWS_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
+
+namespace perfetto {
+
+// Implements the SharedMemory and its factory for the Windows IPC transport.
+// This used only for standalone builds and NOT in chromium, which instead uses
+// a custom Mojo wrapper (MojoSharedMemory in chromium's //services/tracing/).
+class SharedMemoryWindows : public SharedMemory {
+ public:
+  class Factory : public SharedMemory::Factory {
+   public:
+    ~Factory() override;
+    std::unique_ptr<SharedMemory> CreateSharedMemory(size_t) override;
+  };
+
+  // Create a brand new SHM region.
+  enum Flags { kNone = 0, kInheritableHandles };
+  static std::unique_ptr<SharedMemoryWindows> Create(
+      size_t size, Flags flags=Flags::kNone);
+  static std::unique_ptr<SharedMemoryWindows> Attach(const std::string& key);
+  static std::unique_ptr<SharedMemoryWindows> AttachToHandleWithKey(
+      base::ScopedPlatformHandle fd, const std::string& key);
+  ~SharedMemoryWindows() override;
+  const std::string& key() const { return key_; }
+  const base::ScopedPlatformHandle& handle() const { return handle_; }
+
+  // SharedMemory implementation.
+  void* start() const override { return start_; }
+  size_t size() const override { return size_; }
+
+ private:
+  SharedMemoryWindows(void* start,
+                      size_t size,
+                      std::string,
+                      base::ScopedPlatformHandle);
+  SharedMemoryWindows(const SharedMemoryWindows&) = delete;
+  SharedMemoryWindows& operator=(const SharedMemoryWindows&) = delete;
+
+  void* const start_;
+  const size_t size_;
+  std::string key_;
+  base::ScopedPlatformHandle handle_;
+};
+
+}  // namespace perfetto
+
+#endif  // OS_WIN
+
+#endif  // SRC_TRACING_IPC_SHARED_MEMORY_WINDOWS_H_
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/ipc/shared_memory_windows.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+#include <memory>
+#include <random>
+
+#include <Windows.h>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
+
+namespace perfetto {
+
+// static
+std::unique_ptr<SharedMemoryWindows> SharedMemoryWindows::Create(
+    size_t size, Flags flags) {
+  base::ScopedPlatformHandle shmem_handle;
+  std::random_device rnd_dev;
+  uint64_t rnd_key = (static_cast<uint64_t>(rnd_dev()) << 32) | rnd_dev();
+  std::string key = "perfetto_shm_" + base::Uint64ToHexStringNoPrefix(rnd_key);
+
+  SECURITY_ATTRIBUTES security_attributes = {};
+  security_attributes.nLength = sizeof(SECURITY_ATTRIBUTES);
+  if (flags & Flags::kInheritableHandles)
+    security_attributes.bInheritHandle = TRUE;
+
+  shmem_handle.reset(CreateFileMappingA(
+      INVALID_HANDLE_VALUE,  // Use paging file.
+      &security_attributes,
+      PAGE_READWRITE,
+      static_cast<DWORD>(size >> 32),  // maximum object size (high-order DWORD)
+      static_cast<DWORD>(size),        // maximum object size (low-order DWORD)
+      key.c_str()));
+
+  if (!shmem_handle) {
+    PERFETTO_PLOG("CreateFileMapping() call failed");
+    return nullptr;
+  }
+  void* start =
+      MapViewOfFile(*shmem_handle, FILE_MAP_ALL_ACCESS, /*offsetHigh=*/0,
+                    /*offsetLow=*/0, size);
+  if (!start) {
+    PERFETTO_PLOG("MapViewOfFile() failed");
+    return nullptr;
+  }
+
+  return std::unique_ptr<SharedMemoryWindows>(new SharedMemoryWindows(
+      start, size, std::move(key), std::move(shmem_handle)));
+}
+
+// static
+std::unique_ptr<SharedMemoryWindows> SharedMemoryWindows::Attach(
+    const std::string& key) {
+  base::ScopedPlatformHandle shmem_handle;
+  shmem_handle.reset(
+      OpenFileMappingA(FILE_MAP_ALL_ACCESS, /*inherit=*/false, key.c_str()));
+  if (!shmem_handle) {
+    PERFETTO_PLOG("Failed to OpenFileMapping()");
+    return nullptr;
+  }
+
+  void* start =
+      MapViewOfFile(*shmem_handle, FILE_MAP_ALL_ACCESS, /*offsetHigh=*/0,
+                    /*offsetLow=*/0, /*dwNumberOfBytesToMap=*/0);
+  if (!start) {
+    PERFETTO_PLOG("MapViewOfFile() failed");
+    return nullptr;
+  }
+
+  MEMORY_BASIC_INFORMATION info{};
+  if (!VirtualQuery(start, &info, sizeof(info))) {
+    PERFETTO_PLOG("VirtualQuery() failed");
+    return nullptr;
+  }
+  size_t size = info.RegionSize;
+  return std::unique_ptr<SharedMemoryWindows>(
+      new SharedMemoryWindows(start, size, key, std::move(shmem_handle)));
+}
+
+// static
+std::unique_ptr<SharedMemoryWindows> SharedMemoryWindows::AttachToHandleWithKey(
+    base::ScopedPlatformHandle shmem_handle, const std::string& key) {
+  void* start =
+      MapViewOfFile(*shmem_handle, FILE_MAP_ALL_ACCESS, /*offsetHigh=*/0,
+                    /*offsetLow=*/0, /*dwNumberOfBytesToMap=*/0);
+  if (!start) {
+    PERFETTO_PLOG("MapViewOfFile() failed");
+    return nullptr;
+  }
+
+  MEMORY_BASIC_INFORMATION info{};
+  if (!VirtualQuery(start, &info, sizeof(info))) {
+    PERFETTO_PLOG("VirtualQuery() failed");
+    return nullptr;
+  }
+  size_t size = info.RegionSize;
+
+  return std::unique_ptr<SharedMemoryWindows>(
+      new SharedMemoryWindows(start, size, key, std::move(shmem_handle)));
+}
+
+SharedMemoryWindows::SharedMemoryWindows(void* start,
+                                         size_t size,
+                                         std::string key,
+                                         base::ScopedPlatformHandle handle)
+    : start_(start),
+      size_(size),
+      key_(std::move(key)),
+      handle_(std::move(handle)) {}
+
+SharedMemoryWindows::~SharedMemoryWindows() {
+  if (start_)
+    UnmapViewOfFile(start_);
+}
+
+SharedMemoryWindows::Factory::~Factory() = default;
+
+std::unique_ptr<SharedMemory> SharedMemoryWindows::Factory::CreateSharedMemory(
+    size_t size) {
+  return SharedMemoryWindows::Create(size);
+}
+
+}  // namespace perfetto
+
+#endif  // !OS_WIN
+// gen_amalgamated begin source: src/tracing/ipc/consumer/consumer_ipc_client_impl.cc
+// gen_amalgamated begin header: src/tracing/ipc/consumer/consumer_ipc_client_impl.h
+// gen_amalgamated begin header: include/perfetto/ext/tracing/ipc/consumer_ipc_client.h
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACING_IPC_CONSUMER_IPC_CLIENT_H_
+#define INCLUDE_PERFETTO_EXT_TRACING_IPC_CONSUMER_IPC_CLIENT_H_
+
+#include <memory>
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
+
+namespace perfetto {
+
+class Consumer;
+
+// Allows to connect to a remote Service through a UNIX domain socket.
+// Exposed to:
+//   Consumer(s) of the tracing library.
+// Implemented in:
+//   src/tracing/ipc/consumer/consumer_ipc_client_impl.cc
+class PERFETTO_EXPORT_COMPONENT ConsumerIPCClient {
+ public:
+  // Connects to the producer port of the Service listening on the given
+  // |service_sock_name|. If the connection is successful, the OnConnect()
+  // method will be invoked asynchronously on the passed Consumer interface.
+  // If the connection fails, OnDisconnect() will be invoked instead.
+  // The returned ConsumerEndpoint serves also to delimit the scope of the
+  // callbacks invoked on the Consumer interface: no more Consumer callbacks are
+  // invoked immediately after its destruction and any pending callback will be
+  // dropped.
+  static std::unique_ptr<TracingService::ConsumerEndpoint>
+  Connect(const char* service_sock_name, Consumer*, base::TaskRunner*);
+
+ protected:
+  ConsumerIPCClient() = delete;
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_TRACING_IPC_CONSUMER_IPC_CLIENT_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACING_IPC_CONSUMER_CONSUMER_IPC_CLIENT_IMPL_H_
+#define SRC_TRACING_IPC_CONSUMER_CONSUMER_IPC_CLIENT_IMPL_H_
+
+#include <stdint.h>
+
+#include <list>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/consumer_ipc_client.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/ipc/consumer_port.ipc.h"
+
+namespace perfetto {
+
+namespace base {
+class TaskRunner;
+}  // namespace base
+
+namespace ipc {
+class Client;
+}  // namespace ipc
+
+class Consumer;
+
+// Exposes a Service endpoint to Consumer(s), proxying all requests through a
+// IPC channel to the remote Service. This class is the glue layer between the
+// generic Service interface exposed to the clients of the library and the
+// actual IPC transport.
+class ConsumerIPCClientImpl : public TracingService::ConsumerEndpoint,
+                              public ipc::ServiceProxy::EventListener {
+ public:
+  ConsumerIPCClientImpl(const char* service_sock_name,
+                        Consumer*,
+                        base::TaskRunner*);
+  ~ConsumerIPCClientImpl() override;
+
+  // TracingService::ConsumerEndpoint implementation.
+  // These methods are invoked by the actual Consumer(s) code by clients of the
+  // tracing library, which know nothing about the IPC transport.
+  void EnableTracing(const TraceConfig&, base::ScopedFile) override;
+  void StartTracing() override;
+  void ChangeTraceConfig(const TraceConfig&) override;
+  void DisableTracing() override;
+  void ReadBuffers() override;
+  void FreeBuffers() override;
+  void Flush(uint32_t timeout_ms, FlushCallback, FlushFlags) override;
+  void Detach(const std::string& key) override;
+  void Attach(const std::string& key) override;
+  void GetTraceStats() override;
+  void ObserveEvents(uint32_t enabled_event_types) override;
+  void QueryServiceState(QueryServiceStateArgs,
+                         QueryServiceStateCallback) override;
+  void QueryCapabilities(QueryCapabilitiesCallback) override;
+  void SaveTraceForBugreport(SaveTraceForBugreportCallback) override;
+  void CloneSession(TracingSessionID, CloneSessionArgs) override;
+
+  // ipc::ServiceProxy::EventListener implementation.
+  // These methods are invoked by the IPC layer, which knows nothing about
+  // tracing, consumers and consumers.
+  void OnConnect() override;
+  void OnDisconnect() override;
+
+ private:
+  struct PendingQueryServiceRequest {
+    QueryServiceStateCallback callback;
+
+    // All the replies will be appended here until |has_more| == false.
+    std::vector<uint8_t> merged_resp;
+  };
+
+  // List because we need stable iterators.
+  using PendingQueryServiceRequests = std::list<PendingQueryServiceRequest>;
+
+  void OnReadBuffersResponse(
+      ipc::AsyncResult<protos::gen::ReadBuffersResponse>);
+  void OnEnableTracingResponse(
+      ipc::AsyncResult<protos::gen::EnableTracingResponse>);
+  void OnQueryServiceStateResponse(
+      ipc::AsyncResult<protos::gen::QueryServiceStateResponse>,
+      PendingQueryServiceRequests::iterator);
+
+  // TODO(primiano): think to dtor order, do we rely on any specific sequence?
+  Consumer* const consumer_;
+
+  // The object that owns the client socket and takes care of IPC traffic.
+  std::unique_ptr<ipc::Client> ipc_channel_;
+
+  // The proxy interface for the consumer port of the service. It is bound
+  // to |ipc_channel_| and (de)serializes method invocations over the wire.
+  protos::gen::ConsumerPortProxy consumer_port_;
+
+  bool connected_ = false;
+
+  PendingQueryServiceRequests pending_query_svc_reqs_;
+
+  // When a packet is too big to fit into a ReadBuffersResponse IPC, the service
+  // will chunk it into several IPCs, each containing few slices of the packet
+  // (a packet's slice is always guaranteed to be << kIPCBufferSize). When
+  // chunking happens this field accumulates the slices received until the
+  // one with |last_slice_for_packet| == true is received.
+  TracePacket partial_packet_;
+
+  // Keep last.
+  base::WeakPtrFactory<ConsumerIPCClientImpl> weak_ptr_factory_;
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_IPC_CONSUMER_CONSUMER_IPC_CLIENT_IMPL_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/ipc/consumer/consumer_ipc_client_impl.h"
+
+#include <string.h>
+
+#include <cinttypes>
+
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/client.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/consumer.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/observable_events.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_stats.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/trace_config.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/tracing_service_state.h"
+
+// TODO(fmayer): Add a test to check to what happens when ConsumerIPCClientImpl
+// gets destroyed w.r.t. the Consumer pointer. Also think to lifetime of the
+// Consumer* during the callbacks.
+
+namespace perfetto {
+
+// static. (Declared in include/tracing/ipc/consumer_ipc_client.h).
+std::unique_ptr<TracingService::ConsumerEndpoint> ConsumerIPCClient::Connect(
+    const char* service_sock_name,
+    Consumer* consumer,
+    base::TaskRunner* task_runner) {
+  return std::unique_ptr<TracingService::ConsumerEndpoint>(
+      new ConsumerIPCClientImpl(service_sock_name, consumer, task_runner));
+}
+
+ConsumerIPCClientImpl::ConsumerIPCClientImpl(const char* service_sock_name,
+                                             Consumer* consumer,
+                                             base::TaskRunner* task_runner)
+    : consumer_(consumer),
+      ipc_channel_(
+          ipc::Client::CreateInstance({service_sock_name, /*sock_retry=*/false},
+                                      task_runner)),
+      consumer_port_(this /* event_listener */),
+      weak_ptr_factory_(this) {
+  ipc_channel_->BindService(consumer_port_.GetWeakPtr());
+}
+
+ConsumerIPCClientImpl::~ConsumerIPCClientImpl() = default;
+
+// Called by the IPC layer if the BindService() succeeds.
+void ConsumerIPCClientImpl::OnConnect() {
+  connected_ = true;
+  consumer_->OnConnect();
+}
+
+void ConsumerIPCClientImpl::OnDisconnect() {
+  PERFETTO_DLOG("Tracing service connection failure");
+  connected_ = false;
+  consumer_->OnDisconnect();  // Note: may delete |this|.
+}
+
+void ConsumerIPCClientImpl::EnableTracing(const TraceConfig& trace_config,
+                                          base::ScopedFile fd) {
+  if (!connected_) {
+    PERFETTO_DLOG("Cannot EnableTracing(), not connected to tracing service");
+    return;
+  }
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  if (fd) {
+    consumer_->OnTracingDisabled(
+        "Passing FDs for write_into_file is not supported on Windows");
+    return;
+  }
+#endif
+
+  protos::gen::EnableTracingRequest req;
+  *req.mutable_trace_config() = trace_config;
+  ipc::Deferred<protos::gen::EnableTracingResponse> async_response;
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  async_response.Bind(
+      [weak_this](
+          ipc::AsyncResult<protos::gen::EnableTracingResponse> response) {
+        if (weak_this)
+          weak_this->OnEnableTracingResponse(std::move(response));
+      });
+
+  // |fd| will be closed when this function returns, but it's fine because the
+  // IPC layer dup()'s it when sending the IPC.
+  consumer_port_.EnableTracing(req, std::move(async_response), *fd);
+}
+
+void ConsumerIPCClientImpl::ChangeTraceConfig(const TraceConfig& trace_config) {
+  if (!connected_) {
+    PERFETTO_DLOG(
+        "Cannot ChangeTraceConfig(), not connected to tracing service");
+    return;
+  }
+
+  ipc::Deferred<protos::gen::ChangeTraceConfigResponse> async_response;
+  async_response.Bind(
+      [](ipc::AsyncResult<protos::gen::ChangeTraceConfigResponse> response) {
+        if (!response)
+          PERFETTO_DLOG("ChangeTraceConfig() failed");
+      });
+  protos::gen::ChangeTraceConfigRequest req;
+  *req.mutable_trace_config() = trace_config;
+  consumer_port_.ChangeTraceConfig(req, std::move(async_response));
+}
+
+void ConsumerIPCClientImpl::StartTracing() {
+  if (!connected_) {
+    PERFETTO_DLOG("Cannot StartTracing(), not connected to tracing service");
+    return;
+  }
+
+  ipc::Deferred<protos::gen::StartTracingResponse> async_response;
+  async_response.Bind(
+      [](ipc::AsyncResult<protos::gen::StartTracingResponse> response) {
+        if (!response)
+          PERFETTO_DLOG("StartTracing() failed");
+      });
+  protos::gen::StartTracingRequest req;
+  consumer_port_.StartTracing(req, std::move(async_response));
+}
+
+void ConsumerIPCClientImpl::DisableTracing() {
+  if (!connected_) {
+    PERFETTO_DLOG("Cannot DisableTracing(), not connected to tracing service");
+    return;
+  }
+
+  ipc::Deferred<protos::gen::DisableTracingResponse> async_response;
+  async_response.Bind(
+      [](ipc::AsyncResult<protos::gen::DisableTracingResponse> response) {
+        if (!response)
+          PERFETTO_DLOG("DisableTracing() failed");
+      });
+  consumer_port_.DisableTracing(protos::gen::DisableTracingRequest(),
+                                std::move(async_response));
+}
+
+void ConsumerIPCClientImpl::ReadBuffers() {
+  if (!connected_) {
+    PERFETTO_DLOG("Cannot ReadBuffers(), not connected to tracing service");
+    return;
+  }
+
+  ipc::Deferred<protos::gen::ReadBuffersResponse> async_response;
+
+  // The IPC layer guarantees that callbacks are destroyed after this object
+  // is destroyed (by virtue of destroying the |consumer_port_|). In turn the
+  // contract of this class expects the caller to not destroy the Consumer class
+  // before having destroyed this class. Hence binding |this| here is safe.
+  async_response.Bind(
+      [this](ipc::AsyncResult<protos::gen::ReadBuffersResponse> response) {
+        OnReadBuffersResponse(std::move(response));
+      });
+  consumer_port_.ReadBuffers(protos::gen::ReadBuffersRequest(),
+                             std::move(async_response));
+}
+
+void ConsumerIPCClientImpl::OnReadBuffersResponse(
+    ipc::AsyncResult<protos::gen::ReadBuffersResponse> response) {
+  if (!response) {
+    PERFETTO_DLOG("ReadBuffers() failed");
+    return;
+  }
+  std::vector<TracePacket> trace_packets;
+  for (auto& resp_slice : response->slices()) {
+    const std::string& slice_data = resp_slice.data();
+    Slice slice = Slice::Allocate(slice_data.size());
+    memcpy(slice.own_data(), slice_data.data(), slice.size);
+    partial_packet_.AddSlice(std::move(slice));
+    if (resp_slice.last_slice_for_packet())
+      trace_packets.emplace_back(std::move(partial_packet_));
+  }
+  if (!trace_packets.empty() || !response.has_more())
+    consumer_->OnTraceData(std::move(trace_packets), response.has_more());
+}
+
+void ConsumerIPCClientImpl::OnEnableTracingResponse(
+    ipc::AsyncResult<protos::gen::EnableTracingResponse> response) {
+  std::string error;
+  // |response| might be empty when the request gets rejected (if the connection
+  // with the service is dropped all outstanding requests are auto-rejected).
+  if (!response) {
+    error =
+        "EnableTracing IPC request rejected. This is likely due to a loss of "
+        "the traced connection";
+  } else {
+    error = response->error();
+  }
+  if (!response || response->disabled())
+    consumer_->OnTracingDisabled(error);
+}
+
+void ConsumerIPCClientImpl::FreeBuffers() {
+  if (!connected_) {
+    PERFETTO_DLOG("Cannot FreeBuffers(), not connected to tracing service");
+    return;
+  }
+
+  protos::gen::FreeBuffersRequest req;
+  ipc::Deferred<protos::gen::FreeBuffersResponse> async_response;
+  async_response.Bind(
+      [](ipc::AsyncResult<protos::gen::FreeBuffersResponse> response) {
+        if (!response)
+          PERFETTO_DLOG("FreeBuffers() failed");
+      });
+  consumer_port_.FreeBuffers(req, std::move(async_response));
+}
+
+void ConsumerIPCClientImpl::Flush(uint32_t timeout_ms,
+                                  FlushCallback callback,
+                                  FlushFlags flush_flags) {
+  if (!connected_) {
+    PERFETTO_DLOG("Cannot Flush(), not connected to tracing service");
+    return callback(/*success=*/false);
+  }
+
+  protos::gen::FlushRequest req;
+  req.set_timeout_ms(static_cast<uint32_t>(timeout_ms));
+  req.set_flags(flush_flags.flags());
+  ipc::Deferred<protos::gen::FlushResponse> async_response;
+  async_response.Bind(
+      [callback](ipc::AsyncResult<protos::gen::FlushResponse> response) {
+        callback(!!response);
+      });
+  consumer_port_.Flush(req, std::move(async_response));
+}
+
+void ConsumerIPCClientImpl::Detach(const std::string& key) {
+  if (!connected_) {
+    PERFETTO_DLOG("Cannot Detach(), not connected to tracing service");
+    return;
+  }
+
+  protos::gen::DetachRequest req;
+  req.set_key(key);
+  ipc::Deferred<protos::gen::DetachResponse> async_response;
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+
+  async_response.Bind(
+      [weak_this](ipc::AsyncResult<protos::gen::DetachResponse> response) {
+        if (weak_this)
+          weak_this->consumer_->OnDetach(!!response);
+      });
+  consumer_port_.Detach(req, std::move(async_response));
+}
+
+void ConsumerIPCClientImpl::Attach(const std::string& key) {
+  if (!connected_) {
+    PERFETTO_DLOG("Cannot Attach(), not connected to tracing service");
+    return;
+  }
+
+  {
+    protos::gen::AttachRequest req;
+    req.set_key(key);
+    ipc::Deferred<protos::gen::AttachResponse> async_response;
+    auto weak_this = weak_ptr_factory_.GetWeakPtr();
+
+    async_response.Bind(
+        [weak_this](ipc::AsyncResult<protos::gen::AttachResponse> response) {
+          if (!weak_this)
+            return;
+          if (!response) {
+            weak_this->consumer_->OnAttach(/*success=*/false, TraceConfig());
+            return;
+          }
+          const TraceConfig& trace_config = response->trace_config();
+
+          // If attached successfully, also attach to the end-of-trace
+          // notificaton callback, via EnableTracing(attach_notification_only).
+          protos::gen::EnableTracingRequest enable_req;
+          enable_req.set_attach_notification_only(true);
+          ipc::Deferred<protos::gen::EnableTracingResponse> enable_resp;
+          enable_resp.Bind(
+              [weak_this](
+                  ipc::AsyncResult<protos::gen::EnableTracingResponse> resp) {
+                if (weak_this)
+                  weak_this->OnEnableTracingResponse(std::move(resp));
+              });
+          weak_this->consumer_port_.EnableTracing(enable_req,
+                                                  std::move(enable_resp));
+
+          weak_this->consumer_->OnAttach(/*success=*/true, trace_config);
+        });
+    consumer_port_.Attach(req, std::move(async_response));
+  }
+}
+
+void ConsumerIPCClientImpl::GetTraceStats() {
+  if (!connected_) {
+    PERFETTO_DLOG("Cannot GetTraceStats(), not connected to tracing service");
+    return;
+  }
+
+  protos::gen::GetTraceStatsRequest req;
+  ipc::Deferred<protos::gen::GetTraceStatsResponse> async_response;
+
+  // The IPC layer guarantees that callbacks are destroyed after this object
+  // is destroyed (by virtue of destroying the |consumer_port_|). In turn the
+  // contract of this class expects the caller to not destroy the Consumer class
+  // before having destroyed this class. Hence binding |this| here is safe.
+  async_response.Bind(
+      [this](ipc::AsyncResult<protos::gen::GetTraceStatsResponse> response) {
+        if (!response) {
+          consumer_->OnTraceStats(/*success=*/false, TraceStats());
+          return;
+        }
+        consumer_->OnTraceStats(/*success=*/true, response->trace_stats());
+      });
+  consumer_port_.GetTraceStats(req, std::move(async_response));
+}
+
+void ConsumerIPCClientImpl::ObserveEvents(uint32_t enabled_event_types) {
+  if (!connected_) {
+    PERFETTO_DLOG("Cannot ObserveEvents(), not connected to tracing service");
+    return;
+  }
+
+  protos::gen::ObserveEventsRequest req;
+  for (uint32_t i = 0; i < 32; i++) {
+    const uint32_t event_id = 1u << i;
+    if (enabled_event_types & event_id)
+      req.add_events_to_observe(static_cast<ObservableEvents::Type>(event_id));
+  }
+
+  ipc::Deferred<protos::gen::ObserveEventsResponse> async_response;
+  // The IPC layer guarantees that callbacks are destroyed after this object
+  // is destroyed (by virtue of destroying the |consumer_port_|). In turn the
+  // contract of this class expects the caller to not destroy the Consumer class
+  // before having destroyed this class. Hence binding |this| here is safe.
+  async_response.Bind(
+      [this](ipc::AsyncResult<protos::gen::ObserveEventsResponse> response) {
+        // Skip empty response, which the service sends to close the stream.
+        if (!response.has_more()) {
+          PERFETTO_DCHECK(!response.success());
+          return;
+        }
+        consumer_->OnObservableEvents(response->events());
+      });
+  consumer_port_.ObserveEvents(req, std::move(async_response));
+}
+
+void ConsumerIPCClientImpl::QueryServiceState(
+    QueryServiceStateArgs args,
+    QueryServiceStateCallback callback) {
+  if (!connected_) {
+    PERFETTO_DLOG(
+        "Cannot QueryServiceState(), not connected to tracing service");
+    return;
+  }
+
+  auto it = pending_query_svc_reqs_.insert(pending_query_svc_reqs_.end(),
+                                           {std::move(callback), {}});
+  protos::gen::QueryServiceStateRequest req;
+  req.set_sessions_only(args.sessions_only);
+  ipc::Deferred<protos::gen::QueryServiceStateResponse> async_response;
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  async_response.Bind(
+      [weak_this,
+       it](ipc::AsyncResult<protos::gen::QueryServiceStateResponse> response) {
+        if (weak_this)
+          weak_this->OnQueryServiceStateResponse(std::move(response), it);
+      });
+  consumer_port_.QueryServiceState(req, std::move(async_response));
+}
+
+void ConsumerIPCClientImpl::OnQueryServiceStateResponse(
+    ipc::AsyncResult<protos::gen::QueryServiceStateResponse> response,
+    PendingQueryServiceRequests::iterator req_it) {
+  PERFETTO_DCHECK(req_it->callback);
+
+  if (!response) {
+    auto callback = std::move(req_it->callback);
+    pending_query_svc_reqs_.erase(req_it);
+    callback(false, TracingServiceState());
+    return;
+  }
+
+  // The QueryServiceState response can be split in several chunks if the
+  // service has several data sources. The client is supposed to merge all the
+  // replies. The easiest way to achieve this is to re-serialize the partial
+  // response and then re-decode the merged result in one shot.
+  std::vector<uint8_t>& merged_resp = req_it->merged_resp;
+  std::vector<uint8_t> part = response->service_state().SerializeAsArray();
+  merged_resp.insert(merged_resp.end(), part.begin(), part.end());
+
+  if (response.has_more())
+    return;
+
+  // All replies have been received. Decode the merged result and reply to the
+  // callback.
+  protos::gen::TracingServiceState svc_state;
+  bool ok = svc_state.ParseFromArray(merged_resp.data(), merged_resp.size());
+  if (!ok)
+    PERFETTO_ELOG("Failed to decode merged QueryServiceStateResponse");
+  auto callback = std::move(req_it->callback);
+  pending_query_svc_reqs_.erase(req_it);
+  callback(ok, std::move(svc_state));
+}
+
+void ConsumerIPCClientImpl::QueryCapabilities(
+    QueryCapabilitiesCallback callback) {
+  if (!connected_) {
+    PERFETTO_DLOG(
+        "Cannot QueryCapabilities(), not connected to tracing service");
+    return;
+  }
+
+  protos::gen::QueryCapabilitiesRequest req;
+  ipc::Deferred<protos::gen::QueryCapabilitiesResponse> async_response;
+  async_response.Bind(
+      [callback](
+          ipc::AsyncResult<protos::gen::QueryCapabilitiesResponse> response) {
+        if (!response) {
+          // If the IPC fails, we are talking to an older version of the service
+          // that didn't support QueryCapabilities at all. In this case return
+          // an empty capabilities message.
+          callback(TracingServiceCapabilities());
+        } else {
+          callback(response->capabilities());
+        }
+      });
+  consumer_port_.QueryCapabilities(req, std::move(async_response));
+}
+
+void ConsumerIPCClientImpl::SaveTraceForBugreport(
+    SaveTraceForBugreportCallback callback) {
+  if (!connected_) {
+    PERFETTO_DLOG(
+        "Cannot SaveTraceForBugreport(), not connected to tracing service");
+    return;
+  }
+
+  protos::gen::SaveTraceForBugreportRequest req;
+  ipc::Deferred<protos::gen::SaveTraceForBugreportResponse> async_response;
+  async_response.Bind(
+      [callback](ipc::AsyncResult<protos::gen::SaveTraceForBugreportResponse>
+                     response) {
+        if (!response) {
+          // If the IPC fails, we are talking to an older version of the service
+          // that didn't support SaveTraceForBugreport at all.
+          callback(
+              false,
+              "The tracing service doesn't support SaveTraceForBugreport()");
+        } else {
+          callback(response->success(), response->msg());
+        }
+      });
+  consumer_port_.SaveTraceForBugreport(req, std::move(async_response));
+}
+
+void ConsumerIPCClientImpl::CloneSession(TracingSessionID tsid,
+                                         CloneSessionArgs args) {
+  if (!connected_) {
+    PERFETTO_DLOG("Cannot CloneSession(), not connected to tracing service");
+    return;
+  }
+
+  protos::gen::CloneSessionRequest req;
+  req.set_session_id(tsid);
+  req.set_skip_trace_filter(args.skip_trace_filter);
+  req.set_for_bugreport(args.for_bugreport);
+  ipc::Deferred<protos::gen::CloneSessionResponse> async_response;
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+
+  async_response.Bind(
+      [weak_this](
+          ipc::AsyncResult<protos::gen::CloneSessionResponse> response) {
+        if (!weak_this)
+          return;
+        if (!response) {
+          // If the IPC fails, we are talking to an older version of the service
+          // that didn't support CloneSession at all.
+          weak_this->consumer_->OnSessionCloned(
+              {false, "CloneSession IPC not supported", {}});
+        } else {
+          base::Uuid uuid(response->uuid_lsb(), response->uuid_msb());
+          weak_this->consumer_->OnSessionCloned(
+              {response->success(), response->error(), uuid});
+        }
+      });
+  consumer_port_.CloneSession(req, std::move(async_response));
+}
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/ipc/producer/producer_ipc_client_impl.cc
+// gen_amalgamated begin header: src/tracing/ipc/producer/producer_ipc_client_impl.h
+// gen_amalgamated begin header: include/perfetto/ext/tracing/ipc/producer_ipc_client.h
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACING_IPC_PRODUCER_IPC_CLIENT_H_
+#define INCLUDE_PERFETTO_EXT_TRACING_IPC_PRODUCER_IPC_CLIENT_H_
+
+#include <memory>
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/client.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/tracing_backend.h"
+
+namespace perfetto {
+
+class Producer;
+
+// Allows to connect to a remote Service through a UNIX domain socket.
+// Exposed to:
+//   Producer(s) of the tracing library.
+// Implemented in:
+//   src/tracing/ipc/producer/producer_ipc_client_impl.cc
+class PERFETTO_EXPORT_COMPONENT ProducerIPCClient {
+ public:
+  enum class ConnectionFlags {
+    // Fails immediately with OnConnect(false) if the service connection cannot
+    // be established.
+    kDefault = 0,
+
+    // Keeps retrying with exponential backoff indefinitely. The caller will
+    // never see an OnConnect(false).
+    kRetryIfUnreachable = 1,
+  };
+
+  // Connects to the producer port of the Service listening on the given
+  // |service_sock_name|. If the connection is successful, the OnConnect()
+  // method will be invoked asynchronously on the passed Producer interface. If
+  // the connection fails, OnDisconnect() will be invoked instead. The returned
+  // ProducerEndpoint serves also to delimit the scope of the callbacks invoked
+  // on the Producer interface: no more Producer callbacks are invoked
+  // immediately after its destruction and any pending callback will be dropped.
+  // To provide a producer-allocated shared memory buffer, both |shm| and
+  // |shm_arbiter| should be set. |shm_arbiter| should be an unbound
+  // SharedMemoryArbiter instance. When |shm| and |shm_arbiter| are provided,
+  // the service will attempt to adopt the provided SMB. If this fails, the
+  // ProducerEndpoint will disconnect, but the SMB and arbiter will remain valid
+  // until the client is destroyed.
+  //
+  // TODO(eseckler): Support adoption failure more gracefully.
+  // TODO(primiano): move all the existing use cases to the Connect(ConnArgs)
+  // below. Also move the functionality of ConnectionFlags into ConnArgs.
+  static std::unique_ptr<TracingService::ProducerEndpoint> Connect(
+      const char* service_sock_name,
+      Producer*,
+      const std::string& producer_name,
+      base::TaskRunner*,
+      TracingService::ProducerSMBScrapingMode smb_scraping_mode =
+          TracingService::ProducerSMBScrapingMode::kDefault,
+      size_t shared_memory_size_hint_bytes = 0,
+      size_t shared_memory_page_size_hint_bytes = 0,
+      std::unique_ptr<SharedMemory> shm = nullptr,
+      std::unique_ptr<SharedMemoryArbiter> shm_arbiter = nullptr,
+      ConnectionFlags = ConnectionFlags::kDefault);
+
+  // Overload of Connect() to support adopting a connected socket using
+  // ipc::Client::ConnArgs.
+  static std::unique_ptr<TracingService::ProducerEndpoint> Connect(
+      ipc::Client::ConnArgs,
+      Producer*,
+      const std::string& producer_name,
+      base::TaskRunner*,
+      TracingService::ProducerSMBScrapingMode smb_scraping_mode =
+          TracingService::ProducerSMBScrapingMode::kDefault,
+      size_t shared_memory_size_hint_bytes = 0,
+      size_t shared_memory_page_size_hint_bytes = 0,
+      std::unique_ptr<SharedMemory> shm = nullptr,
+      std::unique_ptr<SharedMemoryArbiter> shm_arbiter = nullptr,
+      CreateSocketAsync create_socket_async = nullptr);
+
+ protected:
+  ProducerIPCClient() = delete;
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_TRACING_IPC_PRODUCER_IPC_CLIENT_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACING_IPC_PRODUCER_PRODUCER_IPC_CLIENT_IMPL_H_
+#define SRC_TRACING_IPC_PRODUCER_PRODUCER_IPC_CLIENT_IMPL_H_
+
+#include <stdint.h>
+
+#include <set>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/client.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/producer_ipc_client.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/ipc/producer_port.ipc.h"
+
+namespace perfetto {
+
+namespace base {
+class TaskRunner;
+}  // namespace base
+
+class Producer;
+class SharedMemoryArbiter;
+
+// Exposes a Service endpoint to Producer(s), proxying all requests through a
+// IPC channel to the remote Service. This class is the glue layer between the
+// generic Service interface exposed to the clients of the library and the
+// actual IPC transport.
+// If create_socket_async is set, it will be called to create and connect to a
+// socket to the service. If unset, the producer will create and connect itself.
+class ProducerIPCClientImpl : public TracingService::ProducerEndpoint,
+                              public ipc::ServiceProxy::EventListener {
+ public:
+  ProducerIPCClientImpl(ipc::Client::ConnArgs,
+                        Producer*,
+                        const std::string& producer_name,
+                        base::TaskRunner*,
+                        TracingService::ProducerSMBScrapingMode,
+                        size_t shared_memory_size_hint_bytes,
+                        size_t shared_memory_page_size_hint_bytes,
+                        std::unique_ptr<SharedMemory> shm,
+                        std::unique_ptr<SharedMemoryArbiter> shm_arbiter,
+                        CreateSocketAsync create_socket_async);
+  ~ProducerIPCClientImpl() override;
+
+  // TracingService::ProducerEndpoint implementation.
+  // These methods are invoked by the actual Producer(s) code by clients of the
+  // tracing library, which know nothing about the IPC transport.
+  void Disconnect() override;
+  void RegisterDataSource(const DataSourceDescriptor&) override;
+  void UpdateDataSource(const DataSourceDescriptor&) override;
+  void UnregisterDataSource(const std::string& name) override;
+  void RegisterTraceWriter(uint32_t writer_id, uint32_t target_buffer) override;
+  void UnregisterTraceWriter(uint32_t writer_id) override;
+  void CommitData(const CommitDataRequest&, CommitDataCallback) override;
+  void NotifyDataSourceStarted(DataSourceInstanceID) override;
+  void NotifyDataSourceStopped(DataSourceInstanceID) override;
+  void ActivateTriggers(const std::vector<std::string>&) override;
+  void Sync(std::function<void()> callback) override;
+
+  std::unique_ptr<TraceWriter> CreateTraceWriter(
+      BufferID target_buffer,
+      BufferExhaustedPolicy) override;
+  SharedMemoryArbiter* MaybeSharedMemoryArbiter() override;
+  bool IsShmemProvidedByProducer() const override;
+  void NotifyFlushComplete(FlushRequestID) override;
+  SharedMemory* shared_memory() const override;
+  size_t shared_buffer_page_size_kb() const override;
+
+  // ipc::ServiceProxy::EventListener implementation.
+  // These methods are invoked by the IPC layer, which knows nothing about
+  // tracing, producers and consumers.
+  void OnConnect() override;
+  void OnDisconnect() override;
+
+  ipc::Client* GetClientForTesting() { return ipc_channel_.get(); }
+
+ private:
+  // Drops the provider connection if a protocol error was detected while
+  // processing an IPC command.
+  void ScheduleDisconnect();
+
+  // Invoked soon after having established the connection with the service.
+  void OnConnectionInitialized(bool connection_succeeded,
+                               bool using_shmem_provided_by_producer,
+                               bool direct_smb_patching_supported,
+                               bool use_shmem_emulation);
+
+  // Invoked when the remote Service sends an IPC to tell us to do something
+  // (e.g. start/stop a data source).
+  void OnServiceRequest(const protos::gen::GetAsyncCommandResponse&);
+
+  // TODO think to destruction order, do we rely on any specific dtor sequence?
+  Producer* const producer_;
+  base::TaskRunner* const task_runner_;
+
+  // A callback used to receive the shmem region out of band of the socket.
+  std::function<int(void)> receive_shmem_fd_cb_fuchsia_;
+
+  // The object that owns the client socket and takes care of IPC traffic.
+  std::unique_ptr<ipc::Client> ipc_channel_;
+
+  // The proxy interface for the producer port of the service. It is bound
+  // to |ipc_channel_| and (de)serializes method invocations over the wire.
+  std::unique_ptr<protos::gen::ProducerPortProxy> producer_port_;
+
+  std::unique_ptr<SharedMemory> shared_memory_;
+  std::unique_ptr<SharedMemoryArbiter> shared_memory_arbiter_;
+  size_t shared_buffer_page_size_kb_ = 0;
+  std::set<DataSourceInstanceID> data_sources_setup_;
+  bool connected_ = false;
+  std::string const name_;
+  size_t shared_memory_page_size_hint_bytes_ = 0;
+  size_t shared_memory_size_hint_bytes_ = 0;
+  TracingService::ProducerSMBScrapingMode const smb_scraping_mode_;
+  bool is_shmem_provided_by_producer_ = false;
+  bool direct_smb_patching_supported_ = false;
+  bool use_shmem_emulation_ = false;
+  std::vector<std::function<void()>> pending_sync_reqs_;
+  base::WeakPtrFactory<ProducerIPCClientImpl> weak_factory_{this};
+  PERFETTO_THREAD_CHECKER(thread_checker_)
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_IPC_PRODUCER_PRODUCER_IPC_CLIENT_IMPL_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/ipc/producer/producer_ipc_client_impl.h"
+
+#include <cinttypes>
+
+#include <string.h>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/version.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/client.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/commit_data_request.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/producer.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_config.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/trace_config.h"
+// gen_amalgamated expanded: #include "src/tracing/core/in_process_shared_memory.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+// gen_amalgamated expanded: #include "src/tracing/ipc/shared_memory_windows.h"
+#else
+// gen_amalgamated expanded: #include "src/tracing/ipc/posix_shared_memory.h"
+#endif
+
+// TODO(fmayer): think to what happens when ProducerIPCClientImpl gets destroyed
+// w.r.t. the Producer pointer. Also think to lifetime of the Producer* during
+// the callbacks.
+
+namespace perfetto {
+
+// static. (Declared in include/tracing/ipc/producer_ipc_client.h).
+std::unique_ptr<TracingService::ProducerEndpoint> ProducerIPCClient::Connect(
+    const char* service_sock_name,
+    Producer* producer,
+    const std::string& producer_name,
+    base::TaskRunner* task_runner,
+    TracingService::ProducerSMBScrapingMode smb_scraping_mode,
+    size_t shared_memory_size_hint_bytes,
+    size_t shared_memory_page_size_hint_bytes,
+    std::unique_ptr<SharedMemory> shm,
+    std::unique_ptr<SharedMemoryArbiter> shm_arbiter,
+    ConnectionFlags conn_flags) {
+  return std::unique_ptr<TracingService::ProducerEndpoint>(
+      new ProducerIPCClientImpl(
+          {service_sock_name,
+           conn_flags ==
+               ProducerIPCClient::ConnectionFlags::kRetryIfUnreachable},
+          producer, producer_name, task_runner, smb_scraping_mode,
+          shared_memory_size_hint_bytes, shared_memory_page_size_hint_bytes,
+          std::move(shm), std::move(shm_arbiter), nullptr));
+}
+
+// static. (Declared in include/tracing/ipc/producer_ipc_client.h).
+std::unique_ptr<TracingService::ProducerEndpoint> ProducerIPCClient::Connect(
+    ipc::Client::ConnArgs conn_args,
+    Producer* producer,
+    const std::string& producer_name,
+    base::TaskRunner* task_runner,
+    TracingService::ProducerSMBScrapingMode smb_scraping_mode,
+    size_t shared_memory_size_hint_bytes,
+    size_t shared_memory_page_size_hint_bytes,
+    std::unique_ptr<SharedMemory> shm,
+    std::unique_ptr<SharedMemoryArbiter> shm_arbiter,
+    CreateSocketAsync create_socket_async) {
+  return std::unique_ptr<TracingService::ProducerEndpoint>(
+      new ProducerIPCClientImpl(
+          std::move(conn_args), producer, producer_name, task_runner,
+          smb_scraping_mode, shared_memory_size_hint_bytes,
+          shared_memory_page_size_hint_bytes, std::move(shm),
+          std::move(shm_arbiter), create_socket_async));
+}
+
+ProducerIPCClientImpl::ProducerIPCClientImpl(
+    ipc::Client::ConnArgs conn_args,
+    Producer* producer,
+    const std::string& producer_name,
+    base::TaskRunner* task_runner,
+    TracingService::ProducerSMBScrapingMode smb_scraping_mode,
+    size_t shared_memory_size_hint_bytes,
+    size_t shared_memory_page_size_hint_bytes,
+    std::unique_ptr<SharedMemory> shm,
+    std::unique_ptr<SharedMemoryArbiter> shm_arbiter,
+    CreateSocketAsync create_socket_async)
+    : producer_(producer),
+      task_runner_(task_runner),
+      receive_shmem_fd_cb_fuchsia_(
+          std::move(conn_args.receive_shmem_fd_cb_fuchsia)),
+      producer_port_(
+          new protos::gen::ProducerPortProxy(this /* event_listener */)),
+      shared_memory_(std::move(shm)),
+      shared_memory_arbiter_(std::move(shm_arbiter)),
+      name_(producer_name),
+      shared_memory_page_size_hint_bytes_(shared_memory_page_size_hint_bytes),
+      shared_memory_size_hint_bytes_(shared_memory_size_hint_bytes),
+      smb_scraping_mode_(smb_scraping_mode) {
+  // Check for producer-provided SMB (used by Chrome for startup tracing).
+  if (shared_memory_) {
+    // We also expect a valid (unbound) arbiter. Bind it to this endpoint now.
+    PERFETTO_CHECK(shared_memory_arbiter_);
+    shared_memory_arbiter_->BindToProducerEndpoint(this, task_runner_);
+
+    // If the service accepts our SMB, then it must match our requested page
+    // layout. The protocol doesn't allow the service to change the size and
+    // layout when the SMB is provided by the producer.
+    shared_buffer_page_size_kb_ = shared_memory_page_size_hint_bytes_ / 1024;
+  }
+
+  if (create_socket_async) {
+    PERFETTO_DCHECK(conn_args.socket_name);
+    auto weak_this = weak_factory_.GetWeakPtr();
+    create_socket_async(
+        [weak_this, task_runner = task_runner_](base::SocketHandle fd) {
+          task_runner->PostTask([weak_this, fd] {
+            base::ScopedSocketHandle handle(fd);
+            if (!weak_this) {
+              return;
+            }
+            ipc::Client::ConnArgs args(std::move(handle));
+            weak_this->ipc_channel_ = ipc::Client::CreateInstance(
+                std::move(args), weak_this->task_runner_);
+            weak_this->ipc_channel_->BindService(
+                weak_this->producer_port_->GetWeakPtr());
+          });
+        });
+  } else {
+    ipc_channel_ =
+        ipc::Client::CreateInstance(std::move(conn_args), task_runner);
+    ipc_channel_->BindService(producer_port_->GetWeakPtr());
+  }
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+}
+
+ProducerIPCClientImpl::~ProducerIPCClientImpl() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+}
+
+void ProducerIPCClientImpl::Disconnect() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!producer_port_)
+    return;
+  // Reset the producer port so that no further IPCs are received and IPC
+  // callbacks are no longer executed. Also reset the IPC channel so that the
+  // service is notified of the disconnection.
+  producer_port_.reset();
+  ipc_channel_.reset();
+  // Perform disconnect synchronously.
+  OnDisconnect();
+}
+
+// Called by the IPC layer if the BindService() succeeds.
+void ProducerIPCClientImpl::OnConnect() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  connected_ = true;
+
+  // The IPC layer guarantees that any outstanding callback will be dropped on
+  // the floor if producer_port_ is destroyed between the request and the reply.
+  // Binding |this| is hence safe.
+  ipc::Deferred<protos::gen::InitializeConnectionResponse> on_init;
+  on_init.Bind(
+      [this](ipc::AsyncResult<protos::gen::InitializeConnectionResponse> resp) {
+        OnConnectionInitialized(
+            resp.success(),
+            resp.success() ? resp->using_shmem_provided_by_producer() : false,
+            resp.success() ? resp->direct_smb_patching_supported() : false,
+            resp.success() ? resp->use_shmem_emulation() : false);
+      });
+  protos::gen::InitializeConnectionRequest req;
+  req.set_producer_name(name_);
+  req.set_shared_memory_size_hint_bytes(
+      static_cast<uint32_t>(shared_memory_size_hint_bytes_));
+  req.set_shared_memory_page_size_hint_bytes(
+      static_cast<uint32_t>(shared_memory_page_size_hint_bytes_));
+  switch (smb_scraping_mode_) {
+    case TracingService::ProducerSMBScrapingMode::kDefault:
+      // No need to set the mode, it defaults to use the service default if
+      // unspecified.
+      break;
+    case TracingService::ProducerSMBScrapingMode::kEnabled:
+      req.set_smb_scraping_mode(
+          protos::gen::InitializeConnectionRequest::SMB_SCRAPING_ENABLED);
+      break;
+    case TracingService::ProducerSMBScrapingMode::kDisabled:
+      req.set_smb_scraping_mode(
+          protos::gen::InitializeConnectionRequest::SMB_SCRAPING_DISABLED);
+      break;
+  }
+
+  int shm_fd = -1;
+  if (shared_memory_) {
+    req.set_producer_provided_shmem(true);
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    auto key = static_cast<SharedMemoryWindows*>(shared_memory_.get())->key();
+    req.set_shm_key_windows(key);
+#else
+    shm_fd = static_cast<PosixSharedMemory*>(shared_memory_.get())->fd();
+#endif
+  }
+
+  req.set_sdk_version(base::GetVersionString());
+  producer_port_->InitializeConnection(req, std::move(on_init), shm_fd);
+
+  // Create the back channel to receive commands from the Service.
+  ipc::Deferred<protos::gen::GetAsyncCommandResponse> on_cmd;
+  on_cmd.Bind(
+      [this](ipc::AsyncResult<protos::gen::GetAsyncCommandResponse> resp) {
+        if (!resp)
+          return;  // The IPC channel was closed and |resp| was auto-rejected.
+        OnServiceRequest(*resp);
+      });
+  producer_port_->GetAsyncCommand(protos::gen::GetAsyncCommandRequest(),
+                                  std::move(on_cmd));
+
+  // If there are pending Sync() requests, send them now.
+  for (const auto& pending_sync : pending_sync_reqs_)
+    Sync(std::move(pending_sync));
+  pending_sync_reqs_.clear();
+}
+
+void ProducerIPCClientImpl::OnDisconnect() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DLOG("Tracing service connection failure");
+  connected_ = false;
+  data_sources_setup_.clear();
+  producer_->OnDisconnect();  // Note: may delete |this|.
+}
+
+void ProducerIPCClientImpl::ScheduleDisconnect() {
+  // |ipc_channel| doesn't allow disconnection in the middle of handling
+  // an IPC call, so the connection drop must take place over two phases.
+
+  // First, synchronously drop the |producer_port_| so that no more IPC
+  // messages are handled.
+  producer_port_.reset();
+
+  // Then schedule an async task for performing the remainder of the
+  // disconnection operations outside the context of the IPC method handler.
+  auto weak_this = weak_factory_.GetWeakPtr();
+  task_runner_->PostTask([weak_this]() {
+    if (weak_this) {
+      weak_this->Disconnect();
+    }
+  });
+}
+
+void ProducerIPCClientImpl::OnConnectionInitialized(
+    bool connection_succeeded,
+    bool using_shmem_provided_by_producer,
+    bool direct_smb_patching_supported,
+    bool use_shmem_emulation) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  // If connection_succeeded == false, the OnDisconnect() call will follow next
+  // and there we'll notify the |producer_|. TODO: add a test for this.
+  if (!connection_succeeded)
+    return;
+  is_shmem_provided_by_producer_ = using_shmem_provided_by_producer;
+  direct_smb_patching_supported_ = direct_smb_patching_supported;
+  // The tracing service may reject using shared memory and tell the client to
+  // commit data over the socket. This can happen when the client connects to
+  // the service via a relay service:
+  // client <-Unix socket-> relay service <- vsock -> tracing service.
+  use_shmem_emulation_ = use_shmem_emulation;
+  producer_->OnConnect();
+
+  // Bail out if the service failed to adopt our producer-allocated SMB.
+  // TODO(eseckler): Handle adoption failure more gracefully.
+  if (shared_memory_ && !is_shmem_provided_by_producer_) {
+    PERFETTO_DLOG("Service failed adopt producer-provided SMB, disconnecting.");
+    Disconnect();
+    return;
+  }
+}
+
+void ProducerIPCClientImpl::OnServiceRequest(
+    const protos::gen::GetAsyncCommandResponse& cmd) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  // This message is sent only when connecting to a service running Android Q+.
+  // See comment below in kStartDataSource.
+  if (cmd.has_setup_data_source()) {
+    const auto& req = cmd.setup_data_source();
+    const DataSourceInstanceID dsid = req.new_instance_id();
+    data_sources_setup_.insert(dsid);
+    producer_->SetupDataSource(dsid, req.config());
+    return;
+  }
+
+  if (cmd.has_start_data_source()) {
+    const auto& req = cmd.start_data_source();
+    const DataSourceInstanceID dsid = req.new_instance_id();
+    const DataSourceConfig& cfg = req.config();
+    if (!data_sources_setup_.count(dsid)) {
+      // When connecting with an older (Android P) service, the service will not
+      // send a SetupDataSource message. We synthesize it here in that case.
+      producer_->SetupDataSource(dsid, cfg);
+    }
+    producer_->StartDataSource(dsid, cfg);
+    return;
+  }
+
+  if (cmd.has_stop_data_source()) {
+    const DataSourceInstanceID dsid = cmd.stop_data_source().instance_id();
+    producer_->StopDataSource(dsid);
+    data_sources_setup_.erase(dsid);
+    return;
+  }
+
+  if (cmd.has_setup_tracing()) {
+    std::unique_ptr<SharedMemory> ipc_shared_memory;
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    const std::string& shm_key = cmd.setup_tracing().shm_key_windows();
+    if (!shm_key.empty())
+      ipc_shared_memory = SharedMemoryWindows::Attach(shm_key);
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+    // On Fuchsia, the embedder is responsible for routing the shared memory
+    // FD, which is provided to this code via a blocking callback.
+    PERFETTO_CHECK(receive_shmem_fd_cb_fuchsia_);
+
+    base::ScopedFile shmem_fd(receive_shmem_fd_cb_fuchsia_());
+    if (!shmem_fd) {
+      // Failure to get a shared memory buffer is a protocol violation and
+      // therefore we should drop the Protocol connection.
+      PERFETTO_ELOG("Could not get shared memory FD from embedder.");
+      ScheduleDisconnect();
+      return;
+    }
+
+    ipc_shared_memory =
+        PosixSharedMemory::AttachToFd(std::move(shmem_fd),
+                                      /*require_seals_if_supported=*/false);
+#else
+    base::ScopedFile shmem_fd = ipc_channel_->TakeReceivedFD();
+    if (shmem_fd) {
+      // TODO(primiano): handle mmap failure in case of OOM.
+      ipc_shared_memory =
+          PosixSharedMemory::AttachToFd(std::move(shmem_fd),
+                                        /*require_seals_if_supported=*/false);
+    }
+#endif
+    if (use_shmem_emulation_) {
+      PERFETTO_CHECK(!ipc_shared_memory);
+      // Need to create an emulated shmem buffer when the transport deosn't
+      // support it.
+      // TODO(chinglinyu): Let the tracing service decide on the shmem size and
+      // propagate the size in InitializeConnectionResponse.
+      ipc_shared_memory = InProcessSharedMemory::Create(
+          /*size=*/InProcessSharedMemory::kDefaultSize);
+    }
+    if (ipc_shared_memory) {
+      auto shmem_mode = use_shmem_emulation_
+                            ? SharedMemoryABI::ShmemMode::kShmemEmulation
+                            : SharedMemoryABI::ShmemMode::kDefault;
+      // This is the nominal case used in most configurations, where the service
+      // provides the SMB.
+      PERFETTO_CHECK(!is_shmem_provided_by_producer_ && !shared_memory_);
+      shared_memory_ = std::move(ipc_shared_memory);
+      shared_buffer_page_size_kb_ =
+          cmd.setup_tracing().shared_buffer_page_size_kb();
+      shared_memory_arbiter_ = SharedMemoryArbiter::CreateInstance(
+          shared_memory_.get(), shared_buffer_page_size_kb_ * 1024, shmem_mode,
+          this, task_runner_);
+      if (direct_smb_patching_supported_)
+        shared_memory_arbiter_->SetDirectSMBPatchingSupportedByService();
+    } else {
+      // Producer-provided SMB (used by Chrome for startup tracing).
+      PERFETTO_CHECK(is_shmem_provided_by_producer_ && shared_memory_ &&
+                     shared_memory_arbiter_);
+    }
+    producer_->OnTracingSetup();
+    return;
+  }
+
+  if (cmd.has_flush()) {
+    // This cast boilerplate is required only because protobuf uses its own
+    // uint64 and not stdint's uint64_t. On some 64 bit archs they differ on the
+    // type (long vs long long) even though they have the same size.
+    const auto* data_source_ids = cmd.flush().data_source_ids().data();
+    static_assert(sizeof(data_source_ids[0]) == sizeof(DataSourceInstanceID),
+                  "data_source_ids should be 64-bit");
+
+    FlushFlags flags(cmd.flush().flags());
+    producer_->Flush(
+        cmd.flush().request_id(),
+        reinterpret_cast<const DataSourceInstanceID*>(data_source_ids),
+        static_cast<size_t>(cmd.flush().data_source_ids().size()), flags);
+    return;
+  }
+
+  if (cmd.has_clear_incremental_state()) {
+    const auto* data_source_ids =
+        cmd.clear_incremental_state().data_source_ids().data();
+    static_assert(sizeof(data_source_ids[0]) == sizeof(DataSourceInstanceID),
+                  "data_source_ids should be 64-bit");
+    producer_->ClearIncrementalState(
+        reinterpret_cast<const DataSourceInstanceID*>(data_source_ids),
+        static_cast<size_t>(
+            cmd.clear_incremental_state().data_source_ids().size()));
+    return;
+  }
+
+  PERFETTO_DFATAL("Unknown async request received from tracing service");
+}
+
+void ProducerIPCClientImpl::RegisterDataSource(
+    const DataSourceDescriptor& descriptor) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!connected_) {
+    PERFETTO_DLOG(
+        "Cannot RegisterDataSource(), not connected to tracing service");
+  }
+  protos::gen::RegisterDataSourceRequest req;
+  *req.mutable_data_source_descriptor() = descriptor;
+  ipc::Deferred<protos::gen::RegisterDataSourceResponse> async_response;
+  async_response.Bind(
+      [](ipc::AsyncResult<protos::gen::RegisterDataSourceResponse> response) {
+        if (!response)
+          PERFETTO_DLOG("RegisterDataSource() failed: connection reset");
+      });
+  producer_port_->RegisterDataSource(req, std::move(async_response));
+}
+
+void ProducerIPCClientImpl::UpdateDataSource(
+    const DataSourceDescriptor& descriptor) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!connected_) {
+    PERFETTO_DLOG(
+        "Cannot UpdateDataSource(), not connected to tracing service");
+  }
+  protos::gen::UpdateDataSourceRequest req;
+  *req.mutable_data_source_descriptor() = descriptor;
+  ipc::Deferred<protos::gen::UpdateDataSourceResponse> async_response;
+  async_response.Bind(
+      [](ipc::AsyncResult<protos::gen::UpdateDataSourceResponse> response) {
+        if (!response)
+          PERFETTO_DLOG("UpdateDataSource() failed: connection reset");
+      });
+  producer_port_->UpdateDataSource(req, std::move(async_response));
+}
+
+void ProducerIPCClientImpl::UnregisterDataSource(const std::string& name) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!connected_) {
+    PERFETTO_DLOG(
+        "Cannot UnregisterDataSource(), not connected to tracing service");
+    return;
+  }
+  protos::gen::UnregisterDataSourceRequest req;
+  req.set_data_source_name(name);
+  producer_port_->UnregisterDataSource(
+      req, ipc::Deferred<protos::gen::UnregisterDataSourceResponse>());
+}
+
+void ProducerIPCClientImpl::RegisterTraceWriter(uint32_t writer_id,
+                                                uint32_t target_buffer) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!connected_) {
+    PERFETTO_DLOG(
+        "Cannot RegisterTraceWriter(), not connected to tracing service");
+    return;
+  }
+  protos::gen::RegisterTraceWriterRequest req;
+  req.set_trace_writer_id(writer_id);
+  req.set_target_buffer(target_buffer);
+  producer_port_->RegisterTraceWriter(
+      req, ipc::Deferred<protos::gen::RegisterTraceWriterResponse>());
+}
+
+void ProducerIPCClientImpl::UnregisterTraceWriter(uint32_t writer_id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!connected_) {
+    PERFETTO_DLOG(
+        "Cannot UnregisterTraceWriter(), not connected to tracing service");
+    return;
+  }
+  protos::gen::UnregisterTraceWriterRequest req;
+  req.set_trace_writer_id(writer_id);
+  producer_port_->UnregisterTraceWriter(
+      req, ipc::Deferred<protos::gen::UnregisterTraceWriterResponse>());
+}
+
+void ProducerIPCClientImpl::CommitData(const CommitDataRequest& req,
+                                       CommitDataCallback callback) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!connected_) {
+    PERFETTO_DLOG("Cannot CommitData(), not connected to tracing service");
+    return;
+  }
+  ipc::Deferred<protos::gen::CommitDataResponse> async_response;
+  // TODO(primiano): add a test that destroys ProducerIPCClientImpl soon after
+  // this call and checks that the callback is dropped.
+  if (callback) {
+    async_response.Bind(
+        [callback](ipc::AsyncResult<protos::gen::CommitDataResponse> response) {
+          if (!response) {
+            PERFETTO_DLOG("CommitData() failed: connection reset");
+            return;
+          }
+          callback();
+        });
+  }
+  producer_port_->CommitData(req, std::move(async_response));
+}
+
+void ProducerIPCClientImpl::NotifyDataSourceStarted(DataSourceInstanceID id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!connected_) {
+    PERFETTO_DLOG(
+        "Cannot NotifyDataSourceStarted(), not connected to tracing service");
+    return;
+  }
+  protos::gen::NotifyDataSourceStartedRequest req;
+  req.set_data_source_id(id);
+  producer_port_->NotifyDataSourceStarted(
+      req, ipc::Deferred<protos::gen::NotifyDataSourceStartedResponse>());
+}
+
+void ProducerIPCClientImpl::NotifyDataSourceStopped(DataSourceInstanceID id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!connected_) {
+    PERFETTO_DLOG(
+        "Cannot NotifyDataSourceStopped(), not connected to tracing service");
+    return;
+  }
+  protos::gen::NotifyDataSourceStoppedRequest req;
+  req.set_data_source_id(id);
+  producer_port_->NotifyDataSourceStopped(
+      req, ipc::Deferred<protos::gen::NotifyDataSourceStoppedResponse>());
+}
+
+void ProducerIPCClientImpl::ActivateTriggers(
+    const std::vector<std::string>& triggers) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!connected_) {
+    PERFETTO_DLOG(
+        "Cannot ActivateTriggers(), not connected to tracing service");
+    return;
+  }
+  protos::gen::ActivateTriggersRequest proto_req;
+  for (const auto& name : triggers) {
+    *proto_req.add_trigger_names() = name;
+  }
+  producer_port_->ActivateTriggers(
+      proto_req, ipc::Deferred<protos::gen::ActivateTriggersResponse>());
+}
+
+void ProducerIPCClientImpl::Sync(std::function<void()> callback) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!connected_) {
+    pending_sync_reqs_.emplace_back(std::move(callback));
+    return;
+  }
+  ipc::Deferred<protos::gen::SyncResponse> resp;
+  resp.Bind([callback](ipc::AsyncResult<protos::gen::SyncResponse>) {
+    // Here we ACK the callback even if the service replies with a failure
+    // (i.e. the service is too old and doesn't understand Sync()). In that
+    // case the service has still seen the request, the IPC roundtrip is
+    // still a (weaker) linearization fence.
+    callback();
+  });
+  producer_port_->Sync(protos::gen::SyncRequest(), std::move(resp));
+}
+
+std::unique_ptr<TraceWriter> ProducerIPCClientImpl::CreateTraceWriter(
+    BufferID target_buffer,
+    BufferExhaustedPolicy buffer_exhausted_policy) {
+  // This method can be called by different threads. |shared_memory_arbiter_| is
+  // thread-safe but be aware of accessing any other state in this function.
+  return shared_memory_arbiter_->CreateTraceWriter(target_buffer,
+                                                   buffer_exhausted_policy);
+}
+
+SharedMemoryArbiter* ProducerIPCClientImpl::MaybeSharedMemoryArbiter() {
+  return shared_memory_arbiter_.get();
+}
+
+bool ProducerIPCClientImpl::IsShmemProvidedByProducer() const {
+  return is_shmem_provided_by_producer_;
+}
+
+void ProducerIPCClientImpl::NotifyFlushComplete(FlushRequestID req_id) {
+  return shared_memory_arbiter_->NotifyFlushComplete(req_id);
+}
+
+SharedMemory* ProducerIPCClientImpl::shared_memory() const {
+  return shared_memory_.get();
+}
+
+size_t ProducerIPCClientImpl::shared_buffer_page_size_kb() const {
+  return shared_buffer_page_size_kb_;
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/ipc/service/consumer_ipc_service.cc
+// gen_amalgamated begin header: src/tracing/ipc/service/consumer_ipc_service.h
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACING_IPC_SERVICE_CONSUMER_IPC_SERVICE_H_
+#define SRC_TRACING_IPC_SERVICE_CONSUMER_IPC_SERVICE_H_
+
+#include <list>
+#include <map>
+#include <memory>
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/consumer.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+// gen_amalgamated expanded: #include "protos/perfetto/ipc/consumer_port.ipc.h"
+
+namespace perfetto {
+
+namespace ipc {
+class Host;
+}  // namespace ipc
+
+// Implements the Consumer port of the IPC service. This class proxies requests
+// and responses between the core service logic (|svc_|) and remote Consumer(s)
+// on the IPC socket, through the methods overriddden from ConsumerPort.
+class ConsumerIPCService : public protos::gen::ConsumerPort {
+ public:
+  explicit ConsumerIPCService(TracingService* core_service);
+  ~ConsumerIPCService() override;
+
+  // ConsumerPort implementation (from .proto IPC definition).
+  void EnableTracing(const protos::gen::EnableTracingRequest&,
+                     DeferredEnableTracingResponse) override;
+  void StartTracing(const protos::gen::StartTracingRequest&,
+                    DeferredStartTracingResponse) override;
+  void ChangeTraceConfig(const protos::gen::ChangeTraceConfigRequest&,
+                         DeferredChangeTraceConfigResponse) override;
+  void DisableTracing(const protos::gen::DisableTracingRequest&,
+                      DeferredDisableTracingResponse) override;
+  void ReadBuffers(const protos::gen::ReadBuffersRequest&,
+                   DeferredReadBuffersResponse) override;
+  void FreeBuffers(const protos::gen::FreeBuffersRequest&,
+                   DeferredFreeBuffersResponse) override;
+  void Flush(const protos::gen::FlushRequest&, DeferredFlushResponse) override;
+  void Detach(const protos::gen::DetachRequest&,
+              DeferredDetachResponse) override;
+  void Attach(const protos::gen::AttachRequest&,
+              DeferredAttachResponse) override;
+  void GetTraceStats(const protos::gen::GetTraceStatsRequest&,
+                     DeferredGetTraceStatsResponse) override;
+  void ObserveEvents(const protos::gen::ObserveEventsRequest&,
+                     DeferredObserveEventsResponse) override;
+  void QueryServiceState(const protos::gen::QueryServiceStateRequest&,
+                         DeferredQueryServiceStateResponse) override;
+  void QueryCapabilities(const protos::gen::QueryCapabilitiesRequest&,
+                         DeferredQueryCapabilitiesResponse) override;
+  void SaveTraceForBugreport(const protos::gen::SaveTraceForBugreportRequest&,
+                             DeferredSaveTraceForBugreportResponse) override;
+  void CloneSession(const protos::gen::CloneSessionRequest&,
+                    DeferredCloneSessionResponse) override;
+  void OnClientDisconnected() override;
+
+ private:
+  // Acts like a Consumer with the core Service business logic (which doesn't
+  // know anything about the remote transport), but all it does is proxying
+  // methods to the remote Consumer on the other side of the IPC channel.
+  class RemoteConsumer : public Consumer {
+   public:
+    RemoteConsumer();
+    ~RemoteConsumer() override;
+
+    // These methods are called by the |core_service_| business logic. There is
+    // no connection here, these methods are posted straight away.
+    void OnConnect() override;
+    void OnDisconnect() override;
+    void OnTracingDisabled(const std::string& error) override;
+    void OnTraceData(std::vector<TracePacket>, bool has_more) override;
+    void OnDetach(bool) override;
+    void OnAttach(bool, const TraceConfig&) override;
+    void OnTraceStats(bool, const TraceStats&) override;
+    void OnObservableEvents(const ObservableEvents&) override;
+    void OnSessionCloned(const OnSessionClonedArgs&) override;
+
+    void CloseObserveEventsResponseStream();
+
+    // The interface obtained from the core service business logic through
+    // TracingService::ConnectConsumer(this). This allows to invoke methods for
+    // a specific Consumer on the Service business logic.
+    std::unique_ptr<TracingService::ConsumerEndpoint> service_endpoint;
+
+    // After ReadBuffers() is invoked, this binds the async callback that
+    // allows to stream trace packets back to the client.
+    DeferredReadBuffersResponse read_buffers_response;
+
+    // After EnableTracing() is invoked, this binds the async callback that
+    // allows to send the OnTracingDisabled notification.
+    DeferredEnableTracingResponse enable_tracing_response;
+
+    // After Detach() is invoked, this binds the async callback that allows to
+    // send the session id to the consumer.
+    DeferredDetachResponse detach_response;
+
+    // As above, but for the Attach() case.
+    DeferredAttachResponse attach_response;
+
+    // As above, but for GetTraceStats().
+    DeferredGetTraceStatsResponse get_trace_stats_response;
+
+    // As above, but for CloneSession().
+    DeferredCloneSessionResponse clone_session_response;
+
+    // After ObserveEvents() is invoked, this binds the async callback that
+    // allows to stream ObservableEvents back to the client.
+    DeferredObserveEventsResponse observe_events_response;
+  };
+
+  // This has to be a container that doesn't invalidate iterators.
+  using PendingFlushResponses = std::list<DeferredFlushResponse>;
+  using PendingQuerySvcResponses = std::list<DeferredQueryServiceStateResponse>;
+  using PendingQueryCapabilitiesResponses =
+      std::list<DeferredQueryCapabilitiesResponse>;
+  using PendingSaveTraceForBugreportResponses =
+      std::list<DeferredSaveTraceForBugreportResponse>;
+
+  ConsumerIPCService(const ConsumerIPCService&) = delete;
+  ConsumerIPCService& operator=(const ConsumerIPCService&) = delete;
+
+  // Returns the ConsumerEndpoint in the core business logic that corresponds to
+  // the current IPC request.
+  RemoteConsumer* GetConsumerForCurrentRequest();
+
+  void OnFlushCallback(bool success, PendingFlushResponses::iterator);
+  void OnQueryServiceCallback(bool success,
+                              const TracingServiceState&,
+                              PendingQuerySvcResponses::iterator);
+  void OnQueryCapabilitiesCallback(const TracingServiceCapabilities&,
+                                   PendingQueryCapabilitiesResponses::iterator);
+  void OnSaveTraceForBugreportCallback(
+      bool success,
+      const std::string& msg,
+      PendingSaveTraceForBugreportResponses::iterator);
+
+  TracingService* const core_service_;
+
+  // Maps IPC clients to ConsumerEndpoint instances registered on the
+  // |core_service_| business logic.
+  std::map<ipc::ClientID, std::unique_ptr<RemoteConsumer>> consumers_;
+
+  PendingFlushResponses pending_flush_responses_;
+  PendingQuerySvcResponses pending_query_service_responses_;
+  PendingQueryCapabilitiesResponses pending_query_capabilities_responses_;
+  PendingSaveTraceForBugreportResponses pending_bugreport_responses_;
+
+  base::WeakPtrFactory<ConsumerIPCService> weak_ptr_factory_;  // Keep last.
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_IPC_SERVICE_CONSUMER_IPC_SERVICE_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/ipc/service/consumer_ipc_service.h"
+
+#include <cinttypes>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/host.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/slice.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_stats.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/trace_config.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/tracing_service_capabilities.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/tracing_service_state.h"
+
+namespace perfetto {
+
+ConsumerIPCService::ConsumerIPCService(TracingService* core_service)
+    : core_service_(core_service), weak_ptr_factory_(this) {}
+
+ConsumerIPCService::~ConsumerIPCService() = default;
+
+ConsumerIPCService::RemoteConsumer*
+ConsumerIPCService::GetConsumerForCurrentRequest() {
+  const ipc::ClientID ipc_client_id = ipc::Service::client_info().client_id();
+  const uid_t uid = ipc::Service::client_info().uid();
+  PERFETTO_CHECK(ipc_client_id);
+  auto it = consumers_.find(ipc_client_id);
+  if (it == consumers_.end()) {
+    auto* remote_consumer = new RemoteConsumer();
+    consumers_[ipc_client_id].reset(remote_consumer);
+    remote_consumer->service_endpoint =
+        core_service_->ConnectConsumer(remote_consumer, uid);
+    return remote_consumer;
+  }
+  return it->second.get();
+}
+
+// Called by the IPC layer.
+void ConsumerIPCService::OnClientDisconnected() {
+  ipc::ClientID client_id = ipc::Service::client_info().client_id();
+  consumers_.erase(client_id);
+}
+
+// Called by the IPC layer.
+void ConsumerIPCService::EnableTracing(
+    const protos::gen::EnableTracingRequest& req,
+    DeferredEnableTracingResponse resp) {
+  RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
+  if (req.attach_notification_only()) {
+    remote_consumer->enable_tracing_response = std::move(resp);
+    return;
+  }
+  const TraceConfig& trace_config = req.trace_config();
+  base::ScopedFile fd;
+  if (trace_config.write_into_file() && trace_config.output_path().empty())
+    fd = ipc::Service::TakeReceivedFD();
+  remote_consumer->service_endpoint->EnableTracing(trace_config, std::move(fd));
+  remote_consumer->enable_tracing_response = std::move(resp);
+}
+
+// Called by the IPC layer.
+void ConsumerIPCService::StartTracing(const protos::gen::StartTracingRequest&,
+                                      DeferredStartTracingResponse resp) {
+  RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
+  remote_consumer->service_endpoint->StartTracing();
+  resp.Resolve(ipc::AsyncResult<protos::gen::StartTracingResponse>::Create());
+}
+
+// Called by the IPC layer.
+void ConsumerIPCService::ChangeTraceConfig(
+    const protos::gen::ChangeTraceConfigRequest& req,
+    DeferredChangeTraceConfigResponse resp) {
+  RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
+  remote_consumer->service_endpoint->ChangeTraceConfig(req.trace_config());
+  resp.Resolve(
+      ipc::AsyncResult<protos::gen::ChangeTraceConfigResponse>::Create());
+}
+
+// Called by the IPC layer.
+void ConsumerIPCService::DisableTracing(
+    const protos::gen::DisableTracingRequest&,
+    DeferredDisableTracingResponse resp) {
+  GetConsumerForCurrentRequest()->service_endpoint->DisableTracing();
+  resp.Resolve(ipc::AsyncResult<protos::gen::DisableTracingResponse>::Create());
+}
+
+// Called by the IPC layer.
+void ConsumerIPCService::ReadBuffers(const protos::gen::ReadBuffersRequest&,
+                                     DeferredReadBuffersResponse resp) {
+  RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
+  remote_consumer->read_buffers_response = std::move(resp);
+  remote_consumer->service_endpoint->ReadBuffers();
+}
+
+// Called by the IPC layer.
+void ConsumerIPCService::FreeBuffers(const protos::gen::FreeBuffersRequest&,
+                                     DeferredFreeBuffersResponse resp) {
+  GetConsumerForCurrentRequest()->service_endpoint->FreeBuffers();
+  resp.Resolve(ipc::AsyncResult<protos::gen::FreeBuffersResponse>::Create());
+}
+
+// Called by the IPC layer.
+void ConsumerIPCService::Flush(const protos::gen::FlushRequest& req,
+                               DeferredFlushResponse resp) {
+  auto it = pending_flush_responses_.insert(pending_flush_responses_.end(),
+                                            std::move(resp));
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  auto callback = [weak_this, it](bool success) {
+    if (weak_this)
+      weak_this->OnFlushCallback(success, std::move(it));
+  };
+  FlushFlags flags(req.flags());
+  GetConsumerForCurrentRequest()->service_endpoint->Flush(
+      req.timeout_ms(), std::move(callback), flags);
+}
+
+// Called by the IPC layer.
+void ConsumerIPCService::Detach(const protos::gen::DetachRequest& req,
+                                DeferredDetachResponse resp) {
+  // OnDetach() will resolve the |detach_response|.
+  RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
+  remote_consumer->detach_response = std::move(resp);
+  remote_consumer->service_endpoint->Detach(req.key());
+}
+
+// Called by the IPC layer.
+void ConsumerIPCService::Attach(const protos::gen::AttachRequest& req,
+                                DeferredAttachResponse resp) {
+  // OnAttach() will resolve the |attach_response|.
+  RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
+  remote_consumer->attach_response = std::move(resp);
+  remote_consumer->service_endpoint->Attach(req.key());
+}
+
+// Called by the IPC layer.
+void ConsumerIPCService::GetTraceStats(const protos::gen::GetTraceStatsRequest&,
+                                       DeferredGetTraceStatsResponse resp) {
+  // OnTraceStats() will resolve the |get_trace_stats_response|.
+  RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
+  remote_consumer->get_trace_stats_response = std::move(resp);
+  remote_consumer->service_endpoint->GetTraceStats();
+}
+
+// Called by the IPC layer.
+void ConsumerIPCService::ObserveEvents(
+    const protos::gen::ObserveEventsRequest& req,
+    DeferredObserveEventsResponse resp) {
+  RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
+
+  // If there's a prior stream, close it so that client can clean it up.
+  remote_consumer->CloseObserveEventsResponseStream();
+
+  remote_consumer->observe_events_response = std::move(resp);
+
+  uint32_t events_mask = 0;
+  for (const auto& type : req.events_to_observe()) {
+    events_mask |= static_cast<uint32_t>(type);
+  }
+  remote_consumer->service_endpoint->ObserveEvents(events_mask);
+
+  // If no events are to be observed, close the stream immediately so that the
+  // client can clean up.
+  if (events_mask == 0)
+    remote_consumer->CloseObserveEventsResponseStream();
+}
+
+// Called by the IPC layer.
+void ConsumerIPCService::QueryServiceState(
+    const protos::gen::QueryServiceStateRequest& req,
+    DeferredQueryServiceStateResponse resp) {
+  RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
+  auto it = pending_query_service_responses_.insert(
+      pending_query_service_responses_.end(), std::move(resp));
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  auto callback = [weak_this, it](bool success,
+                                  const TracingServiceState& svc_state) {
+    if (weak_this)
+      weak_this->OnQueryServiceCallback(success, svc_state, std::move(it));
+  };
+  ConsumerEndpoint::QueryServiceStateArgs args;
+  args.sessions_only = req.sessions_only();
+  remote_consumer->service_endpoint->QueryServiceState(args, callback);
+}
+
+// Called by the service in response to service_endpoint->QueryServiceState().
+void ConsumerIPCService::OnQueryServiceCallback(
+    bool success,
+    const TracingServiceState& svc_state,
+    PendingQuerySvcResponses::iterator pending_response_it) {
+  DeferredQueryServiceStateResponse response(std::move(*pending_response_it));
+  pending_query_service_responses_.erase(pending_response_it);
+  if (!success) {
+    response.Reject();
+    return;
+  }
+
+  // The TracingServiceState object might be too big to fit into a single IPC
+  // message because it contains the DataSourceDescriptor of each data source.
+  // Here we split it in chunks to fit in the IPC limit, observing the
+  // following rule: each chunk must be invididually a valid TracingServiceState
+  // message; all the chunks concatenated together must form the original
+  // message. This is to deal with the legacy API that was just sending one
+  // whole message (failing in presence of too many data sources, b/153142114).
+  // The message is split as follows: we take the whole TracingServiceState,
+  // take out the data sources section (which is a top-level repeated field)
+  // and re-add them one-by-one. If, in the process of appending, the IPC msg
+  // size is reached, a new chunk is created. This assumes that the rest of
+  // TracingServiceState fits in one IPC message and each DataSourceDescriptor
+  // fits in the worst case in a dedicated message (which is true, because
+  // otherwise the RegisterDataSource() which passes the descriptor in the first
+  // place would fail).
+
+  std::vector<uint8_t> chunked_reply;
+
+  // Transmits the current chunk and starts a new one.
+  bool sent_eof = false;
+  auto send_chunked_reply = [&chunked_reply, &response,
+                             &sent_eof](bool has_more) {
+    PERFETTO_CHECK(!sent_eof);
+    sent_eof = !has_more;
+    auto resp =
+        ipc::AsyncResult<protos::gen::QueryServiceStateResponse>::Create();
+    resp.set_has_more(has_more);
+    PERFETTO_CHECK(resp->mutable_service_state()->ParseFromArray(
+        chunked_reply.data(), chunked_reply.size()));
+    chunked_reply.clear();
+    response.Resolve(std::move(resp));
+  };
+
+  // Create a copy of the whole response and cut away the data_sources section.
+  protos::gen::TracingServiceState svc_state_copy = svc_state;
+  auto data_sources = std::move(*svc_state_copy.mutable_data_sources());
+  chunked_reply = svc_state_copy.SerializeAsArray();
+
+  // Now re-add them fitting within the IPC message limits (- some margin for
+  // the outer IPC frame).
+  constexpr size_t kMaxMsgSize = ipc::kIPCBufferSize - 128;
+  for (const auto& data_source : data_sources) {
+    protos::gen::TracingServiceState tmp;
+    tmp.mutable_data_sources()->emplace_back(std::move(data_source));
+    std::vector<uint8_t> chunk = tmp.SerializeAsArray();
+    if (chunked_reply.size() + chunk.size() < kMaxMsgSize) {
+      chunked_reply.insert(chunked_reply.end(), chunk.begin(), chunk.end());
+    } else {
+      send_chunked_reply(/*has_more=*/true);
+      chunked_reply = std::move(chunk);
+    }
+  }
+
+  PERFETTO_DCHECK(!chunked_reply.empty());
+  send_chunked_reply(/*has_more=*/false);
+  PERFETTO_CHECK(sent_eof);
+}
+
+// Called by the service in response to a service_endpoint->Flush() request.
+void ConsumerIPCService::OnFlushCallback(
+    bool success,
+    PendingFlushResponses::iterator pending_response_it) {
+  DeferredFlushResponse response(std::move(*pending_response_it));
+  pending_flush_responses_.erase(pending_response_it);
+  if (success) {
+    response.Resolve(ipc::AsyncResult<protos::gen::FlushResponse>::Create());
+  } else {
+    response.Reject();
+  }
+}
+
+void ConsumerIPCService::QueryCapabilities(
+    const protos::gen::QueryCapabilitiesRequest&,
+    DeferredQueryCapabilitiesResponse resp) {
+  RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
+  auto it = pending_query_capabilities_responses_.insert(
+      pending_query_capabilities_responses_.end(), std::move(resp));
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  auto callback = [weak_this, it](const TracingServiceCapabilities& caps) {
+    if (weak_this)
+      weak_this->OnQueryCapabilitiesCallback(caps, std::move(it));
+  };
+  remote_consumer->service_endpoint->QueryCapabilities(callback);
+}
+
+// Called by the service in response to service_endpoint->QueryCapabilities().
+void ConsumerIPCService::OnQueryCapabilitiesCallback(
+    const TracingServiceCapabilities& caps,
+    PendingQueryCapabilitiesResponses::iterator pending_response_it) {
+  DeferredQueryCapabilitiesResponse response(std::move(*pending_response_it));
+  pending_query_capabilities_responses_.erase(pending_response_it);
+  auto resp =
+      ipc::AsyncResult<protos::gen::QueryCapabilitiesResponse>::Create();
+  *resp->mutable_capabilities() = caps;
+  response.Resolve(std::move(resp));
+}
+
+void ConsumerIPCService::SaveTraceForBugreport(
+    const protos::gen::SaveTraceForBugreportRequest&,
+    DeferredSaveTraceForBugreportResponse resp) {
+  RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
+  auto it = pending_bugreport_responses_.insert(
+      pending_bugreport_responses_.end(), std::move(resp));
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  auto callback = [weak_this, it](bool success, const std::string& msg) {
+    if (weak_this)
+      weak_this->OnSaveTraceForBugreportCallback(success, msg, std::move(it));
+  };
+  remote_consumer->service_endpoint->SaveTraceForBugreport(callback);
+}
+
+void ConsumerIPCService::CloneSession(
+    const protos::gen::CloneSessionRequest& req,
+    DeferredCloneSessionResponse resp) {
+  RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
+  remote_consumer->clone_session_response = std::move(resp);
+  ConsumerEndpoint::CloneSessionArgs args;
+  args.skip_trace_filter = req.skip_trace_filter();
+  args.for_bugreport = req.for_bugreport();
+  remote_consumer->service_endpoint->CloneSession(req.session_id(),
+                                                  std::move(args));
+}
+
+// Called by the service in response to
+// service_endpoint->SaveTraceForBugreport().
+void ConsumerIPCService::OnSaveTraceForBugreportCallback(
+    bool success,
+    const std::string& msg,
+    PendingSaveTraceForBugreportResponses::iterator pending_response_it) {
+  DeferredSaveTraceForBugreportResponse response(
+      std::move(*pending_response_it));
+  pending_bugreport_responses_.erase(pending_response_it);
+  auto resp =
+      ipc::AsyncResult<protos::gen::SaveTraceForBugreportResponse>::Create();
+  resp->set_success(success);
+  resp->set_msg(msg);
+  response.Resolve(std::move(resp));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// RemoteConsumer methods
+////////////////////////////////////////////////////////////////////////////////
+
+ConsumerIPCService::RemoteConsumer::RemoteConsumer() = default;
+ConsumerIPCService::RemoteConsumer::~RemoteConsumer() = default;
+
+// Invoked by the |core_service_| business logic after the ConnectConsumer()
+// call. There is nothing to do here, we really expected the ConnectConsumer()
+// to just work in the local case.
+void ConsumerIPCService::RemoteConsumer::OnConnect() {}
+
+// Invoked by the |core_service_| business logic after we destroy the
+// |service_endpoint| (in the RemoteConsumer dtor).
+void ConsumerIPCService::RemoteConsumer::OnDisconnect() {}
+
+void ConsumerIPCService::RemoteConsumer::OnTracingDisabled(
+    const std::string& error) {
+  if (enable_tracing_response.IsBound()) {
+    auto result =
+        ipc::AsyncResult<protos::gen::EnableTracingResponse>::Create();
+    result->set_disabled(true);
+    if (!error.empty())
+      result->set_error(error);
+    enable_tracing_response.Resolve(std::move(result));
+  }
+}
+
+void ConsumerIPCService::RemoteConsumer::OnTraceData(
+    std::vector<TracePacket> trace_packets,
+    bool has_more) {
+  if (!read_buffers_response.IsBound())
+    return;
+
+  auto result = ipc::AsyncResult<protos::gen::ReadBuffersResponse>::Create();
+
+  // A TracePacket might be too big to fit into a single IPC message (max
+  // kIPCBufferSize). However a TracePacket is made of slices and each slice
+  // is way smaller than kIPCBufferSize (a slice size is effectively bounded by
+  // the max chunk size of the SharedMemoryABI). When sending a TracePacket,
+  // if its slices don't fit within one IPC, chunk them over several contiguous
+  // IPCs using the |last_slice_for_packet| for glueing on the other side.
+  static_assert(ipc::kIPCBufferSize >= SharedMemoryABI::kMaxPageSize * 2,
+                "kIPCBufferSize too small given the max possible slice size");
+
+  auto send_ipc_reply = [this, &result](bool more) {
+    result.set_has_more(more);
+    read_buffers_response.Resolve(std::move(result));
+    result = ipc::AsyncResult<protos::gen::ReadBuffersResponse>::Create();
+  };
+
+  size_t approx_reply_size = 0;
+  for (const TracePacket& trace_packet : trace_packets) {
+    size_t num_slices_left_for_packet = trace_packet.slices().size();
+    for (const Slice& slice : trace_packet.slices()) {
+      // Check if this slice would cause the IPC to overflow its max size and,
+      // if that is the case, split the IPCs. The "16" and "64" below are
+      // over-estimations of, respectively:
+      // 16: the preamble that prefixes each slice (there are 2 x size fields
+      //     in the proto + the |last_slice_for_packet| bool).
+      // 64: the overhead of the IPC InvokeMethodReply + wire_protocol's frame.
+      // If these estimations are wrong, BufferedFrameDeserializer::Serialize()
+      // will hit a DCHECK anyways.
+      const size_t approx_slice_size = slice.size + 16;
+      if (approx_reply_size + approx_slice_size > ipc::kIPCBufferSize - 64) {
+        // If we hit this CHECK we got a single slice that is > kIPCBufferSize.
+        PERFETTO_CHECK(result->slices_size() > 0);
+        send_ipc_reply(/*has_more=*/true);
+        approx_reply_size = 0;
+      }
+      approx_reply_size += approx_slice_size;
+
+      auto* res_slice = result->add_slices();
+      res_slice->set_last_slice_for_packet(--num_slices_left_for_packet == 0);
+      res_slice->set_data(slice.start, slice.size);
+    }
+  }
+  send_ipc_reply(has_more);
+}
+
+void ConsumerIPCService::RemoteConsumer::OnDetach(bool success) {
+  if (!success) {
+    std::move(detach_response).Reject();
+    return;
+  }
+  auto resp = ipc::AsyncResult<protos::gen::DetachResponse>::Create();
+  std::move(detach_response).Resolve(std::move(resp));
+}
+
+void ConsumerIPCService::RemoteConsumer::OnAttach(
+    bool success,
+    const TraceConfig& trace_config) {
+  if (!success) {
+    std::move(attach_response).Reject();
+    return;
+  }
+  auto response = ipc::AsyncResult<protos::gen::AttachResponse>::Create();
+  *response->mutable_trace_config() = trace_config;
+  std::move(attach_response).Resolve(std::move(response));
+}
+
+void ConsumerIPCService::RemoteConsumer::OnTraceStats(bool success,
+                                                      const TraceStats& stats) {
+  if (!success) {
+    std::move(get_trace_stats_response).Reject();
+    return;
+  }
+  auto response =
+      ipc::AsyncResult<protos::gen::GetTraceStatsResponse>::Create();
+  *response->mutable_trace_stats() = stats;
+  std::move(get_trace_stats_response).Resolve(std::move(response));
+}
+
+void ConsumerIPCService::RemoteConsumer::OnObservableEvents(
+    const ObservableEvents& events) {
+  if (!observe_events_response.IsBound())
+    return;
+
+  auto result = ipc::AsyncResult<protos::gen::ObserveEventsResponse>::Create();
+  result.set_has_more(true);
+  *result->mutable_events() = events;
+  observe_events_response.Resolve(std::move(result));
+}
+
+void ConsumerIPCService::RemoteConsumer::CloseObserveEventsResponseStream() {
+  if (!observe_events_response.IsBound())
+    return;
+
+  auto result = ipc::AsyncResult<protos::gen::ObserveEventsResponse>::Create();
+  result.set_has_more(false);
+  observe_events_response.Resolve(std::move(result));
+}
+
+void ConsumerIPCService::RemoteConsumer::OnSessionCloned(
+    const OnSessionClonedArgs& args) {
+  if (!clone_session_response.IsBound())
+    return;
+
+  auto resp = ipc::AsyncResult<protos::gen::CloneSessionResponse>::Create();
+  resp->set_success(args.success);
+  resp->set_error(args.error);
+  resp->set_uuid_msb(args.uuid.msb());
+  resp->set_uuid_lsb(args.uuid.lsb());
+  std::move(clone_session_response).Resolve(std::move(resp));
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/ipc/service/producer_ipc_service.cc
+// gen_amalgamated begin header: src/tracing/ipc/service/producer_ipc_service.h
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACING_IPC_SERVICE_PRODUCER_IPC_SERVICE_H_
+#define SRC_TRACING_IPC_SERVICE_PRODUCER_IPC_SERVICE_H_
+
+#include <list>
+#include <map>
+#include <memory>
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/producer.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/ipc/producer_port.ipc.h"
+
+namespace perfetto {
+
+namespace ipc {
+class Host;
+}  // namespace ipc
+
+// Implements the Producer port of the IPC service. This class proxies requests
+// and responses between the core service logic (|svc_|) and remote Producer(s)
+// on the IPC socket, through the methods overriddden from ProducerPort.
+class ProducerIPCService : public protos::gen::ProducerPort {
+ public:
+  explicit ProducerIPCService(TracingService* core_service);
+  ~ProducerIPCService() override;
+
+  // ProducerPort implementation (from .proto IPC definition).
+  void InitializeConnection(const protos::gen::InitializeConnectionRequest&,
+                            DeferredInitializeConnectionResponse) override;
+  void RegisterDataSource(const protos::gen::RegisterDataSourceRequest&,
+                          DeferredRegisterDataSourceResponse) override;
+  void UpdateDataSource(const protos::gen::UpdateDataSourceRequest&,
+                        DeferredUpdateDataSourceResponse) override;
+  void UnregisterDataSource(const protos::gen::UnregisterDataSourceRequest&,
+                            DeferredUnregisterDataSourceResponse) override;
+  void RegisterTraceWriter(const protos::gen::RegisterTraceWriterRequest&,
+                           DeferredRegisterTraceWriterResponse) override;
+  void UnregisterTraceWriter(const protos::gen::UnregisterTraceWriterRequest&,
+                             DeferredUnregisterTraceWriterResponse) override;
+  void CommitData(const protos::gen::CommitDataRequest&,
+                  DeferredCommitDataResponse) override;
+  void NotifyDataSourceStarted(
+      const protos::gen::NotifyDataSourceStartedRequest&,
+      DeferredNotifyDataSourceStartedResponse) override;
+  void NotifyDataSourceStopped(
+      const protos::gen::NotifyDataSourceStoppedRequest&,
+      DeferredNotifyDataSourceStoppedResponse) override;
+  void ActivateTriggers(const protos::gen::ActivateTriggersRequest&,
+                        DeferredActivateTriggersResponse) override;
+
+  void GetAsyncCommand(const protos::gen::GetAsyncCommandRequest&,
+                       DeferredGetAsyncCommandResponse) override;
+  void Sync(const protos::gen::SyncRequest&, DeferredSyncResponse) override;
+  void OnClientDisconnected() override;
+
+ private:
+  // Acts like a Producer with the core Service business logic (which doesn't
+  // know anything about the remote transport), but all it does is proxying
+  // methods to the remote Producer on the other side of the IPC channel.
+  class RemoteProducer : public Producer {
+   public:
+    RemoteProducer();
+    ~RemoteProducer() override;
+
+    // These methods are called by the |core_service_| business logic. There is
+    // no connection here, these methods are posted straight away.
+    void OnConnect() override;
+    void OnDisconnect() override;
+    void SetupDataSource(DataSourceInstanceID,
+                         const DataSourceConfig&) override;
+    void StartDataSource(DataSourceInstanceID,
+                         const DataSourceConfig&) override;
+    void StopDataSource(DataSourceInstanceID) override;
+    void OnTracingSetup() override;
+    void Flush(FlushRequestID,
+               const DataSourceInstanceID* data_source_ids,
+               size_t num_data_sources,
+               FlushFlags) override;
+
+    void ClearIncrementalState(const DataSourceInstanceID* data_source_ids,
+                               size_t num_data_sources) override;
+
+    void SendSetupTracing();
+
+    // The interface obtained from the core service business logic through
+    // Service::ConnectProducer(this). This allows to invoke methods for a
+    // specific Producer on the Service business logic.
+    std::unique_ptr<TracingService::ProducerEndpoint> service_endpoint;
+
+    // The back-channel (based on a never ending stream request) that allows us
+    // to send asynchronous commands to the remote Producer (e.g. start/stop a
+    // data source).
+    DeferredGetAsyncCommandResponse async_producer_commands;
+
+    // Set if the service calls OnTracingSetup() before the
+    // |async_producer_commands| was bound by the service. In this case, we
+    // forward the SetupTracing command when it is bound later.
+    bool send_setup_tracing_on_async_commands_bound = false;
+  };
+
+  ProducerIPCService(const ProducerIPCService&) = delete;
+  ProducerIPCService& operator=(const ProducerIPCService&) = delete;
+
+  // Returns the ProducerEndpoint in the core business logic that corresponds to
+  // the current IPC request.
+  RemoteProducer* GetProducerForCurrentRequest();
+
+  TracingService* const core_service_;
+
+  // Maps IPC clients to ProducerEndpoint instances registered on the
+  // |core_service_| business logic.
+  std::map<ipc::ClientID, std::unique_ptr<RemoteProducer>> producers_;
+
+  // List because pointers need to be stable.
+  std::list<DeferredSyncResponse> pending_syncs_;
+
+  base::WeakPtrFactory<ProducerIPCService> weak_ptr_factory_;  // Keep last.
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_IPC_SERVICE_PRODUCER_IPC_SERVICE_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/ipc/service/producer_ipc_service.h"
+
+#include <cinttypes>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/host.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/client_identity.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/commit_data_request.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_config.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+// gen_amalgamated expanded: #include "src/tracing/ipc/shared_memory_windows.h"
+#else
+// gen_amalgamated expanded: #include "src/tracing/ipc/posix_shared_memory.h"
+#endif
+
+// The remote Producer(s) are not trusted. All the methods from the ProducerPort
+// IPC layer (e.g. RegisterDataSource()) must assume that the remote Producer is
+// compromised.
+
+namespace perfetto {
+
+ProducerIPCService::ProducerIPCService(TracingService* core_service)
+    : core_service_(core_service), weak_ptr_factory_(this) {}
+
+ProducerIPCService::~ProducerIPCService() = default;
+
+ProducerIPCService::RemoteProducer*
+ProducerIPCService::GetProducerForCurrentRequest() {
+  const ipc::ClientID ipc_client_id = ipc::Service::client_info().client_id();
+  PERFETTO_CHECK(ipc_client_id);
+  auto it = producers_.find(ipc_client_id);
+  if (it == producers_.end())
+    return nullptr;
+  return it->second.get();
+}
+
+// Called by the remote Producer through the IPC channel soon after connecting.
+void ProducerIPCService::InitializeConnection(
+    const protos::gen::InitializeConnectionRequest& req,
+    DeferredInitializeConnectionResponse response) {
+  const auto& client_info = ipc::Service::client_info();
+  const ipc::ClientID ipc_client_id = client_info.client_id();
+  PERFETTO_CHECK(ipc_client_id);
+
+  if (producers_.count(ipc_client_id) > 0) {
+    PERFETTO_DLOG(
+        "The remote Producer is trying to re-initialize the connection");
+    return response.Reject();
+  }
+
+  // Create a new entry.
+  std::unique_ptr<RemoteProducer> producer(new RemoteProducer());
+
+  TracingService::ProducerSMBScrapingMode smb_scraping_mode =
+      TracingService::ProducerSMBScrapingMode::kDefault;
+  switch (req.smb_scraping_mode()) {
+    case protos::gen::InitializeConnectionRequest::SMB_SCRAPING_UNSPECIFIED:
+      break;
+    case protos::gen::InitializeConnectionRequest::SMB_SCRAPING_DISABLED:
+      smb_scraping_mode = TracingService::ProducerSMBScrapingMode::kDisabled;
+      break;
+    case protos::gen::InitializeConnectionRequest::SMB_SCRAPING_ENABLED:
+      smb_scraping_mode = TracingService::ProducerSMBScrapingMode::kEnabled;
+      break;
+  }
+
+  // If the producer provided an SMB, tell the service to attempt to adopt it.
+  std::unique_ptr<SharedMemory> shmem;
+  if (req.producer_provided_shmem()) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    if (!req.has_shm_key_windows() || req.shm_key_windows().empty()) {
+      PERFETTO_ELOG(
+          "shm_key_windows must be non-empty when "
+          "producer_provided_shmem = true");
+    } else {
+      shmem = SharedMemoryWindows::Attach(req.shm_key_windows());
+      // Attach() does error logging if something fails, no need to extra ELOGs.
+    }
+#else
+    base::ScopedFile shmem_fd = ipc::Service::TakeReceivedFD();
+
+    if (shmem_fd) {
+      shmem = PosixSharedMemory::AttachToFd(
+          std::move(shmem_fd), /*require_seals_if_supported=*/true);
+      if (!shmem) {
+        PERFETTO_ELOG(
+            "Couldn't map producer-provided SMB, falling back to "
+            "service-provided SMB");
+      }
+    } else {
+      PERFETTO_DLOG(
+          "InitializeConnectionRequest's producer_provided_shmem flag is set "
+          "but the producer didn't provide an FD");
+    }
+#endif
+  }
+
+  // Copy the data fields to be emitted to trace packets into ClientIdentity.
+  ClientIdentity client_identity(client_info.uid(), client_info.pid(),
+                                 client_info.machine_id());
+  // ConnectProducer will call OnConnect() on the next task.
+  producer->service_endpoint = core_service_->ConnectProducer(
+      producer.get(), client_identity, req.producer_name(),
+      req.shared_memory_size_hint_bytes(),
+      /*in_process=*/false, smb_scraping_mode,
+      req.shared_memory_page_size_hint_bytes(), std::move(shmem),
+      req.sdk_version());
+
+  // Could happen if the service has too many producers connected.
+  if (!producer->service_endpoint) {
+    response.Reject();
+    return;
+  }
+
+  bool use_shmem_emulation = ipc::Service::use_shmem_emulation();
+  bool using_producer_shmem =
+      !use_shmem_emulation &&
+      producer->service_endpoint->IsShmemProvidedByProducer();
+
+  producers_.emplace(ipc_client_id, std::move(producer));
+  // Because of the std::move() |producer| is invalid after this point.
+
+  auto async_res =
+      ipc::AsyncResult<protos::gen::InitializeConnectionResponse>::Create();
+  async_res->set_using_shmem_provided_by_producer(using_producer_shmem);
+  async_res->set_direct_smb_patching_supported(true);
+  async_res->set_use_shmem_emulation(use_shmem_emulation);
+  response.Resolve(std::move(async_res));
+}
+
+// Called by the remote Producer through the IPC channel.
+void ProducerIPCService::RegisterDataSource(
+    const protos::gen::RegisterDataSourceRequest& req,
+    DeferredRegisterDataSourceResponse response) {
+  RemoteProducer* producer = GetProducerForCurrentRequest();
+  if (!producer) {
+    PERFETTO_DLOG(
+        "Producer invoked RegisterDataSource() before InitializeConnection()");
+    if (response.IsBound())
+      response.Reject();
+    return;
+  }
+
+  const DataSourceDescriptor& dsd = req.data_source_descriptor();
+  GetProducerForCurrentRequest()->service_endpoint->RegisterDataSource(dsd);
+
+  // RegisterDataSource doesn't expect any meaningful response.
+  if (response.IsBound()) {
+    response.Resolve(
+        ipc::AsyncResult<protos::gen::RegisterDataSourceResponse>::Create());
+  }
+}
+
+// Called by the remote Producer through the IPC channel.
+void ProducerIPCService::UpdateDataSource(
+    const protos::gen::UpdateDataSourceRequest& req,
+    DeferredUpdateDataSourceResponse response) {
+  RemoteProducer* producer = GetProducerForCurrentRequest();
+  if (!producer) {
+    PERFETTO_DLOG(
+        "Producer invoked UpdateDataSource() before InitializeConnection()");
+    if (response.IsBound())
+      response.Reject();
+    return;
+  }
+
+  const DataSourceDescriptor& dsd = req.data_source_descriptor();
+  GetProducerForCurrentRequest()->service_endpoint->UpdateDataSource(dsd);
+
+  // UpdateDataSource doesn't expect any meaningful response.
+  if (response.IsBound()) {
+    response.Resolve(
+        ipc::AsyncResult<protos::gen::UpdateDataSourceResponse>::Create());
+  }
+}
+
+// Called by the IPC layer.
+void ProducerIPCService::OnClientDisconnected() {
+  ipc::ClientID client_id = ipc::Service::client_info().client_id();
+  PERFETTO_DLOG("Client %" PRIu64 " disconnected", client_id);
+  producers_.erase(client_id);
+}
+
+// TODO(fmayer): test what happens if we receive the following tasks, in order:
+// RegisterDataSource, UnregisterDataSource, OnDataSourceRegistered.
+// which essentially means that the client posted back to back a
+// ReqisterDataSource and UnregisterDataSource speculating on the next id.
+// Called by the remote Service through the IPC channel.
+void ProducerIPCService::UnregisterDataSource(
+    const protos::gen::UnregisterDataSourceRequest& req,
+    DeferredUnregisterDataSourceResponse response) {
+  RemoteProducer* producer = GetProducerForCurrentRequest();
+  if (!producer) {
+    PERFETTO_DLOG(
+        "Producer invoked UnregisterDataSource() before "
+        "InitializeConnection()");
+    if (response.IsBound())
+      response.Reject();
+    return;
+  }
+  producer->service_endpoint->UnregisterDataSource(req.data_source_name());
+
+  // UnregisterDataSource doesn't expect any meaningful response.
+  if (response.IsBound()) {
+    response.Resolve(
+        ipc::AsyncResult<protos::gen::UnregisterDataSourceResponse>::Create());
+  }
+}
+
+void ProducerIPCService::RegisterTraceWriter(
+    const protos::gen::RegisterTraceWriterRequest& req,
+    DeferredRegisterTraceWriterResponse response) {
+  RemoteProducer* producer = GetProducerForCurrentRequest();
+  if (!producer) {
+    PERFETTO_DLOG(
+        "Producer invoked RegisterTraceWriter() before "
+        "InitializeConnection()");
+    if (response.IsBound())
+      response.Reject();
+    return;
+  }
+  producer->service_endpoint->RegisterTraceWriter(req.trace_writer_id(),
+                                                  req.target_buffer());
+
+  // RegisterTraceWriter doesn't expect any meaningful response.
+  if (response.IsBound()) {
+    response.Resolve(
+        ipc::AsyncResult<protos::gen::RegisterTraceWriterResponse>::Create());
+  }
+}
+
+void ProducerIPCService::UnregisterTraceWriter(
+    const protos::gen::UnregisterTraceWriterRequest& req,
+    DeferredUnregisterTraceWriterResponse response) {
+  RemoteProducer* producer = GetProducerForCurrentRequest();
+  if (!producer) {
+    PERFETTO_DLOG(
+        "Producer invoked UnregisterTraceWriter() before "
+        "InitializeConnection()");
+    if (response.IsBound())
+      response.Reject();
+    return;
+  }
+  producer->service_endpoint->UnregisterTraceWriter(req.trace_writer_id());
+
+  // UnregisterTraceWriter doesn't expect any meaningful response.
+  if (response.IsBound()) {
+    response.Resolve(
+        ipc::AsyncResult<protos::gen::UnregisterTraceWriterResponse>::Create());
+  }
+}
+
+void ProducerIPCService::CommitData(const protos::gen::CommitDataRequest& req,
+                                    DeferredCommitDataResponse resp) {
+  RemoteProducer* producer = GetProducerForCurrentRequest();
+  if (!producer) {
+    PERFETTO_DLOG(
+        "Producer invoked CommitData() before InitializeConnection()");
+    if (resp.IsBound())
+      resp.Reject();
+    return;
+  }
+
+  // We don't want to send a response if the client didn't attach a callback to
+  // the original request. Doing so would generate unnecessary wakeups and
+  // context switches.
+  std::function<void()> callback;
+  if (resp.IsBound()) {
+    // Capturing |resp| by reference here speculates on the fact that
+    // CommitData() in tracing_service_impl.cc invokes the passed callback
+    // inline, without posting it. If that assumption changes this code needs to
+    // wrap the response in a shared_ptr (C+11 lambdas don't support move) and
+    // use a weak ptr in the caller.
+    callback = [&resp] {
+      resp.Resolve(ipc::AsyncResult<protos::gen::CommitDataResponse>::Create());
+    };
+  }
+  producer->service_endpoint->CommitData(req, callback);
+}
+
+void ProducerIPCService::NotifyDataSourceStarted(
+    const protos::gen::NotifyDataSourceStartedRequest& request,
+    DeferredNotifyDataSourceStartedResponse response) {
+  RemoteProducer* producer = GetProducerForCurrentRequest();
+  if (!producer) {
+    PERFETTO_DLOG(
+        "Producer invoked NotifyDataSourceStarted() before "
+        "InitializeConnection()");
+    if (response.IsBound())
+      response.Reject();
+    return;
+  }
+  producer->service_endpoint->NotifyDataSourceStarted(request.data_source_id());
+
+  // NotifyDataSourceStopped shouldn't expect any meaningful response, avoid
+  // a useless IPC in that case.
+  if (response.IsBound()) {
+    response.Resolve(ipc::AsyncResult<
+                     protos::gen::NotifyDataSourceStartedResponse>::Create());
+  }
+}
+
+void ProducerIPCService::NotifyDataSourceStopped(
+    const protos::gen::NotifyDataSourceStoppedRequest& request,
+    DeferredNotifyDataSourceStoppedResponse response) {
+  RemoteProducer* producer = GetProducerForCurrentRequest();
+  if (!producer) {
+    PERFETTO_DLOG(
+        "Producer invoked NotifyDataSourceStopped() before "
+        "InitializeConnection()");
+    if (response.IsBound())
+      response.Reject();
+    return;
+  }
+  producer->service_endpoint->NotifyDataSourceStopped(request.data_source_id());
+
+  // NotifyDataSourceStopped shouldn't expect any meaningful response, avoid
+  // a useless IPC in that case.
+  if (response.IsBound()) {
+    response.Resolve(ipc::AsyncResult<
+                     protos::gen::NotifyDataSourceStoppedResponse>::Create());
+  }
+}
+
+void ProducerIPCService::ActivateTriggers(
+    const protos::gen::ActivateTriggersRequest& proto_req,
+    DeferredActivateTriggersResponse resp) {
+  RemoteProducer* producer = GetProducerForCurrentRequest();
+  if (!producer) {
+    PERFETTO_DLOG(
+        "Producer invoked ActivateTriggers() before InitializeConnection()");
+    if (resp.IsBound())
+      resp.Reject();
+    return;
+  }
+  std::vector<std::string> triggers;
+  for (const auto& name : proto_req.trigger_names()) {
+    triggers.push_back(name);
+  }
+  producer->service_endpoint->ActivateTriggers(triggers);
+  // ActivateTriggers shouldn't expect any meaningful response, avoid
+  // a useless IPC in that case.
+  if (resp.IsBound()) {
+    resp.Resolve(
+        ipc::AsyncResult<protos::gen::ActivateTriggersResponse>::Create());
+  }
+}
+
+void ProducerIPCService::GetAsyncCommand(
+    const protos::gen::GetAsyncCommandRequest&,
+    DeferredGetAsyncCommandResponse response) {
+  RemoteProducer* producer = GetProducerForCurrentRequest();
+  if (!producer) {
+    PERFETTO_DLOG(
+        "Producer invoked GetAsyncCommand() before "
+        "InitializeConnection()");
+    return response.Reject();
+  }
+  // Keep the back channel open, without ever resolving the ipc::Deferred fully,
+  // to send async commands to the RemoteProducer (e.g., starting/stopping a
+  // data source).
+  producer->async_producer_commands = std::move(response);
+
+  // Service may already have issued the OnTracingSetup() event, in which case
+  // we should forward it to the producer now.
+  if (producer->send_setup_tracing_on_async_commands_bound)
+    producer->SendSetupTracing();
+}
+
+void ProducerIPCService::Sync(const protos::gen::SyncRequest&,
+                              DeferredSyncResponse resp) {
+  RemoteProducer* producer = GetProducerForCurrentRequest();
+  if (!producer) {
+    PERFETTO_DLOG("Producer invoked Sync() before InitializeConnection()");
+    return resp.Reject();
+  }
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  auto resp_it = pending_syncs_.insert(pending_syncs_.end(), std::move(resp));
+  auto callback = [weak_this, resp_it]() {
+    if (!weak_this)
+      return;
+    auto pending_resp = std::move(*resp_it);
+    weak_this->pending_syncs_.erase(resp_it);
+    pending_resp.Resolve(ipc::AsyncResult<protos::gen::SyncResponse>::Create());
+  };
+  producer->service_endpoint->Sync(callback);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// RemoteProducer methods
+////////////////////////////////////////////////////////////////////////////////
+
+ProducerIPCService::RemoteProducer::RemoteProducer() = default;
+ProducerIPCService::RemoteProducer::~RemoteProducer() = default;
+
+// Invoked by the |core_service_| business logic after the ConnectProducer()
+// call. There is nothing to do here, we really expected the ConnectProducer()
+// to just work in the local case.
+void ProducerIPCService::RemoteProducer::OnConnect() {}
+
+// Invoked by the |core_service_| business logic after we destroy the
+// |service_endpoint| (in the RemoteProducer dtor).
+void ProducerIPCService::RemoteProducer::OnDisconnect() {}
+
+// Invoked by the |core_service_| business logic when it wants to create a new
+// data source.
+void ProducerIPCService::RemoteProducer::SetupDataSource(
+    DataSourceInstanceID dsid,
+    const DataSourceConfig& cfg) {
+  if (!async_producer_commands.IsBound()) {
+    PERFETTO_DLOG(
+        "The Service tried to create a new data source but the remote Producer "
+        "has not yet initialized the connection");
+    return;
+  }
+  auto cmd = ipc::AsyncResult<protos::gen::GetAsyncCommandResponse>::Create();
+  cmd.set_has_more(true);
+  cmd->mutable_setup_data_source()->set_new_instance_id(dsid);
+  *cmd->mutable_setup_data_source()->mutable_config() = cfg;
+  async_producer_commands.Resolve(std::move(cmd));
+}
+
+// Invoked by the |core_service_| business logic when it wants to start a new
+// data source.
+void ProducerIPCService::RemoteProducer::StartDataSource(
+    DataSourceInstanceID dsid,
+    const DataSourceConfig& cfg) {
+  if (!async_producer_commands.IsBound()) {
+    PERFETTO_DLOG(
+        "The Service tried to start a new data source but the remote Producer "
+        "has not yet initialized the connection");
+    return;
+  }
+  auto cmd = ipc::AsyncResult<protos::gen::GetAsyncCommandResponse>::Create();
+  cmd.set_has_more(true);
+  cmd->mutable_start_data_source()->set_new_instance_id(dsid);
+  *cmd->mutable_start_data_source()->mutable_config() = cfg;
+  async_producer_commands.Resolve(std::move(cmd));
+}
+
+void ProducerIPCService::RemoteProducer::StopDataSource(
+    DataSourceInstanceID dsid) {
+  if (!async_producer_commands.IsBound()) {
+    PERFETTO_DLOG(
+        "The Service tried to stop a data source but the remote Producer "
+        "has not yet initialized the connection");
+    return;
+  }
+  auto cmd = ipc::AsyncResult<protos::gen::GetAsyncCommandResponse>::Create();
+  cmd.set_has_more(true);
+  cmd->mutable_stop_data_source()->set_instance_id(dsid);
+  async_producer_commands.Resolve(std::move(cmd));
+}
+
+void ProducerIPCService::RemoteProducer::OnTracingSetup() {
+  if (!async_producer_commands.IsBound()) {
+    // Service may call this before the producer issued GetAsyncCommand.
+    send_setup_tracing_on_async_commands_bound = true;
+    return;
+  }
+  SendSetupTracing();
+}
+
+void ProducerIPCService::RemoteProducer::SendSetupTracing() {
+  PERFETTO_CHECK(async_producer_commands.IsBound());
+  PERFETTO_CHECK(service_endpoint->shared_memory());
+  auto cmd = ipc::AsyncResult<protos::gen::GetAsyncCommandResponse>::Create();
+  cmd.set_has_more(true);
+  auto setup_tracing = cmd->mutable_setup_tracing();
+  if (!service_endpoint->IsShmemProvidedByProducer()) {
+    // Nominal case (% Chrome): service provides SMB.
+    setup_tracing->set_shared_buffer_page_size_kb(
+        static_cast<uint32_t>(service_endpoint->shared_buffer_page_size_kb()));
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    const std::string& shm_key =
+        static_cast<SharedMemoryWindows*>(service_endpoint->shared_memory())
+            ->key();
+    setup_tracing->set_shm_key_windows(shm_key);
+#else
+    const int shm_fd =
+        static_cast<PosixSharedMemory*>(service_endpoint->shared_memory())
+            ->fd();
+    cmd.set_fd(shm_fd);
+#endif
+  }
+  async_producer_commands.Resolve(std::move(cmd));
+}
+
+void ProducerIPCService::RemoteProducer::Flush(
+    FlushRequestID flush_request_id,
+    const DataSourceInstanceID* data_source_ids,
+    size_t num_data_sources,
+    FlushFlags flush_flags) {
+  if (!async_producer_commands.IsBound()) {
+    PERFETTO_DLOG(
+        "The Service tried to request a flush but the remote Producer has not "
+        "yet initialized the connection");
+    return;
+  }
+  auto cmd = ipc::AsyncResult<protos::gen::GetAsyncCommandResponse>::Create();
+  cmd.set_has_more(true);
+  for (size_t i = 0; i < num_data_sources; i++)
+    cmd->mutable_flush()->add_data_source_ids(data_source_ids[i]);
+  cmd->mutable_flush()->set_request_id(flush_request_id);
+  cmd->mutable_flush()->set_flags(flush_flags.flags());
+  async_producer_commands.Resolve(std::move(cmd));
+}
+
+void ProducerIPCService::RemoteProducer::ClearIncrementalState(
+    const DataSourceInstanceID* data_source_ids,
+    size_t num_data_sources) {
+  if (!async_producer_commands.IsBound()) {
+    PERFETTO_DLOG(
+        "The Service tried to request an incremental state invalidation, but "
+        "the remote Producer has not yet initialized the connection");
+    return;
+  }
+  auto cmd = ipc::AsyncResult<protos::gen::GetAsyncCommandResponse>::Create();
+  cmd.set_has_more(true);
+  for (size_t i = 0; i < num_data_sources; i++)
+    cmd->mutable_clear_incremental_state()->add_data_source_ids(
+        data_source_ids[i]);
+  async_producer_commands.Resolve(std::move(cmd));
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/ipc/service/relay_ipc_service.cc
+// gen_amalgamated begin header: src/tracing/ipc/service/relay_ipc_service.h
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACING_IPC_SERVICE_RELAY_IPC_SERVICE_H_
+#define SRC_TRACING_IPC_SERVICE_RELAY_IPC_SERVICE_H_
+
+#include <limits>
+#include <list>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/flat_hash_map.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/sys_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/ipc/relay_port.ipc.h"
+
+namespace perfetto {
+
+// Implements the RelayPort IPC service.
+class RelayIPCService : public protos::gen::RelayPort {
+ public:
+  explicit RelayIPCService(TracingService* core_service);
+  ~RelayIPCService() override = default;
+
+  void OnClientDisconnected() override;
+  void SyncClock(const protos::gen::SyncClockRequest&,
+                 DeferredSyncClockResponse) override;
+
+ private:
+  TracingService* const core_service_;
+
+  using ClockSnapshots =
+      base::FlatHashMap<uint32_t, std::pair<uint64_t, uint64_t>>;
+  struct ClockSnapshotRecords {
+    base::MachineID machine_id = base::kDefaultMachineID;
+
+    // Keep track of most recent clock snapshots, ordered by local timestamps
+    // (CLOCK_BOOTTIME).
+    std::list<ClockSnapshots> clock_snapshots;
+
+    uint64_t min_rtt = std::numeric_limits<uint64_t>::max();
+  };
+
+  TracingService::RelayEndpoint* GetRelayEndpoint(ipc::ClientID);
+
+  base::FlatHashMap<ipc::ClientID,
+                    std::unique_ptr<TracingService::RelayEndpoint>>
+      relay_endpoints_;
+
+  base::WeakPtrFactory<RelayIPCService> weak_ptr_factory_;  // Keep last.
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_IPC_SERVICE_RELAY_IPC_SERVICE_H_
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/ipc/service/relay_ipc_service.h"
+
+#include <cinttypes>
+#include <utility>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/clock_snapshots.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+
+namespace perfetto {
+
+RelayIPCService::RelayIPCService(TracingService* core_service)
+    : core_service_(core_service), weak_ptr_factory_(this) {}
+
+TracingService::RelayEndpoint* RelayIPCService::GetRelayEndpoint(
+    ipc::ClientID client_id) {
+  auto* endpoint = relay_endpoints_.Find(client_id);
+  if (!endpoint)
+    return nullptr;
+  return endpoint->get();
+}
+
+void RelayIPCService::OnClientDisconnected() {
+  auto client_id = ipc::Service::client_info().client_id();
+  PERFETTO_DLOG("Relay endpoint %" PRIu64 "disconnected ", client_id);
+
+  auto* endpoint = GetRelayEndpoint(client_id);
+  if (!endpoint)
+    return;
+
+  endpoint->Disconnect();
+  relay_endpoints_.Erase(client_id);
+}
+
+void RelayIPCService::SyncClock(const protos::gen::SyncClockRequest& req,
+                                DeferredSyncClockResponse resp) {
+  auto host_clock_snapshots = CaptureClockSnapshots();
+
+  // Send the response to client to reduce RTT.
+  auto async_resp = ipc::AsyncResult<protos::gen::SyncClockResponse>::Create();
+  resp.Resolve(std::move(async_resp));
+
+  ClockSnapshotVector client_clock_snapshots;
+  for (size_t i = 0; i < req.clocks().size(); i++) {
+    auto& client_clock = req.clocks()[i];
+    client_clock_snapshots.emplace_back(client_clock.clock_id(),
+                                        client_clock.timestamp());
+  }
+
+  // Handle the request in the core service.
+  auto machine_id = ipc::Service::client_info().machine_id();
+  auto client_id = ipc::Service::client_info().client_id();
+  auto* endpoint = GetRelayEndpoint(client_id);
+  if (!endpoint) {
+    auto ep = core_service_->ConnectRelayClient(
+        std::make_pair(machine_id, client_id));
+    endpoint = ep.get();
+    relay_endpoints_.Insert(client_id, std::move(ep));
+  }
+
+  RelayEndpoint::SyncMode mode = req.phase() == SyncClockRequest::PING
+                                     ? RelayEndpoint::SyncMode::PING
+                                     : RelayEndpoint::SyncMode::UPDATE;
+  endpoint->SyncClocks(mode, std::move(client_clock_snapshots),
+                       std::move(host_clock_snapshots));
+}
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/ipc/service/service_ipc_host_impl.cc
+// gen_amalgamated begin header: src/tracing/ipc/service/service_ipc_host_impl.h
+// gen_amalgamated begin header: include/perfetto/ext/tracing/ipc/service_ipc_host.h
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACING_IPC_SERVICE_IPC_HOST_H_
+#define INCLUDE_PERFETTO_EXT_TRACING_IPC_SERVICE_IPC_HOST_H_
+
+#include <memory>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/default_socket.h"
+
+namespace perfetto {
+namespace base {
+class TaskRunner;
+}  // namespace base.
+
+namespace ipc {
+class Host;
+}  // namespace ipc
+
+// Creates an instance of the service (business logic + UNIX socket transport).
+// Exposed to:
+//   The code in the tracing client that will host the service e.g., traced.
+// Implemented in:
+//   src/tracing/ipc/service/service_ipc_host_impl.cc
+class PERFETTO_EXPORT_COMPONENT ServiceIPCHost {
+ public:
+  static std::unique_ptr<ServiceIPCHost> CreateInstance(
+      base::TaskRunner*,
+      TracingService::InitOpts = {});
+  virtual ~ServiceIPCHost();
+
+  // The overload to wrap the multi-value producer socket name in the
+  // single-value variant for compatibility in tests.
+  bool Start(const char* producer_socket_name,
+             const char* consumer_socket_name) {
+    return Start(TokenizeProducerSockets(producer_socket_name),
+                 consumer_socket_name);
+  }
+  // Start listening on the Producer & Consumer ports. Returns false in case of
+  // failure (e.g., something else is listening on |socket_name|).
+  virtual bool Start(const std::vector<std::string>& producer_socket_names,
+                     const char* consumer_socket_name) = 0;
+
+  // Like the above, but takes two file descriptors to already bound sockets.
+  // This is used when building as part of the Android tree, where init opens
+  // and binds the socket beore exec()-ing us.
+  virtual bool Start(base::ScopedSocketHandle producer_socket_fd,
+                     base::ScopedSocketHandle consumer_socket_fd) = 0;
+
+  // Allows callers to supply preconstructed Hosts.
+  virtual bool Start(std::unique_ptr<ipc::Host> producer_host,
+                     std::unique_ptr<ipc::Host> consumer_host) = 0;
+
+  virtual TracingService* service() const = 0;
+
+ protected:
+  ServiceIPCHost();
+
+ private:
+  ServiceIPCHost(const ServiceIPCHost&) = delete;
+  ServiceIPCHost& operator=(const ServiceIPCHost&) = delete;
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_TRACING_IPC_SERVICE_IPC_HOST_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACING_IPC_SERVICE_SERVICE_IPC_HOST_IMPL_H_
+#define SRC_TRACING_IPC_SERVICE_SERVICE_IPC_HOST_IMPL_H_
+
+#include <memory>
+
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/service_ipc_host.h"
+
+namespace perfetto {
+
+namespace ipc {
+class Host;
+}
+
+// The implementation of the IPC host for the tracing service. This class does
+// very few things: it mostly initializes the IPC transport. The actual
+// implementation of the IPC <> Service business logic glue lives in
+// producer_ipc_service.cc and consumer_ipc_service.cc.
+class ServiceIPCHostImpl : public ServiceIPCHost {
+ public:
+  explicit ServiceIPCHostImpl(base::TaskRunner*,
+                              TracingService::InitOpts init_opts = {});
+  ~ServiceIPCHostImpl() override;
+
+  // ServiceIPCHost implementation.
+  bool Start(const std::vector<std::string>& producer_socket_names,
+             const char* consumer_socket_name) override;
+  bool Start(base::ScopedSocketHandle producer_socket_fd,
+             base::ScopedSocketHandle consumer_socket_fd) override;
+  bool Start(std::unique_ptr<ipc::Host> producer_host,
+             std::unique_ptr<ipc::Host> consumer_host) override;
+
+  TracingService* service() const override;
+
+ private:
+  bool DoStart();
+  void Shutdown();
+
+  base::TaskRunner* const task_runner_;
+  const TracingService::InitOpts init_opts_;
+  std::unique_ptr<TracingService> svc_;  // The service business logic.
+
+  // The IPC hosts that listen on the Producer sockets. They own the
+  // PosixServiceProducerPort instances which deal with all producers' IPC(s).
+  // Note that there can be multiple producer sockets if it's specified in the
+  // producer socket name (e.g. for listening both on vsock for VMs and AF_UNIX
+  // for processes on the same machine).
+  std::vector<std::unique_ptr<ipc::Host>> producer_ipc_ports_;
+
+  // As above, but for the Consumer port.
+  std::unique_ptr<ipc::Host> consumer_ipc_port_;
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_IPC_SERVICE_SERVICE_IPC_HOST_IMPL_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/ipc/service/service_ipc_host_impl.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/host.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
+// gen_amalgamated expanded: #include "src/tracing/ipc/service/consumer_ipc_service.h"
+// gen_amalgamated expanded: #include "src/tracing/ipc/service/producer_ipc_service.h"
+// gen_amalgamated expanded: #include "src/tracing/ipc/service/relay_ipc_service.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+// gen_amalgamated expanded: #include "src/tracing/ipc/shared_memory_windows.h"
+#else
+// gen_amalgamated expanded: #include "src/tracing/ipc/posix_shared_memory.h"
+#endif
+
+namespace perfetto {
+
+namespace {
+constexpr uint32_t kProducerSocketTxTimeoutMs = 10;
+}
+
+// TODO(fmayer): implement per-uid connection limit (b/69093705).
+
+// Implements the publicly exposed factory method declared in
+// include/tracing/posix_ipc/posix_service_host.h.
+std::unique_ptr<ServiceIPCHost> ServiceIPCHost::CreateInstance(
+    base::TaskRunner* task_runner,
+    TracingService::InitOpts init_opts) {
+  return std::unique_ptr<ServiceIPCHost>(
+      new ServiceIPCHostImpl(task_runner, init_opts));
+}
+
+ServiceIPCHostImpl::ServiceIPCHostImpl(base::TaskRunner* task_runner,
+                                       TracingService::InitOpts init_opts)
+    : task_runner_(task_runner), init_opts_(init_opts) {}
+
+ServiceIPCHostImpl::~ServiceIPCHostImpl() {}
+
+bool ServiceIPCHostImpl::Start(
+    const std::vector<std::string>& producer_socket_names,
+    const char* consumer_socket_name) {
+  PERFETTO_CHECK(!svc_);  // Check if already started.
+
+  // Initialize the IPC transport.
+  for (const auto& producer_socket_name : producer_socket_names)
+    producer_ipc_ports_.emplace_back(
+        ipc::Host::CreateInstance(producer_socket_name.c_str(), task_runner_));
+  consumer_ipc_port_ =
+      ipc::Host::CreateInstance(consumer_socket_name, task_runner_);
+  return DoStart();
+}
+
+bool ServiceIPCHostImpl::Start(base::ScopedSocketHandle producer_socket_fd,
+                               base::ScopedSocketHandle consumer_socket_fd) {
+  PERFETTO_CHECK(!svc_);  // Check if already started.
+
+  // Initialize the IPC transport.
+  producer_ipc_ports_.emplace_back(
+      ipc::Host::CreateInstance(std::move(producer_socket_fd), task_runner_));
+  consumer_ipc_port_ =
+      ipc::Host::CreateInstance(std::move(consumer_socket_fd), task_runner_);
+  return DoStart();
+}
+
+bool ServiceIPCHostImpl::Start(std::unique_ptr<ipc::Host> producer_host,
+                               std::unique_ptr<ipc::Host> consumer_host) {
+  PERFETTO_CHECK(!svc_);  // Check if already started.
+  PERFETTO_DCHECK(producer_host);
+  PERFETTO_DCHECK(consumer_host);
+
+  // Initialize the IPC transport.
+  producer_ipc_ports_.emplace_back(std::move(producer_host));
+  consumer_ipc_port_ = std::move(consumer_host);
+
+  return DoStart();
+}
+
+bool ServiceIPCHostImpl::DoStart() {
+  // Create and initialize the platform-independent tracing business logic.
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  std::unique_ptr<SharedMemory::Factory> shm_factory(
+      new SharedMemoryWindows::Factory());
+#else
+  std::unique_ptr<SharedMemory::Factory> shm_factory(
+      new PosixSharedMemory::Factory());
+#endif
+  svc_ = TracingService::CreateInstance(std::move(shm_factory), task_runner_,
+                                        init_opts_);
+
+  if (producer_ipc_ports_.empty() || !consumer_ipc_port_) {
+    Shutdown();
+    return false;
+  }
+
+  // Lower the timeout for blocking socket sends to producers as we shouldn't
+  // normally exhaust the kernel send buffer unless the producer is
+  // unresponsive. We'll drop the connection if the timeout is hit (see
+  // UnixSocket::Send). Context in b/236813972, b/193234818.
+  // Consumer port continues using the default timeout (10s) as there are
+  // generally fewer consumer processes, and they're better behaved. Also the
+  // consumer port ipcs might exhaust the send buffer under normal operation
+  // due to large messages such as ReadBuffersResponse.
+  for (auto& producer_ipc_port : producer_ipc_ports_)
+    producer_ipc_port->SetSocketSendTimeoutMs(kProducerSocketTxTimeoutMs);
+
+  // TODO(fmayer): add a test that destroyes the ServiceIPCHostImpl soon after
+  // Start() and checks that no spurious callbacks are issued.
+  for (auto& producer_ipc_port : producer_ipc_ports_) {
+    bool producer_service_exposed = producer_ipc_port->ExposeService(
+        std::unique_ptr<ipc::Service>(new ProducerIPCService(svc_.get())));
+    PERFETTO_CHECK(producer_service_exposed);
+
+    if (!init_opts_.enable_relay_endpoint)
+      continue;
+    // Expose a secondary service for sync with remote relay service
+    // if requested.
+    bool relay_service_exposed = producer_ipc_port->ExposeService(
+        std::unique_ptr<ipc::Service>(new RelayIPCService(svc_.get())));
+    PERFETTO_CHECK(relay_service_exposed);
+  }
+
+  bool consumer_service_exposed = consumer_ipc_port_->ExposeService(
+      std::unique_ptr<ipc::Service>(new ConsumerIPCService(svc_.get())));
+  PERFETTO_CHECK(consumer_service_exposed);
+
+  return true;
+}
+
+TracingService* ServiceIPCHostImpl::service() const {
+  return svc_.get();
+}
+
+void ServiceIPCHostImpl::Shutdown() {
+  // TODO(primiano): add a test that causes the Shutdown() and checks that no
+  // spurious callbacks are issued.
+  producer_ipc_ports_.clear();
+  consumer_ipc_port_.reset();
+  svc_.reset();
+}
+
+// Definitions for the base class ctor/dtor.
+ServiceIPCHost::ServiceIPCHost() = default;
+ServiceIPCHost::~ServiceIPCHost() = default;
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/internal/system_tracing_backend.cc
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/system_tracing_backend.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/producer_ipc_client.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/default_socket.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_SYSTEM_CONSUMER)
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/consumer_ipc_client.h"
+#endif
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+// gen_amalgamated expanded: #include "src/tracing/ipc/shared_memory_windows.h"
+#else
+// gen_amalgamated expanded: #include "src/tracing/ipc/posix_shared_memory.h"
+#endif
+
+namespace perfetto {
+namespace internal {
+
+// static
+TracingProducerBackend* SystemProducerTracingBackend::GetInstance() {
+  static auto* instance = new SystemProducerTracingBackend();
+  return instance;
+}
+
+SystemProducerTracingBackend::SystemProducerTracingBackend() {}
+
+std::unique_ptr<ProducerEndpoint> SystemProducerTracingBackend::ConnectProducer(
+    const ConnectProducerArgs& args) {
+  PERFETTO_DCHECK(args.task_runner->RunsTasksOnCurrentThread());
+
+  std::unique_ptr<SharedMemory> shm;
+  std::unique_ptr<SharedMemoryArbiter> arbiter;
+  uint32_t shmem_size_hint = args.shmem_size_hint_bytes;
+  uint32_t shmem_page_size_hint = args.shmem_page_size_hint_bytes;
+  if (args.use_producer_provided_smb) {
+    if (shmem_size_hint == 0)
+      shmem_size_hint = TracingService::kDefaultShmSize;
+    if (shmem_page_size_hint == 0)
+      shmem_page_size_hint = TracingService::kDefaultShmPageSize;
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    shm = SharedMemoryWindows::Create(shmem_size_hint);
+#else
+    shm = PosixSharedMemory::Create(shmem_size_hint);
+#endif
+    arbiter = SharedMemoryArbiter::CreateUnboundInstance(
+        shm.get(), shmem_page_size_hint, SharedMemoryABI::ShmemMode::kDefault);
+  }
+
+  ipc::Client::ConnArgs conn_args(GetProducerSocket(), true);
+  auto endpoint = ProducerIPCClient::Connect(
+      std::move(conn_args), args.producer, args.producer_name, args.task_runner,
+      TracingService::ProducerSMBScrapingMode::kEnabled, shmem_size_hint,
+      shmem_page_size_hint, std::move(shm), std::move(arbiter),
+      args.create_socket_async);
+  PERFETTO_CHECK(endpoint);
+  return endpoint;
+}
+
+// static
+TracingConsumerBackend* SystemConsumerTracingBackend::GetInstance() {
+  static auto* instance = new SystemConsumerTracingBackend();
+  return instance;
+}
+
+SystemConsumerTracingBackend::SystemConsumerTracingBackend() {}
+
+std::unique_ptr<ConsumerEndpoint> SystemConsumerTracingBackend::ConnectConsumer(
+    const ConnectConsumerArgs& args) {
+#if PERFETTO_BUILDFLAG(PERFETTO_SYSTEM_CONSUMER)
+  auto endpoint = ConsumerIPCClient::Connect(GetConsumerSocket(), args.consumer,
+                                             args.task_runner);
+  PERFETTO_CHECK(endpoint);
+  return endpoint;
+#else
+  base::ignore_result(args);
+  PERFETTO_FATAL("System backend consumer support disabled");
+  return nullptr;
+#endif
+}
+
+}  // namespace internal
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/platform_posix.cc
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_tls.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/platform.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
+
+#include <pthread.h>
+#include <stdlib.h>
+
+namespace perfetto {
+
+namespace {
+
+class PlatformPosix : public Platform {
+ public:
+  PlatformPosix();
+  ~PlatformPosix() override;
+
+  ThreadLocalObject* GetOrCreateThreadLocalObject() override;
+
+  std::unique_ptr<base::TaskRunner> CreateTaskRunner(
+      const CreateTaskRunnerArgs&) override;
+  std::string GetCurrentProcessName() override;
+  void Shutdown() override;
+
+ private:
+  pthread_key_t tls_key_{};
+};
+
+PlatformPosix* g_instance = nullptr;
+
+using ThreadLocalObject = Platform::ThreadLocalObject;
+
+PlatformPosix::PlatformPosix() {
+  PERFETTO_CHECK(!g_instance);
+  g_instance = this;
+  auto tls_dtor = [](void* obj) {
+    // The Posix TLS implementation resets the key before calling this dtor.
+    // Here we re-reset it to the object we are about to delete. This is to
+    // handle re-entrant usages of tracing in the PostTask done during the dtor
+    // (see comments in TracingTLS::~TracingTLS()). Chromium's platform
+    // implementation (which does NOT use this platform impl) has a similar
+    // workaround (https://crrev.com/c/2748300).
+    pthread_setspecific(g_instance->tls_key_, obj);
+    delete static_cast<ThreadLocalObject*>(obj);
+    pthread_setspecific(g_instance->tls_key_, nullptr);
+  };
+  PERFETTO_CHECK(pthread_key_create(&tls_key_, tls_dtor) == 0);
+}
+
+PlatformPosix::~PlatformPosix() {
+  // pthread_key_delete doesn't call destructors, so do it manually for the
+  // calling thread.
+  void* tls_ptr = pthread_getspecific(tls_key_);
+  delete static_cast<ThreadLocalObject*>(tls_ptr);
+
+  pthread_key_delete(tls_key_);
+  g_instance = nullptr;
+}
+
+void PlatformPosix::Shutdown() {
+  PERFETTO_CHECK(g_instance == this);
+  delete this;
+  PERFETTO_CHECK(!g_instance);
+  // We're not clearing out the instance in GetDefaultPlatform() since it's not
+  // possible to re-initialize Perfetto after calling this function anyway.
+}
+
+ThreadLocalObject* PlatformPosix::GetOrCreateThreadLocalObject() {
+  // In chromium this should be implemented using base::ThreadLocalStorage.
+  void* tls_ptr = pthread_getspecific(tls_key_);
+
+  // This is needed to handle re-entrant calls during TLS dtor.
+  // See comments in platform.cc and aosp/1712371 .
+  ThreadLocalObject* tls = static_cast<ThreadLocalObject*>(tls_ptr);
+  if (!tls) {
+    tls = ThreadLocalObject::CreateInstance().release();
+    pthread_setspecific(tls_key_, tls);
+  }
+  return tls;
+}
+
+std::unique_ptr<base::TaskRunner> PlatformPosix::CreateTaskRunner(
+    const CreateTaskRunnerArgs& args) {
+  return std::unique_ptr<base::TaskRunner>(new base::ThreadTaskRunner(
+      base::ThreadTaskRunner::CreateAndStart(args.name_for_debugging)));
+}
+
+std::string PlatformPosix::GetCurrentProcessName() {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  std::string cmdline;
+  base::ReadFile("/proc/self/cmdline", &cmdline);
+  return cmdline.substr(0, cmdline.find('\0'));
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+  return std::string(getprogname());
+#else
+  return "unknown_producer";
+#endif
+}
+
+}  // namespace
+
+// static
+Platform* Platform::GetDefaultPlatform() {
+  static PlatformPosix* instance = new PlatformPosix();
+  return instance;
+}
+
+}  // namespace perfetto
+#endif  // OS_LINUX || OS_ANDROID || OS_APPLE || OS_FUCHSIA
+// gen_amalgamated begin source: src/tracing/platform_windows.cc
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+#include <Windows.h>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_tls.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/platform.h"
+
+// Thread Termination Callbacks.
+// Windows doesn't support a per-thread destructor with its
+// TLS primitives. So, we build it manually by inserting a
+// function to be called on each thread's exit.
+// This magic is from chromium's base/threading/thread_local_storage_win.cc
+// which in turn is from http://www.codeproject.com/threads/tls.asp.
+
+#ifdef _WIN64
+#pragma comment(linker, "/INCLUDE:_tls_used")
+#pragma comment(linker, "/INCLUDE:perfetto_thread_callback_base")
+#else
+#pragma comment(linker, "/INCLUDE:__tls_used")
+#pragma comment(linker, "/INCLUDE:_perfetto_thread_callback_base")
+#endif
+
+namespace perfetto {
+
+namespace {
+
+class PlatformWindows : public Platform {
+ public:
+  static PlatformWindows* instance;
+  PlatformWindows();
+  ~PlatformWindows() override;
+
+  ThreadLocalObject* GetOrCreateThreadLocalObject() override;
+  std::unique_ptr<base::TaskRunner> CreateTaskRunner(
+      const CreateTaskRunnerArgs&) override;
+  std::string GetCurrentProcessName() override;
+  void OnThreadExit();
+
+ private:
+  DWORD tls_key_{};
+};
+
+using ThreadLocalObject = Platform::ThreadLocalObject;
+
+// static
+PlatformWindows* PlatformWindows::instance = nullptr;
+
+PlatformWindows::PlatformWindows() {
+  instance = this;
+  tls_key_ = ::TlsAlloc();
+  PERFETTO_CHECK(tls_key_ != TLS_OUT_OF_INDEXES);
+}
+
+PlatformWindows::~PlatformWindows() {
+  ::TlsFree(tls_key_);
+  instance = nullptr;
+}
+
+void PlatformWindows::OnThreadExit() {
+  auto tls = static_cast<ThreadLocalObject*>(::TlsGetValue(tls_key_));
+  if (tls) {
+    // At this point we rely on the TLS object to be still set to the TracingTLS
+    // we are deleting. See comments in TracingTLS::~TracingTLS().
+    delete tls;
+  }
+}
+
+ThreadLocalObject* PlatformWindows::GetOrCreateThreadLocalObject() {
+  void* tls_ptr = ::TlsGetValue(tls_key_);
+
+  auto* tls = static_cast<ThreadLocalObject*>(tls_ptr);
+  if (!tls) {
+    tls = ThreadLocalObject::CreateInstance().release();
+    ::TlsSetValue(tls_key_, tls);
+  }
+  return tls;
+}
+
+std::unique_ptr<base::TaskRunner> PlatformWindows::CreateTaskRunner(
+    const CreateTaskRunnerArgs& args) {
+  return std::unique_ptr<base::TaskRunner>(new base::ThreadTaskRunner(
+      base::ThreadTaskRunner::CreateAndStart(args.name_for_debugging)));
+}
+
+std::string PlatformWindows::GetCurrentProcessName() {
+  char buf[MAX_PATH];
+  auto len = ::GetModuleFileNameA(nullptr /*current*/, buf, sizeof(buf));
+  std::string name(buf, static_cast<size_t>(len));
+  size_t sep = name.find_last_of('\\');
+  if (sep != std::string::npos)
+    name = name.substr(sep + 1);
+  return name;
+}
+
+}  // namespace
+
+// static
+Platform* Platform::GetDefaultPlatform() {
+  static PlatformWindows* thread_safe_init_instance = new PlatformWindows();
+  return thread_safe_init_instance;
+}
+
+}  // namespace perfetto
+
+// -----------------------
+// Thread-local destructor
+// -----------------------
+
+// .CRT$XLA to .CRT$XLZ is an array of PIMAGE_TLS_CALLBACK pointers that are
+// called automatically by the OS loader code (not the CRT) when the module is
+// loaded and on thread creation. They are NOT called if the module has been
+// loaded by a LoadLibrary() call. It must have implicitly been loaded at
+// process startup.
+// See VC\crt\src\tlssup.c for reference.
+
+// extern "C" suppresses C++ name mangling so we know the symbol name for the
+// linker /INCLUDE:symbol pragma above.
+extern "C" {
+// The linker must not discard perfetto_thread_callback_base. (We force a
+// reference to this variable with a linker /INCLUDE:symbol pragma to ensure
+// that.) If this variable is discarded, the OnThreadExit function will never be
+// called.
+
+void NTAPI PerfettoOnThreadExit(PVOID, DWORD, PVOID);
+void NTAPI PerfettoOnThreadExit(PVOID, DWORD reason, PVOID) {
+  if (reason == DLL_THREAD_DETACH || reason == DLL_PROCESS_DETACH) {
+    if (perfetto::PlatformWindows::instance)
+      perfetto::PlatformWindows::instance->OnThreadExit();
+  }
+}
+
+#ifdef _WIN64
+
+// .CRT section is merged with .rdata on x64 so it must be constant data.
+#pragma const_seg(".CRT$XLP")
+
+// When defining a const variable, it must have external linkage to be sure the
+// linker doesn't discard it.
+extern const PIMAGE_TLS_CALLBACK perfetto_thread_callback_base;
+const PIMAGE_TLS_CALLBACK perfetto_thread_callback_base = PerfettoOnThreadExit;
+
+// Reset the default section.
+#pragma const_seg()
+
+#else  // _WIN64
+
+#pragma data_seg(".CRT$XLP")
+PIMAGE_TLS_CALLBACK perfetto_thread_callback_base = PerfettoOnThreadExit;
+// Reset the default section.
+#pragma data_seg()
+
+#endif  // _WIN64
+
+}  // extern "C"
+
+#endif  // OS_WIN
+
diff --git a/sdk/perfetto.h b/sdk/perfetto.h
new file mode 100644
index 0000000..e0dde32
--- /dev/null
+++ b/sdk/perfetto.h
@@ -0,0 +1,166356 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// This file is automatically generated by gen_amalgamated. Do not edit.
+
+// gen_amalgamated begin header: include/perfetto/tracing.h
+// gen_amalgamated begin header: include/perfetto/base/time.h
+// gen_amalgamated begin header: include/perfetto/base/build_config.h
+// gen_amalgamated begin header: gen/build_config/perfetto_build_flags.h
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Generated by write_buildflag_header.py
+
+// fix_include_guards: off
+#ifndef GEN_BUILD_CONFIG_PERFETTO_BUILD_FLAGS_H_
+#define GEN_BUILD_CONFIG_PERFETTO_BUILD_FLAGS_H_
+
+// clang-format off
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ANDROID_BUILD() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_CHROMIUM_BUILD() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_STANDALONE_BUILD() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_START_DAEMONS() (1)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_IPC() (1)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_WATCHDOG() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPONENT_BUILD() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_FORCE_DLOG_ON() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_FORCE_DLOG_OFF() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_FORCE_DCHECK_ON() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_FORCE_DCHECK_OFF() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_VERBOSE_LOGS() (1)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_VERSION_GEN() (1)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_PERCENTILE() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_LINENOISE() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_HTTPD() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_JSON() (1)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_LOCAL_SYMBOLIZER() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ZLIB() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TRACED_PERF() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_HEAPPROFD() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_STDERR_CRASH_DUMP() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_X64_CPU_OPT() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_LLVM_DEMANGLE() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_SYSTEM_CONSUMER() (1)
+
+// clang-format on
+#endif  // GEN_BUILD_CONFIG_PERFETTO_BUILD_FLAGS_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_BASE_BUILD_CONFIG_H_
+#define INCLUDE_PERFETTO_BASE_BUILD_CONFIG_H_
+
+// Allows to define build flags that give a compiler error if the header that
+// defined the flag is not included, instead of silently ignoring the #if block.
+#define PERFETTO_BUILDFLAG_CAT_INDIRECT(a, b) a##b
+#define PERFETTO_BUILDFLAG_CAT(a, b) PERFETTO_BUILDFLAG_CAT_INDIRECT(a, b)
+#define PERFETTO_BUILDFLAG(flag) \
+  (PERFETTO_BUILDFLAG_CAT(PERFETTO_BUILDFLAG_DEFINE_, flag)())
+
+#if defined(__ANDROID__)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_ANDROID() 1
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WIN() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_APPLE() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_MAC() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_IOS() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WASM() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_FUCHSIA() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_NACL() 0
+#elif defined(__APPLE__)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_ANDROID() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_APPLE() 1
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WIN() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WASM() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_FUCHSIA() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_NACL() 0
+// Include TARGET_OS_IPHONE when on __APPLE__ systems.
+#include <TargetConditionals.h>
+#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_MAC() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_IOS() 1
+#else
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_MAC() 1
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_IOS() 0
+#endif
+#elif defined(__linux__)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_ANDROID() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX() 1
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WIN() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_APPLE() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_MAC() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_IOS() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WASM() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_FUCHSIA() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_NACL() 0
+#elif defined(_WIN32)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_ANDROID() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WIN() 1
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_APPLE() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_MAC() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_IOS() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WASM() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_FUCHSIA() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_NACL() 0
+#elif defined(__EMSCRIPTEN__)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_ANDROID() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WIN() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_APPLE() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_MAC() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_IOS() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WASM() 1
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_FUCHSIA() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_NACL() 0
+#elif defined(__Fuchsia__)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_ANDROID() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_APPLE() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_MAC() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_IOS() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WIN() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WASM() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_FUCHSIA() 1
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_NACL() 0
+#elif defined(__native_client__)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_ANDROID() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WIN() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_APPLE() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_MAC() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_IOS() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WASM() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_FUCHSIA() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_NACL() 1
+#else
+#error OS not supported (see build_config.h)
+#endif
+
+#if defined(__clang__)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPILER_CLANG() 1
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPILER_GCC() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPILER_MSVC() 0
+#elif defined(__GNUC__) // Careful: Clang also defines this!
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPILER_CLANG() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPILER_GCC() 1
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPILER_MSVC() 0
+#elif defined(_MSC_VER)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPILER_CLANG() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPILER_GCC() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPILER_MSVC() 1
+#else
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPILER_CLANG() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPILER_GCC() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPILER_MSVC() 0
+#endif
+
+#if defined(PERFETTO_BUILD_WITH_ANDROID_USERDEBUG)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ANDROID_USERDEBUG_BUILD() 1
+#else
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ANDROID_USERDEBUG_BUILD() 0
+#endif
+
+// Processor architecture detection.  For more info on what's defined, see:
+//   http://msdn.microsoft.com/en-us/library/b0084kay.aspx
+//   http://www.agner.org/optimize/calling_conventions.pdf
+//   or with gcc, run: "echo | gcc -E -dM -"
+#if defined(__aarch64__) || defined(_M_ARM64)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ARCH_CPU_ARM64() 1
+#else
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ARCH_CPU_ARM64() 0
+#endif
+
+#if defined(__x86_64__) || defined(_M_X64)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ARCH_CPU_X86_64() 1
+#else
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ARCH_CPU_X86_64() 0
+#endif
+
+// perfetto_build_flags.h contains the tweakable build flags defined via GN.
+// - In GN builds (e.g., standalone, chromium, v8) this file is generated at
+//   build time via the gen_rule //gn/gen_buildflags.
+// - In Android in-tree builds, this file is generated by tools/gen_android_bp
+//   and checked in into include/perfetto/base/build_configs/android_tree/. The
+//   default cflags add this path to the default include path.
+// - Similarly, in bazel builds, this file is generated by tools/gen_bazel and
+//   checked in into include/perfetto/base/build_configs/bazel/.
+// - In amalgamated builds, this file is generated by tools/gen_amalgamated and
+//   added to the amalgamated headers.
+// gen_amalgamated expanded: #include "perfetto_build_flags.h"  // no-include-violation-check
+
+#endif  // INCLUDE_PERFETTO_BASE_BUILD_CONFIG_H_
+// gen_amalgamated begin header: include/perfetto/base/logging.h
+// gen_amalgamated begin header: include/perfetto/base/compiler.h
+// gen_amalgamated begin header: include/perfetto/public/compiler.h
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_PUBLIC_COMPILER_H_
+#define INCLUDE_PERFETTO_PUBLIC_COMPILER_H_
+
+#include <stddef.h>
+
+#if defined(__GNUC__) || defined(__clang__)
+#define PERFETTO_LIKELY(_x) __builtin_expect(!!(_x), 1)
+#define PERFETTO_UNLIKELY(_x) __builtin_expect(!!(_x), 0)
+#else
+#define PERFETTO_LIKELY(_x) (_x)
+#define PERFETTO_UNLIKELY(_x) (_x)
+#endif
+
+// PERFETTO_STATIC_CAST(TYPE, VAL): avoids the -Wold-style-cast warning when
+// writing code that needs to be compiled as C and C++.
+#ifdef __cplusplus
+#define PERFETTO_STATIC_CAST(TYPE, VAL) static_cast<TYPE>(VAL)
+#else
+#define PERFETTO_STATIC_CAST(TYPE, VAL) ((TYPE)(VAL))
+#endif
+
+// PERFETTO_REINTERPRET_CAST(TYPE, VAL): avoids the -Wold-style-cast warning
+// when writing code that needs to be compiled as C and C++.
+#ifdef __cplusplus
+#define PERFETTO_REINTERPRET_CAST(TYPE, VAL) reinterpret_cast<TYPE>(VAL)
+#else
+#define PERFETTO_REINTERPRET_CAST(TYPE, VAL) ((TYPE)(VAL))
+#endif
+
+// PERFETTO_NULL: avoids the -Wzero-as-null-pointer-constant warning when
+// writing code that needs to be compiled as C and C++.
+#ifdef __cplusplus
+#define PERFETTO_NULL nullptr
+#else
+#define PERFETTO_NULL NULL
+#endif
+
+#endif  // INCLUDE_PERFETTO_PUBLIC_COMPILER_H_
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_BASE_COMPILER_H_
+#define INCLUDE_PERFETTO_BASE_COMPILER_H_
+
+#include <stddef.h>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/public/compiler.h"
+
+// __has_attribute is supported only by clang and recent versions of GCC.
+// Add a layer to wrap the __has_attribute macro.
+#if defined(__has_attribute)
+#define PERFETTO_HAS_ATTRIBUTE(x) __has_attribute(x)
+#else
+#define PERFETTO_HAS_ATTRIBUTE(x) 0
+#endif
+
+#if defined(__GNUC__) || defined(__clang__)
+#define PERFETTO_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
+#else
+#define PERFETTO_WARN_UNUSED_RESULT
+#endif
+
+#if defined(__GNUC__) || defined(__clang__)
+#define PERFETTO_UNUSED __attribute__((unused))
+#else
+#define PERFETTO_UNUSED
+#endif
+
+#if defined(__clang__)
+#define PERFETTO_ALWAYS_INLINE __attribute__((__always_inline__))
+#define PERFETTO_NO_INLINE __attribute__((__noinline__))
+#else
+// GCC is too pedantic and often fails with the error:
+// "always_inline function might not be inlinable"
+#define PERFETTO_ALWAYS_INLINE
+#define PERFETTO_NO_INLINE
+#endif
+
+#if defined(__GNUC__) || defined(__clang__)
+#define PERFETTO_NORETURN __attribute__((__noreturn__))
+#else
+#define PERFETTO_NORETURN __declspec(noreturn)
+#endif
+
+#if defined(__GNUC__) || defined(__clang__)
+#define PERFETTO_DEBUG_FUNCTION_IDENTIFIER() __PRETTY_FUNCTION__
+#elif defined(_MSC_VER)
+#define PERFETTO_DEBUG_FUNCTION_IDENTIFIER() __FUNCSIG__
+#else
+#define PERFETTO_DEBUG_FUNCTION_IDENTIFIER() \
+  static_assert(false, "Not implemented for this compiler")
+#endif
+
+#if defined(__GNUC__) || defined(__clang__)
+#define PERFETTO_PRINTF_FORMAT(x, y) \
+  __attribute__((__format__(__printf__, x, y)))
+#else
+#define PERFETTO_PRINTF_FORMAT(x, y)
+#endif
+
+#if defined(__GNUC__) || defined(__clang__)
+#define PERFETTO_POPCOUNT(x) __builtin_popcountll(x)
+#else
+#include <intrin.h>
+#define PERFETTO_POPCOUNT(x) __popcnt64(x)
+#endif
+
+#if defined(__clang__)
+#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
+extern "C" void __asan_poison_memory_region(void const volatile*, size_t);
+extern "C" void __asan_unpoison_memory_region(void const volatile*, size_t);
+#define PERFETTO_ASAN_POISON(a, s) __asan_poison_memory_region((a), (s))
+#define PERFETTO_ASAN_UNPOISON(a, s) __asan_unpoison_memory_region((a), (s))
+#else
+#define PERFETTO_ASAN_POISON(addr, size)
+#define PERFETTO_ASAN_UNPOISON(addr, size)
+#endif  // __has_feature(address_sanitizer)
+#else
+#define PERFETTO_ASAN_POISON(addr, size)
+#define PERFETTO_ASAN_UNPOISON(addr, size)
+#endif  // __clang__
+
+#if defined(__GNUC__) || defined(__clang__)
+#define PERFETTO_IS_LITTLE_ENDIAN() __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+#else
+// Assume all MSVC targets are little endian.
+#define PERFETTO_IS_LITTLE_ENDIAN() 1
+#endif
+
+// This is used for exporting xxxMain() symbols (e.g., PerfettoCmdMain,
+// ProbesMain) from libperfetto.so when the GN arg monolithic_binaries = false.
+#if defined(__GNUC__) || defined(__clang__)
+#define PERFETTO_EXPORT_ENTRYPOINT __attribute__((visibility("default")))
+#else
+// TODO(primiano): on Windows this should be a pair of dllexport/dllimport. But
+// that requires a -DXXX_IMPLEMENTATION depending on whether we are on the
+// impl-site or call-site. Right now it's not worth the trouble as we
+// force-export the xxxMain() symbols only on Android, where we pack all the
+// code for N binaries into one .so to save binary size. On Windows we support
+// only monolithic binaries, as they are easier to deal with.
+#define PERFETTO_EXPORT_ENTRYPOINT
+#endif
+
+// Disables thread safety analysis for functions where the compiler can't
+// accurate figure out which locks are being held.
+#if defined(__clang__)
+#define PERFETTO_NO_THREAD_SAFETY_ANALYSIS \
+  __attribute__((no_thread_safety_analysis))
+#else
+#define PERFETTO_NO_THREAD_SAFETY_ANALYSIS
+#endif
+
+// Disables undefined behavior analysis for a function.
+#if defined(__clang__)
+#define PERFETTO_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize("undefined")))
+#else
+#define PERFETTO_NO_SANITIZE_UNDEFINED
+#endif
+
+// Avoid calling the exit-time destructor on an object with static lifetime.
+#if PERFETTO_HAS_ATTRIBUTE(no_destroy)
+#define PERFETTO_HAS_NO_DESTROY() 1
+#define PERFETTO_NO_DESTROY __attribute__((no_destroy))
+#else
+#define PERFETTO_HAS_NO_DESTROY() 0
+#define PERFETTO_NO_DESTROY
+#endif
+
+// Macro for telling -Wimplicit-fallthrough that a fallthrough is intentional.
+#define PERFETTO_FALLTHROUGH [[fallthrough]]
+
+namespace perfetto {
+namespace base {
+
+template <typename... T>
+inline void ignore_result(const T&...) {}
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_BASE_COMPILER_H_
+// gen_amalgamated begin header: include/perfetto/base/export.h
+// gen_amalgamated begin header: include/perfetto/public/abi/export.h
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_PUBLIC_ABI_EXPORT_H_
+#define INCLUDE_PERFETTO_PUBLIC_ABI_EXPORT_H_
+
+#ifdef _WIN32
+#define PERFETTO_INTERNAL_DLL_EXPORT __declspec(dllexport)
+#define PERFETTO_INTERNAL_DLL_IMPORT __declspec(dllimport)
+#else
+#define PERFETTO_INTERNAL_DLL_EXPORT __attribute__((visibility("default")))
+#define PERFETTO_INTERNAL_DLL_IMPORT
+#endif
+
+// PERFETTO_SDK_EXPORT: Exports a symbol from the perfetto SDK shared library.
+//
+// This is controlled by two defines (that likely come from the compiler command
+// line):
+// * PERFETTO_SDK_DISABLE_SHLIB_EXPORT: If this is defined, no export
+//   annotations are added. This might be useful when static linking.
+// * PERFETTO_SDK_SHLIB_IMPLEMENTATION: This must be defined when compiling the
+//   shared library itself (in order to export the symbols), but must be
+//   undefined when compiling objects that use the shared library (in order to
+//   import the symbols).
+#if !defined(PERFETTO_SDK_DISABLE_SHLIB_EXPORT)
+#if defined(PERFETTO_SHLIB_SDK_IMPLEMENTATION)
+#define PERFETTO_SDK_EXPORT PERFETTO_INTERNAL_DLL_EXPORT
+#else
+#define PERFETTO_SDK_EXPORT PERFETTO_INTERNAL_DLL_IMPORT
+#endif
+#else  // defined(PERFETTO_SDK_DISABLE_SHLIB_EXPORT)
+#define PERFETTO_SDK_EXPORT
+#endif  // defined(PERFETTO_SDK_DISABLE_SHLIB_EXPORT)
+
+#endif  // INCLUDE_PERFETTO_PUBLIC_ABI_EXPORT_H_
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_BASE_EXPORT_H_
+#define INCLUDE_PERFETTO_BASE_EXPORT_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/public/abi/export.h"
+
+// PERFETTO_EXPORT_COMPONENT: Exports a symbol among C++ components when
+// building with is_component = true (mostly used by chromium build).
+#if PERFETTO_BUILDFLAG(PERFETTO_COMPONENT_BUILD)
+
+#if defined(PERFETTO_IMPLEMENTATION)
+#define PERFETTO_EXPORT_COMPONENT PERFETTO_INTERNAL_DLL_EXPORT
+#else
+#define PERFETTO_EXPORT_COMPONENT PERFETTO_INTERNAL_DLL_IMPORT
+#endif
+
+#else  // !PERFETTO_BUILDFLAG(PERFETTO_COMPONENT_BUILD)
+
+#if !defined(PERFETTO_EXPORT_COMPONENT)
+#define PERFETTO_EXPORT_COMPONENT
+#endif  // !defined(PERFETTO_EXPORT_COMPONENT)
+
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_COMPONENT_BUILD)
+
+#endif  // INCLUDE_PERFETTO_BASE_EXPORT_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_BASE_LOGGING_H_
+#define INCLUDE_PERFETTO_BASE_LOGGING_H_
+
+#include <errno.h>
+#include <string.h>  // For strerror.
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+#if defined(__GNUC__) || defined(__clang__)
+// Ignore GCC warning about a missing argument for a variadic macro parameter.
+#pragma GCC system_header
+#endif
+
+#if PERFETTO_BUILDFLAG(PERFETTO_FORCE_DCHECK_ON)
+#define PERFETTO_DCHECK_IS_ON() 1
+#elif PERFETTO_BUILDFLAG(PERFETTO_FORCE_DCHECK_OFF)
+#define PERFETTO_DCHECK_IS_ON() 0
+#elif defined(DCHECK_ALWAYS_ON) ||                                         \
+    (!defined(NDEBUG) && (PERFETTO_BUILDFLAG(PERFETTO_STANDALONE_BUILD) || \
+                          PERFETTO_BUILDFLAG(PERFETTO_CHROMIUM_BUILD) ||   \
+                          PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)))
+#define PERFETTO_DCHECK_IS_ON() 1
+#else
+#define PERFETTO_DCHECK_IS_ON() 0
+#endif
+
+#if PERFETTO_BUILDFLAG(PERFETTO_FORCE_DLOG_ON)
+#define PERFETTO_DLOG_IS_ON() 1
+#elif PERFETTO_BUILDFLAG(PERFETTO_FORCE_DLOG_OFF)
+#define PERFETTO_DLOG_IS_ON() 0
+#else
+#define PERFETTO_DLOG_IS_ON() PERFETTO_DCHECK_IS_ON()
+#endif
+
+#if defined(PERFETTO_ANDROID_ASYNC_SAFE_LOG)
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    !PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
+#error "Async-safe logging is limited to Android tree builds"
+#endif
+// For binaries which need a very lightweight logging implementation.
+// Note that this header is incompatible with android/log.h.
+#include <async_safe/log.h>
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+// Normal android logging.
+#include <android/log.h>
+#endif
+
+// Enable the "Print the most recent PERFETTO_LOG(s) before crashing" feature
+// on Android in-tree builds and on standalone builds (mainly for testing).
+// This is deliberately no PERFETTO_OS_ANDROID because we don't want this
+// feature when perfetto is embedded in other Android projects (e.g. SDK).
+// TODO(b/203795298): TFLite is using the client library in blaze builds and is
+// targeting API 19. For now disable the feature based on API level.
+#if defined(PERFETTO_ANDROID_ASYNC_SAFE_LOG)
+#define PERFETTO_ENABLE_LOG_RING_BUFFER() 0
+#elif PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
+#define PERFETTO_ENABLE_LOG_RING_BUFFER() 1
+#elif PERFETTO_BUILDFLAG(PERFETTO_STANDALONE_BUILD) && \
+    (!PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) ||       \
+     (defined(__ANDROID_API__) && __ANDROID_API__ >= 21))
+#define PERFETTO_ENABLE_LOG_RING_BUFFER() 1
+#else
+#define PERFETTO_ENABLE_LOG_RING_BUFFER() 0
+#endif
+
+namespace perfetto {
+namespace base {
+
+// Constexpr functions to extract basename(__FILE__), e.g.: ../foo/f.c -> f.c .
+constexpr const char* StrEnd(const char* s) {
+  return *s ? StrEnd(s + 1) : s;
+}
+
+constexpr const char* BasenameRecursive(const char* s,
+                                        const char* begin,
+                                        const char* end) {
+  return (*s == '/' && s < end)
+             ? (s + 1)
+             : ((s > begin) ? BasenameRecursive(s - 1, begin, end) : s);
+}
+
+constexpr const char* Basename(const char* str) {
+  return BasenameRecursive(StrEnd(str), str, StrEnd(str));
+}
+
+enum LogLev { kLogDebug = 0, kLogInfo, kLogImportant, kLogError };
+
+struct LogMessageCallbackArgs {
+  LogLev level;
+  int line;
+  const char* filename;
+  const char* message;
+};
+
+using LogMessageCallback = void (*)(LogMessageCallbackArgs);
+
+// This is not thread safe and must be called before using tracing from other
+// threads.
+PERFETTO_EXPORT_COMPONENT void SetLogMessageCallback(
+    LogMessageCallback callback);
+
+PERFETTO_EXPORT_COMPONENT void LogMessage(LogLev,
+                                          const char* fname,
+                                          int line,
+                                          const char* fmt,
+                                          ...) PERFETTO_PRINTF_FORMAT(4, 5);
+
+// This is defined in debug_crash_stack_trace.cc, but that is only linked in
+// standalone && debug builds, see enable_perfetto_stderr_crash_dump in
+// perfetto.gni.
+PERFETTO_EXPORT_COMPONENT void EnableStacktraceOnCrashForDebug();
+
+#if PERFETTO_ENABLE_LOG_RING_BUFFER()
+// Gets a snapshot of the logs from the internal log ring buffer and:
+// - On Android in-tree builds: Passes that to android_set_abort_message().
+//   That will attach the logs to the crash report.
+// - On standalone builds (all otther OSes) prints that on stderr.
+// This function must called only once, right before inducing a crash (This is
+// because android_set_abort_message() can only be called once).
+PERFETTO_EXPORT_COMPONENT void MaybeSerializeLastLogsForCrashReporting();
+#else
+inline void MaybeSerializeLastLogsForCrashReporting() {}
+#endif
+
+#if defined(PERFETTO_ANDROID_ASYNC_SAFE_LOG)
+#define PERFETTO_XLOG(level, fmt, ...)                                        \
+  do {                                                                        \
+    async_safe_format_log((ANDROID_LOG_DEBUG + level), "perfetto",            \
+                          "%s:%d " fmt, ::perfetto::base::Basename(__FILE__), \
+                          __LINE__, ##__VA_ARGS__);                           \
+  } while (0)
+#elif defined(PERFETTO_DISABLE_LOG)
+#define PERFETTO_XLOG(level, fmt, ...) ::perfetto::base::ignore_result(level, \
+                                fmt, ##__VA_ARGS__)
+#else
+#define PERFETTO_XLOG(level, fmt, ...)                                      \
+  ::perfetto::base::LogMessage(level, ::perfetto::base::Basename(__FILE__), \
+                               __LINE__, fmt, ##__VA_ARGS__)
+#endif
+
+#if defined(_MSC_VER)
+#define PERFETTO_IMMEDIATE_CRASH()                               \
+  do {                                                           \
+    ::perfetto::base::MaybeSerializeLastLogsForCrashReporting(); \
+    __debugbreak();                                              \
+    __assume(0);                                                 \
+  } while (0)
+#else
+#define PERFETTO_IMMEDIATE_CRASH()                               \
+  do {                                                           \
+    ::perfetto::base::MaybeSerializeLastLogsForCrashReporting(); \
+    __builtin_trap();                                            \
+    __builtin_unreachable();                                     \
+  } while (0)
+#endif
+
+#if PERFETTO_BUILDFLAG(PERFETTO_VERBOSE_LOGS)
+#define PERFETTO_LOG(fmt, ...) \
+  PERFETTO_XLOG(::perfetto::base::kLogInfo, fmt, ##__VA_ARGS__)
+#else  // PERFETTO_BUILDFLAG(PERFETTO_VERBOSE_LOGS)
+#define PERFETTO_LOG(...) ::perfetto::base::ignore_result(__VA_ARGS__)
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_VERBOSE_LOGS)
+
+#define PERFETTO_ILOG(fmt, ...) \
+  PERFETTO_XLOG(::perfetto::base::kLogImportant, fmt, ##__VA_ARGS__)
+#define PERFETTO_ELOG(fmt, ...) \
+  PERFETTO_XLOG(::perfetto::base::kLogError, fmt, ##__VA_ARGS__)
+#define PERFETTO_FATAL(fmt, ...)       \
+  do {                                 \
+    PERFETTO_PLOG(fmt, ##__VA_ARGS__); \
+    PERFETTO_IMMEDIATE_CRASH();        \
+  } while (0)
+
+#if defined(__GNUC__) || defined(__clang__)
+#define PERFETTO_PLOG(x, ...) \
+  PERFETTO_ELOG(x " (errno: %d, %s)", ##__VA_ARGS__, errno, strerror(errno))
+#else
+// MSVC expands __VA_ARGS__ in a different order. Give up, not worth it.
+#define PERFETTO_PLOG PERFETTO_ELOG
+#endif
+
+#define PERFETTO_CHECK(x)                            \
+  do {                                               \
+    if (PERFETTO_UNLIKELY(!(x))) {                   \
+      PERFETTO_PLOG("%s", "PERFETTO_CHECK(" #x ")"); \
+      PERFETTO_IMMEDIATE_CRASH();                    \
+    }                                                \
+  } while (0)
+
+#if PERFETTO_DLOG_IS_ON()
+
+#define PERFETTO_DLOG(fmt, ...) \
+  PERFETTO_XLOG(::perfetto::base::kLogDebug, fmt, ##__VA_ARGS__)
+
+#if defined(__GNUC__) || defined(__clang__)
+#define PERFETTO_DPLOG(x, ...) \
+  PERFETTO_DLOG(x " (errno: %d, %s)", ##__VA_ARGS__, errno, strerror(errno))
+#else
+// MSVC expands __VA_ARGS__ in a different order. Give up, not worth it.
+#define PERFETTO_DPLOG PERFETTO_DLOG
+#endif
+
+#else  // PERFETTO_DLOG_IS_ON()
+
+#define PERFETTO_DLOG(...) ::perfetto::base::ignore_result(__VA_ARGS__)
+#define PERFETTO_DPLOG(...) ::perfetto::base::ignore_result(__VA_ARGS__)
+
+#endif  // PERFETTO_DLOG_IS_ON()
+
+#if PERFETTO_DCHECK_IS_ON()
+
+#define PERFETTO_DCHECK(x) PERFETTO_CHECK(x)
+#define PERFETTO_DFATAL(...) PERFETTO_FATAL(__VA_ARGS__)
+#define PERFETTO_DFATAL_OR_ELOG(...) PERFETTO_DFATAL(__VA_ARGS__)
+
+#else  // PERFETTO_DCHECK_IS_ON()
+
+#define PERFETTO_DCHECK(x) \
+  do {                     \
+  } while (false && (x))
+
+#define PERFETTO_DFATAL(...) ::perfetto::base::ignore_result(__VA_ARGS__)
+#define PERFETTO_DFATAL_OR_ELOG(...) PERFETTO_ELOG(__VA_ARGS__)
+
+#endif  // PERFETTO_DCHECK_IS_ON()
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_BASE_LOGGING_H_
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_BASE_TIME_H_
+#define INCLUDE_PERFETTO_BASE_TIME_H_
+
+#include <time.h>
+
+#include <chrono>
+#include <optional>
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+#include <mach/mach_init.h>
+#include <mach/mach_port.h>
+#include <mach/mach_time.h>
+#include <mach/thread_act.h>
+#endif
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WASM)
+#include <emscripten/emscripten.h>
+#endif
+
+#if PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_X86_64)
+#if PERFETTO_BUILDFLAG(PERFETTO_COMPILER_MSVC)
+#include <intrin.h>
+#endif
+#endif
+
+namespace perfetto {
+namespace base {
+
+using TimeSeconds = std::chrono::seconds;
+using TimeMillis = std::chrono::milliseconds;
+using TimeNanos = std::chrono::nanoseconds;
+
+inline TimeNanos FromPosixTimespec(const struct timespec& ts) {
+  return TimeNanos(ts.tv_sec * 1000000000LL + ts.tv_nsec);
+}
+
+void SleepMicroseconds(unsigned interval_us);
+void InitializeTime();
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+TimeNanos GetWallTimeNs();
+TimeNanos GetThreadCPUTimeNs();
+inline TimeNanos GetWallTimeRawNs() {
+  return GetWallTimeNs();
+}
+
+// TODO: Clock that counts time during suspend is not implemented on Windows.
+inline TimeNanos GetBootTimeNs() {
+  return GetWallTimeNs();
+}
+
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+
+inline TimeNanos GetWallTimeNs() {
+  auto init_timebase_info = []() -> mach_timebase_info_data_t {
+    mach_timebase_info_data_t timebase_info;
+    mach_timebase_info(&timebase_info);
+    return timebase_info;
+  };
+
+  static mach_timebase_info_data_t timebase_info = init_timebase_info();
+  uint64_t mach_time = mach_absolute_time();
+
+  // Take the fast path when the conversion is 1:1. The result will for sure fit
+  // into an int_64 because we're going from nanoseconds to microseconds.
+  if (timebase_info.numer == timebase_info.denom) {
+    return TimeNanos(mach_time);
+  }
+
+  // Nanoseconds is mach_time * timebase.numer // timebase.denom. Divide first
+  // to reduce the chance of overflow. Also stash the remainder right now,
+  // a likely byproduct of the division.
+  uint64_t nanoseconds = mach_time / timebase_info.denom;
+  const uint64_t mach_time_remainder = mach_time % timebase_info.denom;
+
+  // Now multiply, keeping an eye out for overflow.
+  PERFETTO_CHECK(!__builtin_umulll_overflow(nanoseconds, timebase_info.numer,
+                                            &nanoseconds));
+
+  // By dividing first we lose precision. Regain it by adding back the
+  // nanoseconds from the remainder, with an eye out for overflow.
+  uint64_t least_significant_nanoseconds =
+      (mach_time_remainder * timebase_info.numer) / timebase_info.denom;
+  PERFETTO_CHECK(!__builtin_uaddll_overflow(
+      nanoseconds, least_significant_nanoseconds, &nanoseconds));
+
+  return TimeNanos(nanoseconds);
+}
+
+inline TimeNanos GetWallTimeRawNs() {
+  return GetWallTimeNs();
+}
+
+// TODO: Clock that counts time during suspend is not implemented on Mac.
+inline TimeNanos GetBootTimeNs() {
+  return GetWallTimeNs();
+}
+
+// Before MacOS 10.12 clock_gettime() was not implemented.
+#if __MAC_OS_X_VERSION_MIN_REQUIRED < 101200
+inline TimeNanos GetThreadCPUTimeNs() {
+  mach_port_t this_thread = mach_thread_self();
+  mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT;
+  thread_basic_info_data_t info{};
+  kern_return_t kr =
+      thread_info(this_thread, THREAD_BASIC_INFO,
+                  reinterpret_cast<thread_info_t>(&info), &count);
+  mach_port_deallocate(mach_task_self(), this_thread);
+
+  if (kr != KERN_SUCCESS) {
+    PERFETTO_DFATAL("Failed to get CPU time.");
+    return TimeNanos(0);
+  }
+  return TimeNanos(info.user_time.seconds * 1000000000LL +
+                   info.user_time.microseconds * 1000LL +
+                   info.system_time.seconds * 1000000000LL +
+                   info.system_time.microseconds * 1000LL);
+}
+#else
+inline TimeNanos GetThreadCPUTimeNs() {
+  struct timespec ts = {};
+  PERFETTO_CHECK(clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts) == 0);
+  return FromPosixTimespec(ts);
+}
+#endif
+
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WASM)
+
+inline TimeNanos GetWallTimeNs() {
+  return TimeNanos(static_cast<uint64_t>(emscripten_get_now()) * 1000000);
+}
+
+inline TimeNanos GetWallTimeRawNs() {
+  return GetWallTimeNs();
+}
+
+inline TimeNanos GetThreadCPUTimeNs() {
+  return TimeNanos(0);
+}
+
+// TODO: Clock that counts time during suspend is not implemented on WASM.
+inline TimeNanos GetBootTimeNs() {
+  return GetWallTimeNs();
+}
+
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
+
+// Tracing time doesn't need to work on NaCl since its going away shortly. We
+// just need to compile on it. The only function NaCl could support is
+// GetWallTimeNs(), but to prevent false hope we leave it unimplemented.
+
+inline TimeNanos GetWallTimeNs() {
+  return TimeNanos(0);
+}
+
+inline TimeNanos GetWallTimeRawNs() {
+  return TimeNanos(0);
+}
+
+inline TimeNanos GetThreadCPUTimeNs() {
+  return TimeNanos(0);
+}
+
+inline TimeNanos GetBootTimeNs() {
+  return TimeNanos(0);
+}
+
+#else  // posix
+
+constexpr clockid_t kWallTimeClockSource = CLOCK_MONOTONIC;
+
+inline TimeNanos GetTimeInternalNs(clockid_t clk_id) {
+  struct timespec ts = {};
+  PERFETTO_CHECK(clock_gettime(clk_id, &ts) == 0);
+  return FromPosixTimespec(ts);
+}
+
+// Return ns from boot. Conversely to GetWallTimeNs, this clock counts also time
+// during suspend (when supported).
+inline TimeNanos GetBootTimeNs() {
+  // Determine if CLOCK_BOOTTIME is available on the first call.
+  static const clockid_t kBootTimeClockSource = [] {
+    struct timespec ts = {};
+    int res = clock_gettime(CLOCK_BOOTTIME, &ts);
+    return res == 0 ? CLOCK_BOOTTIME : kWallTimeClockSource;
+  }();
+  return GetTimeInternalNs(kBootTimeClockSource);
+}
+
+inline TimeNanos GetWallTimeNs() {
+  return GetTimeInternalNs(kWallTimeClockSource);
+}
+
+inline TimeNanos GetWallTimeRawNs() {
+  return GetTimeInternalNs(CLOCK_MONOTONIC_RAW);
+}
+
+inline TimeNanos GetThreadCPUTimeNs() {
+  return GetTimeInternalNs(CLOCK_THREAD_CPUTIME_ID);
+}
+#endif
+
+inline TimeSeconds GetBootTimeS() {
+  return std::chrono::duration_cast<TimeSeconds>(GetBootTimeNs());
+}
+
+inline TimeMillis GetBootTimeMs() {
+  return std::chrono::duration_cast<TimeMillis>(GetBootTimeNs());
+}
+
+inline TimeMillis GetWallTimeMs() {
+  return std::chrono::duration_cast<TimeMillis>(GetWallTimeNs());
+}
+
+inline TimeSeconds GetWallTimeS() {
+  return std::chrono::duration_cast<TimeSeconds>(GetWallTimeNs());
+}
+
+inline struct timespec ToPosixTimespec(TimeMillis time) {
+  struct timespec ts {};
+  const long time_s = static_cast<long>(time.count() / 1000);
+  ts.tv_sec = time_s;
+  ts.tv_nsec = (static_cast<long>(time.count()) - time_s * 1000L) * 1000000L;
+  return ts;
+}
+
+std::string GetTimeFmt(const std::string& fmt);
+
+inline int64_t TimeGm(struct tm* tms) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  return static_cast<int64_t>(_mkgmtime(tms));
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
+  // NaCL has no timegm.
+  if (tms)  // Kinda if (true), but avoids "mark as noreturn" errors.
+    PERFETTO_FATAL("timegm not supported");
+  return -1;
+#else
+  return static_cast<int64_t>(timegm(tms));
+#endif
+}
+
+// Creates a time_t-compatible timestamp (seconds since epoch) from a tuple of
+// y-m-d-h-m-s. It's a saner version of timegm(). Some remarks:
+// The year is just the actual year (it's Y-1900 in timegm()).
+// The month ranges 1-12 (it's 0-11 in timegm()).
+inline int64_t MkTime(int year, int month, int day, int h, int m, int s) {
+  PERFETTO_DCHECK(year >= 1900);
+  PERFETTO_DCHECK(month > 0 && month <= 12);
+  PERFETTO_DCHECK(day > 0 && day <= 31);
+  struct tm tms {};
+  tms.tm_year = year - 1900;
+  tms.tm_mon = month - 1;
+  tms.tm_mday = day;
+  tms.tm_hour = h;
+  tms.tm_min = m;
+  tms.tm_sec = s;
+  return TimeGm(&tms);
+}
+
+#if PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_X86_64)
+inline uint64_t Rdtsc() {
+#if PERFETTO_BUILDFLAG(PERFETTO_COMPILER_MSVC)
+  return static_cast<uint64_t>(__rdtsc());
+#else
+  // Use inline asm for clang and gcc: rust ffi bindgen crashes in using
+  // intrinsics on ChromeOS.
+  uint64_t low, high;
+  __asm__ volatile("rdtsc" : "=a"(low), "=d"(high));
+  return (high << 32) | low;
+#endif
+}
+#endif
+
+std::optional<int32_t> GetTimezoneOffsetMins();
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_BASE_TIME_H_
+// gen_amalgamated begin header: include/perfetto/tracing/buffer_exhausted_policy.h
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_BUFFER_EXHAUSTED_POLICY_H_
+#define INCLUDE_PERFETTO_TRACING_BUFFER_EXHAUSTED_POLICY_H_
+
+namespace perfetto {
+
+// Determines how SharedMemoryArbiterImpl::GetNewChunk() behaves when no free
+// chunks are available.
+enum class BufferExhaustedPolicy {
+  // SharedMemoryArbiterImpl::GetNewChunk() will stall if no free SMB chunk is
+  // available and wait for the tracing service to free one. Note that this
+  // requires that messages the arbiter sends to the tracing service (from any
+  // TraceWriter thread) will be received by it, even if all TraceWriter threads
+  // are stalled.
+  kStall,
+
+  // SharedMemoryArbiterImpl::GetNewChunk() will return an invalid chunk if no
+  // free SMB chunk is available. In this case, the TraceWriter will fall back
+  // to a garbage chunk and drop written data until acquiring a future chunk
+  // succeeds again.
+  kDrop,
+
+  // TODO(eseckler): Switch to kDrop by default and change the Android code to
+  // explicitly request kStall instead.
+  kDefault = kStall
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_BUFFER_EXHAUSTED_POLICY_H_
+// gen_amalgamated begin header: include/perfetto/tracing/console_interceptor.h
+// gen_amalgamated begin header: include/perfetto/tracing/interceptor.h
+// gen_amalgamated begin header: include/perfetto/protozero/field.h
+// gen_amalgamated begin header: include/perfetto/protozero/contiguous_memory_range.h
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_PROTOZERO_CONTIGUOUS_MEMORY_RANGE_H_
+#define INCLUDE_PERFETTO_PROTOZERO_CONTIGUOUS_MEMORY_RANGE_H_
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+
+namespace protozero {
+
+// Keep this struct trivially constructible (no ctors, no default initializers).
+struct ContiguousMemoryRange {
+  uint8_t* begin;
+  uint8_t* end;  // STL style: one byte past the end of the buffer.
+
+  inline bool is_valid() const { return begin != nullptr; }
+  inline void reset() { begin = nullptr; }
+  inline size_t size() const { return static_cast<size_t>(end - begin); }
+};
+
+}  // namespace protozero
+
+#endif  // INCLUDE_PERFETTO_PROTOZERO_CONTIGUOUS_MEMORY_RANGE_H_
+// gen_amalgamated begin header: include/perfetto/protozero/proto_utils.h
+// gen_amalgamated begin header: include/perfetto/public/pb_utils.h
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_PUBLIC_PB_UTILS_H_
+#define INCLUDE_PERFETTO_PUBLIC_PB_UTILS_H_
+
+#include <assert.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/public/compiler.h"
+
+// Type of fields that can be found in a protobuf serialized message.
+enum PerfettoPbWireType {
+  PERFETTO_PB_WIRE_TYPE_VARINT = 0,
+  PERFETTO_PB_WIRE_TYPE_FIXED64 = 1,
+  PERFETTO_PB_WIRE_TYPE_DELIMITED = 2,
+  PERFETTO_PB_WIRE_TYPE_FIXED32 = 5,
+};
+
+// Creates a field tag, which encodes the field type and the field id.
+static inline uint32_t PerfettoPbMakeTag(int32_t field_id,
+                                         enum PerfettoPbWireType wire_type) {
+  return ((PERFETTO_STATIC_CAST(uint32_t, field_id)) << 3) |
+         PERFETTO_STATIC_CAST(uint32_t, wire_type);
+}
+
+enum {
+  // Maximum bytes size of a 64-bit integer encoded as a VarInt.
+  PERFETTO_PB_VARINT_MAX_SIZE_64 = 10,
+  // Maximum bytes size of a 32-bit integer encoded as a VarInt.
+  PERFETTO_PB_VARINT_MAX_SIZE_32 = 5,
+};
+
+// Encodes `value` as a VarInt into `*dst`.
+//
+// `dst` must point into a buffer big enough to represent `value`:
+// PERFETTO_PB_VARINT_MAX_SIZE_* can help.
+static inline uint8_t* PerfettoPbWriteVarInt(uint64_t value, uint8_t* dst) {
+  uint8_t byte;
+  while (value >= 0x80) {
+    byte = (value & 0x7f) | 0x80;
+    *dst++ = byte;
+    value >>= 7;
+  }
+  byte = value & 0x7f;
+  *dst++ = byte;
+
+  return dst;
+}
+
+// Encodes `value` as a fixed32 (little endian) into `*dst`.
+//
+// `dst` must point into a buffer with at least 4 bytes of space.
+static inline uint8_t* PerfettoPbWriteFixed32(uint32_t value, uint8_t* buf) {
+  buf[0] = PERFETTO_STATIC_CAST(uint8_t, value);
+  buf[1] = PERFETTO_STATIC_CAST(uint8_t, value >> 8);
+  buf[2] = PERFETTO_STATIC_CAST(uint8_t, value >> 16);
+  buf[3] = PERFETTO_STATIC_CAST(uint8_t, value >> 24);
+  return buf + 4;
+}
+
+// Encodes `value` as a fixed32 (little endian) into `*dst`.
+//
+// `dst` must point into a buffer with at least 8 bytes of space.
+static inline uint8_t* PerfettoPbWriteFixed64(uint64_t value, uint8_t* buf) {
+  buf[0] = PERFETTO_STATIC_CAST(uint8_t, value);
+  buf[1] = PERFETTO_STATIC_CAST(uint8_t, value >> 8);
+  buf[2] = PERFETTO_STATIC_CAST(uint8_t, value >> 16);
+  buf[3] = PERFETTO_STATIC_CAST(uint8_t, value >> 24);
+  buf[4] = PERFETTO_STATIC_CAST(uint8_t, value >> 32);
+  buf[5] = PERFETTO_STATIC_CAST(uint8_t, value >> 40);
+  buf[6] = PERFETTO_STATIC_CAST(uint8_t, value >> 48);
+  buf[7] = PERFETTO_STATIC_CAST(uint8_t, value >> 56);
+  return buf + 8;
+}
+
+// Parses a VarInt from the encoded buffer [start, end). |end| is STL-style and
+// points one byte past the end of buffer.
+// The parsed int value is stored in the output arg |value|. Returns a pointer
+// to the next unconsumed byte (so start < retval <= end) or |start| if the
+// VarInt could not be fully parsed because there was not enough space in the
+// buffer.
+static inline const uint8_t* PerfettoPbParseVarInt(const uint8_t* start,
+                                                   const uint8_t* end,
+                                                   uint64_t* out_value) {
+  const uint8_t* pos = start;
+  uint64_t value = 0;
+  for (uint32_t shift = 0; pos < end && shift < 64u; shift += 7) {
+    // Cache *pos into |cur_byte| to prevent that the compiler dereferences the
+    // pointer twice (here and in the if() below) due to char* aliasing rules.
+    uint8_t cur_byte = *pos++;
+    value |= PERFETTO_STATIC_CAST(uint64_t, cur_byte & 0x7f) << shift;
+    if ((cur_byte & 0x80) == 0) {
+      // In valid cases we get here.
+      *out_value = value;
+      return pos;
+    }
+  }
+  *out_value = 0;
+  return start;
+}
+
+static inline uint32_t PerfettoPbZigZagEncode32(int32_t value) {
+#if defined(__cplusplus) || \
+    (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L)
+  // Right-shift of negative values is implementation specific.
+  // Assert the implementation does what we expect, which is that shifting an
+  // positive int32_t by 31 gives an all 0 bitmap, and a negative int32_t gives
+  // an all 1 bitmap.
+  static_assert(
+      PERFETTO_STATIC_CAST(uint32_t, INT32_C(-1) >> 31) == ~UINT32_C(0),
+      "implementation does not support assumed rightshift");
+  static_assert(PERFETTO_STATIC_CAST(uint32_t, INT32_C(1) >> 31) == UINT32_C(0),
+                "implementation does not support assumed rightshift");
+#endif
+
+  return (PERFETTO_STATIC_CAST(uint32_t, value) << 1) ^
+         PERFETTO_STATIC_CAST(uint32_t, value >> 31);
+}
+
+static inline uint64_t PerfettoPbZigZagEncode64(int64_t value) {
+#if defined(__cplusplus) || \
+    (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L)
+  // Right-shift of negative values is implementation specific.
+  // Assert the implementation does what we expect, which is that shifting an
+  // positive int64_t by 63 gives an all 0 bitmap, and a negative int64_t gives
+  // an all 1 bitmap.
+  static_assert(
+      PERFETTO_STATIC_CAST(uint64_t, INT64_C(-1) >> 63) == ~UINT64_C(0),
+      "implementation does not support assumed rightshift");
+  static_assert(PERFETTO_STATIC_CAST(uint64_t, INT64_C(1) >> 63) == UINT64_C(0),
+                "implementation does not support assumed rightshift");
+#endif
+
+  return (PERFETTO_STATIC_CAST(uint64_t, value) << 1) ^
+         PERFETTO_STATIC_CAST(uint64_t, value >> 63);
+}
+
+static inline int32_t PerfettoPbZigZagDecode32(uint32_t value) {
+  uint32_t mask =
+      PERFETTO_STATIC_CAST(uint32_t, -PERFETTO_STATIC_CAST(int32_t, value & 1));
+  return PERFETTO_STATIC_CAST(int32_t, ((value >> 1) ^ mask));
+}
+
+static inline int64_t PerfettoPbZigZagDecode64(uint64_t value) {
+  uint64_t mask =
+      PERFETTO_STATIC_CAST(uint64_t, -PERFETTO_STATIC_CAST(int64_t, value & 1));
+  return PERFETTO_STATIC_CAST(int64_t, ((value >> 1) ^ mask));
+}
+
+#endif  // INCLUDE_PERFETTO_PUBLIC_PB_UTILS_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_PROTOZERO_PROTO_UTILS_H_
+#define INCLUDE_PERFETTO_PROTOZERO_PROTO_UTILS_H_
+
+#include <stddef.h>
+
+#include <cinttypes>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/public/pb_utils.h"
+
+// Helper macro for the constexpr functions containing
+// the switch statement: if C++14 is supported, this macro
+// resolves to `constexpr` and just `inline` otherwise.
+#if __cpp_constexpr >= 201304
+#define PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE constexpr
+#else
+#define PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE inline
+#endif
+
+namespace protozero {
+namespace proto_utils {
+
+// See https://developers.google.com/protocol-buffers/docs/encoding wire types.
+// This is a type encoded into the proto that provides just enough info to
+// find the length of the following value.
+enum class ProtoWireType : uint32_t {
+  kVarInt = 0,
+  kFixed64 = 1,
+  kLengthDelimited = 2,
+  kFixed32 = 5,
+};
+
+// This is the type defined in the proto for each field. This information
+// is used to decide the translation strategy when writing the trace.
+enum class ProtoSchemaType {
+  kUnknown = 0,
+  kDouble,
+  kFloat,
+  kInt64,
+  kUint64,
+  kInt32,
+  kFixed64,
+  kFixed32,
+  kBool,
+  kString,
+  kGroup,  // Deprecated (proto2 only)
+  kMessage,
+  kBytes,
+  kUint32,
+  kEnum,
+  kSfixed32,
+  kSfixed64,
+  kSint32,
+  kSint64,
+};
+
+inline const char* ProtoSchemaToString(ProtoSchemaType v) {
+  switch (v) {
+    case ProtoSchemaType::kUnknown:
+      return "unknown";
+    case ProtoSchemaType::kDouble:
+      return "double";
+    case ProtoSchemaType::kFloat:
+      return "float";
+    case ProtoSchemaType::kInt64:
+      return "int64";
+    case ProtoSchemaType::kUint64:
+      return "uint64";
+    case ProtoSchemaType::kInt32:
+      return "int32";
+    case ProtoSchemaType::kFixed64:
+      return "fixed64";
+    case ProtoSchemaType::kFixed32:
+      return "fixed32";
+    case ProtoSchemaType::kBool:
+      return "bool";
+    case ProtoSchemaType::kString:
+      return "string";
+    case ProtoSchemaType::kGroup:
+      return "group";
+    case ProtoSchemaType::kMessage:
+      return "message";
+    case ProtoSchemaType::kBytes:
+      return "bytes";
+    case ProtoSchemaType::kUint32:
+      return "uint32";
+    case ProtoSchemaType::kEnum:
+      return "enum";
+    case ProtoSchemaType::kSfixed32:
+      return "sfixed32";
+    case ProtoSchemaType::kSfixed64:
+      return "sfixed64";
+    case ProtoSchemaType::kSint32:
+      return "sint32";
+    case ProtoSchemaType::kSint64:
+      return "sint64";
+  }
+  // For gcc:
+  PERFETTO_DCHECK(false);
+  return "";
+}
+
+// Maximum message size supported: 256 MiB (4 x 7-bit due to varint encoding).
+constexpr size_t kMessageLengthFieldSize = 4;
+constexpr size_t kMaxMessageLength = (1u << (kMessageLengthFieldSize * 7)) - 1;
+constexpr size_t kMaxOneByteMessageLength = (1 << 7) - 1;
+
+// Field tag is encoded as 32-bit varint (5 bytes at most).
+// Largest value of simple (not length-delimited) field is 64-bit varint
+// (10 bytes at most). 15 bytes buffer is enough to store a simple field.
+constexpr size_t kMaxTagEncodedSize = 5;
+constexpr size_t kMaxSimpleFieldEncodedSize = kMaxTagEncodedSize + 10;
+
+// Proto types: (int|uint|sint)(32|64), bool, enum.
+constexpr uint32_t MakeTagVarInt(uint32_t field_id) {
+  return (field_id << 3) | static_cast<uint32_t>(ProtoWireType::kVarInt);
+}
+
+// Proto types: fixed64, sfixed64, fixed32, sfixed32, double, float.
+template <typename T>
+constexpr uint32_t MakeTagFixed(uint32_t field_id) {
+  static_assert(sizeof(T) == 8 || sizeof(T) == 4, "Value must be 4 or 8 bytes");
+  return (field_id << 3) |
+         static_cast<uint32_t>((sizeof(T) == 8 ? ProtoWireType::kFixed64
+                                               : ProtoWireType::kFixed32));
+}
+
+// Proto types: string, bytes, embedded messages.
+constexpr uint32_t MakeTagLengthDelimited(uint32_t field_id) {
+  return (field_id << 3) |
+         static_cast<uint32_t>(ProtoWireType::kLengthDelimited);
+}
+
+// Proto types: sint64, sint32.
+template <typename T>
+inline typename std::make_unsigned<T>::type ZigZagEncode(T value) {
+  using UnsignedType = typename std::make_unsigned<T>::type;
+
+  // Right-shift of negative values is implementation specific.
+  // Assert the implementation does what we expect, which is that shifting any
+  // positive value by sizeof(T) * 8 - 1 gives an all 0 bitmap, and a negative
+  // value gives an all 1 bitmap.
+  constexpr uint64_t kUnsignedZero = 0u;
+  constexpr int64_t kNegativeOne = -1;
+  constexpr int64_t kPositiveOne = 1;
+  static_assert(static_cast<uint64_t>(kNegativeOne >> 63) == ~kUnsignedZero,
+                "implementation does not support assumed rightshift");
+  static_assert(static_cast<uint64_t>(kPositiveOne >> 63) == kUnsignedZero,
+                "implementation does not support assumed rightshift");
+
+  return (static_cast<UnsignedType>(value) << 1) ^
+         static_cast<UnsignedType>(value >> (sizeof(T) * 8 - 1));
+}
+
+// Proto types: sint64, sint32.
+template <typename T>
+inline typename std::make_signed<T>::type ZigZagDecode(T value) {
+  using UnsignedType = typename std::make_unsigned<T>::type;
+  using SignedType = typename std::make_signed<T>::type;
+  auto u_value = static_cast<UnsignedType>(value);
+  auto mask = static_cast<UnsignedType>(-static_cast<SignedType>(u_value & 1));
+  return static_cast<SignedType>((u_value >> 1) ^ mask);
+}
+
+template <typename T>
+auto ExtendValueForVarIntSerialization(T value) -> typename std::make_unsigned<
+    typename std::conditional<std::is_unsigned<T>::value, T, int64_t>::type>::
+    type {
+  // If value is <= 0 we must first sign extend to int64_t (see [1]).
+  // Finally we always cast to an unsigned value to to avoid arithmetic
+  // (sign expanding) shifts in the while loop.
+  // [1]: "If you use int32 or int64 as the type for a negative number, the
+  // resulting varint is always ten bytes long".
+  // - developers.google.com/protocol-buffers/docs/encoding
+  // So for each input type we do the following casts:
+  // uintX_t -> uintX_t -> uintX_t
+  // int8_t  -> int64_t -> uint64_t
+  // int16_t -> int64_t -> uint64_t
+  // int32_t -> int64_t -> uint64_t
+  // int64_t -> int64_t -> uint64_t
+  using MaybeExtendedType =
+      typename std::conditional<std::is_unsigned<T>::value, T, int64_t>::type;
+  using UnsignedType = typename std::make_unsigned<MaybeExtendedType>::type;
+
+  MaybeExtendedType extended_value = static_cast<MaybeExtendedType>(value);
+  UnsignedType unsigned_value = static_cast<UnsignedType>(extended_value);
+
+  return unsigned_value;
+}
+
+template <typename T>
+inline uint8_t* WriteVarInt(T value, uint8_t* target) {
+  auto unsigned_value = ExtendValueForVarIntSerialization(value);
+
+  while (unsigned_value >= 0x80) {
+    *target++ = static_cast<uint8_t>(unsigned_value) | 0x80;
+    unsigned_value >>= 7;
+  }
+  *target = static_cast<uint8_t>(unsigned_value);
+  return target + 1;
+}
+
+// Writes a fixed-size redundant encoding of the given |value|. This is
+// used to backfill fixed-size reservations for the length field using a
+// non-canonical varint encoding (e.g. \x81\x80\x80\x00 instead of \x01).
+// See https://github.com/google/protobuf/issues/1530.
+// This is used mainly in two cases:
+// 1) At trace writing time, when starting a nested messages. The size of a
+//    nested message is not known until all its field have been written.
+//    |kMessageLengthFieldSize| bytes are reserved to encode the size field and
+//    backfilled at the end.
+// 2) When rewriting a message at trace filtering time, in protozero/filtering.
+//    At that point we know only the upper bound of the length (a filtered
+//    message is <= the original one) and we backfill after the message has been
+//    filtered.
+inline void WriteRedundantVarInt(uint32_t value,
+                                 uint8_t* buf,
+                                 size_t size = kMessageLengthFieldSize) {
+  for (size_t i = 0; i < size; ++i) {
+    const uint8_t msb = (i < size - 1) ? 0x80 : 0;
+    buf[i] = static_cast<uint8_t>(value) | msb;
+    value >>= 7;
+  }
+}
+
+template <uint32_t field_id>
+void StaticAssertSingleBytePreamble() {
+  static_assert(field_id < 16,
+                "Proto field id too big to fit in a single byte preamble");
+}
+
+// Parses a VarInt from the encoded buffer [start, end). |end| is STL-style and
+// points one byte past the end of buffer.
+// The parsed int value is stored in the output arg |value|. Returns a pointer
+// to the next unconsumed byte (so start < retval <= end) or |start| if the
+// VarInt could not be fully parsed because there was not enough space in the
+// buffer.
+inline const uint8_t* ParseVarInt(const uint8_t* start,
+                                  const uint8_t* end,
+                                  uint64_t* out_value) {
+  return PerfettoPbParseVarInt(start, end, out_value);
+}
+
+enum class RepetitionType {
+  kNotRepeated,
+  kRepeatedPacked,
+  kRepeatedNotPacked,
+};
+
+// Provide a common base struct for all templated FieldMetadata types to allow
+// simple checks if a given type is a FieldMetadata or not.
+struct FieldMetadataBase {
+  constexpr FieldMetadataBase() = default;
+};
+
+template <uint32_t field_id,
+          RepetitionType repetition_type,
+          ProtoSchemaType proto_schema_type,
+          typename CppFieldType,
+          typename MessageType>
+struct FieldMetadata : public FieldMetadataBase {
+  constexpr FieldMetadata() = default;
+
+  static constexpr int kFieldId = field_id;
+  // Whether this field is repeated, packed (repeated [packed-true]) or not
+  // (optional).
+  static constexpr RepetitionType kRepetitionType = repetition_type;
+  // Proto type of this field (e.g. int64, fixed32 or nested message).
+  static constexpr ProtoSchemaType kProtoFieldType = proto_schema_type;
+  // C++ type of this field (for nested messages - C++ protozero class).
+  using cpp_field_type = CppFieldType;
+  // Protozero message which this field belongs to.
+  using message_type = MessageType;
+};
+
+}  // namespace proto_utils
+}  // namespace protozero
+
+#endif  // INCLUDE_PERFETTO_PROTOZERO_PROTO_UTILS_H_
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_PROTOZERO_FIELD_H_
+#define INCLUDE_PERFETTO_PROTOZERO_FIELD_H_
+
+#include <stdint.h>
+
+#include <string>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/contiguous_memory_range.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace protozero {
+
+struct ConstBytes {
+  std::string ToStdString() const {
+    return std::string(reinterpret_cast<const char*>(data), size);
+  }
+
+  const uint8_t* data;
+  size_t size;
+};
+
+struct ConstChars {
+  // Allow implicit conversion to perfetto's base::StringView without depending
+  // on perfetto/base or viceversa.
+  static constexpr bool kConvertibleToStringView = true;
+  std::string ToStdString() const { return std::string(data, size); }
+
+  const char* data;
+  size_t size;
+};
+
+// A protobuf field decoded by the protozero proto decoders. It exposes
+// convenience accessors with minimal debug checks.
+// This class is used both by the iterator-based ProtoDecoder and by the
+// one-shot TypedProtoDecoder.
+// If the field is not valid the accessors consistently return zero-integers or
+// null strings.
+class Field {
+ public:
+  bool valid() const { return id_ != 0; }
+  uint32_t id() const { return id_; }
+  explicit operator bool() const { return valid(); }
+
+  proto_utils::ProtoWireType type() const {
+    auto res = static_cast<proto_utils::ProtoWireType>(type_);
+    PERFETTO_DCHECK(res == proto_utils::ProtoWireType::kVarInt ||
+                    res == proto_utils::ProtoWireType::kLengthDelimited ||
+                    res == proto_utils::ProtoWireType::kFixed32 ||
+                    res == proto_utils::ProtoWireType::kFixed64);
+    return res;
+  }
+
+  bool as_bool() const {
+    PERFETTO_DCHECK(!valid() || type() == proto_utils::ProtoWireType::kVarInt);
+    return static_cast<bool>(int_value_);
+  }
+
+  uint32_t as_uint32() const {
+    PERFETTO_DCHECK(!valid() || type() == proto_utils::ProtoWireType::kVarInt ||
+                    type() == proto_utils::ProtoWireType::kFixed32);
+    return static_cast<uint32_t>(int_value_);
+  }
+
+  int32_t as_int32() const {
+    PERFETTO_DCHECK(!valid() || type() == proto_utils::ProtoWireType::kVarInt ||
+                    type() == proto_utils::ProtoWireType::kFixed32);
+    return static_cast<int32_t>(int_value_);
+  }
+
+  int32_t as_sint32() const {
+    PERFETTO_DCHECK(!valid() || type() == proto_utils::ProtoWireType::kVarInt);
+    return proto_utils::ZigZagDecode(static_cast<uint32_t>(int_value_));
+  }
+
+  uint64_t as_uint64() const {
+    PERFETTO_DCHECK(!valid() || type() == proto_utils::ProtoWireType::kVarInt ||
+                    type() == proto_utils::ProtoWireType::kFixed32 ||
+                    type() == proto_utils::ProtoWireType::kFixed64);
+    return int_value_;
+  }
+
+  int64_t as_int64() const {
+    PERFETTO_DCHECK(!valid() || type() == proto_utils::ProtoWireType::kVarInt ||
+                    type() == proto_utils::ProtoWireType::kFixed32 ||
+                    type() == proto_utils::ProtoWireType::kFixed64);
+    return static_cast<int64_t>(int_value_);
+  }
+
+  int64_t as_sint64() const {
+    PERFETTO_DCHECK(!valid() || type() == proto_utils::ProtoWireType::kVarInt);
+    return proto_utils::ZigZagDecode(static_cast<uint64_t>(int_value_));
+  }
+
+  float as_float() const {
+    PERFETTO_DCHECK(!valid() || type() == proto_utils::ProtoWireType::kFixed32);
+    float res;
+    uint32_t value32 = static_cast<uint32_t>(int_value_);
+    memcpy(&res, &value32, sizeof(res));
+    return res;
+  }
+
+  double as_double() const {
+    PERFETTO_DCHECK(!valid() || type() == proto_utils::ProtoWireType::kFixed64);
+    double res;
+    memcpy(&res, &int_value_, sizeof(res));
+    return res;
+  }
+
+  ConstChars as_string() const {
+    PERFETTO_DCHECK(!valid() ||
+                    type() == proto_utils::ProtoWireType::kLengthDelimited);
+    return ConstChars{reinterpret_cast<const char*>(data()), size_};
+  }
+
+  std::string as_std_string() const { return as_string().ToStdString(); }
+
+  ConstBytes as_bytes() const {
+    PERFETTO_DCHECK(!valid() ||
+                    type() == proto_utils::ProtoWireType::kLengthDelimited);
+    return ConstBytes{data(), size_};
+  }
+
+  const uint8_t* data() const {
+    PERFETTO_DCHECK(!valid() ||
+                    type() == proto_utils::ProtoWireType::kLengthDelimited);
+    return reinterpret_cast<const uint8_t*>(int_value_);
+  }
+
+  size_t size() const {
+    PERFETTO_DCHECK(!valid() ||
+                    type() == proto_utils::ProtoWireType::kLengthDelimited);
+    return size_;
+  }
+
+  uint64_t raw_int_value() const { return int_value_; }
+
+  void initialize(uint32_t id,
+                  uint8_t type,
+                  uint64_t int_value,
+                  uint32_t size) {
+    id_ = id & kMaxId;
+    type_ = type;
+    int_value_ = int_value;
+    size_ = size;
+  }
+
+  // For use with templates. This is used by RepeatedFieldIterator::operator*().
+  void get(bool* val) const { *val = as_bool(); }
+  void get(uint32_t* val) const { *val = as_uint32(); }
+  void get(int32_t* val) const { *val = as_int32(); }
+  void get(uint64_t* val) const { *val = as_uint64(); }
+  void get(int64_t* val) const { *val = as_int64(); }
+  void get(float* val) const { *val = as_float(); }
+  void get(double* val) const { *val = as_double(); }
+  void get(std::string* val) const { *val = as_std_string(); }
+  void get(ConstChars* val) const { *val = as_string(); }
+  void get(ConstBytes* val) const { *val = as_bytes(); }
+  void get_signed(int32_t* val) const { *val = as_sint32(); }
+  void get_signed(int64_t* val) const { *val = as_sint64(); }
+
+  // For enum types.
+  template <typename T,
+            typename = typename std::enable_if<std::is_enum<T>::value, T>::type>
+  void get(T* val) const {
+    *val = static_cast<T>(as_int32());
+  }
+
+  // Serializes the field back into a proto-encoded byte stream and appends it
+  // to |dst|. |dst| is resized accordingly.
+  void SerializeAndAppendTo(std::string* dst) const;
+
+  // Serializes the field back into a proto-encoded byte stream and appends it
+  // to |dst|. |dst| is resized accordingly.
+  void SerializeAndAppendTo(std::vector<uint8_t>* dst) const;
+
+  static constexpr uint32_t kMaxId = (1 << 24) - 1;  // See id_ : 24 below.
+ private:
+  template <typename Container>
+  void SerializeAndAppendToInternal(Container* dst) const;
+
+  // Fields are deliberately not initialized to keep the class trivially
+  // constructible. It makes a large perf difference for ProtoDecoder.
+  uint64_t int_value_;  // In kLengthDelimited this contains the data() addr.
+  uint32_t size_;       // Only valid when when type == kLengthDelimited.
+
+  // Note: MSVC and clang-cl require bit-fields to be of the same type, hence
+  // the `: 8` below rather than uint8_t.
+  uint32_t id_ : 24;   // Proto field ordinal.
+  uint32_t type_ : 8;  // proto_utils::ProtoWireType.
+};
+// The Field struct is used in a lot of perf-sensitive contexts.
+static_assert(sizeof(Field) == 16, "Field struct too big");
+
+}  // namespace protozero
+
+#endif  // INCLUDE_PERFETTO_PROTOZERO_FIELD_H_
+// gen_amalgamated begin header: include/perfetto/tracing/core/forward_decls.h
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_CORE_FORWARD_DECLS_H_
+#define INCLUDE_PERFETTO_TRACING_CORE_FORWARD_DECLS_H_
+
+// Forward declares classes that are generated at build-time from protos.
+// First of all, why are we forward declaring at all?
+//  1. Chromium diverges from the Google style guide on this, because forward
+//     declarations typically make build times faster, and that's a desirable
+//     property for a large and complex codebase.
+//  2. Adding #include to build-time-generated headers from headers typically
+//     creates subtle build errors that are hard to spot in GN. This is because
+//     once a standard header (say foo.h) has an #include "protos/foo.gen.h",
+//     the build target that depends on foo.h needs to depend on the genrule
+//     that generates foo.gen.h. This is achievable using public_deps in GN but
+//     is not testable / enforceable, hence too easy to get wrong.
+
+// Historically the classes below used to be generated from the corresponding
+// .proto(s) at CL *check-in* time (!= build time) in the ::perfetto namespace.
+// Nowadays we have code everywhere that assume the right class is
+// ::perfetto::TraceConfig or the like. Back then other headers could just
+// forward declared ::perfetto::TraceConfig. These days, the real class is
+// ::perfetto::protos::gen::TraceConfig and core/trace_config.h aliases that as
+// using ::perfetto::TraceConfig = ::perfetto::protos::gen::TraceConfig.
+// In C++ one cannot forward declare a type alias (but only the aliased type).
+// Hence this header, which should be used every time one wants to forward
+// declare classes like TraceConfig.
+
+// The overall plan is that, when one of the classes below is needed:
+// The .h file includes this file.
+// The .cc file includes perfetto/tracing/core/trace_config.h (or equiv). That
+// header will pull the full declaration from trace_config.gen.h and will also
+// setup the alias in the ::perfetto namespace.
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class ChromeConfig;
+class CommitDataRequest;
+class DataSourceConfig;
+class DataSourceDescriptor;
+class ObservableEvents;
+class TraceConfig;
+class TraceStats;
+class TracingServiceCapabilities;
+class TracingServiceState;
+class SyncClockRequest;
+class SyncClockResponse;
+
+}  // namespace gen
+}  // namespace protos
+
+using ChromeConfig = ::perfetto::protos::gen::ChromeConfig;
+using CommitDataRequest = ::perfetto::protos::gen::CommitDataRequest;
+using DataSourceConfig = ::perfetto::protos::gen::DataSourceConfig;
+using DataSourceDescriptor = ::perfetto::protos::gen::DataSourceDescriptor;
+using ObservableEvents = ::perfetto::protos::gen::ObservableEvents;
+using TraceConfig = ::perfetto::protos::gen::TraceConfig;
+using TraceStats = ::perfetto::protos::gen::TraceStats;
+using TracingServiceCapabilities =
+    ::perfetto::protos::gen::TracingServiceCapabilities;
+using TracingServiceState = ::perfetto::protos::gen::TracingServiceState;
+using SyncClockRequest = ::perfetto::protos::gen::SyncClockRequest;
+using SyncClockResponse = ::perfetto::protos::gen::SyncClockResponse;
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_CORE_FORWARD_DECLS_H_
+// gen_amalgamated begin header: include/perfetto/tracing/internal/basic_types.h
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_BASIC_TYPES_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_BASIC_TYPES_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace perfetto {
+namespace internal {
+
+// A static_assert in tracing_muxer_impl.cc guarantees that this stays in sync
+// with the definition in tracing/core/basic_types.h
+using BufferId = uint16_t;
+
+// This is an id of a backend in the TracingMuxer::producer_backends_ list.
+// Backends are only added and never removed.
+using TracingBackendId = size_t;
+
+// Max numbers of data sources that can be registered in a process.
+constexpr size_t kMaxDataSources = 32;
+
+// Max instances for each data source type. This typically matches the
+// "max number of concurrent tracing sessions". However remember that a data
+// source can be instantiated more than once within one tracing session by
+// creating two entries for it in the trace config.
+constexpr size_t kMaxDataSourceInstances = 8;
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_BASIC_TYPES_H_
+// gen_amalgamated begin header: include/perfetto/tracing/internal/data_source_internal.h
+// gen_amalgamated begin header: include/perfetto/tracing/core/data_source_config.h
+// gen_amalgamated begin header: gen/protos/perfetto/config/data_source_config.gen.h
+// gen_amalgamated begin header: include/perfetto/protozero/cpp_message_obj.h
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_PROTOZERO_CPP_MESSAGE_OBJ_H_
+#define INCLUDE_PERFETTO_PROTOZERO_CPP_MESSAGE_OBJ_H_
+
+#include <stdint.h>
+
+#include <string>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace protozero {
+
+// Base class for generated .gen.h classes, which are full C++ objects that
+// support both ser and deserialization (but are not zero-copy).
+// This is only used by the "cpp" targets not the "pbzero" ones.
+class PERFETTO_EXPORT_COMPONENT CppMessageObj {
+ public:
+  virtual ~CppMessageObj();
+  virtual std::string SerializeAsString() const = 0;
+  virtual std::vector<uint8_t> SerializeAsArray() const = 0;
+  virtual bool ParseFromArray(const void*, size_t) = 0;
+
+  bool ParseFromString(const std::string& str) {
+    return ParseFromArray(str.data(), str.size());
+  }
+};
+
+}  // namespace protozero
+
+#endif  // INCLUDE_PERFETTO_PROTOZERO_CPP_MESSAGE_OBJ_H_
+// gen_amalgamated begin header: include/perfetto/protozero/copyable_ptr.h
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_PROTOZERO_COPYABLE_PTR_H_
+#define INCLUDE_PERFETTO_PROTOZERO_COPYABLE_PTR_H_
+
+#include <memory>
+
+namespace protozero {
+
+// This class is essentially a std::vector<T> of fixed size = 1.
+// It's a pointer wrapper with deep copying and deep equality comparison.
+// At all effects this wrapper behaves like the underlying T, with the exception
+// of the heap indirection.
+// Conversely to a std::unique_ptr, the pointer will be always valid, never
+// null. The problem it solves is the following: when generating C++ classes
+// from proto files, we want to keep each header hermetic (i.e. not #include
+// headers of dependent types). As such we can't directly instantiate T
+// field members but we can instead rely on pointers, so only the .cc file needs
+// to see the actual definition of T. If the generated classes were move-only we
+// could just use a unique_ptr there. But they aren't, hence this wrapper.
+// Converesely to unique_ptr, this wrapper:
+// - Default constructs the T instance in its constructor.
+// - Implements deep comparison in operator== instead of pointer comparison.
+template <typename T>
+class CopyablePtr {
+ public:
+  CopyablePtr() : ptr_(new T()) {}
+  ~CopyablePtr() = default;
+
+  // Copy operators.
+  CopyablePtr(const CopyablePtr& other) : ptr_(new T(*other.ptr_)) {}
+  CopyablePtr& operator=(const CopyablePtr& other) {
+    *ptr_ = *other.ptr_;
+    return *this;
+  }
+
+  // Move operators.
+  CopyablePtr(CopyablePtr&& other) noexcept : ptr_(std::move(other.ptr_)) {
+    other.ptr_.reset(new T());
+  }
+
+  CopyablePtr& operator=(CopyablePtr&& other) {
+    ptr_ = std::move(other.ptr_);
+    other.ptr_.reset(new T());
+    return *this;
+  }
+
+  T* get() { return ptr_.get(); }
+  const T* get() const { return ptr_.get(); }
+
+  T* operator->() { return ptr_.get(); }
+  const T* operator->() const { return ptr_.get(); }
+
+  T& operator*() { return *ptr_; }
+  const T& operator*() const { return *ptr_; }
+
+  friend bool operator==(const CopyablePtr& lhs, const CopyablePtr& rhs) {
+    return *lhs == *rhs;
+  }
+
+  friend bool operator!=(const CopyablePtr& lhs, const CopyablePtr& rhs) {
+    // In theory the underlying type might have a special operator!=
+    // implementation which is not just !(x == y). Respect that.
+    return *lhs != *rhs;
+  }
+
+ private:
+  std::unique_ptr<T> ptr_;
+};
+
+}  // namespace protozero
+
+#endif  // INCLUDE_PERFETTO_PROTOZERO_COPYABLE_PTR_H_
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_DATA_SOURCE_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_DATA_SOURCE_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class DataSourceConfig;
+class TestConfig;
+class TestConfig_DummyFields;
+class InterceptorConfig;
+class ConsoleConfig;
+class ChromeConfig;
+class SystemInfoConfig;
+enum DataSourceConfig_SessionInitiator : int;
+enum ConsoleConfig_Output : int;
+enum ChromeConfig_ClientPriority : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum DataSourceConfig_SessionInitiator : int {
+  DataSourceConfig_SessionInitiator_SESSION_INITIATOR_UNSPECIFIED = 0,
+  DataSourceConfig_SessionInitiator_SESSION_INITIATOR_TRUSTED_SYSTEM = 1,
+};
+
+class PERFETTO_EXPORT_COMPONENT DataSourceConfig : public ::protozero::CppMessageObj {
+ public:
+  using SessionInitiator = DataSourceConfig_SessionInitiator;
+  static constexpr auto SESSION_INITIATOR_UNSPECIFIED = DataSourceConfig_SessionInitiator_SESSION_INITIATOR_UNSPECIFIED;
+  static constexpr auto SESSION_INITIATOR_TRUSTED_SYSTEM = DataSourceConfig_SessionInitiator_SESSION_INITIATOR_TRUSTED_SYSTEM;
+  static constexpr auto SessionInitiator_MIN = DataSourceConfig_SessionInitiator_SESSION_INITIATOR_UNSPECIFIED;
+  static constexpr auto SessionInitiator_MAX = DataSourceConfig_SessionInitiator_SESSION_INITIATOR_TRUSTED_SYSTEM;
+  enum FieldNumbers {
+    kNameFieldNumber = 1,
+    kTargetBufferFieldNumber = 2,
+    kTraceDurationMsFieldNumber = 3,
+    kPreferSuspendClockForDurationFieldNumber = 122,
+    kStopTimeoutMsFieldNumber = 7,
+    kEnableExtraGuardrailsFieldNumber = 6,
+    kSessionInitiatorFieldNumber = 8,
+    kTracingSessionIdFieldNumber = 4,
+    kFtraceConfigFieldNumber = 100,
+    kInodeFileConfigFieldNumber = 102,
+    kProcessStatsConfigFieldNumber = 103,
+    kSysStatsConfigFieldNumber = 104,
+    kHeapprofdConfigFieldNumber = 105,
+    kJavaHprofConfigFieldNumber = 110,
+    kAndroidPowerConfigFieldNumber = 106,
+    kAndroidLogConfigFieldNumber = 107,
+    kGpuCounterConfigFieldNumber = 108,
+    kAndroidGameInterventionListConfigFieldNumber = 116,
+    kPackagesListConfigFieldNumber = 109,
+    kPerfEventConfigFieldNumber = 111,
+    kVulkanMemoryConfigFieldNumber = 112,
+    kTrackEventConfigFieldNumber = 113,
+    kAndroidPolledStateConfigFieldNumber = 114,
+    kAndroidSystemPropertyConfigFieldNumber = 118,
+    kStatsdTracingConfigFieldNumber = 117,
+    kSystemInfoConfigFieldNumber = 119,
+    kChromeConfigFieldNumber = 101,
+    kV8ConfigFieldNumber = 127,
+    kInterceptorConfigFieldNumber = 115,
+    kNetworkPacketTraceConfigFieldNumber = 120,
+    kSurfaceflingerLayersConfigFieldNumber = 121,
+    kSurfaceflingerTransactionsConfigFieldNumber = 123,
+    kAndroidSdkSyspropGuardConfigFieldNumber = 124,
+    kEtwConfigFieldNumber = 125,
+    kProtologConfigFieldNumber = 126,
+    kAndroidInputEventConfigFieldNumber = 128,
+    kPixelModemConfigFieldNumber = 129,
+    kLegacyConfigFieldNumber = 1000,
+    kForTestingFieldNumber = 1001,
+  };
+
+  DataSourceConfig();
+  ~DataSourceConfig() override;
+  DataSourceConfig(DataSourceConfig&&) noexcept;
+  DataSourceConfig& operator=(DataSourceConfig&&);
+  DataSourceConfig(const DataSourceConfig&);
+  DataSourceConfig& operator=(const DataSourceConfig&);
+  bool operator==(const DataSourceConfig&) const;
+  bool operator!=(const DataSourceConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name() const { return _has_field_[1]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
+
+  bool has_target_buffer() const { return _has_field_[2]; }
+  uint32_t target_buffer() const { return target_buffer_; }
+  void set_target_buffer(uint32_t value) { target_buffer_ = value; _has_field_.set(2); }
+
+  bool has_trace_duration_ms() const { return _has_field_[3]; }
+  uint32_t trace_duration_ms() const { return trace_duration_ms_; }
+  void set_trace_duration_ms(uint32_t value) { trace_duration_ms_ = value; _has_field_.set(3); }
+
+  bool has_prefer_suspend_clock_for_duration() const { return _has_field_[122]; }
+  bool prefer_suspend_clock_for_duration() const { return prefer_suspend_clock_for_duration_; }
+  void set_prefer_suspend_clock_for_duration(bool value) { prefer_suspend_clock_for_duration_ = value; _has_field_.set(122); }
+
+  bool has_stop_timeout_ms() const { return _has_field_[7]; }
+  uint32_t stop_timeout_ms() const { return stop_timeout_ms_; }
+  void set_stop_timeout_ms(uint32_t value) { stop_timeout_ms_ = value; _has_field_.set(7); }
+
+  bool has_enable_extra_guardrails() const { return _has_field_[6]; }
+  bool enable_extra_guardrails() const { return enable_extra_guardrails_; }
+  void set_enable_extra_guardrails(bool value) { enable_extra_guardrails_ = value; _has_field_.set(6); }
+
+  bool has_session_initiator() const { return _has_field_[8]; }
+  DataSourceConfig_SessionInitiator session_initiator() const { return session_initiator_; }
+  void set_session_initiator(DataSourceConfig_SessionInitiator value) { session_initiator_ = value; _has_field_.set(8); }
+
+  bool has_tracing_session_id() const { return _has_field_[4]; }
+  uint64_t tracing_session_id() const { return tracing_session_id_; }
+  void set_tracing_session_id(uint64_t value) { tracing_session_id_ = value; _has_field_.set(4); }
+
+  const std::string& ftrace_config_raw() const { return ftrace_config_; }
+  void set_ftrace_config_raw(const std::string& raw) { ftrace_config_ = raw; _has_field_.set(100); }
+
+  const std::string& inode_file_config_raw() const { return inode_file_config_; }
+  void set_inode_file_config_raw(const std::string& raw) { inode_file_config_ = raw; _has_field_.set(102); }
+
+  const std::string& process_stats_config_raw() const { return process_stats_config_; }
+  void set_process_stats_config_raw(const std::string& raw) { process_stats_config_ = raw; _has_field_.set(103); }
+
+  const std::string& sys_stats_config_raw() const { return sys_stats_config_; }
+  void set_sys_stats_config_raw(const std::string& raw) { sys_stats_config_ = raw; _has_field_.set(104); }
+
+  const std::string& heapprofd_config_raw() const { return heapprofd_config_; }
+  void set_heapprofd_config_raw(const std::string& raw) { heapprofd_config_ = raw; _has_field_.set(105); }
+
+  const std::string& java_hprof_config_raw() const { return java_hprof_config_; }
+  void set_java_hprof_config_raw(const std::string& raw) { java_hprof_config_ = raw; _has_field_.set(110); }
+
+  const std::string& android_power_config_raw() const { return android_power_config_; }
+  void set_android_power_config_raw(const std::string& raw) { android_power_config_ = raw; _has_field_.set(106); }
+
+  const std::string& android_log_config_raw() const { return android_log_config_; }
+  void set_android_log_config_raw(const std::string& raw) { android_log_config_ = raw; _has_field_.set(107); }
+
+  const std::string& gpu_counter_config_raw() const { return gpu_counter_config_; }
+  void set_gpu_counter_config_raw(const std::string& raw) { gpu_counter_config_ = raw; _has_field_.set(108); }
+
+  const std::string& android_game_intervention_list_config_raw() const { return android_game_intervention_list_config_; }
+  void set_android_game_intervention_list_config_raw(const std::string& raw) { android_game_intervention_list_config_ = raw; _has_field_.set(116); }
+
+  const std::string& packages_list_config_raw() const { return packages_list_config_; }
+  void set_packages_list_config_raw(const std::string& raw) { packages_list_config_ = raw; _has_field_.set(109); }
+
+  const std::string& perf_event_config_raw() const { return perf_event_config_; }
+  void set_perf_event_config_raw(const std::string& raw) { perf_event_config_ = raw; _has_field_.set(111); }
+
+  const std::string& vulkan_memory_config_raw() const { return vulkan_memory_config_; }
+  void set_vulkan_memory_config_raw(const std::string& raw) { vulkan_memory_config_ = raw; _has_field_.set(112); }
+
+  const std::string& track_event_config_raw() const { return track_event_config_; }
+  void set_track_event_config_raw(const std::string& raw) { track_event_config_ = raw; _has_field_.set(113); }
+
+  const std::string& android_polled_state_config_raw() const { return android_polled_state_config_; }
+  void set_android_polled_state_config_raw(const std::string& raw) { android_polled_state_config_ = raw; _has_field_.set(114); }
+
+  const std::string& android_system_property_config_raw() const { return android_system_property_config_; }
+  void set_android_system_property_config_raw(const std::string& raw) { android_system_property_config_ = raw; _has_field_.set(118); }
+
+  const std::string& statsd_tracing_config_raw() const { return statsd_tracing_config_; }
+  void set_statsd_tracing_config_raw(const std::string& raw) { statsd_tracing_config_ = raw; _has_field_.set(117); }
+
+  bool has_system_info_config() const { return _has_field_[119]; }
+  const SystemInfoConfig& system_info_config() const { return *system_info_config_; }
+  SystemInfoConfig* mutable_system_info_config() { _has_field_.set(119); return system_info_config_.get(); }
+
+  bool has_chrome_config() const { return _has_field_[101]; }
+  const ChromeConfig& chrome_config() const { return *chrome_config_; }
+  ChromeConfig* mutable_chrome_config() { _has_field_.set(101); return chrome_config_.get(); }
+
+  const std::string& v8_config_raw() const { return v8_config_; }
+  void set_v8_config_raw(const std::string& raw) { v8_config_ = raw; _has_field_.set(127); }
+
+  bool has_interceptor_config() const { return _has_field_[115]; }
+  const InterceptorConfig& interceptor_config() const { return *interceptor_config_; }
+  InterceptorConfig* mutable_interceptor_config() { _has_field_.set(115); return interceptor_config_.get(); }
+
+  const std::string& network_packet_trace_config_raw() const { return network_packet_trace_config_; }
+  void set_network_packet_trace_config_raw(const std::string& raw) { network_packet_trace_config_ = raw; _has_field_.set(120); }
+
+  const std::string& surfaceflinger_layers_config_raw() const { return surfaceflinger_layers_config_; }
+  void set_surfaceflinger_layers_config_raw(const std::string& raw) { surfaceflinger_layers_config_ = raw; _has_field_.set(121); }
+
+  const std::string& surfaceflinger_transactions_config_raw() const { return surfaceflinger_transactions_config_; }
+  void set_surfaceflinger_transactions_config_raw(const std::string& raw) { surfaceflinger_transactions_config_ = raw; _has_field_.set(123); }
+
+  const std::string& android_sdk_sysprop_guard_config_raw() const { return android_sdk_sysprop_guard_config_; }
+  void set_android_sdk_sysprop_guard_config_raw(const std::string& raw) { android_sdk_sysprop_guard_config_ = raw; _has_field_.set(124); }
+
+  const std::string& etw_config_raw() const { return etw_config_; }
+  void set_etw_config_raw(const std::string& raw) { etw_config_ = raw; _has_field_.set(125); }
+
+  const std::string& protolog_config_raw() const { return protolog_config_; }
+  void set_protolog_config_raw(const std::string& raw) { protolog_config_ = raw; _has_field_.set(126); }
+
+  const std::string& android_input_event_config_raw() const { return android_input_event_config_; }
+  void set_android_input_event_config_raw(const std::string& raw) { android_input_event_config_ = raw; _has_field_.set(128); }
+
+  const std::string& pixel_modem_config_raw() const { return pixel_modem_config_; }
+  void set_pixel_modem_config_raw(const std::string& raw) { pixel_modem_config_ = raw; _has_field_.set(129); }
+
+  bool has_legacy_config() const { return _has_field_[1000]; }
+  const std::string& legacy_config() const { return legacy_config_; }
+  void set_legacy_config(const std::string& value) { legacy_config_ = value; _has_field_.set(1000); }
+
+  bool has_for_testing() const { return _has_field_[1001]; }
+  const TestConfig& for_testing() const { return *for_testing_; }
+  TestConfig* mutable_for_testing() { _has_field_.set(1001); return for_testing_.get(); }
+
+ private:
+  std::string name_{};
+  uint32_t target_buffer_{};
+  uint32_t trace_duration_ms_{};
+  bool prefer_suspend_clock_for_duration_{};
+  uint32_t stop_timeout_ms_{};
+  bool enable_extra_guardrails_{};
+  DataSourceConfig_SessionInitiator session_initiator_{};
+  uint64_t tracing_session_id_{};
+  std::string ftrace_config_;  // [lazy=true]
+  std::string inode_file_config_;  // [lazy=true]
+  std::string process_stats_config_;  // [lazy=true]
+  std::string sys_stats_config_;  // [lazy=true]
+  std::string heapprofd_config_;  // [lazy=true]
+  std::string java_hprof_config_;  // [lazy=true]
+  std::string android_power_config_;  // [lazy=true]
+  std::string android_log_config_;  // [lazy=true]
+  std::string gpu_counter_config_;  // [lazy=true]
+  std::string android_game_intervention_list_config_;  // [lazy=true]
+  std::string packages_list_config_;  // [lazy=true]
+  std::string perf_event_config_;  // [lazy=true]
+  std::string vulkan_memory_config_;  // [lazy=true]
+  std::string track_event_config_;  // [lazy=true]
+  std::string android_polled_state_config_;  // [lazy=true]
+  std::string android_system_property_config_;  // [lazy=true]
+  std::string statsd_tracing_config_;  // [lazy=true]
+  ::protozero::CopyablePtr<SystemInfoConfig> system_info_config_;
+  ::protozero::CopyablePtr<ChromeConfig> chrome_config_;
+  std::string v8_config_;  // [lazy=true]
+  ::protozero::CopyablePtr<InterceptorConfig> interceptor_config_;
+  std::string network_packet_trace_config_;  // [lazy=true]
+  std::string surfaceflinger_layers_config_;  // [lazy=true]
+  std::string surfaceflinger_transactions_config_;  // [lazy=true]
+  std::string android_sdk_sysprop_guard_config_;  // [lazy=true]
+  std::string etw_config_;  // [lazy=true]
+  std::string protolog_config_;  // [lazy=true]
+  std::string android_input_event_config_;  // [lazy=true]
+  std::string pixel_modem_config_;  // [lazy=true]
+  std::string legacy_config_{};
+  ::protozero::CopyablePtr<TestConfig> for_testing_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<1002> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_DATA_SOURCE_CONFIG_PROTO_CPP_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_CORE_DATA_SOURCE_CONFIG_H_
+#define INCLUDE_PERFETTO_TRACING_CORE_DATA_SOURCE_CONFIG_H_
+
+// Creates the aliases in the ::perfetto namespace, doing things like:
+// using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
+// See comments in forward_decls.h for the historical reasons of this
+// indirection layer.
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
+
+#endif  // INCLUDE_PERFETTO_TRACING_CORE_DATA_SOURCE_CONFIG_H_
+// gen_amalgamated begin header: include/perfetto/tracing/trace_writer_base.h
+// gen_amalgamated begin header: include/perfetto/protozero/message_handle.h
+// gen_amalgamated begin header: include/perfetto/protozero/message.h
+// gen_amalgamated begin header: include/perfetto/protozero/scattered_stream_writer.h
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_PROTOZERO_SCATTERED_STREAM_WRITER_H_
+#define INCLUDE_PERFETTO_PROTOZERO_SCATTERED_STREAM_WRITER_H_
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <algorithm>
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/contiguous_memory_range.h"
+
+namespace protozero {
+
+// This class deals with the following problem: append-only proto messages want
+// to write a stream of bytes, without caring about the implementation of the
+// underlying buffer (which concretely will be either the trace ring buffer
+// or a heap-allocated buffer). The main deal is: proto messages don't know in
+// advance what their size will be.
+// Due to the tracing buffer being split into fixed-size chunks, on some
+// occasions, these writes need to be spread over two (or more) non-contiguous
+// chunks of memory. Similarly, when the buffer is backed by the heap, we want
+// to avoid realloc() calls, as they might cause a full copy of the contents
+// of the buffer.
+// The purpose of this class is to abstract away the non-contiguous write logic.
+// This class knows how to deal with writes as long as they fall in the same
+// ContiguousMemoryRange and defers the chunk-chaining logic to the Delegate.
+class PERFETTO_EXPORT_COMPONENT ScatteredStreamWriter {
+ public:
+  class PERFETTO_EXPORT_COMPONENT Delegate {
+   public:
+    static constexpr size_t kPatchSize = 4;
+    virtual ~Delegate();
+
+    // Returns a new chunk for writing.
+    virtual ContiguousMemoryRange GetNewBuffer() = 0;
+
+    // Signals the delegate that the location pointed by `to_patch` (which must
+    // be in the last chunk returned by GetNewBuffer()), kPatchSize long, needs
+    // to be updated later (after potentially multiple GetNewBuffer calls).
+    //
+    // The caller must write to the returned location later. If the returned
+    // pointer is nullptr, the caller should not write anything.
+    //
+    // The implementation considers the patch ready to apply when the caller
+    // writes the first byte a value that's different than 0 (the
+    // implementation periodically checks for this).
+    virtual uint8_t* AnnotatePatch(uint8_t* patch_addr);
+  };
+
+  explicit ScatteredStreamWriter(Delegate* delegate);
+  ~ScatteredStreamWriter();
+
+  inline void WriteByte(uint8_t value) {
+    if (write_ptr_ >= cur_range_.end)
+      Extend();
+    *write_ptr_++ = value;
+  }
+
+  // Assumes that the caller checked that there is enough headroom.
+  // TODO(primiano): perf optimization, this is a tracing hot path. The
+  // compiler can make strong optimization on std::copy if the size arg is a
+  // constexpr. Make a templated variant of this for fixed-size writes.
+  // TODO(primiano): restrict / noalias might also help.
+  inline void WriteBytesUnsafe(const uint8_t* src, size_t size) {
+    uint8_t* const end = write_ptr_ + size;
+    assert(end <= cur_range_.end);
+    std::copy(src, src + size, write_ptr_);
+    write_ptr_ = end;
+  }
+
+  inline void WriteBytes(const uint8_t* src,
+                         size_t size) PERFETTO_NO_SANITIZE_UNDEFINED {
+    // If the stream writer hasn't been initialized, constructing the end
+    // pointer below invokes undefined behavior because `write_ptr_` is null.
+    // Since this function is on the hot path, we suppress the warning instead
+    // of adding a conditional branch.
+    uint8_t* const end = write_ptr_ + size;
+    if (PERFETTO_LIKELY(end <= cur_range_.end))
+      return WriteBytesUnsafe(src, size);
+    WriteBytesSlowPath(src, size);
+  }
+
+  void WriteBytesSlowPath(const uint8_t* src, size_t size);
+
+  // Reserves a fixed amount of bytes to be backfilled later. The reserved range
+  // is guaranteed to be contiguous and not span across chunks. |size| has to be
+  // <= than the size of a new buffer returned by the Delegate::GetNewBuffer().
+  uint8_t* ReserveBytes(size_t size);
+
+  // Fast (but unsafe) version of the above. The caller must have previously
+  // checked that there are at least |size| contiguous bytes available.
+  // Returns only the start pointer of the reservation.
+  uint8_t* ReserveBytesUnsafe(size_t size) {
+    uint8_t* begin = write_ptr_;
+    write_ptr_ += size;
+    assert(write_ptr_ <= cur_range_.end);
+    return begin;
+  }
+
+  // Shifts the previously written `size` bytes backwards in memory by `offset`
+  // bytes, moving the write pointer back accordingly. The shifted result must
+  // still be fully contained by the current range.
+  void Rewind(size_t size, size_t offset) {
+    uint8_t* src = write_ptr_ - size;
+    uint8_t* dst = src - offset;
+    PERFETTO_DCHECK(src >= cur_range_.begin);
+    PERFETTO_DCHECK(src + size <= cur_range_.end);
+    PERFETTO_DCHECK(dst >= cur_range_.begin);
+    PERFETTO_DCHECK(dst + size <= cur_range_.end);
+    memmove(dst, src, size);
+    write_ptr_ -= offset;
+  }
+
+  // Resets the buffer boundaries and the write pointer to the given |range|.
+  // Subsequent WriteByte(s) will write into |range|.
+  void Reset(ContiguousMemoryRange range);
+
+  // Commits the current chunk and gets a new chunk from the delegate.
+  void Extend();
+
+  // Number of contiguous free bytes in |cur_range_| that can be written without
+  // requesting a new buffer.
+  size_t bytes_available() const {
+    return static_cast<size_t>(cur_range_.end - write_ptr_);
+  }
+
+  ContiguousMemoryRange cur_range() const { return cur_range_; }
+
+  uint8_t* write_ptr() const { return write_ptr_; }
+
+  void set_write_ptr(uint8_t* write_ptr) {
+    assert(cur_range_.begin <= write_ptr && write_ptr <= cur_range_.end);
+    write_ptr_ = write_ptr;
+  }
+
+  uint64_t written() const {
+    return written_previously_ +
+           static_cast<uint64_t>(write_ptr_ - cur_range_.begin);
+  }
+
+  uint64_t written_previously() const { return written_previously_; }
+
+  uint8_t* AnnotatePatch(uint8_t* patch_addr) {
+    return delegate_->AnnotatePatch(patch_addr);
+  }
+
+ private:
+  ScatteredStreamWriter(const ScatteredStreamWriter&) = delete;
+  ScatteredStreamWriter& operator=(const ScatteredStreamWriter&) = delete;
+
+  Delegate* const delegate_;
+  ContiguousMemoryRange cur_range_;
+  uint8_t* write_ptr_;
+  uint64_t written_previously_ = 0;
+};
+
+}  // namespace protozero
+
+#endif  // INCLUDE_PERFETTO_PROTOZERO_SCATTERED_STREAM_WRITER_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_PROTOZERO_MESSAGE_H_
+#define INCLUDE_PERFETTO_PROTOZERO_MESSAGE_H_
+
+#include <assert.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/contiguous_memory_range.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
+
+namespace perfetto {
+namespace shm_fuzz {
+class FakeProducer;
+}  // namespace shm_fuzz
+}  // namespace perfetto
+
+namespace protozero {
+
+class MessageArena;
+class MessageHandleBase;
+
+// Base class extended by the proto C++ stubs generated by the ProtoZero
+// compiler. This class provides the minimal runtime required to support
+// append-only operations and is designed for performance. None of the methods
+// require any dynamic memory allocation, unless more than 16 nested messages
+// are created via BeginNestedMessage() calls.
+class PERFETTO_EXPORT_COMPONENT Message {
+ public:
+  friend class MessageHandleBase;
+
+  // The ctor is deliberately a no-op to avoid forwarding args from all
+  // subclasses. The real initialization is performed by Reset().
+  // Nested messages are allocated via placement new by MessageArena and
+  // implictly destroyed when the RootMessage's arena goes away. This is
+  // fine as long as all the fields are PODs, which is checked by the
+  // static_assert()s in the Reset() method.
+  Message() = default;
+
+  // Clears up the state, allowing the message to be reused as a fresh one.
+  void Reset(ScatteredStreamWriter*, MessageArena*);
+
+  // Commits all the changes to the buffer (backfills the size field of this and
+  // all nested messages) and seals the message. Returns the size of the message
+  // (and all nested sub-messages), without taking into account any chunking.
+  // Finalize is idempotent and can be called several times w/o side effects.
+  // Short messages may be compacted in memory into the size field, since their
+  // size can be represented with fewer than
+  // proto_utils::kMessageLengthFieldSize bytes.
+  uint32_t Finalize();
+
+  // Optional. If is_valid() == true, the corresponding memory region (its
+  // length == proto_utils::kMessageLengthFieldSize) is backfilled with the size
+  // of this message. This is the mechanism used by messages to backfill their
+  // corresponding size field in the parent message. In most cases this is only
+  // used for nested messages and the ScatteredStreamWriter::Delegate (e.g.
+  // TraceWriterImpl), takes case of the outer message.
+  uint8_t* size_field() const { return size_field_; }
+  void set_size_field(uint8_t* size_field) { size_field_ = size_field; }
+
+  Message* nested_message() { return nested_message_; }
+
+  bool is_finalized() const {
+    return message_state_ != MessageState::kNotFinalized;
+  }
+
+#if PERFETTO_DCHECK_IS_ON()
+  void set_handle(MessageHandleBase* handle) { handle_ = handle; }
+#endif
+
+  // Proto types: uint64, uint32, int64, int32, bool, enum.
+  template <typename T>
+  void AppendVarInt(uint32_t field_id, T value) {
+    if (nested_message_)
+      EndNestedMessage();
+
+    uint8_t buffer[proto_utils::kMaxSimpleFieldEncodedSize];
+    uint8_t* pos = buffer;
+
+    pos = proto_utils::WriteVarInt(proto_utils::MakeTagVarInt(field_id), pos);
+    // WriteVarInt encodes signed values in two's complement form.
+    pos = proto_utils::WriteVarInt(value, pos);
+    WriteToStream(buffer, pos);
+  }
+
+  // Proto types: sint64, sint32.
+  template <typename T>
+  void AppendSignedVarInt(uint32_t field_id, T value) {
+    AppendVarInt(field_id, proto_utils::ZigZagEncode(value));
+  }
+
+  // Proto types: bool, enum (small).
+  // Faster version of AppendVarInt for tiny numbers.
+  void AppendTinyVarInt(uint32_t field_id, int32_t value) {
+    PERFETTO_DCHECK(0 <= value && value < 0x80);
+    if (nested_message_)
+      EndNestedMessage();
+
+    uint8_t buffer[proto_utils::kMaxSimpleFieldEncodedSize];
+    uint8_t* pos = buffer;
+    // MakeTagVarInt gets super optimized here for constexpr.
+    pos = proto_utils::WriteVarInt(proto_utils::MakeTagVarInt(field_id), pos);
+    *pos++ = static_cast<uint8_t>(value);
+    WriteToStream(buffer, pos);
+  }
+
+  // Proto types: fixed64, sfixed64, fixed32, sfixed32, double, float.
+  template <typename T>
+  void AppendFixed(uint32_t field_id, T value) {
+    if (nested_message_)
+      EndNestedMessage();
+
+    uint8_t buffer[proto_utils::kMaxSimpleFieldEncodedSize];
+    uint8_t* pos = buffer;
+
+    pos = proto_utils::WriteVarInt(proto_utils::MakeTagFixed<T>(field_id), pos);
+    memcpy(pos, &value, sizeof(T));
+    pos += sizeof(T);
+    // TODO: Optimize memcpy performance, see http://crbug.com/624311 .
+    WriteToStream(buffer, pos);
+  }
+
+  void AppendString(uint32_t field_id, const char* str);
+
+  void AppendString(uint32_t field_id, const std::string& str) {
+    AppendBytes(field_id, str.data(), str.size());
+  }
+
+  void AppendBytes(uint32_t field_id, const void* value, size_t size);
+
+  // Append raw bytes for a field, using the supplied |ranges| to
+  // copy from |num_ranges| individual buffers.
+  size_t AppendScatteredBytes(uint32_t field_id,
+                              ContiguousMemoryRange* ranges,
+                              size_t num_ranges);
+
+  // Begins a nested message. The returned object is owned by the MessageArena
+  // of the root message. The nested message ends either when Finalize() is
+  // called or when any other Append* method is called in the parent class.
+  // The template argument T is supposed to be a stub class auto generated from
+  // a .proto, hence a subclass of Message.
+  template <class T>
+  T* BeginNestedMessage(uint32_t field_id) {
+    // This is to prevent subclasses (which should be autogenerated, though), to
+    // introduce extra state fields (which wouldn't be initialized by Reset()).
+    static_assert(std::is_base_of<Message, T>::value,
+                  "T must be a subclass of Message");
+    static_assert(sizeof(T) == sizeof(Message),
+                  "Message subclasses cannot introduce extra state.");
+    return static_cast<T*>(BeginNestedMessageInternal(field_id));
+  }
+
+  // Gives read-only access to the underlying stream_writer. This is used only
+  // by few internals to query the state of the underlying buffer. It is almost
+  // always a bad idea to poke at the stream_writer() internals.
+  const ScatteredStreamWriter* stream_writer() const { return stream_writer_; }
+
+  // Appends some raw bytes to the message. The use-case for this is preserving
+  // unknown fields in the decode -> re-encode path of xxx.gen.cc classes
+  // generated by the cppgen_plugin.cc.
+  // The caller needs to guarantee that the appended data is properly
+  // proto-encoded and each field has a proto preamble.
+  void AppendRawProtoBytes(const void* data, size_t size) {
+    if (nested_message_)
+      EndNestedMessage();
+    const uint8_t* src = reinterpret_cast<const uint8_t*>(data);
+    WriteToStream(src, src + size);
+  }
+
+ private:
+  Message(const Message&) = delete;
+  Message& operator=(const Message&) = delete;
+
+  Message* BeginNestedMessageInternal(uint32_t field_id);
+
+  // Called by Finalize and Append* methods.
+  void EndNestedMessage();
+
+  void WriteToStream(const uint8_t* src_begin, const uint8_t* src_end) {
+    PERFETTO_DCHECK(!is_finalized());
+    PERFETTO_DCHECK(src_begin <= src_end);
+    const uint32_t size = static_cast<uint32_t>(src_end - src_begin);
+    stream_writer_->WriteBytes(src_begin, size);
+    size_ += size;
+  }
+
+  // Only POD fields are allowed. This class's dtor is never called.
+  // See the comment on the static_assert in the corresponding .cc file.
+
+  // The stream writer interface used for the serialization.
+  ScatteredStreamWriter* stream_writer_;
+
+  // The storage used to allocate nested Message objects.
+  // This is owned by RootMessage<T>.
+  MessageArena* arena_;
+
+  // Pointer to the last child message created through BeginNestedMessage(), if
+  // any, nullptr otherwise. There is no need to keep track of more than one
+  // message per nesting level as the proto-zero API contract mandates that
+  // nested fields can be filled only in a stacked fashion. In other words,
+  // nested messages are finalized and sealed when any other field is set in the
+  // parent message (or the parent message itself is finalized) and cannot be
+  // accessed anymore afterwards.
+  Message* nested_message_;
+
+  // [optional] Pointer to a non-aligned pre-reserved var-int slot of
+  // kMessageLengthFieldSize bytes. When set, the Finalize() method will write
+  // the size of proto-encoded message in the pointed memory region.
+  uint8_t* size_field_;
+
+  // Keeps track of the size of the current message.
+  uint32_t size_;
+
+  enum class MessageState : uint8_t {
+    // Message is still being written to.
+    kNotFinalized,
+    // Finalized, no more changes to the message are allowed. This is to DCHECK
+    // attempts of writing to a message which has been Finalize()-d.
+    kFinalized,
+    // Finalized, and additionally the message data has been partially or fully
+    // compacted into the last 3 bytes of `size_field_`. See the comment in
+    // Finalize().
+    kFinalizedWithCompaction,
+  };
+
+  MessageState message_state_;
+
+#if PERFETTO_DCHECK_IS_ON()
+  // Current generation of message. Incremented on Reset.
+  // Used to detect stale handles.
+  uint32_t generation_;
+
+  MessageHandleBase* handle_;
+#endif
+};
+
+}  // namespace protozero
+
+#endif  // INCLUDE_PERFETTO_PROTOZERO_MESSAGE_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_PROTOZERO_MESSAGE_HANDLE_H_
+#define INCLUDE_PERFETTO_PROTOZERO_MESSAGE_HANDLE_H_
+
+#include <functional>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
+
+namespace protozero {
+
+class Message;
+
+class PERFETTO_EXPORT_COMPONENT MessageFinalizationListener {
+ public:
+  virtual ~MessageFinalizationListener();
+  virtual void OnMessageFinalized(Message* message) = 0;
+};
+
+// MessageHandle allows to decouple the lifetime of a proto message
+// from the underlying storage. It gives the following guarantees:
+// - The underlying message is finalized (if still alive) if the handle goes
+//   out of scope.
+// - In Debug / DCHECK_ALWAYS_ON builds, the handle becomes null once the
+//   message is finalized. This is to enforce the append-only API. For instance
+//   when adding two repeated messages, the addition of the 2nd one forces
+//   the finalization of the first.
+// Think about this as a WeakPtr<Message> which calls
+// Message::Finalize() when going out of scope.
+
+class PERFETTO_EXPORT_COMPONENT MessageHandleBase {
+ public:
+  ~MessageHandleBase() {
+    if (message_) {
+#if PERFETTO_DCHECK_IS_ON()
+      PERFETTO_DCHECK(generation_ == message_->generation_);
+#endif
+      FinalizeMessage();
+    }
+  }
+
+  // Move-only type.
+  MessageHandleBase(MessageHandleBase&& other) noexcept {
+    Move(std::move(other));
+  }
+
+  MessageHandleBase& operator=(MessageHandleBase&& other) noexcept {
+    // If the current handle was pointing to a message and is being reset to a
+    // new one, finalize the old message. However, if the other message is the
+    // same as the one we point to, don't finalize.
+    if (message_ && message_ != other.message_)
+      FinalizeMessage();
+    Move(std::move(other));
+    return *this;
+  }
+
+  explicit operator bool() const {
+#if PERFETTO_DCHECK_IS_ON()
+    PERFETTO_DCHECK(!message_ || generation_ == message_->generation_);
+#endif
+    return !!message_;
+  }
+
+  void set_finalization_listener(MessageFinalizationListener* listener) {
+    listener_ = listener;
+  }
+
+  // Returns a (non-owned, it should not be deleted) pointer to the
+  // ScatteredStreamWriter used to write the message data. The Message becomes
+  // unusable after this point.
+  //
+  // The caller can now write directly, without using protozero::Message.
+  ScatteredStreamWriter* TakeStreamWriter() {
+    ScatteredStreamWriter* stream_writer = message_->stream_writer_;
+#if PERFETTO_DCHECK_IS_ON()
+    message_->set_handle(nullptr);
+#endif
+    message_ = nullptr;
+    listener_ = nullptr;
+    return stream_writer;
+  }
+
+ protected:
+  explicit MessageHandleBase(Message* message = nullptr) : message_(message) {
+#if PERFETTO_DCHECK_IS_ON()
+    generation_ = message_ ? message->generation_ : 0;
+    if (message_)
+      message_->set_handle(this);
+#endif
+  }
+
+  Message* operator->() const {
+#if PERFETTO_DCHECK_IS_ON()
+    PERFETTO_DCHECK(!message_ || generation_ == message_->generation_);
+#endif
+    return message_;
+  }
+  Message& operator*() const { return *(operator->()); }
+
+ private:
+  friend class Message;
+  MessageHandleBase(const MessageHandleBase&) = delete;
+  MessageHandleBase& operator=(const MessageHandleBase&) = delete;
+
+  void reset_message() {
+    // This is called by Message::Finalize().
+    PERFETTO_DCHECK(message_->is_finalized());
+    message_ = nullptr;
+    listener_ = nullptr;
+  }
+
+  void Move(MessageHandleBase&& other) {
+    message_ = other.message_;
+    other.message_ = nullptr;
+    listener_ = other.listener_;
+    other.listener_ = nullptr;
+#if PERFETTO_DCHECK_IS_ON()
+    if (message_) {
+      generation_ = message_->generation_;
+      message_->set_handle(this);
+    }
+#endif
+  }
+
+  void FinalizeMessage() {
+    // |message_| and |listener_| may be cleared by reset_message() during
+    // Message::Finalize().
+    auto* listener = listener_;
+    auto* message = message_;
+    message->Finalize();
+    if (listener)
+      listener->OnMessageFinalized(message);
+  }
+
+  Message* message_;
+  MessageFinalizationListener* listener_ = nullptr;
+#if PERFETTO_DCHECK_IS_ON()
+  uint32_t generation_;
+#endif
+};
+
+template <typename T>
+class MessageHandle : public MessageHandleBase {
+ public:
+  MessageHandle() : MessageHandle(nullptr) {}
+  explicit MessageHandle(T* message) : MessageHandleBase(message) {}
+
+  explicit operator bool() const { return MessageHandleBase::operator bool(); }
+
+  T& operator*() const {
+    return static_cast<T&>(MessageHandleBase::operator*());
+  }
+
+  T* operator->() const {
+    return static_cast<T*>(MessageHandleBase::operator->());
+  }
+
+  T* get() const { return static_cast<T*>(MessageHandleBase::operator->()); }
+};
+
+}  // namespace protozero
+
+#endif  // INCLUDE_PERFETTO_PROTOZERO_MESSAGE_HANDLE_H_
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_TRACE_WRITER_BASE_H_
+#define INCLUDE_PERFETTO_TRACING_TRACE_WRITER_BASE_H_
+
+// gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
+
+namespace perfetto {
+
+namespace protos {
+namespace pbzero {
+class TracePacket;
+}  // namespace pbzero
+}  // namespace protos
+
+// This is a single-thread write interface that allows to write protobufs
+// directly into the tracing shared buffer without making any copies.
+// The idea is that each data source creates one (or more) TraceWriter for each
+// thread it wants to write from. Each TraceWriter will get its own dedicated
+// chunk and will write into the shared buffer without any locking most of the
+// time.
+
+class TraceWriterBase {
+ public:
+  virtual ~TraceWriterBase();
+
+  // Creates a new trace packet and returns a handle to a protozero Message that
+  // will write to it. The message will be finalized either by calling directly
+  // handle.Finalize() or by letting the handle go out of scope (the message
+  // should be finalized before a new call to NewTracePacket is made). The
+  // returned handle can be std::move()'d but cannot be used after either: (i)
+  // the TraceWriter instance is destroyed, (ii) a subsequence NewTracePacket()
+  // call is made on the same TraceWriter instance.
+  //
+  // The caller can use protozero::MessageHandle::TakeStreamWriter() to write.
+  //
+  // The caller must call ->Finalize() on the returned trace packet (the handle
+  // destructor will take care of that) or explicitly call FinishTracePacket (if
+  // using TakeStreamWriter) before calling any method on the same TraceWriter
+  // instance.
+  //
+  // The returned packet handle is always valid, but note that, when using
+  // BufferExhaustedPolicy::kDrop and the SMB is exhausted, it may be assigned
+  // a garbage chunk and any trace data written into it will be lost. For more
+  // details on buffer size choices: https://perfetto.dev/docs/concepts/buffers.
+  virtual protozero::MessageHandle<protos::pbzero::TracePacket>
+  NewTracePacket() = 0;
+
+  // Tells the TraceWriterBase that the previous packet started with
+  // NewTracePacket() is finished.
+  //
+  // Calling this is optional: the TraceWriterBase can realize that the previous
+  // packet is finished when the next NewTracePacket() is called. It is still
+  // useful, because the next NewTracePacket may not happen for a while.
+  virtual void FinishTracePacket() = 0;
+
+  // Commits the data pending for the current chunk. This can be called
+  // only if the handle returned by NewTracePacket() has been destroyed (i.e. we
+  // cannot Flush() while writing a TracePacket).
+  //
+  // Note: Flush() also happens implicitly when destroying the TraceWriter.
+  //
+  // |callback| is an optional callback. When non-null it will request the
+  // service to ACK the flush and will be invoked after the service has
+  // acknowledged it. The callback might be NEVER INVOKED if the service crashes
+  // or the IPC connection is dropped. The callback should be used only by tests
+  // and best-effort features (logging).
+  virtual void Flush(std::function<void()> callback = {}) = 0;
+
+  // Bytes written since creation. Not reset when new chunks are acquired.
+  virtual uint64_t written() const = 0;
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_TRACE_WRITER_BASE_H_
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_DATA_SOURCE_INTERNAL_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_DATA_SOURCE_INTERNAL_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <array>
+#include <atomic>
+#include <functional>
+#include <memory>
+#include <mutex>
+
+// No perfetto headers (other than tracing/api and protozero) should be here.
+// gen_amalgamated expanded: #include "perfetto/tracing/buffer_exhausted_policy.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_config.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
+
+namespace perfetto {
+
+class DataSourceBase;
+class InterceptorBase;
+class TraceWriterBase;
+
+namespace internal {
+
+class TracingTLS;
+
+// This maintains the internal state of a data source instance that is used only
+// to implement the tracing mechanics and is not exposed to the API client.
+// There is one of these object per DataSource instance (up to
+// kMaxDataSourceInstances).
+struct DataSourceState {
+  // This boolean flag determines whether the DataSource::Trace() method should
+  // do something or be a no-op. This flag doesn't give the full guarantee
+  // that tracing data will be visible in the trace, it just makes it so that
+  // the client attemps writing trace data and interacting with the service.
+  // For instance, when a tracing session ends the service will reject data
+  // commits that arrive too late even if the producer hasn't received the stop
+  // IPC message.
+  // This flag is set right before calling OnStart() and cleared right before
+  // calling OnStop(), unless using HandleStopAsynchronously() (see comments
+  // in data_source.h).
+  // Keep this flag as the first field. This allows the compiler to directly
+  // dereference the DataSourceState* pointer in the trace fast-path without
+  // doing extra pointr arithmetic.
+  std::atomic<bool> trace_lambda_enabled{false};
+
+  // The overall TracingMuxerImpl instance id, which gets incremented by
+  // ResetForTesting.
+  uint32_t muxer_id_for_testing = 0;
+
+  // The central buffer id that all TraceWriter(s) created by this data source
+  // must target.
+  BufferId buffer_id = 0;
+
+  // The index within TracingMuxerImpl.backends_. Practically it allows to
+  // lookup the Producer object, and hence the IPC channel, for this data
+  // source.
+  TracingBackendId backend_id = 0;
+
+  // Each backend may connect to the tracing service multiple times if a
+  // disconnection occurs. This counter is used to uniquely identify each
+  // connection so that trace writers don't get reused across connections.
+  uint32_t backend_connection_id = 0;
+
+  // The instance id as assigned by the tracing service. Note that because a
+  // process can be connected to >1 services, this ID is not globally unique but
+  // is only unique within the scope of its backend.
+  // Only the tuple (backend_id, data_source_instance_id) is globally unique.
+  uint64_t data_source_instance_id = 0;
+
+  // Set to a non-0 target buffer reservation ID iff startup tracing is
+  // currently enabled for this data source.
+  std::atomic<uint16_t> startup_target_buffer_reservation{0};
+
+  // If the data source was originally started for startup tracing, this is set
+  // to the startup session's ID.
+  uint64_t startup_session_id = 0;
+
+  // The trace config used by this instance. This is used to de-duplicate
+  // instances for data sources with identical names (e.g., track event).
+  // We store it as a pointer to be able to free memory after the datasource
+  // is stopped.
+  std::unique_ptr<DataSourceConfig> config;
+
+  // If this data source is being intercepted (see Interceptor), this field
+  // contains the non-zero id of a registered interceptor which should receive
+  // trace packets for this session. Note: interceptor id 1 refers to the first
+  // element of TracingMuxerImpl::interceptors_ with successive numbers using
+  // the following slots.
+  uint32_t interceptor_id = 0;
+
+  // This is set to true when the datasource is in the process of async stop.
+  // The flag is checked by the tracing muxer to avoid calling OnStop for the
+  // second time.
+  bool async_stop_in_progress = false;
+
+  // This lock is not held to implement Trace() and it's used only if the trace
+  // code wants to access its own data source state.
+  // This is to prevent that accessing the data source on an arbitrary embedder
+  // thread races with the internal IPC thread destroying the data source
+  // because of a end-of-tracing notification from the service.
+  // This lock is also used to protect access to a possible interceptor for this
+  // data source session.
+  std::recursive_mutex lock;
+  std::unique_ptr<DataSourceBase> data_source;
+  std::unique_ptr<InterceptorBase> interceptor;
+};
+
+// This is to allow lazy-initialization and avoid static initializers and
+// at-exit destructors. All the entries are initialized via placement-new when
+// DataSource::Register() is called, see TracingMuxerImpl::RegisterDataSource().
+struct DataSourceStateStorage {
+  alignas(DataSourceState) char storage[sizeof(DataSourceState)]{};
+};
+
+// Per-DataSource-type global state.
+struct DataSourceStaticState {
+  // System-wide unique id of the data source.
+  uint64_t id = 0;
+
+  // Unique index of the data source, assigned at registration time.
+  uint32_t index = kMaxDataSources;
+
+  // A bitmap that tells about the validity of each |instances| entry. When the
+  // i-th bit of the bitmap it's set, instances[i] is valid.
+  std::atomic<uint32_t> valid_instances{};
+  std::array<DataSourceStateStorage, kMaxDataSourceInstances> instances{};
+
+  // Incremented whenever incremental state should be reset for any instance of
+  // this data source.
+  std::atomic<uint32_t> incremental_state_generation{};
+
+  // Can be used with a cached |valid_instances| bitmap.
+  DataSourceState* TryGetCached(uint32_t cached_bitmap, size_t n) {
+    return cached_bitmap & (1 << n)
+               ? reinterpret_cast<DataSourceState*>(&instances[n])
+               : nullptr;
+  }
+
+  DataSourceState* TryGet(size_t n) {
+    return TryGetCached(valid_instances.load(std::memory_order_acquire), n);
+  }
+
+  void CompilerAsserts() {
+    static_assert(sizeof(valid_instances.load()) * 8 >= kMaxDataSourceInstances,
+                  "kMaxDataSourceInstances too high");
+  }
+
+  void ResetForTesting() {
+    id = 0;
+    index = kMaxDataSources;
+    valid_instances.store(0, std::memory_order_release);
+    instances = {};
+    incremental_state_generation.store(0, std::memory_order_release);
+  }
+};
+
+// Per-DataSource-instance thread-local state.
+struct DataSourceInstanceThreadLocalState {
+  void Reset() { *this = DataSourceInstanceThreadLocalState{}; }
+
+  std::unique_ptr<TraceWriterBase> trace_writer;
+  using ObjectWithDeleter = std::unique_ptr<void, void (*)(void*)>;
+  ObjectWithDeleter incremental_state = {nullptr, [](void*) {}};
+  ObjectWithDeleter data_source_custom_tls = {nullptr, [](void*) {}};
+  uint32_t incremental_state_generation = 0;
+  uint32_t muxer_id_for_testing = 0;
+  TracingBackendId backend_id = 0;
+  uint32_t backend_connection_id = 0;
+  BufferId buffer_id = 0;
+  uint64_t data_source_instance_id = 0;
+  bool is_intercepted = false;
+  uint64_t last_empty_packet_position = 0;
+  uint16_t startup_target_buffer_reservation = 0;
+};
+
+// Per-DataSource-type thread-local state.
+struct DataSourceThreadLocalState {
+  DataSourceStaticState* static_state = nullptr;
+
+  // Pointer to the parent tls object that holds us. Used to retrieve the
+  // generation, which is per-global-TLS and not per data-source.
+  TracingTLS* root_tls = nullptr;
+
+  // One entry per each data source instance.
+  std::array<DataSourceInstanceThreadLocalState, kMaxDataSourceInstances>
+      per_instance{};
+};
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_DATA_SOURCE_INTERNAL_H_
+// gen_amalgamated begin header: include/perfetto/tracing/locked_handle.h
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_LOCKED_HANDLE_H_
+#define INCLUDE_PERFETTO_TRACING_LOCKED_HANDLE_H_
+
+#include <mutex>
+
+namespace perfetto {
+
+// This is used for GetDataSourceLocked(), in the (rare) case where the
+// tracing code wants to access the state of its data source from the Trace()
+// method.
+template <typename T>
+class LockedHandle {
+ public:
+  LockedHandle(std::unique_lock<std::recursive_mutex> lock, T* obj)
+      : lock_(std::move(lock)), obj_(obj) {}
+  LockedHandle() = default;  // For the invalid case.
+  LockedHandle(LockedHandle&&) = default;
+  LockedHandle& operator=(LockedHandle&&) = default;
+
+  bool valid() const { return obj_; }
+  explicit operator bool() const { return valid(); }
+
+  T* operator->() {
+    assert(valid());
+    return obj_;
+  }
+
+  T& operator*() { return *(this->operator->()); }
+
+ private:
+  std::unique_lock<std::recursive_mutex> lock_;
+  T* obj_ = nullptr;
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_LOCKED_HANDLE_H_
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_INTERCEPTOR_H_
+#define INCLUDE_PERFETTO_TRACING_INTERCEPTOR_H_
+
+// An interceptor is used to redirect trace packets written by a data source
+// into a custom backend instead of the normal Perfetto tracing service. For
+// example, the console interceptor prints all trace packets to the console as
+// they are generated. Another potential use is exporting trace data to another
+// tracing service such as Android ATrace or Windows ETW.
+//
+// An interceptor is defined by subclassing the perfetto::Interceptor template:
+//
+// class MyInterceptor : public perfetto::Interceptor<MyInterceptor> {
+//  public:
+//   ~MyInterceptor() override = default;
+//
+//   // This function is called for each intercepted trace packet. |context|
+//   // contains information about the trace packet as well as other state
+//   // tracked by the interceptor (e.g., see ThreadLocalState).
+//   //
+//   // Intercepted trace data is provided in the form of serialized protobuf
+//   // bytes, accessed through the |context.packet_data| field.
+//   //
+//   // Warning: this function can be called on any thread at any time. See
+//   // below for how to safely access shared interceptor data from here.
+//   static void OnTracePacket(InterceptorContext context) {
+//     perfetto::protos::pbzero::TracePacket::Decoder packet(
+//         context.packet_data.data, context.packet_data.size);
+//     // ... Write |packet| to the desired destination ...
+//   }
+// };
+//
+// An interceptor should be registered before any tracing sessions are started.
+// Note that the interceptor also needs to be activated through the trace config
+// as shown below.
+//
+//   perfetto::InterceptorDescriptor desc;
+//   desc.set_name("my_interceptor");
+//   MyInterceptor::Register(desc);
+//
+// Finally, an interceptor is enabled through the trace config like this:
+//
+//   perfetto::TraceConfig cfg;
+//   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
+//   ds_cfg->set_name("data_source_to_intercept");   // e.g. "track_event"
+//   ds_cfg->mutable_interceptor_config()->set_name("my_interceptor");
+//
+// Once an interceptor is enabled, all data from the affected data sources is
+// sent to the interceptor instead of the main tracing buffer.
+//
+// Interceptor state
+// =================
+//
+// Besides the serialized trace packet data, the |OnTracePacket| interceptor
+// function can access three other types of state:
+//
+// 1. Global state: this is no different from a normal static function, but care
+//    must be taken because |OnTracePacket| can be called concurrently on any
+//    thread at any time.
+//
+// 2. Per-data source instance state: since the interceptor class is
+//    automatically instantiated for each intercepted data source, its fields
+//    can be used to store per-instance data such as the trace config. This data
+//    can be maintained through the OnSetup/OnStart/OnStop callbacks:
+//
+//    class MyInterceptor : public perfetto::Interceptor<MyInterceptor> {
+//     public:
+//      void OnSetup(const SetupArgs& args) override {
+//        enable_foo_ = args.config.interceptor_config().enable_foo();
+//      }
+//
+//      bool enable_foo_{};
+//    };
+//
+//    In the interceptor function this data must be accessed through a scoped
+//    lock for safety:
+//
+//    class MyInterceptor : public perfetto::Interceptor<MyInterceptor> {
+//      ...
+//      static void OnTracePacket(InterceptorContext context) {
+//        auto my_interceptor = context.GetInterceptorLocked();
+//        if (my_interceptor) {
+//           // Access fields of MyInterceptor here.
+//           if (my_interceptor->enable_foo_) { ... }
+//        }
+//        ...
+//      }
+//    };
+//
+//    Since accessing this data involves holding a lock, it should be done
+//    sparingly.
+//
+// 3. Per-thread/TraceWriter state: many data sources use interning to avoid
+//    repeating common data in the trace. Since the interning dictionaries are
+//    typically kept individually for each TraceWriter sequence (i.e., per
+//    thread), an interceptor can declare a data structure with lifetime
+//    matching the TraceWriter:
+//
+//    class MyInterceptor : public perfetto::Interceptor<MyInterceptor> {
+//     public:
+//      struct ThreadLocalState
+//          : public perfetto::InterceptorBase::ThreadLocalState {
+//        ThreadLocalState(ThreadLocalStateArgs&) override = default;
+//        ~ThreadLocalState() override = default;
+//
+//        std::map<size_t, std::string> event_names;
+//      };
+//    };
+//
+//    This per-thread state can then be accessed and maintained in
+//    |OnTracePacket| like this:
+//
+//    class MyInterceptor : public perfetto::Interceptor<MyInterceptor> {
+//      ...
+//      static void OnTracePacket(InterceptorContext context) {
+//        // Updating interned data.
+//        auto& tls = context.GetThreadLocalState();
+//        if (parsed_packet.sequence_flags() & perfetto::protos::pbzero::
+//                TracePacket::SEQ_INCREMENTAL_STATE_CLEARED) {
+//          tls.event_names.clear();
+//        }
+//        for (const auto& entry : parsed_packet.interned_data().event_names())
+//          tls.event_names[entry.iid()] = entry.name();
+//
+//        // Looking up interned data.
+//        if (parsed_packet.has_track_event()) {
+//          size_t name_iid = parsed_packet.track_event().name_iid();
+//          const std::string& event_name = tls.event_names[name_iid];
+//        }
+//        ...
+//      }
+//    };
+//
+
+#include <functional>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/data_source_internal.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/locked_handle.h"
+
+namespace {
+class MockTracingMuxer;
+}
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class DataSourceConfig;
+class InterceptorDescriptor;
+}  // namespace gen
+}  // namespace protos
+
+using protos::gen::InterceptorDescriptor;
+
+namespace internal {
+class InterceptorTraceWriter;
+class InterceptorTraceWriterTest;
+class TracingMuxer;
+class TracingMuxerFake;
+class TracingMuxerImpl;
+}  // namespace internal
+
+// A virtual base class for interceptors. Users should derive from the templated
+// subclass below instead of this one.
+class PERFETTO_EXPORT_COMPONENT InterceptorBase {
+ public:
+  virtual ~InterceptorBase();
+
+  // A virtual base class for thread-local state needed by the interceptor.
+  // To define your own state, subclass this with the same name in the
+  // interceptor class. A reference to the state can then be looked up through
+  // context.GetThreadLocalState() in the trace packet interceptor function.
+  class PERFETTO_EXPORT_COMPONENT ThreadLocalState {
+   public:
+    virtual ~ThreadLocalState();
+  };
+
+  struct SetupArgs {
+    const DataSourceConfig& config;
+  };
+  struct StartArgs {};
+  struct StopArgs {};
+
+  // Called when an intercepted data source is set up. Both the interceptor's
+  // and the data source's configuration is available in
+  // |SetupArgs|. Called on an internal Perfetto service thread, but not
+  // concurrently.
+  virtual void OnSetup(const SetupArgs&) {}
+
+  // Called when an intercepted data source starts. Called on an internal
+  // Perfetto service thread, but not concurrently.
+  virtual void OnStart(const StartArgs&) {}
+
+  // Called when an intercepted data source stops. Called on an internal
+  // Perfetto service thread, but not concurrently.
+  virtual void OnStop(const StopArgs&) {}
+
+ private:
+  friend class internal::InterceptorTraceWriter;
+  friend class internal::InterceptorTraceWriterTest;
+  friend class internal::TracingMuxer;
+  friend class internal::TracingMuxerFake;
+  friend class internal::TracingMuxerImpl;
+  friend MockTracingMuxer;
+  template <class T>
+  friend class Interceptor;
+
+  // Data passed from DataSource::Trace() into the interceptor.
+  struct TracePacketCallbackArgs {
+    internal::DataSourceStaticState* static_state;
+    uint32_t instance_index;
+    protozero::ConstBytes packet_data;
+    ThreadLocalState* tls;
+  };
+
+  // These callback functions are defined as stateless to avoid accidentally
+  // introducing cross-thread data races.
+  using TLSFactory = std::unique_ptr<ThreadLocalState> (*)(
+      internal::DataSourceStaticState*,
+      uint32_t data_source_instance_index);
+  using TracePacketCallback = void (*)(TracePacketCallbackArgs);
+
+  static void RegisterImpl(
+      const InterceptorDescriptor& descriptor,
+      std::function<std::unique_ptr<InterceptorBase>()> factory,
+      InterceptorBase::TLSFactory tls_factory,
+      InterceptorBase::TracePacketCallback on_trace_packet);
+};
+
+// Templated interceptor instantiation. See above for usage.
+template <class InterceptorType>
+class PERFETTO_EXPORT_COMPONENT Interceptor : public InterceptorBase {
+ public:
+  // A context object provided to the ThreadLocalState constructor. Provides
+  // access to the per-instance interceptor object.
+  class ThreadLocalStateArgs {
+   public:
+    ~ThreadLocalStateArgs() = default;
+
+    ThreadLocalStateArgs(const ThreadLocalStateArgs&) = delete;
+    ThreadLocalStateArgs& operator=(const ThreadLocalStateArgs&) = delete;
+
+    ThreadLocalStateArgs(ThreadLocalStateArgs&&) noexcept = default;
+    ThreadLocalStateArgs& operator=(ThreadLocalStateArgs&&) noexcept = default;
+
+    // Return a locked reference to the interceptor session. The session object
+    // will remain valid as long as the returned handle is in scope.
+    LockedHandle<InterceptorType> GetInterceptorLocked() {
+      auto* internal_state = static_state_->TryGet(data_source_instance_index_);
+      if (!internal_state)
+        return LockedHandle<InterceptorType>();
+      std::unique_lock<std::recursive_mutex> lock(internal_state->lock);
+      return LockedHandle<InterceptorType>(
+          std::move(lock),
+          static_cast<InterceptorType*>(internal_state->interceptor.get()));
+    }
+
+   private:
+    friend class Interceptor<InterceptorType>;
+    friend class InterceptorContext;
+    friend class TracingMuxerImpl;
+
+    ThreadLocalStateArgs(internal::DataSourceStaticState* static_state,
+                         uint32_t data_source_instance_index)
+        : static_state_(static_state),
+          data_source_instance_index_(data_source_instance_index) {}
+
+    internal::DataSourceStaticState* const static_state_;
+    const uint32_t data_source_instance_index_;
+  };
+
+  // A context object provided to each call into |OnTracePacket|. Contains the
+  // intercepted serialized trace packet data.
+  class InterceptorContext {
+   public:
+    InterceptorContext(InterceptorContext&&) noexcept = default;
+    ~InterceptorContext() = default;
+
+    // Return a locked reference to the interceptor session. The session object
+    // will remain valid as long as the returned handle is in scope.
+    LockedHandle<InterceptorType> GetInterceptorLocked() {
+      return tls_args_.GetInterceptorLocked();
+    }
+
+    // Return the thread-local state for this interceptor. See
+    // InterceptorBase::ThreadLocalState.
+    typename InterceptorType::ThreadLocalState& GetThreadLocalState() {
+      return static_cast<typename InterceptorType::ThreadLocalState&>(*tls_);
+    }
+
+    // A buffer containing the serialized TracePacket protocol buffer message.
+    // This memory is only valid during the call to OnTracePacket.
+    protozero::ConstBytes packet_data;
+
+   private:
+    friend class Interceptor<InterceptorType>;
+    InterceptorContext(TracePacketCallbackArgs args)
+        : packet_data(args.packet_data),
+          tls_args_(args.static_state, args.instance_index),
+          tls_(args.tls) {}
+    InterceptorContext(const InterceptorContext&) = delete;
+    InterceptorContext& operator=(const InterceptorContext&) = delete;
+
+    ThreadLocalStateArgs tls_args_;
+    InterceptorBase::ThreadLocalState* const tls_;
+  };
+
+  // Register the interceptor for use in tracing sessions.
+  // The optional |constructor_args| will be passed to the interceptor when it
+  // is constructed.
+  template <class... Args>
+  static void Register(const InterceptorDescriptor& descriptor,
+                       const Args&... constructor_args) {
+    auto factory = [constructor_args...]() {
+      return std::unique_ptr<InterceptorBase>(
+          new InterceptorType(constructor_args...));
+    };
+    auto tls_factory = [](internal::DataSourceStaticState* static_state,
+                          uint32_t data_source_instance_index) {
+      // Don't bother allocating TLS state unless the interceptor is actually
+      // using it.
+      if (std::is_same<typename InterceptorType::ThreadLocalState,
+                       InterceptorBase::ThreadLocalState>::value) {
+        return std::unique_ptr<InterceptorBase::ThreadLocalState>(nullptr);
+      }
+      ThreadLocalStateArgs args(static_state, data_source_instance_index);
+      return std::unique_ptr<InterceptorBase::ThreadLocalState>(
+          new typename InterceptorType::ThreadLocalState(args));
+    };
+    auto on_trace_packet = [](TracePacketCallbackArgs args) {
+      InterceptorType::OnTracePacket(InterceptorContext(std::move(args)));
+    };
+    RegisterImpl(descriptor, std::move(factory), std::move(tls_factory),
+                 std::move(on_trace_packet));
+  }
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_INTERCEPTOR_H_
+// gen_amalgamated begin header: include/perfetto/tracing/track_event_state_tracker.h
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/track_event.pbzero.h
+// gen_amalgamated begin header: include/perfetto/protozero/field_writer.h
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+#ifndef INCLUDE_PERFETTO_PROTOZERO_FIELD_WRITER_H_
+#define INCLUDE_PERFETTO_PROTOZERO_FIELD_WRITER_H_
+
+namespace protozero {
+namespace internal {
+
+template <proto_utils::ProtoSchemaType proto_schema_type>
+struct FieldWriter {
+  static_assert(proto_schema_type != proto_utils::ProtoSchemaType::kMessage,
+                "FieldWriter can't be used with nested messages");
+};
+
+template <>
+struct FieldWriter<proto_utils::ProtoSchemaType::kDouble> {
+  inline static void Append(Message& message, uint32_t field_id, double value) {
+    message.AppendFixed(field_id, value);
+  }
+};
+
+template <>
+struct FieldWriter<proto_utils::ProtoSchemaType::kFloat> {
+  inline static void Append(Message& message, uint32_t field_id, float value) {
+    message.AppendFixed(field_id, value);
+  }
+};
+
+template <>
+struct FieldWriter<proto_utils::ProtoSchemaType::kBool> {
+  inline static void Append(Message& message, uint32_t field_id, bool value) {
+    message.AppendTinyVarInt(field_id, value);
+  }
+};
+
+template <>
+struct FieldWriter<proto_utils::ProtoSchemaType::kInt32> {
+  inline static void Append(Message& message,
+                            uint32_t field_id,
+                            int32_t value) {
+    message.AppendVarInt(field_id, value);
+  }
+};
+
+template <>
+struct FieldWriter<proto_utils::ProtoSchemaType::kInt64> {
+  inline static void Append(Message& message,
+                            uint32_t field_id,
+                            int64_t value) {
+    message.AppendVarInt(field_id, value);
+  }
+};
+
+template <>
+struct FieldWriter<proto_utils::ProtoSchemaType::kUint32> {
+  inline static void Append(Message& message,
+                            uint32_t field_id,
+                            uint32_t value) {
+    message.AppendVarInt(field_id, value);
+  }
+};
+
+template <>
+struct FieldWriter<proto_utils::ProtoSchemaType::kUint64> {
+  inline static void Append(Message& message,
+                            uint32_t field_id,
+                            uint64_t value) {
+    message.AppendVarInt(field_id, value);
+  }
+};
+
+template <>
+struct FieldWriter<proto_utils::ProtoSchemaType::kSint32> {
+  inline static void Append(Message& message,
+                            uint32_t field_id,
+                            int32_t value) {
+    message.AppendSignedVarInt(field_id, value);
+  }
+};
+
+template <>
+struct FieldWriter<proto_utils::ProtoSchemaType::kSint64> {
+  inline static void Append(Message& message,
+                            uint32_t field_id,
+                            int64_t value) {
+    message.AppendSignedVarInt(field_id, value);
+  }
+};
+
+template <>
+struct FieldWriter<proto_utils::ProtoSchemaType::kFixed32> {
+  inline static void Append(Message& message,
+                            uint32_t field_id,
+                            uint32_t value) {
+    message.AppendFixed(field_id, value);
+  }
+};
+
+template <>
+struct FieldWriter<proto_utils::ProtoSchemaType::kFixed64> {
+  inline static void Append(Message& message,
+                            uint32_t field_id,
+                            uint64_t value) {
+    message.AppendFixed(field_id, value);
+  }
+};
+
+template <>
+struct FieldWriter<proto_utils::ProtoSchemaType::kSfixed32> {
+  inline static void Append(Message& message,
+                            uint32_t field_id,
+                            int32_t value) {
+    message.AppendFixed(field_id, value);
+  }
+};
+
+template <>
+struct FieldWriter<proto_utils::ProtoSchemaType::kSfixed64> {
+  inline static void Append(Message& message,
+                            uint32_t field_id,
+                            int64_t value) {
+    message.AppendFixed(field_id, value);
+  }
+};
+
+template <>
+struct FieldWriter<proto_utils::ProtoSchemaType::kEnum> {
+  template <typename EnumType>
+  inline static void Append(Message& message,
+                            uint32_t field_id,
+                            EnumType value) {
+    message.AppendVarInt(field_id, value);
+  }
+};
+
+template <>
+struct FieldWriter<proto_utils::ProtoSchemaType::kString> {
+  inline static void Append(Message& message,
+                            uint32_t field_id,
+                            const char* data,
+                            size_t size) {
+    message.AppendBytes(field_id, data, size);
+  }
+
+  inline static void Append(Message& message,
+                            uint32_t field_id,
+                            const std::string& value) {
+    message.AppendBytes(field_id, value.data(), value.size());
+  }
+};
+
+template <>
+struct FieldWriter<proto_utils::ProtoSchemaType::kBytes> {
+  inline static void Append(Message& message,
+                            uint32_t field_id,
+                            const uint8_t* data,
+                            size_t size) {
+    message.AppendBytes(field_id, data, size);
+  }
+
+  inline static void Append(Message& message,
+                            uint32_t field_id,
+                            const std::string& value) {
+    message.AppendBytes(field_id, value.data(), value.size());
+  }
+};
+
+}  // namespace internal
+}  // namespace protozero
+
+#endif  // INCLUDE_PERFETTO_PROTOZERO_FIELD_WRITER_H_
+// gen_amalgamated begin header: include/perfetto/protozero/packed_repeated_fields.h
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_PROTOZERO_PACKED_REPEATED_FIELDS_H_
+#define INCLUDE_PERFETTO_PROTOZERO_PACKED_REPEATED_FIELDS_H_
+
+#include <stdint.h>
+
+#include <array>
+#include <memory>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace protozero {
+
+// This file contains classes used when encoding packed repeated fields.
+// To encode such a field, the caller is first expected to accumulate all of the
+// values in one of the following types (depending on the wire type of the
+// individual elements), defined below:
+// * protozero::PackedVarInt
+// * protozero::PackedFixedSizeInt</*element_type=*/ uint32_t>
+// Then that buffer is passed to the protozero-generated setters as an argument.
+// After calling the setter, the buffer can be destroyed.
+//
+// An example of encoding a packed field:
+//   protozero::HeapBuffered<protozero::Message> msg;
+//   protozero::PackedVarInt buf;
+//   buf.Append(42);
+//   buf.Append(-1);
+//   msg->set_fieldname(buf);
+//   msg.SerializeAsString();
+
+class PackedBufferBase {
+ public:
+  PackedBufferBase() { Reset(); }
+
+  // Copy or move is disabled due to pointers to stack addresses.
+  PackedBufferBase(const PackedBufferBase&) = delete;
+  PackedBufferBase(PackedBufferBase&&) = delete;
+  PackedBufferBase& operator=(const PackedBufferBase&) = delete;
+  PackedBufferBase& operator=(PackedBufferBase&&) = delete;
+
+  void Reset();
+
+  const uint8_t* data() const { return storage_begin_; }
+
+  size_t size() const {
+    return static_cast<size_t>(write_ptr_ - storage_begin_);
+  }
+
+ protected:
+  void GrowIfNeeded() {
+    PERFETTO_DCHECK(write_ptr_ >= storage_begin_ && write_ptr_ <= storage_end_);
+    if (PERFETTO_UNLIKELY(write_ptr_ + kMaxElementSize > storage_end_)) {
+      GrowSlowpath();
+    }
+  }
+
+  void GrowSlowpath();
+
+  // max(uint64_t varint encoding, biggest fixed type (uint64)).
+  static constexpr size_t kMaxElementSize = 10;
+
+  // So sizeof(this) == 8k.
+  static constexpr size_t kOnStackStorageSize = 8192 - 32;
+
+  uint8_t* storage_begin_;
+  uint8_t* storage_end_;
+  uint8_t* write_ptr_;
+  std::unique_ptr<uint8_t[]> heap_buf_;
+  alignas(uint64_t) uint8_t stack_buf_[kOnStackStorageSize];
+};
+
+class PackedVarInt : public PackedBufferBase {
+ public:
+  template <typename T>
+  void Append(T value) {
+    GrowIfNeeded();
+    write_ptr_ = proto_utils::WriteVarInt(value, write_ptr_);
+  }
+};
+
+template <typename T /* e.g. uint32_t for Fixed32 */>
+class PackedFixedSizeInt : public PackedBufferBase {
+ public:
+  void Append(T value) {
+    static_assert(sizeof(T) == 4 || sizeof(T) == 8,
+                  "PackedFixedSizeInt should be used only with 32/64-bit ints");
+    static_assert(sizeof(T) <= kMaxElementSize,
+                  "kMaxElementSize needs to be updated");
+    GrowIfNeeded();
+    PERFETTO_DCHECK(reinterpret_cast<size_t>(write_ptr_) % alignof(T) == 0);
+    memcpy(reinterpret_cast<T*>(write_ptr_), &value, sizeof(T));
+    write_ptr_ += sizeof(T);
+  }
+};
+
+}  // namespace protozero
+
+#endif  // INCLUDE_PERFETTO_PROTOZERO_PACKED_REPEATED_FIELDS_H_
+// gen_amalgamated begin header: include/perfetto/protozero/proto_decoder.h
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_PROTOZERO_PROTO_DECODER_H_
+#define INCLUDE_PERFETTO_PROTOZERO_PROTO_DECODER_H_
+
+#include <stdint.h>
+#include <array>
+#include <memory>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/field.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace protozero {
+
+// A generic protobuf decoder. Doesn't require any knowledge about the proto
+// schema. It tokenizes fields, retrieves their ID and type and exposes
+// accessors to retrieve its values.
+// It does NOT recurse in nested submessages, instead it just computes their
+// boundaries, recursion is left to the caller.
+// This class is designed to be used in perf-sensitive contexts. It does not
+// allocate and does not perform any proto semantic checks (e.g. repeated /
+// required / optional). It's supposedly safe wrt out-of-bounds memory accesses
+// (see proto_decoder_fuzzer.cc).
+// This class serves also as a building block for TypedProtoDecoder, used when
+// the schema is known at compile time.
+class PERFETTO_EXPORT_COMPONENT ProtoDecoder {
+ public:
+  // Creates a ProtoDecoder using the given |buffer| with size |length| bytes.
+  ProtoDecoder(const void* buffer, size_t length)
+      : begin_(reinterpret_cast<const uint8_t*>(buffer)),
+        end_(begin_ + length),
+        read_ptr_(begin_) {}
+  ProtoDecoder(const std::string& str) : ProtoDecoder(str.data(), str.size()) {}
+  ProtoDecoder(const ConstBytes& cb) : ProtoDecoder(cb.data, cb.size) {}
+
+  // Reads the next field from the buffer and advances the read cursor. If a
+  // full field cannot be read, the returned Field will be invalid (i.e.
+  // field.valid() == false).
+  Field ReadField();
+
+  // Finds the first field with the given id. Doesn't affect the read cursor.
+  Field FindField(uint32_t field_id);
+
+  // Resets the read cursor to the start of the buffer.
+  void Reset() { read_ptr_ = begin_; }
+
+  // Resets the read cursor to the given position (must be within the buffer).
+  void Reset(const uint8_t* pos) {
+    PERFETTO_DCHECK(pos >= begin_ && pos < end_);
+    read_ptr_ = pos;
+  }
+
+  // Returns the position of read cursor, relative to the start of the buffer.
+  size_t read_offset() const { return static_cast<size_t>(read_ptr_ - begin_); }
+
+  size_t bytes_left() const {
+    PERFETTO_DCHECK(read_ptr_ <= end_);
+    return static_cast<size_t>(end_ - read_ptr_);
+  }
+
+  const uint8_t* begin() const { return begin_; }
+  const uint8_t* end() const { return end_; }
+
+ protected:
+  const uint8_t* const begin_;
+  const uint8_t* const end_;
+  const uint8_t* read_ptr_ = nullptr;
+};
+
+// An iterator-like class used to iterate through repeated fields. Used by
+// TypedProtoDecoder. The iteration sequence is a bit counter-intuitive due to
+// the fact that fields_[field_id] holds the *last* value of the field, not the
+// first, but the remaining storage holds repeated fields in FIFO order.
+// Assume that we push the 10,11,12 into a repeated field with ID=1.
+//
+// Decoder memory layout:  [  fields storage  ] [ repeated fields storage ]
+// 1st iteration:           10
+// 2nd iteration:           11                   10
+// 3rd iteration:           12                   10 11
+//
+// We start the iteration @ fields_[num_fields], which is the start of the
+// repeated fields storage, proceed until the end and lastly jump @ fields_[id].
+template <typename T>
+class RepeatedFieldIterator {
+ public:
+  RepeatedFieldIterator(uint32_t field_id,
+                        const Field* begin,
+                        const Field* end,
+                        const Field* last)
+      : field_id_(field_id), iter_(begin), end_(end), last_(last) {
+    FindNextMatchingId();
+  }
+
+  // Constructs an invalid iterator.
+  RepeatedFieldIterator()
+      : field_id_(0u), iter_(nullptr), end_(nullptr), last_(nullptr) {}
+
+  explicit operator bool() const { return iter_ != end_; }
+  const Field& field() const { return *iter_; }
+
+  T operator*() const {
+    T val{};
+    iter_->get(&val);
+    return val;
+  }
+  const Field* operator->() const { return iter_; }
+
+  RepeatedFieldIterator& operator++() {
+    PERFETTO_DCHECK(iter_ != end_);
+    if (iter_ == last_) {
+      iter_ = end_;
+      return *this;
+    }
+    ++iter_;
+    FindNextMatchingId();
+    return *this;
+  }
+
+  RepeatedFieldIterator operator++(int) {
+    PERFETTO_DCHECK(iter_ != end_);
+    RepeatedFieldIterator it(*this);
+    ++(*this);
+    return it;
+  }
+
+ private:
+  void FindNextMatchingId() {
+    PERFETTO_DCHECK(iter_ != last_);
+    for (; iter_ != end_; ++iter_) {
+      if (iter_->id() == field_id_)
+        return;
+    }
+    iter_ = last_->valid() ? last_ : end_;
+  }
+
+  uint32_t field_id_;
+
+  // Initially points to the beginning of the repeated field storage, then is
+  // incremented as we call operator++().
+  const Field* iter_;
+
+  // Always points to fields_[size_], i.e. past the end of the storage.
+  const Field* end_;
+
+  // Always points to fields_[field_id].
+  const Field* last_;
+};
+
+// As RepeatedFieldIterator, but allows iterating over a packed repeated field
+// (which will be initially stored as a single length-delimited field).
+// See |GetPackedRepeatedField| for details.
+//
+// Assumes little endianness, and that the input buffers are well formed -
+// containing an exact multiple of encoded elements.
+template <proto_utils::ProtoWireType wire_type, typename CppType>
+class PackedRepeatedFieldIterator {
+ public:
+  PackedRepeatedFieldIterator(const uint8_t* data_begin,
+                              size_t size,
+                              bool* parse_error_ptr)
+      : data_end_(data_begin ? data_begin + size : nullptr),
+        read_ptr_(data_begin),
+        parse_error_(parse_error_ptr) {
+    using proto_utils::ProtoWireType;
+    static_assert(wire_type == ProtoWireType::kVarInt ||
+                      wire_type == ProtoWireType::kFixed32 ||
+                      wire_type == ProtoWireType::kFixed64,
+                  "invalid type");
+
+    PERFETTO_DCHECK(parse_error_ptr);
+
+    // Either the field is unset (and there are no data pointer), or the field
+    // is set with a zero length payload. Mark the iterator as invalid in both
+    // cases.
+    if (size == 0) {
+      curr_value_valid_ = false;
+      return;
+    }
+
+    if ((wire_type == ProtoWireType::kFixed32 && (size % 4) != 0) ||
+        (wire_type == ProtoWireType::kFixed64 && (size % 8) != 0)) {
+      *parse_error_ = true;
+      curr_value_valid_ = false;
+      return;
+    }
+
+    ++(*this);
+  }
+
+  const CppType operator*() const { return curr_value_; }
+  explicit operator bool() const { return curr_value_valid_; }
+
+  PackedRepeatedFieldIterator& operator++() {
+    using proto_utils::ProtoWireType;
+
+    if (PERFETTO_UNLIKELY(!curr_value_valid_))
+      return *this;
+
+    if (PERFETTO_UNLIKELY(read_ptr_ == data_end_)) {
+      curr_value_valid_ = false;
+      return *this;
+    }
+
+    if (wire_type == ProtoWireType::kVarInt) {
+      uint64_t new_value = 0;
+      const uint8_t* new_pos =
+          proto_utils::ParseVarInt(read_ptr_, data_end_, &new_value);
+
+      if (PERFETTO_UNLIKELY(new_pos == read_ptr_)) {
+        // Failed to decode the varint (probably incomplete buffer).
+        *parse_error_ = true;
+        curr_value_valid_ = false;
+      } else {
+        read_ptr_ = new_pos;
+        curr_value_ = static_cast<CppType>(new_value);
+      }
+    } else {  // kFixed32 or kFixed64
+      constexpr size_t kStep = wire_type == ProtoWireType::kFixed32 ? 4 : 8;
+
+      // NB: the raw buffer is not guaranteed to be aligned, so neither are
+      // these copies.
+      memcpy(&curr_value_, read_ptr_, sizeof(CppType));
+      read_ptr_ += kStep;
+    }
+
+    return *this;
+  }
+
+  PackedRepeatedFieldIterator operator++(int) {
+    PackedRepeatedFieldIterator it(*this);
+    ++(*this);
+    return it;
+  }
+
+ private:
+  // Might be null if the backing proto field isn't set.
+  const uint8_t* const data_end_;
+
+  // The iterator looks ahead by an element, so |curr_value| holds the value
+  // to be returned when the caller dereferences the iterator, and |read_ptr_|
+  // points at the start of the next element to be decoded.
+  // |read_ptr_| might be null if the backing proto field isn't set.
+  const uint8_t* read_ptr_;
+  CppType curr_value_ = {};
+
+  // Set to false once we've exhausted the iterator, or encountered an error.
+  bool curr_value_valid_ = true;
+
+  // Where to set parsing errors, supplied by the caller.
+  bool* const parse_error_;
+};
+
+// This decoder loads all fields upfront, without recursing in nested messages.
+// It is used as a base class for typed decoders generated by the pbzero plugin.
+// The split between TypedProtoDecoderBase and TypedProtoDecoder<> is to have
+// unique definition of functions like ParseAllFields() and ExpandHeapStorage().
+// The storage (either on-stack or on-heap) for this class is organized as
+// follows:
+// |-------------------------- fields_ ----------------------|
+// [ field 0 (invalid) ] [ fields 1 .. N ] [ repeated fields ]
+//                                        ^                  ^
+//                                        num_fields_        size_
+// Note that if a message has high field numbers, upon creation |size_| can be
+// < |num_fields_| (until a heap expansion is hit while inserting).
+class PERFETTO_EXPORT_COMPONENT TypedProtoDecoderBase : public ProtoDecoder {
+ public:
+  // If the field |id| is known at compile time, prefer the templated
+  // specialization at<kFieldNumber>().
+  const Field& Get(uint32_t id) const {
+    if (PERFETTO_LIKELY(id < num_fields_ && id < size_))
+      return fields_[id];
+    // If id >= num_fields_, the field id is invalid (was not known in the
+    // .proto) and we return the 0th field, which is always !valid().
+    // If id >= size_ and <= num_fields, the id is valid but the field has not
+    // been seen while decoding (hence the stack storage has not been expanded)
+    // so we return the 0th invalid field.
+    return fields_[0];
+  }
+
+  // Returns an object that allows to iterate over all instances of a repeated
+  // field given its id. Example usage:
+  //   for (auto it = decoder.GetRepeated<int32_t>(N); it; ++it) { ... }
+  template <typename T>
+  RepeatedFieldIterator<T> GetRepeated(uint32_t field_id) const {
+    const Field* repeated_begin;
+    // The storage for repeated fields starts after the slot for the highest
+    // field id (refer to the diagram in the class-level comment). However, if
+    // a message has more than INITIAL_STACK_CAPACITY field there will be no
+    // slots available for the repeated fields (if ExpandHeapStorage() was not
+    // called). Imagine a message that has highest field id = 102 and that is
+    // still using the stack:
+    // [ F0 ] [ F1 ] ... [ F100 ] [ F101 ] [ F1012] [ repeated fields ]
+    //                                            ^ num_fields_
+    //                          ^ size (== capacity)
+    if (PERFETTO_LIKELY(num_fields_ < size_)) {
+      repeated_begin = &fields_[num_fields_];
+    } else {
+      // This is the case of not having any storage space for repeated fields.
+      // This makes it so begin == end, so the iterator will just skip @ last.
+      repeated_begin = &fields_[size_];
+    }
+    const Field* repeated_end = &fields_[size_];
+    const Field* last = &Get(field_id);
+    return RepeatedFieldIterator<T>(field_id, repeated_begin, repeated_end,
+                                    last);
+  }
+
+  // Returns an objects that allows to iterate over all entries of a packed
+  // repeated field given its id and type. The |wire_type| is necessary for
+  // decoding the packed field, the |cpp_type| is for convenience & stronger
+  // typing.
+  //
+  // The caller must also supply a pointer to a bool that is set to true if the
+  // packed buffer is found to be malformed while iterating (so you need to
+  // exhaust the iterator if you want to check the full extent of the buffer).
+  //
+  // Note that unlike standard protobuf parsers, protozero does not allow
+  // treating of packed repeated fields as non-packed and vice-versa (therefore
+  // not making the packed option forwards and backwards compatible). So
+  // the caller needs to use the right accessor for correct results.
+  template <proto_utils::ProtoWireType wire_type, typename cpp_type>
+  PackedRepeatedFieldIterator<wire_type, cpp_type> GetPackedRepeated(
+      uint32_t field_id,
+      bool* parse_error_location) const {
+    const Field& field = Get(field_id);
+    if (field.valid() &&
+        field.type() == proto_utils::ProtoWireType::kLengthDelimited) {
+      return PackedRepeatedFieldIterator<wire_type, cpp_type>(
+          field.data(), field.size(), parse_error_location);
+    }
+    return PackedRepeatedFieldIterator<wire_type, cpp_type>(
+        nullptr, 0, parse_error_location);
+  }
+
+ protected:
+  TypedProtoDecoderBase(Field* storage,
+                        uint32_t num_fields,
+                        uint32_t capacity,
+                        const uint8_t* buffer,
+                        size_t length)
+      : ProtoDecoder(buffer, length),
+        fields_(storage),
+        num_fields_(num_fields),
+        // The reason for "capacity -1" is to avoid hitting the expansion path
+        // in TypedProtoDecoderBase::ParseAllFields() when we are just setting
+        // fields < INITIAL_STACK_CAPACITY (which is the most common case).
+        size_(std::min(num_fields, capacity - 1)),
+        capacity_(capacity) {
+    // The reason why Field needs to be trivially de/constructible is to avoid
+    // implicit initializers on all the ~1000 entries. We need it to initialize
+    // only on the first |max_field_id| fields, the remaining capacity doesn't
+    // require initialization.
+    static_assert(std::is_trivially_constructible<Field>::value &&
+                      std::is_trivially_destructible<Field>::value &&
+                      std::is_trivial<Field>::value,
+                  "Field must be a trivial aggregate type");
+    memset(fields_, 0, sizeof(Field) * capacity_);
+    PERFETTO_DCHECK(capacity > 0);
+  }
+
+  void ParseAllFields();
+
+  // Called when the default on-stack storage is exhausted and new repeated
+  // fields need to be pushed.
+  void ExpandHeapStorage();
+
+  // Used only in presence of a large number of repeated fields, when the
+  // default on-stack storage is exhausted.
+  std::unique_ptr<Field[]> heap_storage_;
+
+  // Points to the storage, either on-stack (default, provided by the template
+  // specialization) or |heap_storage_| after ExpandHeapStorage() is called, in
+  // case of a large number of repeated fields.
+  Field* fields_;
+
+  // Number of known fields, without accounting repeated storage. This is equal
+  // to MAX_FIELD_ID + 1 (to account for the invalid 0th field). It never
+  // changes after construction.
+  // This is unrelated with |size_| and |capacity_|. If the highest field id of
+  // a proto message is 131, |num_fields_| will be = 132 but, on initialization,
+  // |size_| = |capacity_| = 100 (INITIAL_STACK_CAPACITY).
+  // One cannot generally assume that |fields_| has enough storage to
+  // dereference every field. That is only true:
+  // - For field ids < INITIAL_STACK_CAPACITY.
+  // - After the first call to ExpandHeapStorage().
+  uint32_t num_fields_;
+
+  // Number of active |fields_| entries. This is initially equal to
+  // min(num_fields_, INITIAL_STACK_CAPACITY - 1) and after ExpandHeapStorage()
+  // becomes == |num_fields_|. If the message has non-packed repeated fields, it
+  // can grow further, up to |capacity_|.
+  // |size_| is always <= |capacity_|. But |num_fields_| can be > |size_|.
+  uint32_t size_;
+
+  // Initially equal to kFieldsCapacity of the TypedProtoDecoder
+  // specialization. Can grow when falling back on heap-based storage, in which
+  // case it represents the size (#fields with each entry of a repeated field
+  // counted individually) of the |heap_storage_| array.
+  uint32_t capacity_;
+};
+
+// This constant is a tradeoff between having a larger stack frame and being
+// able to decode field IDs up to N (or N - num_fields repeated fields) without
+// falling back on the heap.
+#define PROTOZERO_DECODER_INITIAL_STACK_CAPACITY 100
+
+// Template class instantiated by the auto-generated decoder classes declared in
+// xxx.pbzero.h files.
+template <int MAX_FIELD_ID, bool HAS_NONPACKED_REPEATED_FIELDS>
+class TypedProtoDecoder : public TypedProtoDecoderBase {
+ public:
+  TypedProtoDecoder(const uint8_t* buffer, size_t length)
+      : TypedProtoDecoderBase(on_stack_storage_,
+                              /*num_fields=*/MAX_FIELD_ID + 1,
+                              PROTOZERO_DECODER_INITIAL_STACK_CAPACITY,
+                              buffer,
+                              length) {
+    TypedProtoDecoderBase::ParseAllFields();
+  }
+
+  template <uint32_t FIELD_ID>
+  const Field& at() const {
+    static_assert(FIELD_ID <= MAX_FIELD_ID, "FIELD_ID > MAX_FIELD_ID");
+    // If the field id is < the on-stack capacity, it's safe to always
+    // dereference |fields_|, whether it's still using the stack or it fell
+    // back on the heap. Because both terms of the if () are known at compile
+    // time, the compiler elides the branch for ids < INITIAL_STACK_CAPACITY.
+    if (FIELD_ID < PROTOZERO_DECODER_INITIAL_STACK_CAPACITY) {
+      return fields_[FIELD_ID];
+    } else {
+      // Otherwise use the slowpath Get() which will do a runtime check.
+      return Get(FIELD_ID);
+    }
+  }
+
+  TypedProtoDecoder(TypedProtoDecoder&& other) noexcept
+      : TypedProtoDecoderBase(std::move(other)) {
+    // If the moved-from decoder was using on-stack storage, we need to update
+    // our pointer to point to this decoder's on-stack storage.
+    if (fields_ == other.on_stack_storage_) {
+      fields_ = on_stack_storage_;
+      memcpy(on_stack_storage_, other.on_stack_storage_,
+             sizeof(on_stack_storage_));
+    }
+  }
+
+ private:
+  Field on_stack_storage_[PROTOZERO_DECODER_INITIAL_STACK_CAPACITY];
+};
+
+}  // namespace protozero
+
+#endif  // INCLUDE_PERFETTO_PROTOZERO_PROTO_DECODER_H_
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TRACK_EVENT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TRACK_EVENT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class ChromeActiveProcesses;
+class ChromeApplicationStateInfo;
+class ChromeCompositorSchedulerState;
+class ChromeContentSettingsEventInfo;
+class ChromeFrameReporter;
+class ChromeHistogramSample;
+class ChromeKeyedService;
+class ChromeLatencyInfo;
+class ChromeLegacyIpc;
+class ChromeMessagePump;
+class ChromeMojoEventInfo;
+class ChromeRendererSchedulerState;
+class ChromeUserEvent;
+class ChromeWindowHandleEventInfo;
+class DebugAnnotation;
+class LogMessage;
+class PixelModemEventInsight;
+class Screenshot;
+class SourceLocation;
+class TaskExecution;
+class TrackEvent_LegacyEvent;
+namespace perfetto_pbzero_enum_TrackEvent_LegacyEvent {
+enum FlowDirection : int32_t;
+}  // namespace perfetto_pbzero_enum_TrackEvent_LegacyEvent
+using TrackEvent_LegacyEvent_FlowDirection = perfetto_pbzero_enum_TrackEvent_LegacyEvent::FlowDirection;
+namespace perfetto_pbzero_enum_TrackEvent_LegacyEvent {
+enum InstantEventScope : int32_t;
+}  // namespace perfetto_pbzero_enum_TrackEvent_LegacyEvent
+using TrackEvent_LegacyEvent_InstantEventScope = perfetto_pbzero_enum_TrackEvent_LegacyEvent::InstantEventScope;
+namespace perfetto_pbzero_enum_TrackEvent {
+enum Type : int32_t;
+}  // namespace perfetto_pbzero_enum_TrackEvent
+using TrackEvent_Type = perfetto_pbzero_enum_TrackEvent::Type;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_TrackEvent {
+enum Type : int32_t {
+  TYPE_UNSPECIFIED = 0,
+  TYPE_SLICE_BEGIN = 1,
+  TYPE_SLICE_END = 2,
+  TYPE_INSTANT = 3,
+  TYPE_COUNTER = 4,
+};
+} // namespace perfetto_pbzero_enum_TrackEvent
+using TrackEvent_Type = perfetto_pbzero_enum_TrackEvent::Type;
+
+
+constexpr TrackEvent_Type TrackEvent_Type_MIN = TrackEvent_Type::TYPE_UNSPECIFIED;
+constexpr TrackEvent_Type TrackEvent_Type_MAX = TrackEvent_Type::TYPE_COUNTER;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* TrackEvent_Type_Name(::perfetto::protos::pbzero::TrackEvent_Type value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::TrackEvent_Type::TYPE_UNSPECIFIED:
+    return "TYPE_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::TrackEvent_Type::TYPE_SLICE_BEGIN:
+    return "TYPE_SLICE_BEGIN";
+
+  case ::perfetto::protos::pbzero::TrackEvent_Type::TYPE_SLICE_END:
+    return "TYPE_SLICE_END";
+
+  case ::perfetto::protos::pbzero::TrackEvent_Type::TYPE_INSTANT:
+    return "TYPE_INSTANT";
+
+  case ::perfetto::protos::pbzero::TrackEvent_Type::TYPE_COUNTER:
+    return "TYPE_COUNTER";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_TrackEvent_LegacyEvent {
+enum FlowDirection : int32_t {
+  FLOW_UNSPECIFIED = 0,
+  FLOW_IN = 1,
+  FLOW_OUT = 2,
+  FLOW_INOUT = 3,
+};
+} // namespace perfetto_pbzero_enum_TrackEvent_LegacyEvent
+using TrackEvent_LegacyEvent_FlowDirection = perfetto_pbzero_enum_TrackEvent_LegacyEvent::FlowDirection;
+
+
+constexpr TrackEvent_LegacyEvent_FlowDirection TrackEvent_LegacyEvent_FlowDirection_MIN = TrackEvent_LegacyEvent_FlowDirection::FLOW_UNSPECIFIED;
+constexpr TrackEvent_LegacyEvent_FlowDirection TrackEvent_LegacyEvent_FlowDirection_MAX = TrackEvent_LegacyEvent_FlowDirection::FLOW_INOUT;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* TrackEvent_LegacyEvent_FlowDirection_Name(::perfetto::protos::pbzero::TrackEvent_LegacyEvent_FlowDirection value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_FlowDirection::FLOW_UNSPECIFIED:
+    return "FLOW_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_FlowDirection::FLOW_IN:
+    return "FLOW_IN";
+
+  case ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_FlowDirection::FLOW_OUT:
+    return "FLOW_OUT";
+
+  case ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_FlowDirection::FLOW_INOUT:
+    return "FLOW_INOUT";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_TrackEvent_LegacyEvent {
+enum InstantEventScope : int32_t {
+  SCOPE_UNSPECIFIED = 0,
+  SCOPE_GLOBAL = 1,
+  SCOPE_PROCESS = 2,
+  SCOPE_THREAD = 3,
+};
+} // namespace perfetto_pbzero_enum_TrackEvent_LegacyEvent
+using TrackEvent_LegacyEvent_InstantEventScope = perfetto_pbzero_enum_TrackEvent_LegacyEvent::InstantEventScope;
+
+
+constexpr TrackEvent_LegacyEvent_InstantEventScope TrackEvent_LegacyEvent_InstantEventScope_MIN = TrackEvent_LegacyEvent_InstantEventScope::SCOPE_UNSPECIFIED;
+constexpr TrackEvent_LegacyEvent_InstantEventScope TrackEvent_LegacyEvent_InstantEventScope_MAX = TrackEvent_LegacyEvent_InstantEventScope::SCOPE_THREAD;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* TrackEvent_LegacyEvent_InstantEventScope_Name(::perfetto::protos::pbzero::TrackEvent_LegacyEvent_InstantEventScope value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_InstantEventScope::SCOPE_UNSPECIFIED:
+    return "SCOPE_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_InstantEventScope::SCOPE_GLOBAL:
+    return "SCOPE_GLOBAL";
+
+  case ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_InstantEventScope::SCOPE_PROCESS:
+    return "SCOPE_PROCESS";
+
+  case ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_InstantEventScope::SCOPE_THREAD:
+    return "SCOPE_THREAD";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class EventName_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  EventName_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit EventName_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit EventName_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+};
+
+class EventName : public ::protozero::Message {
+ public:
+  using Decoder = EventName_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kNameFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.EventName"; }
+
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      EventName>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      EventName>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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);
+  }
+};
+
+class EventCategory_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  EventCategory_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit EventCategory_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit EventCategory_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+};
+
+class EventCategory : public ::protozero::Message {
+ public:
+  using Decoder = EventCategory_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kNameFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.EventCategory"; }
+
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      EventCategory>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      EventCategory>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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);
+  }
+};
+
+class TrackEventDefaults_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/45, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TrackEventDefaults_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrackEventDefaults_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrackEventDefaults_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_track_uuid() const { return at<11>().valid(); }
+  uint64_t track_uuid() const { return at<11>().as_uint64(); }
+  bool has_extra_counter_track_uuids() const { return at<31>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> extra_counter_track_uuids() const { return GetRepeated<uint64_t>(31); }
+  bool has_extra_double_counter_track_uuids() const { return at<45>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> extra_double_counter_track_uuids() const { return GetRepeated<uint64_t>(45); }
+};
+
+class TrackEventDefaults : public ::protozero::Message {
+ public:
+  using Decoder = TrackEventDefaults_Decoder;
+  enum : int32_t {
+    kTrackUuidFieldNumber = 11,
+    kExtraCounterTrackUuidsFieldNumber = 31,
+    kExtraDoubleCounterTrackUuidsFieldNumber = 45,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrackEventDefaults"; }
+
+
+  using FieldMetadata_TrackUuid =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEventDefaults>;
+
+  static constexpr FieldMetadata_TrackUuid kTrackUuid{};
+  void set_track_uuid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TrackUuid::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_ExtraCounterTrackUuids =
+    ::protozero::proto_utils::FieldMetadata<
+      31,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEventDefaults>;
+
+  static constexpr FieldMetadata_ExtraCounterTrackUuids kExtraCounterTrackUuids{};
+  void add_extra_counter_track_uuids(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ExtraCounterTrackUuids::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_ExtraDoubleCounterTrackUuids =
+    ::protozero::proto_utils::FieldMetadata<
+      45,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEventDefaults>;
+
+  static constexpr FieldMetadata_ExtraDoubleCounterTrackUuids kExtraDoubleCounterTrackUuids{};
+  void add_extra_double_counter_track_uuids(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ExtraDoubleCounterTrackUuids::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 TrackEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/51, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TrackEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrackEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrackEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_category_iids() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> category_iids() const { return GetRepeated<uint64_t>(3); }
+  bool has_categories() const { return at<22>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> categories() const { return GetRepeated<::protozero::ConstChars>(22); }
+  bool has_name_iid() const { return at<10>().valid(); }
+  uint64_t name_iid() const { return at<10>().as_uint64(); }
+  bool has_name() const { return at<23>().valid(); }
+  ::protozero::ConstChars name() const { return at<23>().as_string(); }
+  bool has_type() const { return at<9>().valid(); }
+  int32_t type() const { return at<9>().as_int32(); }
+  bool has_track_uuid() const { return at<11>().valid(); }
+  uint64_t track_uuid() const { return at<11>().as_uint64(); }
+  bool has_counter_value() const { return at<30>().valid(); }
+  int64_t counter_value() const { return at<30>().as_int64(); }
+  bool has_double_counter_value() const { return at<44>().valid(); }
+  double double_counter_value() const { return at<44>().as_double(); }
+  bool has_extra_counter_track_uuids() const { return at<31>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> extra_counter_track_uuids() const { return GetRepeated<uint64_t>(31); }
+  bool has_extra_counter_values() const { return at<12>().valid(); }
+  ::protozero::RepeatedFieldIterator<int64_t> extra_counter_values() const { return GetRepeated<int64_t>(12); }
+  bool has_extra_double_counter_track_uuids() const { return at<45>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> extra_double_counter_track_uuids() const { return GetRepeated<uint64_t>(45); }
+  bool has_extra_double_counter_values() const { return at<46>().valid(); }
+  ::protozero::RepeatedFieldIterator<double> extra_double_counter_values() const { return GetRepeated<double>(46); }
+  bool has_flow_ids_old() const { return at<36>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> flow_ids_old() const { return GetRepeated<uint64_t>(36); }
+  bool has_flow_ids() const { return at<47>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> flow_ids() const { return GetRepeated<uint64_t>(47); }
+  bool has_terminating_flow_ids_old() const { return at<42>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> terminating_flow_ids_old() const { return GetRepeated<uint64_t>(42); }
+  bool has_terminating_flow_ids() const { return at<48>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> terminating_flow_ids() const { return GetRepeated<uint64_t>(48); }
+  bool has_debug_annotations() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> debug_annotations() const { return GetRepeated<::protozero::ConstBytes>(4); }
+  bool has_task_execution() const { return at<5>().valid(); }
+  ::protozero::ConstBytes task_execution() const { return at<5>().as_bytes(); }
+  bool has_log_message() const { return at<21>().valid(); }
+  ::protozero::ConstBytes log_message() const { return at<21>().as_bytes(); }
+  bool has_cc_scheduler_state() const { return at<24>().valid(); }
+  ::protozero::ConstBytes cc_scheduler_state() const { return at<24>().as_bytes(); }
+  bool has_chrome_user_event() const { return at<25>().valid(); }
+  ::protozero::ConstBytes chrome_user_event() const { return at<25>().as_bytes(); }
+  bool has_chrome_keyed_service() const { return at<26>().valid(); }
+  ::protozero::ConstBytes chrome_keyed_service() const { return at<26>().as_bytes(); }
+  bool has_chrome_legacy_ipc() const { return at<27>().valid(); }
+  ::protozero::ConstBytes chrome_legacy_ipc() const { return at<27>().as_bytes(); }
+  bool has_chrome_histogram_sample() const { return at<28>().valid(); }
+  ::protozero::ConstBytes chrome_histogram_sample() const { return at<28>().as_bytes(); }
+  bool has_chrome_latency_info() const { return at<29>().valid(); }
+  ::protozero::ConstBytes chrome_latency_info() const { return at<29>().as_bytes(); }
+  bool has_chrome_frame_reporter() const { return at<32>().valid(); }
+  ::protozero::ConstBytes chrome_frame_reporter() const { return at<32>().as_bytes(); }
+  bool has_chrome_application_state_info() const { return at<39>().valid(); }
+  ::protozero::ConstBytes chrome_application_state_info() const { return at<39>().as_bytes(); }
+  bool has_chrome_renderer_scheduler_state() const { return at<40>().valid(); }
+  ::protozero::ConstBytes chrome_renderer_scheduler_state() const { return at<40>().as_bytes(); }
+  bool has_chrome_window_handle_event_info() const { return at<41>().valid(); }
+  ::protozero::ConstBytes chrome_window_handle_event_info() const { return at<41>().as_bytes(); }
+  bool has_chrome_content_settings_event_info() const { return at<43>().valid(); }
+  ::protozero::ConstBytes chrome_content_settings_event_info() const { return at<43>().as_bytes(); }
+  bool has_chrome_active_processes() const { return at<49>().valid(); }
+  ::protozero::ConstBytes chrome_active_processes() const { return at<49>().as_bytes(); }
+  bool has_screenshot() const { return at<50>().valid(); }
+  ::protozero::ConstBytes screenshot() const { return at<50>().as_bytes(); }
+  bool has_pixel_modem_event_insight() const { return at<51>().valid(); }
+  ::protozero::ConstBytes pixel_modem_event_insight() const { return at<51>().as_bytes(); }
+  bool has_source_location() const { return at<33>().valid(); }
+  ::protozero::ConstBytes source_location() const { return at<33>().as_bytes(); }
+  bool has_source_location_iid() const { return at<34>().valid(); }
+  uint64_t source_location_iid() const { return at<34>().as_uint64(); }
+  bool has_chrome_message_pump() const { return at<35>().valid(); }
+  ::protozero::ConstBytes chrome_message_pump() const { return at<35>().as_bytes(); }
+  bool has_chrome_mojo_event_info() const { return at<38>().valid(); }
+  ::protozero::ConstBytes chrome_mojo_event_info() const { return at<38>().as_bytes(); }
+  bool has_timestamp_delta_us() const { return at<1>().valid(); }
+  int64_t timestamp_delta_us() const { return at<1>().as_int64(); }
+  bool has_timestamp_absolute_us() const { return at<16>().valid(); }
+  int64_t timestamp_absolute_us() const { return at<16>().as_int64(); }
+  bool has_thread_time_delta_us() const { return at<2>().valid(); }
+  int64_t thread_time_delta_us() const { return at<2>().as_int64(); }
+  bool has_thread_time_absolute_us() const { return at<17>().valid(); }
+  int64_t thread_time_absolute_us() const { return at<17>().as_int64(); }
+  bool has_thread_instruction_count_delta() const { return at<8>().valid(); }
+  int64_t thread_instruction_count_delta() const { return at<8>().as_int64(); }
+  bool has_thread_instruction_count_absolute() const { return at<20>().valid(); }
+  int64_t thread_instruction_count_absolute() const { return at<20>().as_int64(); }
+  bool has_legacy_event() const { return at<6>().valid(); }
+  ::protozero::ConstBytes legacy_event() const { return at<6>().as_bytes(); }
+};
+
+class TrackEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrackEvent_Decoder;
+  enum : int32_t {
+    kCategoryIidsFieldNumber = 3,
+    kCategoriesFieldNumber = 22,
+    kNameIidFieldNumber = 10,
+    kNameFieldNumber = 23,
+    kTypeFieldNumber = 9,
+    kTrackUuidFieldNumber = 11,
+    kCounterValueFieldNumber = 30,
+    kDoubleCounterValueFieldNumber = 44,
+    kExtraCounterTrackUuidsFieldNumber = 31,
+    kExtraCounterValuesFieldNumber = 12,
+    kExtraDoubleCounterTrackUuidsFieldNumber = 45,
+    kExtraDoubleCounterValuesFieldNumber = 46,
+    kFlowIdsOldFieldNumber = 36,
+    kFlowIdsFieldNumber = 47,
+    kTerminatingFlowIdsOldFieldNumber = 42,
+    kTerminatingFlowIdsFieldNumber = 48,
+    kDebugAnnotationsFieldNumber = 4,
+    kTaskExecutionFieldNumber = 5,
+    kLogMessageFieldNumber = 21,
+    kCcSchedulerStateFieldNumber = 24,
+    kChromeUserEventFieldNumber = 25,
+    kChromeKeyedServiceFieldNumber = 26,
+    kChromeLegacyIpcFieldNumber = 27,
+    kChromeHistogramSampleFieldNumber = 28,
+    kChromeLatencyInfoFieldNumber = 29,
+    kChromeFrameReporterFieldNumber = 32,
+    kChromeApplicationStateInfoFieldNumber = 39,
+    kChromeRendererSchedulerStateFieldNumber = 40,
+    kChromeWindowHandleEventInfoFieldNumber = 41,
+    kChromeContentSettingsEventInfoFieldNumber = 43,
+    kChromeActiveProcessesFieldNumber = 49,
+    kScreenshotFieldNumber = 50,
+    kPixelModemEventInsightFieldNumber = 51,
+    kSourceLocationFieldNumber = 33,
+    kSourceLocationIidFieldNumber = 34,
+    kChromeMessagePumpFieldNumber = 35,
+    kChromeMojoEventInfoFieldNumber = 38,
+    kTimestampDeltaUsFieldNumber = 1,
+    kTimestampAbsoluteUsFieldNumber = 16,
+    kThreadTimeDeltaUsFieldNumber = 2,
+    kThreadTimeAbsoluteUsFieldNumber = 17,
+    kThreadInstructionCountDeltaFieldNumber = 8,
+    kThreadInstructionCountAbsoluteFieldNumber = 20,
+    kLegacyEventFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrackEvent"; }
+
+  using LegacyEvent = ::perfetto::protos::pbzero::TrackEvent_LegacyEvent;
+
+  using Type = ::perfetto::protos::pbzero::TrackEvent_Type;
+  static inline const char* Type_Name(Type value) {
+    return ::perfetto::protos::pbzero::TrackEvent_Type_Name(value);
+  }
+  static inline const Type TYPE_UNSPECIFIED = Type::TYPE_UNSPECIFIED;
+  static inline const Type TYPE_SLICE_BEGIN = Type::TYPE_SLICE_BEGIN;
+  static inline const Type TYPE_SLICE_END = Type::TYPE_SLICE_END;
+  static inline const Type TYPE_INSTANT = Type::TYPE_INSTANT;
+  static inline const Type TYPE_COUNTER = Type::TYPE_COUNTER;
+
+  using FieldMetadata_CategoryIids =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_CategoryIids kCategoryIids{};
+  void add_category_iids(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CategoryIids::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_Categories =
+    ::protozero::proto_utils::FieldMetadata<
+      22,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_Categories kCategories{};
+  void add_categories(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Categories::kFieldId, data, size);
+  }
+  void add_categories(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Categories::kFieldId, chars.data, chars.size);
+  }
+  void add_categories(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Categories::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_NameIid =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_NameIid kNameIid{};
+  void set_name_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NameIid::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      23,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      TrackEvent_Type,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(TrackEvent_Type value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::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_TrackUuid =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_TrackUuid kTrackUuid{};
+  void set_track_uuid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TrackUuid::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_CounterValue =
+    ::protozero::proto_utils::FieldMetadata<
+      30,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_CounterValue kCounterValue{};
+  void set_counter_value(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CounterValue::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_DoubleCounterValue =
+    ::protozero::proto_utils::FieldMetadata<
+      44,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_DoubleCounterValue kDoubleCounterValue{};
+  void set_double_counter_value(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_DoubleCounterValue::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);
+  }
+
+  using FieldMetadata_ExtraCounterTrackUuids =
+    ::protozero::proto_utils::FieldMetadata<
+      31,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ExtraCounterTrackUuids kExtraCounterTrackUuids{};
+  void add_extra_counter_track_uuids(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ExtraCounterTrackUuids::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_ExtraCounterValues =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ExtraCounterValues kExtraCounterValues{};
+  void add_extra_counter_values(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ExtraCounterValues::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_ExtraDoubleCounterTrackUuids =
+    ::protozero::proto_utils::FieldMetadata<
+      45,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ExtraDoubleCounterTrackUuids kExtraDoubleCounterTrackUuids{};
+  void add_extra_double_counter_track_uuids(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ExtraDoubleCounterTrackUuids::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_ExtraDoubleCounterValues =
+    ::protozero::proto_utils::FieldMetadata<
+      46,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ExtraDoubleCounterValues kExtraDoubleCounterValues{};
+  void add_extra_double_counter_values(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_ExtraDoubleCounterValues::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);
+  }
+
+  using FieldMetadata_FlowIdsOld =
+    ::protozero::proto_utils::FieldMetadata<
+      36,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_FlowIdsOld kFlowIdsOld{};
+  void add_flow_ids_old(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FlowIdsOld::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_FlowIds =
+    ::protozero::proto_utils::FieldMetadata<
+      47,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64,
+      uint64_t,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_FlowIds kFlowIds{};
+  void add_flow_ids(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FlowIds::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TerminatingFlowIdsOld =
+    ::protozero::proto_utils::FieldMetadata<
+      42,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_TerminatingFlowIdsOld kTerminatingFlowIdsOld{};
+  void add_terminating_flow_ids_old(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TerminatingFlowIdsOld::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_TerminatingFlowIds =
+    ::protozero::proto_utils::FieldMetadata<
+      48,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64,
+      uint64_t,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_TerminatingFlowIds kTerminatingFlowIds{};
+  void add_terminating_flow_ids(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TerminatingFlowIds::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DebugAnnotations =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DebugAnnotation,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_DebugAnnotations kDebugAnnotations{};
+  template <typename T = DebugAnnotation> T* add_debug_annotations() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_TaskExecution =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TaskExecution,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_TaskExecution kTaskExecution{};
+  template <typename T = TaskExecution> T* set_task_execution() {
+    return BeginNestedMessage<T>(5);
+  }
+
+
+  using FieldMetadata_LogMessage =
+    ::protozero::proto_utils::FieldMetadata<
+      21,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      LogMessage,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_LogMessage kLogMessage{};
+  template <typename T = LogMessage> T* set_log_message() {
+    return BeginNestedMessage<T>(21);
+  }
+
+
+  using FieldMetadata_CcSchedulerState =
+    ::protozero::proto_utils::FieldMetadata<
+      24,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeCompositorSchedulerState,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_CcSchedulerState kCcSchedulerState{};
+  template <typename T = ChromeCompositorSchedulerState> T* set_cc_scheduler_state() {
+    return BeginNestedMessage<T>(24);
+  }
+
+
+  using FieldMetadata_ChromeUserEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      25,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeUserEvent,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ChromeUserEvent kChromeUserEvent{};
+  template <typename T = ChromeUserEvent> T* set_chrome_user_event() {
+    return BeginNestedMessage<T>(25);
+  }
+
+
+  using FieldMetadata_ChromeKeyedService =
+    ::protozero::proto_utils::FieldMetadata<
+      26,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeKeyedService,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ChromeKeyedService kChromeKeyedService{};
+  template <typename T = ChromeKeyedService> T* set_chrome_keyed_service() {
+    return BeginNestedMessage<T>(26);
+  }
+
+
+  using FieldMetadata_ChromeLegacyIpc =
+    ::protozero::proto_utils::FieldMetadata<
+      27,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeLegacyIpc,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ChromeLegacyIpc kChromeLegacyIpc{};
+  template <typename T = ChromeLegacyIpc> T* set_chrome_legacy_ipc() {
+    return BeginNestedMessage<T>(27);
+  }
+
+
+  using FieldMetadata_ChromeHistogramSample =
+    ::protozero::proto_utils::FieldMetadata<
+      28,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeHistogramSample,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ChromeHistogramSample kChromeHistogramSample{};
+  template <typename T = ChromeHistogramSample> T* set_chrome_histogram_sample() {
+    return BeginNestedMessage<T>(28);
+  }
+
+
+  using FieldMetadata_ChromeLatencyInfo =
+    ::protozero::proto_utils::FieldMetadata<
+      29,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeLatencyInfo,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ChromeLatencyInfo kChromeLatencyInfo{};
+  template <typename T = ChromeLatencyInfo> T* set_chrome_latency_info() {
+    return BeginNestedMessage<T>(29);
+  }
+
+
+  using FieldMetadata_ChromeFrameReporter =
+    ::protozero::proto_utils::FieldMetadata<
+      32,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeFrameReporter,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ChromeFrameReporter kChromeFrameReporter{};
+  template <typename T = ChromeFrameReporter> T* set_chrome_frame_reporter() {
+    return BeginNestedMessage<T>(32);
+  }
+
+
+  using FieldMetadata_ChromeApplicationStateInfo =
+    ::protozero::proto_utils::FieldMetadata<
+      39,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeApplicationStateInfo,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ChromeApplicationStateInfo kChromeApplicationStateInfo{};
+  template <typename T = ChromeApplicationStateInfo> T* set_chrome_application_state_info() {
+    return BeginNestedMessage<T>(39);
+  }
+
+
+  using FieldMetadata_ChromeRendererSchedulerState =
+    ::protozero::proto_utils::FieldMetadata<
+      40,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeRendererSchedulerState,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ChromeRendererSchedulerState kChromeRendererSchedulerState{};
+  template <typename T = ChromeRendererSchedulerState> T* set_chrome_renderer_scheduler_state() {
+    return BeginNestedMessage<T>(40);
+  }
+
+
+  using FieldMetadata_ChromeWindowHandleEventInfo =
+    ::protozero::proto_utils::FieldMetadata<
+      41,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeWindowHandleEventInfo,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ChromeWindowHandleEventInfo kChromeWindowHandleEventInfo{};
+  template <typename T = ChromeWindowHandleEventInfo> T* set_chrome_window_handle_event_info() {
+    return BeginNestedMessage<T>(41);
+  }
+
+
+  using FieldMetadata_ChromeContentSettingsEventInfo =
+    ::protozero::proto_utils::FieldMetadata<
+      43,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeContentSettingsEventInfo,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ChromeContentSettingsEventInfo kChromeContentSettingsEventInfo{};
+  template <typename T = ChromeContentSettingsEventInfo> T* set_chrome_content_settings_event_info() {
+    return BeginNestedMessage<T>(43);
+  }
+
+
+  using FieldMetadata_ChromeActiveProcesses =
+    ::protozero::proto_utils::FieldMetadata<
+      49,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeActiveProcesses,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ChromeActiveProcesses kChromeActiveProcesses{};
+  template <typename T = ChromeActiveProcesses> T* set_chrome_active_processes() {
+    return BeginNestedMessage<T>(49);
+  }
+
+
+  using FieldMetadata_Screenshot =
+    ::protozero::proto_utils::FieldMetadata<
+      50,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Screenshot,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_Screenshot kScreenshot{};
+  template <typename T = Screenshot> T* set_screenshot() {
+    return BeginNestedMessage<T>(50);
+  }
+
+
+  using FieldMetadata_PixelModemEventInsight =
+    ::protozero::proto_utils::FieldMetadata<
+      51,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PixelModemEventInsight,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_PixelModemEventInsight kPixelModemEventInsight{};
+  template <typename T = PixelModemEventInsight> T* set_pixel_modem_event_insight() {
+    return BeginNestedMessage<T>(51);
+  }
+
+
+  using FieldMetadata_SourceLocation =
+    ::protozero::proto_utils::FieldMetadata<
+      33,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SourceLocation,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_SourceLocation kSourceLocation{};
+  template <typename T = SourceLocation> T* set_source_location() {
+    return BeginNestedMessage<T>(33);
+  }
+
+
+  using FieldMetadata_SourceLocationIid =
+    ::protozero::proto_utils::FieldMetadata<
+      34,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_SourceLocationIid kSourceLocationIid{};
+  void set_source_location_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SourceLocationIid::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_ChromeMessagePump =
+    ::protozero::proto_utils::FieldMetadata<
+      35,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeMessagePump,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ChromeMessagePump kChromeMessagePump{};
+  template <typename T = ChromeMessagePump> T* set_chrome_message_pump() {
+    return BeginNestedMessage<T>(35);
+  }
+
+
+  using FieldMetadata_ChromeMojoEventInfo =
+    ::protozero::proto_utils::FieldMetadata<
+      38,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeMojoEventInfo,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ChromeMojoEventInfo kChromeMojoEventInfo{};
+  template <typename T = ChromeMojoEventInfo> T* set_chrome_mojo_event_info() {
+    return BeginNestedMessage<T>(38);
+  }
+
+
+  using FieldMetadata_TimestampDeltaUs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_TimestampDeltaUs kTimestampDeltaUs{};
+  void set_timestamp_delta_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimestampDeltaUs::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_TimestampAbsoluteUs =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_TimestampAbsoluteUs kTimestampAbsoluteUs{};
+  void set_timestamp_absolute_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimestampAbsoluteUs::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_ThreadTimeDeltaUs =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ThreadTimeDeltaUs kThreadTimeDeltaUs{};
+  void set_thread_time_delta_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ThreadTimeDeltaUs::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_ThreadTimeAbsoluteUs =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ThreadTimeAbsoluteUs kThreadTimeAbsoluteUs{};
+  void set_thread_time_absolute_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ThreadTimeAbsoluteUs::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_ThreadInstructionCountDelta =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ThreadInstructionCountDelta kThreadInstructionCountDelta{};
+  void set_thread_instruction_count_delta(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ThreadInstructionCountDelta::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_ThreadInstructionCountAbsolute =
+    ::protozero::proto_utils::FieldMetadata<
+      20,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ThreadInstructionCountAbsolute kThreadInstructionCountAbsolute{};
+  void set_thread_instruction_count_absolute(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ThreadInstructionCountAbsolute::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_LegacyEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrackEvent_LegacyEvent,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_LegacyEvent kLegacyEvent{};
+  template <typename T = TrackEvent_LegacyEvent> T* set_legacy_event() {
+    return BeginNestedMessage<T>(6);
+  }
+
+};
+
+class TrackEvent_LegacyEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/19, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrackEvent_LegacyEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrackEvent_LegacyEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrackEvent_LegacyEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name_iid() const { return at<1>().valid(); }
+  uint64_t name_iid() const { return at<1>().as_uint64(); }
+  bool has_phase() const { return at<2>().valid(); }
+  int32_t phase() const { return at<2>().as_int32(); }
+  bool has_duration_us() const { return at<3>().valid(); }
+  int64_t duration_us() const { return at<3>().as_int64(); }
+  bool has_thread_duration_us() const { return at<4>().valid(); }
+  int64_t thread_duration_us() const { return at<4>().as_int64(); }
+  bool has_thread_instruction_delta() const { return at<15>().valid(); }
+  int64_t thread_instruction_delta() const { return at<15>().as_int64(); }
+  bool has_unscoped_id() const { return at<6>().valid(); }
+  uint64_t unscoped_id() const { return at<6>().as_uint64(); }
+  bool has_local_id() const { return at<10>().valid(); }
+  uint64_t local_id() const { return at<10>().as_uint64(); }
+  bool has_global_id() const { return at<11>().valid(); }
+  uint64_t global_id() const { return at<11>().as_uint64(); }
+  bool has_id_scope() const { return at<7>().valid(); }
+  ::protozero::ConstChars id_scope() const { return at<7>().as_string(); }
+  bool has_use_async_tts() const { return at<9>().valid(); }
+  bool use_async_tts() const { return at<9>().as_bool(); }
+  bool has_bind_id() const { return at<8>().valid(); }
+  uint64_t bind_id() const { return at<8>().as_uint64(); }
+  bool has_bind_to_enclosing() const { return at<12>().valid(); }
+  bool bind_to_enclosing() const { return at<12>().as_bool(); }
+  bool has_flow_direction() const { return at<13>().valid(); }
+  int32_t flow_direction() const { return at<13>().as_int32(); }
+  bool has_instant_event_scope() const { return at<14>().valid(); }
+  int32_t instant_event_scope() const { return at<14>().as_int32(); }
+  bool has_pid_override() const { return at<18>().valid(); }
+  int32_t pid_override() const { return at<18>().as_int32(); }
+  bool has_tid_override() const { return at<19>().valid(); }
+  int32_t tid_override() const { return at<19>().as_int32(); }
+};
+
+class TrackEvent_LegacyEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrackEvent_LegacyEvent_Decoder;
+  enum : int32_t {
+    kNameIidFieldNumber = 1,
+    kPhaseFieldNumber = 2,
+    kDurationUsFieldNumber = 3,
+    kThreadDurationUsFieldNumber = 4,
+    kThreadInstructionDeltaFieldNumber = 15,
+    kUnscopedIdFieldNumber = 6,
+    kLocalIdFieldNumber = 10,
+    kGlobalIdFieldNumber = 11,
+    kIdScopeFieldNumber = 7,
+    kUseAsyncTtsFieldNumber = 9,
+    kBindIdFieldNumber = 8,
+    kBindToEnclosingFieldNumber = 12,
+    kFlowDirectionFieldNumber = 13,
+    kInstantEventScopeFieldNumber = 14,
+    kPidOverrideFieldNumber = 18,
+    kTidOverrideFieldNumber = 19,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrackEvent.LegacyEvent"; }
+
+
+  using FlowDirection = ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_FlowDirection;
+  static inline const char* FlowDirection_Name(FlowDirection value) {
+    return ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_FlowDirection_Name(value);
+  }
+
+  using InstantEventScope = ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_InstantEventScope;
+  static inline const char* InstantEventScope_Name(InstantEventScope value) {
+    return ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_InstantEventScope_Name(value);
+  }
+  static inline const FlowDirection FLOW_UNSPECIFIED = FlowDirection::FLOW_UNSPECIFIED;
+  static inline const FlowDirection FLOW_IN = FlowDirection::FLOW_IN;
+  static inline const FlowDirection FLOW_OUT = FlowDirection::FLOW_OUT;
+  static inline const FlowDirection FLOW_INOUT = FlowDirection::FLOW_INOUT;
+  static inline const InstantEventScope SCOPE_UNSPECIFIED = InstantEventScope::SCOPE_UNSPECIFIED;
+  static inline const InstantEventScope SCOPE_GLOBAL = InstantEventScope::SCOPE_GLOBAL;
+  static inline const InstantEventScope SCOPE_PROCESS = InstantEventScope::SCOPE_PROCESS;
+  static inline const InstantEventScope SCOPE_THREAD = InstantEventScope::SCOPE_THREAD;
+
+  using FieldMetadata_NameIid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEvent_LegacyEvent>;
+
+  static constexpr FieldMetadata_NameIid kNameIid{};
+  void set_name_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NameIid::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_Phase =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TrackEvent_LegacyEvent>;
+
+  static constexpr FieldMetadata_Phase kPhase{};
+  void set_phase(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Phase::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_DurationUs =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TrackEvent_LegacyEvent>;
+
+  static constexpr FieldMetadata_DurationUs kDurationUs{};
+  void set_duration_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DurationUs::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_ThreadDurationUs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TrackEvent_LegacyEvent>;
+
+  static constexpr FieldMetadata_ThreadDurationUs kThreadDurationUs{};
+  void set_thread_duration_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ThreadDurationUs::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_ThreadInstructionDelta =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TrackEvent_LegacyEvent>;
+
+  static constexpr FieldMetadata_ThreadInstructionDelta kThreadInstructionDelta{};
+  void set_thread_instruction_delta(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ThreadInstructionDelta::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_UnscopedId =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEvent_LegacyEvent>;
+
+  static constexpr FieldMetadata_UnscopedId kUnscopedId{};
+  void set_unscoped_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UnscopedId::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_LocalId =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEvent_LegacyEvent>;
+
+  static constexpr FieldMetadata_LocalId kLocalId{};
+  void set_local_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LocalId::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_GlobalId =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEvent_LegacyEvent>;
+
+  static constexpr FieldMetadata_GlobalId kGlobalId{};
+  void set_global_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GlobalId::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_IdScope =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrackEvent_LegacyEvent>;
+
+  static constexpr FieldMetadata_IdScope kIdScope{};
+  void set_id_scope(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_IdScope::kFieldId, data, size);
+  }
+  void set_id_scope(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_IdScope::kFieldId, chars.data, chars.size);
+  }
+  void set_id_scope(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_IdScope::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_UseAsyncTts =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TrackEvent_LegacyEvent>;
+
+  static constexpr FieldMetadata_UseAsyncTts kUseAsyncTts{};
+  void set_use_async_tts(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_UseAsyncTts::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_BindId =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEvent_LegacyEvent>;
+
+  static constexpr FieldMetadata_BindId kBindId{};
+  void set_bind_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BindId::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_BindToEnclosing =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TrackEvent_LegacyEvent>;
+
+  static constexpr FieldMetadata_BindToEnclosing kBindToEnclosing{};
+  void set_bind_to_enclosing(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_BindToEnclosing::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_FlowDirection =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      TrackEvent_LegacyEvent_FlowDirection,
+      TrackEvent_LegacyEvent>;
+
+  static constexpr FieldMetadata_FlowDirection kFlowDirection{};
+  void set_flow_direction(TrackEvent_LegacyEvent_FlowDirection value) {
+    static constexpr uint32_t field_id = FieldMetadata_FlowDirection::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_InstantEventScope =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      TrackEvent_LegacyEvent_InstantEventScope,
+      TrackEvent_LegacyEvent>;
+
+  static constexpr FieldMetadata_InstantEventScope kInstantEventScope{};
+  void set_instant_event_scope(TrackEvent_LegacyEvent_InstantEventScope value) {
+    static constexpr uint32_t field_id = FieldMetadata_InstantEventScope::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_PidOverride =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TrackEvent_LegacyEvent>;
+
+  static constexpr FieldMetadata_PidOverride kPidOverride{};
+  void set_pid_override(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PidOverride::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_TidOverride =
+    ::protozero::proto_utils::FieldMetadata<
+      19,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TrackEvent_LegacyEvent>;
+
+  static constexpr FieldMetadata_TidOverride kTidOverride{};
+  void set_tid_override(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TidOverride::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_TRACK_EVENT_STATE_TRACKER_H_
+#define INCLUDE_PERFETTO_TRACING_TRACK_EVENT_STATE_TRACKER_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_event.pbzero.h"
+
+#include <map>
+#include <string>
+#include <vector>
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class TracePacket_Decoder;
+class TrackEvent;
+class TrackEvent_Decoder;
+}  // namespace pbzero
+}  // namespace protos
+
+// A helper for keeping track of incremental state when intercepting track
+// events.
+class PERFETTO_EXPORT_COMPONENT TrackEventStateTracker {
+ public:
+  ~TrackEventStateTracker();
+
+  struct StackFrame {
+    uint64_t timestamp{};
+
+    // Only one of |name| and |name_iid| will be set.
+    std::string name;
+    uint64_t name_iid{};
+    uint64_t name_hash{};
+
+    // Only one of |category| and |category_iid| will be set.
+    std::string category;
+    uint64_t category_iid{};
+  };
+
+  struct Track {
+    uint64_t uuid{};
+    uint32_t index{};  // Ordinal number for the track in the tracing session.
+
+    std::string name;
+    int64_t pid{};
+    int64_t tid{};
+
+    // Opaque user data associated with the track.
+    std::vector<uint8_t> user_data;
+
+    // Stack of opened slices on this track.
+    std::vector<StackFrame> stack;
+  };
+
+  // State for a single trace writer sequence (typically a single thread).
+  struct SequenceState {
+    // Trace packet sequence defaults.
+    Track track;
+
+    // Interned state.
+#if PERFETTO_DCHECK_IS_ON()
+    uint32_t sequence_id{};
+#endif
+    std::map<uint64_t /*iid*/, std::string> event_names;
+    std::map<uint64_t /*iid*/, std::string> event_categories;
+    std::map<uint64_t /*iid*/, std::string> debug_annotation_names;
+    // Current absolute timestamp of the incremental clock.
+    uint64_t most_recent_absolute_time_ns = 0;
+    // default_clock_id == 0 means, no default clock_id is set.
+    uint32_t default_clock_id = 0;
+  };
+
+  // State for the entire tracing session. Shared by all trace writer sequences
+  // participating in the session.
+  struct SessionState {
+    // Non-thread-bound tracks.
+    std::map<uint64_t /*uuid*/, Track> tracks;
+  };
+
+  // Represents a single decoded track event (without arguments).
+  struct ParsedTrackEvent {
+    explicit ParsedTrackEvent(
+        const perfetto::protos::pbzero::TrackEvent::Decoder&);
+
+    // Underlying event.
+    const perfetto::protos::pbzero::TrackEvent::Decoder& track_event;
+
+    // Event metadata.
+    uint64_t timestamp_ns{};
+    uint64_t duration_ns{};
+
+    size_t stack_depth{};
+
+    protozero::ConstChars category{};
+    protozero::ConstChars name{};
+    uint64_t name_hash{};
+  };
+
+  // Interface used by the tracker to access tracing session and sequence state
+  // and to report parsed track events.
+  class PERFETTO_EXPORT_COMPONENT Delegate {
+   public:
+    virtual ~Delegate();
+
+    // Called to retrieve the session-global state shared by all sequences. The
+    // returned pointer must remain valid (locked) throughout the call to
+    // |ProcessTracePacket|.
+    virtual SessionState* GetSessionState() = 0;
+
+    // Called when the metadata (e.g., name) for a track changes. |Track| can be
+    // modified by the callback to attach user data.
+    virtual void OnTrackUpdated(Track&) = 0;
+
+    // If the packet given to |ProcessTracePacket| contains a track event, this
+    // method is called to report the properties of that event. Note that memory
+    // pointers in |TrackEvent| will only be valid during this call.
+    virtual void OnTrackEvent(const Track&, const ParsedTrackEvent&) = 0;
+  };
+
+  // Process a single trace packet, reporting any contained track event back via
+  // the delegate interface. |SequenceState| must correspond to the sequence
+  // that was used to write the packet.
+  static void ProcessTracePacket(Delegate&,
+                                 SequenceState&,
+                                 const protos::pbzero::TracePacket_Decoder&);
+
+ private:
+  static void UpdateIncrementalState(
+      Delegate&,
+      SequenceState&,
+      const protos::pbzero::TracePacket_Decoder&);
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_TRACK_EVENT_STATE_TRACKER_H_
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_CONSOLE_INTERCEPTOR_H_
+#define INCLUDE_PERFETTO_TRACING_CONSOLE_INTERCEPTOR_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/interceptor.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track_event_state_tracker.h"
+
+#include <stdarg.h>
+
+#include <functional>
+#include <map>
+#include <vector>
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+
+#if defined(__GNUC__) || defined(__clang__)
+#define PERFETTO_PRINTF_ATTR \
+  __attribute__((format(printf, /*format_index=*/2, /*first_to_check=*/3)))
+#else
+#define PERFETTO_PRINTF_ATTR
+#endif
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && !defined(STDOUT_FILENO)
+#define STDOUT_FILENO 1
+#define STDERR_FILENO 2
+#endif
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class DebugAnnotation_Decoder;
+class TracePacket_Decoder;
+class TrackEvent_Decoder;
+}  // namespace pbzero
+}  // namespace protos
+
+struct ConsoleColor;
+
+class PERFETTO_EXPORT_COMPONENT ConsoleInterceptor
+    : public Interceptor<ConsoleInterceptor> {
+ public:
+  ~ConsoleInterceptor() override;
+
+  static void Register();
+  static void OnTracePacket(InterceptorContext context);
+
+  static void SetOutputFdForTesting(int fd);
+
+  void OnSetup(const SetupArgs&) override;
+  void OnStart(const StartArgs&) override;
+  void OnStop(const StopArgs&) override;
+
+  struct ThreadLocalState : public InterceptorBase::ThreadLocalState {
+    ThreadLocalState(ThreadLocalStateArgs&);
+    ~ThreadLocalState() override;
+
+    // Destination file. Assumed to stay valid until the program ends (i.e., is
+    // stderr or stdout).
+    int fd{};
+    bool use_colors{};
+
+    // Messages up to this length are buffered and written atomically. If a
+    // message is longer, it will be printed with multiple writes.
+    std::array<char, 1024> message_buffer{};
+    size_t buffer_pos{};
+
+    // We only support a single trace writer sequence per thread, so the
+    // sequence state is stored in TLS.
+    TrackEventStateTracker::SequenceState sequence_state;
+    uint64_t start_time_ns{};
+  };
+
+ private:
+  class Delegate;
+
+  // Appends a formatted message to |message_buffer_| or directly to the output
+  // file if the buffer is full.
+  static void Printf(InterceptorContext& context,
+                     const char* format,
+                     ...) PERFETTO_PRINTF_ATTR;
+  static void Flush(InterceptorContext& context);
+  static void SetColor(InterceptorContext& context, const ConsoleColor&);
+  static void SetColor(InterceptorContext& context, const char*);
+
+  static void PrintDebugAnnotations(InterceptorContext&,
+                                    const protos::pbzero::TrackEvent_Decoder&,
+                                    const ConsoleColor& slice_color,
+                                    const ConsoleColor& highlight_color);
+  static void PrintDebugAnnotationName(
+      InterceptorContext&,
+      const perfetto::protos::pbzero::DebugAnnotation_Decoder& annotation);
+  static void PrintDebugAnnotationValue(
+      InterceptorContext&,
+      const perfetto::protos::pbzero::DebugAnnotation_Decoder& annotation);
+
+  int fd_ = STDOUT_FILENO;
+  bool use_colors_ = true;
+
+  TrackEventStateTracker::SessionState session_state_;
+  uint64_t start_time_ns_{};
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_CONSOLE_INTERCEPTOR_H_
+// gen_amalgamated begin header: include/perfetto/tracing/core/data_source_descriptor.h
+// gen_amalgamated begin header: gen/protos/perfetto/common/data_source_descriptor.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DATA_SOURCE_DESCRIPTOR_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DATA_SOURCE_DESCRIPTOR_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class DataSourceDescriptor;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT DataSourceDescriptor : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kNameFieldNumber = 1,
+    kIdFieldNumber = 7,
+    kWillNotifyOnStopFieldNumber = 2,
+    kWillNotifyOnStartFieldNumber = 3,
+    kHandlesIncrementalStateClearFieldNumber = 4,
+    kNoFlushFieldNumber = 9,
+    kGpuCounterDescriptorFieldNumber = 5,
+    kTrackEventDescriptorFieldNumber = 6,
+    kFtraceDescriptorFieldNumber = 8,
+  };
+
+  DataSourceDescriptor();
+  ~DataSourceDescriptor() override;
+  DataSourceDescriptor(DataSourceDescriptor&&) noexcept;
+  DataSourceDescriptor& operator=(DataSourceDescriptor&&);
+  DataSourceDescriptor(const DataSourceDescriptor&);
+  DataSourceDescriptor& operator=(const DataSourceDescriptor&);
+  bool operator==(const DataSourceDescriptor&) const;
+  bool operator!=(const DataSourceDescriptor& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name() const { return _has_field_[1]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
+
+  bool has_id() const { return _has_field_[7]; }
+  uint64_t id() const { return id_; }
+  void set_id(uint64_t value) { id_ = value; _has_field_.set(7); }
+
+  bool has_will_notify_on_stop() const { return _has_field_[2]; }
+  bool will_notify_on_stop() const { return will_notify_on_stop_; }
+  void set_will_notify_on_stop(bool value) { will_notify_on_stop_ = value; _has_field_.set(2); }
+
+  bool has_will_notify_on_start() const { return _has_field_[3]; }
+  bool will_notify_on_start() const { return will_notify_on_start_; }
+  void set_will_notify_on_start(bool value) { will_notify_on_start_ = value; _has_field_.set(3); }
+
+  bool has_handles_incremental_state_clear() const { return _has_field_[4]; }
+  bool handles_incremental_state_clear() const { return handles_incremental_state_clear_; }
+  void set_handles_incremental_state_clear(bool value) { handles_incremental_state_clear_ = value; _has_field_.set(4); }
+
+  bool has_no_flush() const { return _has_field_[9]; }
+  bool no_flush() const { return no_flush_; }
+  void set_no_flush(bool value) { no_flush_ = value; _has_field_.set(9); }
+
+  const std::string& gpu_counter_descriptor_raw() const { return gpu_counter_descriptor_; }
+  void set_gpu_counter_descriptor_raw(const std::string& raw) { gpu_counter_descriptor_ = raw; _has_field_.set(5); }
+
+  const std::string& track_event_descriptor_raw() const { return track_event_descriptor_; }
+  void set_track_event_descriptor_raw(const std::string& raw) { track_event_descriptor_ = raw; _has_field_.set(6); }
+
+  const std::string& ftrace_descriptor_raw() const { return ftrace_descriptor_; }
+  void set_ftrace_descriptor_raw(const std::string& raw) { ftrace_descriptor_ = raw; _has_field_.set(8); }
+
+ private:
+  std::string name_{};
+  uint64_t id_{};
+  bool will_notify_on_stop_{};
+  bool will_notify_on_start_{};
+  bool handles_incremental_state_clear_{};
+  bool no_flush_{};
+  std::string gpu_counter_descriptor_;  // [lazy=true]
+  std::string track_event_descriptor_;  // [lazy=true]
+  std::string ftrace_descriptor_;  // [lazy=true]
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<10> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DATA_SOURCE_DESCRIPTOR_PROTO_CPP_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_CORE_DATA_SOURCE_DESCRIPTOR_H_
+#define INCLUDE_PERFETTO_TRACING_CORE_DATA_SOURCE_DESCRIPTOR_H_
+
+// Creates the aliases in the ::perfetto namespace, doing things like:
+// using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
+// See comments in forward_decls.h for the historical reasons of this
+// indirection layer.
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
+
+#endif  // INCLUDE_PERFETTO_TRACING_CORE_DATA_SOURCE_DESCRIPTOR_H_
+// gen_amalgamated begin header: include/perfetto/tracing/core/trace_config.h
+// gen_amalgamated begin header: gen/protos/perfetto/config/trace_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TRACE_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TRACE_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class TraceConfig;
+class TraceConfig_CmdTraceStartDelay;
+class TraceConfig_AndroidReportConfig;
+class TraceConfig_TraceFilter;
+class TraceConfig_TraceFilter_StringFilterChain;
+class TraceConfig_TraceFilter_StringFilterRule;
+class TraceConfig_IncidentReportConfig;
+class TraceConfig_IncrementalStateConfig;
+class TraceConfig_TriggerConfig;
+class TraceConfig_TriggerConfig_Trigger;
+class TraceConfig_GuardrailOverrides;
+class TraceConfig_StatsdMetadata;
+class TraceConfig_ProducerConfig;
+class TraceConfig_BuiltinDataSource;
+class TraceConfig_DataSource;
+class DataSourceConfig;
+class TestConfig;
+class TestConfig_DummyFields;
+class InterceptorConfig;
+class ConsoleConfig;
+class ChromeConfig;
+class SystemInfoConfig;
+class TraceConfig_BufferConfig;
+enum TraceConfig_LockdownModeOperation : int;
+enum TraceConfig_CompressionType : int;
+enum TraceConfig_StatsdLogging : int;
+enum TraceConfig_TraceFilter_StringFilterPolicy : int;
+enum TraceConfig_TriggerConfig_TriggerMode : int;
+enum BuiltinClock : int;
+enum DataSourceConfig_SessionInitiator : int;
+enum ConsoleConfig_Output : int;
+enum ChromeConfig_ClientPriority : int;
+enum TraceConfig_BufferConfig_FillPolicy : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum TraceConfig_LockdownModeOperation : int {
+  TraceConfig_LockdownModeOperation_LOCKDOWN_UNCHANGED = 0,
+  TraceConfig_LockdownModeOperation_LOCKDOWN_CLEAR = 1,
+  TraceConfig_LockdownModeOperation_LOCKDOWN_SET = 2,
+};
+enum TraceConfig_CompressionType : int {
+  TraceConfig_CompressionType_COMPRESSION_TYPE_UNSPECIFIED = 0,
+  TraceConfig_CompressionType_COMPRESSION_TYPE_DEFLATE = 1,
+};
+enum TraceConfig_StatsdLogging : int {
+  TraceConfig_StatsdLogging_STATSD_LOGGING_UNSPECIFIED = 0,
+  TraceConfig_StatsdLogging_STATSD_LOGGING_ENABLED = 1,
+  TraceConfig_StatsdLogging_STATSD_LOGGING_DISABLED = 2,
+};
+enum TraceConfig_TraceFilter_StringFilterPolicy : int {
+  TraceConfig_TraceFilter_StringFilterPolicy_SFP_UNSPECIFIED = 0,
+  TraceConfig_TraceFilter_StringFilterPolicy_SFP_MATCH_REDACT_GROUPS = 1,
+  TraceConfig_TraceFilter_StringFilterPolicy_SFP_ATRACE_MATCH_REDACT_GROUPS = 2,
+  TraceConfig_TraceFilter_StringFilterPolicy_SFP_MATCH_BREAK = 3,
+  TraceConfig_TraceFilter_StringFilterPolicy_SFP_ATRACE_MATCH_BREAK = 4,
+  TraceConfig_TraceFilter_StringFilterPolicy_SFP_ATRACE_REPEATED_SEARCH_REDACT_GROUPS = 5,
+};
+enum TraceConfig_TriggerConfig_TriggerMode : int {
+  TraceConfig_TriggerConfig_TriggerMode_UNSPECIFIED = 0,
+  TraceConfig_TriggerConfig_TriggerMode_START_TRACING = 1,
+  TraceConfig_TriggerConfig_TriggerMode_STOP_TRACING = 2,
+  TraceConfig_TriggerConfig_TriggerMode_CLONE_SNAPSHOT = 4,
+};
+enum TraceConfig_BufferConfig_FillPolicy : int {
+  TraceConfig_BufferConfig_FillPolicy_UNSPECIFIED = 0,
+  TraceConfig_BufferConfig_FillPolicy_RING_BUFFER = 1,
+  TraceConfig_BufferConfig_FillPolicy_DISCARD = 2,
+};
+
+class PERFETTO_EXPORT_COMPONENT TraceConfig : public ::protozero::CppMessageObj {
+ public:
+  using BufferConfig = TraceConfig_BufferConfig;
+  using DataSource = TraceConfig_DataSource;
+  using BuiltinDataSource = TraceConfig_BuiltinDataSource;
+  using ProducerConfig = TraceConfig_ProducerConfig;
+  using StatsdMetadata = TraceConfig_StatsdMetadata;
+  using GuardrailOverrides = TraceConfig_GuardrailOverrides;
+  using TriggerConfig = TraceConfig_TriggerConfig;
+  using IncrementalStateConfig = TraceConfig_IncrementalStateConfig;
+  using IncidentReportConfig = TraceConfig_IncidentReportConfig;
+  using TraceFilter = TraceConfig_TraceFilter;
+  using AndroidReportConfig = TraceConfig_AndroidReportConfig;
+  using CmdTraceStartDelay = TraceConfig_CmdTraceStartDelay;
+  using LockdownModeOperation = TraceConfig_LockdownModeOperation;
+  static constexpr auto LOCKDOWN_UNCHANGED = TraceConfig_LockdownModeOperation_LOCKDOWN_UNCHANGED;
+  static constexpr auto LOCKDOWN_CLEAR = TraceConfig_LockdownModeOperation_LOCKDOWN_CLEAR;
+  static constexpr auto LOCKDOWN_SET = TraceConfig_LockdownModeOperation_LOCKDOWN_SET;
+  static constexpr auto LockdownModeOperation_MIN = TraceConfig_LockdownModeOperation_LOCKDOWN_UNCHANGED;
+  static constexpr auto LockdownModeOperation_MAX = TraceConfig_LockdownModeOperation_LOCKDOWN_SET;
+  using CompressionType = TraceConfig_CompressionType;
+  static constexpr auto COMPRESSION_TYPE_UNSPECIFIED = TraceConfig_CompressionType_COMPRESSION_TYPE_UNSPECIFIED;
+  static constexpr auto COMPRESSION_TYPE_DEFLATE = TraceConfig_CompressionType_COMPRESSION_TYPE_DEFLATE;
+  static constexpr auto CompressionType_MIN = TraceConfig_CompressionType_COMPRESSION_TYPE_UNSPECIFIED;
+  static constexpr auto CompressionType_MAX = TraceConfig_CompressionType_COMPRESSION_TYPE_DEFLATE;
+  using StatsdLogging = TraceConfig_StatsdLogging;
+  static constexpr auto STATSD_LOGGING_UNSPECIFIED = TraceConfig_StatsdLogging_STATSD_LOGGING_UNSPECIFIED;
+  static constexpr auto STATSD_LOGGING_ENABLED = TraceConfig_StatsdLogging_STATSD_LOGGING_ENABLED;
+  static constexpr auto STATSD_LOGGING_DISABLED = TraceConfig_StatsdLogging_STATSD_LOGGING_DISABLED;
+  static constexpr auto StatsdLogging_MIN = TraceConfig_StatsdLogging_STATSD_LOGGING_UNSPECIFIED;
+  static constexpr auto StatsdLogging_MAX = TraceConfig_StatsdLogging_STATSD_LOGGING_DISABLED;
+  enum FieldNumbers {
+    kBuffersFieldNumber = 1,
+    kDataSourcesFieldNumber = 2,
+    kBuiltinDataSourcesFieldNumber = 20,
+    kDurationMsFieldNumber = 3,
+    kPreferSuspendClockForDurationFieldNumber = 36,
+    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,
+    kBugreportFilenameFieldNumber = 38,
+    kTriggerConfigFieldNumber = 17,
+    kActivateTriggersFieldNumber = 18,
+    kIncrementalStateConfigFieldNumber = 21,
+    kAllowUserBuildTracingFieldNumber = 19,
+    kUniqueSessionNameFieldNumber = 22,
+    kCompressionTypeFieldNumber = 24,
+    kIncidentReportConfigFieldNumber = 25,
+    kStatsdLoggingFieldNumber = 31,
+    kTraceUuidMsbFieldNumber = 27,
+    kTraceUuidLsbFieldNumber = 28,
+    kTraceFilterFieldNumber = 33,
+    kAndroidReportConfigFieldNumber = 34,
+    kCmdTraceStartDelayFieldNumber = 35,
+  };
+
+  TraceConfig();
+  ~TraceConfig() override;
+  TraceConfig(TraceConfig&&) noexcept;
+  TraceConfig& operator=(TraceConfig&&);
+  TraceConfig(const TraceConfig&);
+  TraceConfig& operator=(const TraceConfig&);
+  bool operator==(const TraceConfig&) const;
+  bool operator!=(const TraceConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<TraceConfig_BufferConfig>& buffers() const { return buffers_; }
+  std::vector<TraceConfig_BufferConfig>* mutable_buffers() { return &buffers_; }
+  int buffers_size() const;
+  void clear_buffers();
+  TraceConfig_BufferConfig* add_buffers();
+
+  const std::vector<TraceConfig_DataSource>& data_sources() const { return data_sources_; }
+  std::vector<TraceConfig_DataSource>* mutable_data_sources() { return &data_sources_; }
+  int data_sources_size() const;
+  void clear_data_sources();
+  TraceConfig_DataSource* add_data_sources();
+
+  bool has_builtin_data_sources() const { return _has_field_[20]; }
+  const TraceConfig_BuiltinDataSource& builtin_data_sources() const { return *builtin_data_sources_; }
+  TraceConfig_BuiltinDataSource* mutable_builtin_data_sources() { _has_field_.set(20); return builtin_data_sources_.get(); }
+
+  bool has_duration_ms() const { return _has_field_[3]; }
+  uint32_t duration_ms() const { return duration_ms_; }
+  void set_duration_ms(uint32_t value) { duration_ms_ = value; _has_field_.set(3); }
+
+  bool has_prefer_suspend_clock_for_duration() const { return _has_field_[36]; }
+  bool prefer_suspend_clock_for_duration() const { return prefer_suspend_clock_for_duration_; }
+  void set_prefer_suspend_clock_for_duration(bool value) { prefer_suspend_clock_for_duration_ = value; _has_field_.set(36); }
+
+  bool has_enable_extra_guardrails() const { return _has_field_[4]; }
+  bool enable_extra_guardrails() const { return enable_extra_guardrails_; }
+  void set_enable_extra_guardrails(bool value) { enable_extra_guardrails_ = value; _has_field_.set(4); }
+
+  bool has_lockdown_mode() const { return _has_field_[5]; }
+  TraceConfig_LockdownModeOperation lockdown_mode() const { return lockdown_mode_; }
+  void set_lockdown_mode(TraceConfig_LockdownModeOperation value) { lockdown_mode_ = value; _has_field_.set(5); }
+
+  const std::vector<TraceConfig_ProducerConfig>& producers() const { return producers_; }
+  std::vector<TraceConfig_ProducerConfig>* mutable_producers() { return &producers_; }
+  int producers_size() const;
+  void clear_producers();
+  TraceConfig_ProducerConfig* add_producers();
+
+  bool has_statsd_metadata() const { return _has_field_[7]; }
+  const TraceConfig_StatsdMetadata& statsd_metadata() const { return *statsd_metadata_; }
+  TraceConfig_StatsdMetadata* mutable_statsd_metadata() { _has_field_.set(7); return statsd_metadata_.get(); }
+
+  bool has_write_into_file() const { return _has_field_[8]; }
+  bool write_into_file() const { return write_into_file_; }
+  void set_write_into_file(bool value) { write_into_file_ = value; _has_field_.set(8); }
+
+  bool has_output_path() const { return _has_field_[29]; }
+  const std::string& output_path() const { return output_path_; }
+  void set_output_path(const std::string& value) { output_path_ = value; _has_field_.set(29); }
+
+  bool has_file_write_period_ms() const { return _has_field_[9]; }
+  uint32_t file_write_period_ms() const { return file_write_period_ms_; }
+  void set_file_write_period_ms(uint32_t value) { file_write_period_ms_ = value; _has_field_.set(9); }
+
+  bool has_max_file_size_bytes() const { return _has_field_[10]; }
+  uint64_t max_file_size_bytes() const { return max_file_size_bytes_; }
+  void set_max_file_size_bytes(uint64_t value) { max_file_size_bytes_ = value; _has_field_.set(10); }
+
+  bool has_guardrail_overrides() const { return _has_field_[11]; }
+  const TraceConfig_GuardrailOverrides& guardrail_overrides() const { return *guardrail_overrides_; }
+  TraceConfig_GuardrailOverrides* mutable_guardrail_overrides() { _has_field_.set(11); return guardrail_overrides_.get(); }
+
+  bool has_deferred_start() const { return _has_field_[12]; }
+  bool deferred_start() const { return deferred_start_; }
+  void set_deferred_start(bool value) { deferred_start_ = value; _has_field_.set(12); }
+
+  bool has_flush_period_ms() const { return _has_field_[13]; }
+  uint32_t flush_period_ms() const { return flush_period_ms_; }
+  void set_flush_period_ms(uint32_t value) { flush_period_ms_ = value; _has_field_.set(13); }
+
+  bool has_flush_timeout_ms() const { return _has_field_[14]; }
+  uint32_t flush_timeout_ms() const { return flush_timeout_ms_; }
+  void set_flush_timeout_ms(uint32_t value) { flush_timeout_ms_ = value; _has_field_.set(14); }
+
+  bool has_data_source_stop_timeout_ms() const { return _has_field_[23]; }
+  uint32_t data_source_stop_timeout_ms() const { return data_source_stop_timeout_ms_; }
+  void set_data_source_stop_timeout_ms(uint32_t value) { data_source_stop_timeout_ms_ = value; _has_field_.set(23); }
+
+  bool has_notify_traceur() const { return _has_field_[16]; }
+  bool notify_traceur() const { return notify_traceur_; }
+  void set_notify_traceur(bool value) { notify_traceur_ = value; _has_field_.set(16); }
+
+  bool has_bugreport_score() const { return _has_field_[30]; }
+  int32_t bugreport_score() const { return bugreport_score_; }
+  void set_bugreport_score(int32_t value) { bugreport_score_ = value; _has_field_.set(30); }
+
+  bool has_bugreport_filename() const { return _has_field_[38]; }
+  const std::string& bugreport_filename() const { return bugreport_filename_; }
+  void set_bugreport_filename(const std::string& value) { bugreport_filename_ = value; _has_field_.set(38); }
+
+  bool has_trigger_config() const { return _has_field_[17]; }
+  const TraceConfig_TriggerConfig& trigger_config() const { return *trigger_config_; }
+  TraceConfig_TriggerConfig* mutable_trigger_config() { _has_field_.set(17); return trigger_config_.get(); }
+
+  const std::vector<std::string>& activate_triggers() const { return activate_triggers_; }
+  std::vector<std::string>* mutable_activate_triggers() { return &activate_triggers_; }
+  int activate_triggers_size() const { return static_cast<int>(activate_triggers_.size()); }
+  void clear_activate_triggers() { activate_triggers_.clear(); }
+  void add_activate_triggers(std::string value) { activate_triggers_.emplace_back(value); }
+  std::string* add_activate_triggers() { activate_triggers_.emplace_back(); return &activate_triggers_.back(); }
+
+  bool has_incremental_state_config() const { return _has_field_[21]; }
+  const TraceConfig_IncrementalStateConfig& incremental_state_config() const { return *incremental_state_config_; }
+  TraceConfig_IncrementalStateConfig* mutable_incremental_state_config() { _has_field_.set(21); return incremental_state_config_.get(); }
+
+  bool has_allow_user_build_tracing() const { return _has_field_[19]; }
+  bool allow_user_build_tracing() const { return allow_user_build_tracing_; }
+  void set_allow_user_build_tracing(bool value) { allow_user_build_tracing_ = value; _has_field_.set(19); }
+
+  bool has_unique_session_name() const { return _has_field_[22]; }
+  const std::string& unique_session_name() const { return unique_session_name_; }
+  void set_unique_session_name(const std::string& value) { unique_session_name_ = value; _has_field_.set(22); }
+
+  bool has_compression_type() const { return _has_field_[24]; }
+  TraceConfig_CompressionType compression_type() const { return compression_type_; }
+  void set_compression_type(TraceConfig_CompressionType value) { compression_type_ = value; _has_field_.set(24); }
+
+  bool has_incident_report_config() const { return _has_field_[25]; }
+  const TraceConfig_IncidentReportConfig& incident_report_config() const { return *incident_report_config_; }
+  TraceConfig_IncidentReportConfig* mutable_incident_report_config() { _has_field_.set(25); return incident_report_config_.get(); }
+
+  bool has_statsd_logging() const { return _has_field_[31]; }
+  TraceConfig_StatsdLogging statsd_logging() const { return statsd_logging_; }
+  void set_statsd_logging(TraceConfig_StatsdLogging value) { statsd_logging_ = value; _has_field_.set(31); }
+
+  bool has_trace_uuid_msb() const { return _has_field_[27]; }
+  int64_t trace_uuid_msb() const { return trace_uuid_msb_; }
+  void set_trace_uuid_msb(int64_t value) { trace_uuid_msb_ = value; _has_field_.set(27); }
+
+  bool has_trace_uuid_lsb() const { return _has_field_[28]; }
+  int64_t trace_uuid_lsb() const { return trace_uuid_lsb_; }
+  void set_trace_uuid_lsb(int64_t value) { trace_uuid_lsb_ = value; _has_field_.set(28); }
+
+  bool has_trace_filter() const { return _has_field_[33]; }
+  const TraceConfig_TraceFilter& trace_filter() const { return *trace_filter_; }
+  TraceConfig_TraceFilter* mutable_trace_filter() { _has_field_.set(33); return trace_filter_.get(); }
+
+  bool has_android_report_config() const { return _has_field_[34]; }
+  const TraceConfig_AndroidReportConfig& android_report_config() const { return *android_report_config_; }
+  TraceConfig_AndroidReportConfig* mutable_android_report_config() { _has_field_.set(34); return android_report_config_.get(); }
+
+  bool has_cmd_trace_start_delay() const { return _has_field_[35]; }
+  const TraceConfig_CmdTraceStartDelay& cmd_trace_start_delay() const { return *cmd_trace_start_delay_; }
+  TraceConfig_CmdTraceStartDelay* mutable_cmd_trace_start_delay() { _has_field_.set(35); return cmd_trace_start_delay_.get(); }
+
+ private:
+  std::vector<TraceConfig_BufferConfig> buffers_;
+  std::vector<TraceConfig_DataSource> data_sources_;
+  ::protozero::CopyablePtr<TraceConfig_BuiltinDataSource> builtin_data_sources_;
+  uint32_t duration_ms_{};
+  bool prefer_suspend_clock_for_duration_{};
+  bool enable_extra_guardrails_{};
+  TraceConfig_LockdownModeOperation lockdown_mode_{};
+  std::vector<TraceConfig_ProducerConfig> producers_;
+  ::protozero::CopyablePtr<TraceConfig_StatsdMetadata> statsd_metadata_;
+  bool write_into_file_{};
+  std::string output_path_{};
+  uint32_t file_write_period_ms_{};
+  uint64_t max_file_size_bytes_{};
+  ::protozero::CopyablePtr<TraceConfig_GuardrailOverrides> guardrail_overrides_;
+  bool deferred_start_{};
+  uint32_t flush_period_ms_{};
+  uint32_t flush_timeout_ms_{};
+  uint32_t data_source_stop_timeout_ms_{};
+  bool notify_traceur_{};
+  int32_t bugreport_score_{};
+  std::string bugreport_filename_{};
+  ::protozero::CopyablePtr<TraceConfig_TriggerConfig> trigger_config_;
+  std::vector<std::string> activate_triggers_;
+  ::protozero::CopyablePtr<TraceConfig_IncrementalStateConfig> incremental_state_config_;
+  bool allow_user_build_tracing_{};
+  std::string unique_session_name_{};
+  TraceConfig_CompressionType compression_type_{};
+  ::protozero::CopyablePtr<TraceConfig_IncidentReportConfig> incident_report_config_;
+  TraceConfig_StatsdLogging statsd_logging_{};
+  int64_t trace_uuid_msb_{};
+  int64_t trace_uuid_lsb_{};
+  ::protozero::CopyablePtr<TraceConfig_TraceFilter> trace_filter_;
+  ::protozero::CopyablePtr<TraceConfig_AndroidReportConfig> android_report_config_;
+  ::protozero::CopyablePtr<TraceConfig_CmdTraceStartDelay> cmd_trace_start_delay_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<39> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TraceConfig_CmdTraceStartDelay : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kMinDelayMsFieldNumber = 1,
+    kMaxDelayMsFieldNumber = 2,
+  };
+
+  TraceConfig_CmdTraceStartDelay();
+  ~TraceConfig_CmdTraceStartDelay() override;
+  TraceConfig_CmdTraceStartDelay(TraceConfig_CmdTraceStartDelay&&) noexcept;
+  TraceConfig_CmdTraceStartDelay& operator=(TraceConfig_CmdTraceStartDelay&&);
+  TraceConfig_CmdTraceStartDelay(const TraceConfig_CmdTraceStartDelay&);
+  TraceConfig_CmdTraceStartDelay& operator=(const TraceConfig_CmdTraceStartDelay&);
+  bool operator==(const TraceConfig_CmdTraceStartDelay&) const;
+  bool operator!=(const TraceConfig_CmdTraceStartDelay& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_min_delay_ms() const { return _has_field_[1]; }
+  uint32_t min_delay_ms() const { return min_delay_ms_; }
+  void set_min_delay_ms(uint32_t value) { min_delay_ms_ = value; _has_field_.set(1); }
+
+  bool has_max_delay_ms() const { return _has_field_[2]; }
+  uint32_t max_delay_ms() const { return max_delay_ms_; }
+  void set_max_delay_ms(uint32_t value) { max_delay_ms_ = value; _has_field_.set(2); }
+
+ private:
+  uint32_t min_delay_ms_{};
+  uint32_t max_delay_ms_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TraceConfig_AndroidReportConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kReporterServicePackageFieldNumber = 1,
+    kReporterServiceClassFieldNumber = 2,
+    kSkipReportFieldNumber = 3,
+    kUsePipeInFrameworkForTestingFieldNumber = 4,
+  };
+
+  TraceConfig_AndroidReportConfig();
+  ~TraceConfig_AndroidReportConfig() override;
+  TraceConfig_AndroidReportConfig(TraceConfig_AndroidReportConfig&&) noexcept;
+  TraceConfig_AndroidReportConfig& operator=(TraceConfig_AndroidReportConfig&&);
+  TraceConfig_AndroidReportConfig(const TraceConfig_AndroidReportConfig&);
+  TraceConfig_AndroidReportConfig& operator=(const TraceConfig_AndroidReportConfig&);
+  bool operator==(const TraceConfig_AndroidReportConfig&) const;
+  bool operator!=(const TraceConfig_AndroidReportConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_reporter_service_package() const { return _has_field_[1]; }
+  const std::string& reporter_service_package() const { return reporter_service_package_; }
+  void set_reporter_service_package(const std::string& value) { reporter_service_package_ = value; _has_field_.set(1); }
+
+  bool has_reporter_service_class() const { return _has_field_[2]; }
+  const std::string& reporter_service_class() const { return reporter_service_class_; }
+  void set_reporter_service_class(const std::string& value) { reporter_service_class_ = value; _has_field_.set(2); }
+
+  bool has_skip_report() const { return _has_field_[3]; }
+  bool skip_report() const { return skip_report_; }
+  void set_skip_report(bool value) { skip_report_ = value; _has_field_.set(3); }
+
+  bool has_use_pipe_in_framework_for_testing() const { return _has_field_[4]; }
+  bool use_pipe_in_framework_for_testing() const { return use_pipe_in_framework_for_testing_; }
+  void set_use_pipe_in_framework_for_testing(bool value) { use_pipe_in_framework_for_testing_ = value; _has_field_.set(4); }
+
+ private:
+  std::string reporter_service_package_{};
+  std::string reporter_service_class_{};
+  bool skip_report_{};
+  bool use_pipe_in_framework_for_testing_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<5> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TraceConfig_TraceFilter : public ::protozero::CppMessageObj {
+ public:
+  using StringFilterRule = TraceConfig_TraceFilter_StringFilterRule;
+  using StringFilterChain = TraceConfig_TraceFilter_StringFilterChain;
+  using StringFilterPolicy = TraceConfig_TraceFilter_StringFilterPolicy;
+  static constexpr auto SFP_UNSPECIFIED = TraceConfig_TraceFilter_StringFilterPolicy_SFP_UNSPECIFIED;
+  static constexpr auto SFP_MATCH_REDACT_GROUPS = TraceConfig_TraceFilter_StringFilterPolicy_SFP_MATCH_REDACT_GROUPS;
+  static constexpr auto SFP_ATRACE_MATCH_REDACT_GROUPS = TraceConfig_TraceFilter_StringFilterPolicy_SFP_ATRACE_MATCH_REDACT_GROUPS;
+  static constexpr auto SFP_MATCH_BREAK = TraceConfig_TraceFilter_StringFilterPolicy_SFP_MATCH_BREAK;
+  static constexpr auto SFP_ATRACE_MATCH_BREAK = TraceConfig_TraceFilter_StringFilterPolicy_SFP_ATRACE_MATCH_BREAK;
+  static constexpr auto SFP_ATRACE_REPEATED_SEARCH_REDACT_GROUPS = TraceConfig_TraceFilter_StringFilterPolicy_SFP_ATRACE_REPEATED_SEARCH_REDACT_GROUPS;
+  static constexpr auto StringFilterPolicy_MIN = TraceConfig_TraceFilter_StringFilterPolicy_SFP_UNSPECIFIED;
+  static constexpr auto StringFilterPolicy_MAX = TraceConfig_TraceFilter_StringFilterPolicy_SFP_ATRACE_REPEATED_SEARCH_REDACT_GROUPS;
+  enum FieldNumbers {
+    kBytecodeFieldNumber = 1,
+    kBytecodeV2FieldNumber = 2,
+    kStringFilterChainFieldNumber = 3,
+  };
+
+  TraceConfig_TraceFilter();
+  ~TraceConfig_TraceFilter() override;
+  TraceConfig_TraceFilter(TraceConfig_TraceFilter&&) noexcept;
+  TraceConfig_TraceFilter& operator=(TraceConfig_TraceFilter&&);
+  TraceConfig_TraceFilter(const TraceConfig_TraceFilter&);
+  TraceConfig_TraceFilter& operator=(const TraceConfig_TraceFilter&);
+  bool operator==(const TraceConfig_TraceFilter&) const;
+  bool operator!=(const TraceConfig_TraceFilter& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_bytecode() const { return _has_field_[1]; }
+  const std::string& bytecode() const { return bytecode_; }
+  void set_bytecode(const std::string& value) { bytecode_ = value; _has_field_.set(1); }
+  void set_bytecode(const void* p, size_t s) { bytecode_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(1); }
+
+  bool has_bytecode_v2() const { return _has_field_[2]; }
+  const std::string& bytecode_v2() const { return bytecode_v2_; }
+  void set_bytecode_v2(const std::string& value) { bytecode_v2_ = value; _has_field_.set(2); }
+  void set_bytecode_v2(const void* p, size_t s) { bytecode_v2_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(2); }
+
+  bool has_string_filter_chain() const { return _has_field_[3]; }
+  const TraceConfig_TraceFilter_StringFilterChain& string_filter_chain() const { return *string_filter_chain_; }
+  TraceConfig_TraceFilter_StringFilterChain* mutable_string_filter_chain() { _has_field_.set(3); return string_filter_chain_.get(); }
+
+ private:
+  std::string bytecode_{};
+  std::string bytecode_v2_{};
+  ::protozero::CopyablePtr<TraceConfig_TraceFilter_StringFilterChain> string_filter_chain_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TraceConfig_TraceFilter_StringFilterChain : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kRulesFieldNumber = 1,
+  };
+
+  TraceConfig_TraceFilter_StringFilterChain();
+  ~TraceConfig_TraceFilter_StringFilterChain() override;
+  TraceConfig_TraceFilter_StringFilterChain(TraceConfig_TraceFilter_StringFilterChain&&) noexcept;
+  TraceConfig_TraceFilter_StringFilterChain& operator=(TraceConfig_TraceFilter_StringFilterChain&&);
+  TraceConfig_TraceFilter_StringFilterChain(const TraceConfig_TraceFilter_StringFilterChain&);
+  TraceConfig_TraceFilter_StringFilterChain& operator=(const TraceConfig_TraceFilter_StringFilterChain&);
+  bool operator==(const TraceConfig_TraceFilter_StringFilterChain&) const;
+  bool operator!=(const TraceConfig_TraceFilter_StringFilterChain& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<TraceConfig_TraceFilter_StringFilterRule>& rules() const { return rules_; }
+  std::vector<TraceConfig_TraceFilter_StringFilterRule>* mutable_rules() { return &rules_; }
+  int rules_size() const;
+  void clear_rules();
+  TraceConfig_TraceFilter_StringFilterRule* add_rules();
+
+ private:
+  std::vector<TraceConfig_TraceFilter_StringFilterRule> rules_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TraceConfig_TraceFilter_StringFilterRule : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kPolicyFieldNumber = 1,
+    kRegexPatternFieldNumber = 2,
+    kAtracePayloadStartsWithFieldNumber = 3,
+  };
+
+  TraceConfig_TraceFilter_StringFilterRule();
+  ~TraceConfig_TraceFilter_StringFilterRule() override;
+  TraceConfig_TraceFilter_StringFilterRule(TraceConfig_TraceFilter_StringFilterRule&&) noexcept;
+  TraceConfig_TraceFilter_StringFilterRule& operator=(TraceConfig_TraceFilter_StringFilterRule&&);
+  TraceConfig_TraceFilter_StringFilterRule(const TraceConfig_TraceFilter_StringFilterRule&);
+  TraceConfig_TraceFilter_StringFilterRule& operator=(const TraceConfig_TraceFilter_StringFilterRule&);
+  bool operator==(const TraceConfig_TraceFilter_StringFilterRule&) const;
+  bool operator!=(const TraceConfig_TraceFilter_StringFilterRule& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_policy() const { return _has_field_[1]; }
+  TraceConfig_TraceFilter_StringFilterPolicy policy() const { return policy_; }
+  void set_policy(TraceConfig_TraceFilter_StringFilterPolicy value) { policy_ = value; _has_field_.set(1); }
+
+  bool has_regex_pattern() const { return _has_field_[2]; }
+  const std::string& regex_pattern() const { return regex_pattern_; }
+  void set_regex_pattern(const std::string& value) { regex_pattern_ = value; _has_field_.set(2); }
+
+  bool has_atrace_payload_starts_with() const { return _has_field_[3]; }
+  const std::string& atrace_payload_starts_with() const { return atrace_payload_starts_with_; }
+  void set_atrace_payload_starts_with(const std::string& value) { atrace_payload_starts_with_ = value; _has_field_.set(3); }
+
+ private:
+  TraceConfig_TraceFilter_StringFilterPolicy policy_{};
+  std::string regex_pattern_{};
+  std::string atrace_payload_starts_with_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TraceConfig_IncidentReportConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDestinationPackageFieldNumber = 1,
+    kDestinationClassFieldNumber = 2,
+    kPrivacyLevelFieldNumber = 3,
+    kSkipIncidentdFieldNumber = 5,
+    kSkipDropboxFieldNumber = 4,
+  };
+
+  TraceConfig_IncidentReportConfig();
+  ~TraceConfig_IncidentReportConfig() override;
+  TraceConfig_IncidentReportConfig(TraceConfig_IncidentReportConfig&&) noexcept;
+  TraceConfig_IncidentReportConfig& operator=(TraceConfig_IncidentReportConfig&&);
+  TraceConfig_IncidentReportConfig(const TraceConfig_IncidentReportConfig&);
+  TraceConfig_IncidentReportConfig& operator=(const TraceConfig_IncidentReportConfig&);
+  bool operator==(const TraceConfig_IncidentReportConfig&) const;
+  bool operator!=(const TraceConfig_IncidentReportConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_destination_package() const { return _has_field_[1]; }
+  const std::string& destination_package() const { return destination_package_; }
+  void set_destination_package(const std::string& value) { destination_package_ = value; _has_field_.set(1); }
+
+  bool has_destination_class() const { return _has_field_[2]; }
+  const std::string& destination_class() const { return destination_class_; }
+  void set_destination_class(const std::string& value) { destination_class_ = value; _has_field_.set(2); }
+
+  bool has_privacy_level() const { return _has_field_[3]; }
+  int32_t privacy_level() const { return privacy_level_; }
+  void set_privacy_level(int32_t value) { privacy_level_ = value; _has_field_.set(3); }
+
+  bool has_skip_incidentd() const { return _has_field_[5]; }
+  bool skip_incidentd() const { return skip_incidentd_; }
+  void set_skip_incidentd(bool value) { skip_incidentd_ = value; _has_field_.set(5); }
+
+  bool has_skip_dropbox() const { return _has_field_[4]; }
+  bool skip_dropbox() const { return skip_dropbox_; }
+  void set_skip_dropbox(bool value) { skip_dropbox_ = value; _has_field_.set(4); }
+
+ private:
+  std::string destination_package_{};
+  std::string destination_class_{};
+  int32_t privacy_level_{};
+  bool skip_incidentd_{};
+  bool skip_dropbox_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<6> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TraceConfig_IncrementalStateConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kClearPeriodMsFieldNumber = 1,
+  };
+
+  TraceConfig_IncrementalStateConfig();
+  ~TraceConfig_IncrementalStateConfig() override;
+  TraceConfig_IncrementalStateConfig(TraceConfig_IncrementalStateConfig&&) noexcept;
+  TraceConfig_IncrementalStateConfig& operator=(TraceConfig_IncrementalStateConfig&&);
+  TraceConfig_IncrementalStateConfig(const TraceConfig_IncrementalStateConfig&);
+  TraceConfig_IncrementalStateConfig& operator=(const TraceConfig_IncrementalStateConfig&);
+  bool operator==(const TraceConfig_IncrementalStateConfig&) const;
+  bool operator!=(const TraceConfig_IncrementalStateConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_clear_period_ms() const { return _has_field_[1]; }
+  uint32_t clear_period_ms() const { return clear_period_ms_; }
+  void set_clear_period_ms(uint32_t value) { clear_period_ms_ = value; _has_field_.set(1); }
+
+ private:
+  uint32_t clear_period_ms_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TraceConfig_TriggerConfig : public ::protozero::CppMessageObj {
+ public:
+  using Trigger = TraceConfig_TriggerConfig_Trigger;
+  using TriggerMode = TraceConfig_TriggerConfig_TriggerMode;
+  static constexpr auto UNSPECIFIED = TraceConfig_TriggerConfig_TriggerMode_UNSPECIFIED;
+  static constexpr auto START_TRACING = TraceConfig_TriggerConfig_TriggerMode_START_TRACING;
+  static constexpr auto STOP_TRACING = TraceConfig_TriggerConfig_TriggerMode_STOP_TRACING;
+  static constexpr auto CLONE_SNAPSHOT = TraceConfig_TriggerConfig_TriggerMode_CLONE_SNAPSHOT;
+  static constexpr auto TriggerMode_MIN = TraceConfig_TriggerConfig_TriggerMode_UNSPECIFIED;
+  static constexpr auto TriggerMode_MAX = TraceConfig_TriggerConfig_TriggerMode_CLONE_SNAPSHOT;
+  enum FieldNumbers {
+    kTriggerModeFieldNumber = 1,
+    kUseCloneSnapshotIfAvailableFieldNumber = 5,
+    kTriggersFieldNumber = 2,
+    kTriggerTimeoutMsFieldNumber = 3,
+  };
+
+  TraceConfig_TriggerConfig();
+  ~TraceConfig_TriggerConfig() override;
+  TraceConfig_TriggerConfig(TraceConfig_TriggerConfig&&) noexcept;
+  TraceConfig_TriggerConfig& operator=(TraceConfig_TriggerConfig&&);
+  TraceConfig_TriggerConfig(const TraceConfig_TriggerConfig&);
+  TraceConfig_TriggerConfig& operator=(const TraceConfig_TriggerConfig&);
+  bool operator==(const TraceConfig_TriggerConfig&) const;
+  bool operator!=(const TraceConfig_TriggerConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_trigger_mode() const { return _has_field_[1]; }
+  TraceConfig_TriggerConfig_TriggerMode trigger_mode() const { return trigger_mode_; }
+  void set_trigger_mode(TraceConfig_TriggerConfig_TriggerMode value) { trigger_mode_ = value; _has_field_.set(1); }
+
+  bool has_use_clone_snapshot_if_available() const { return _has_field_[5]; }
+  bool use_clone_snapshot_if_available() const { return use_clone_snapshot_if_available_; }
+  void set_use_clone_snapshot_if_available(bool value) { use_clone_snapshot_if_available_ = value; _has_field_.set(5); }
+
+  const std::vector<TraceConfig_TriggerConfig_Trigger>& triggers() const { return triggers_; }
+  std::vector<TraceConfig_TriggerConfig_Trigger>* mutable_triggers() { return &triggers_; }
+  int triggers_size() const;
+  void clear_triggers();
+  TraceConfig_TriggerConfig_Trigger* add_triggers();
+
+  bool has_trigger_timeout_ms() const { return _has_field_[3]; }
+  uint32_t trigger_timeout_ms() const { return trigger_timeout_ms_; }
+  void set_trigger_timeout_ms(uint32_t value) { trigger_timeout_ms_ = value; _has_field_.set(3); }
+
+ private:
+  TraceConfig_TriggerConfig_TriggerMode trigger_mode_{};
+  bool use_clone_snapshot_if_available_{};
+  std::vector<TraceConfig_TriggerConfig_Trigger> triggers_;
+  uint32_t trigger_timeout_ms_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<6> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TraceConfig_TriggerConfig_Trigger : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kNameFieldNumber = 1,
+    kProducerNameRegexFieldNumber = 2,
+    kStopDelayMsFieldNumber = 3,
+    kMaxPer24HFieldNumber = 4,
+    kSkipProbabilityFieldNumber = 5,
+  };
+
+  TraceConfig_TriggerConfig_Trigger();
+  ~TraceConfig_TriggerConfig_Trigger() override;
+  TraceConfig_TriggerConfig_Trigger(TraceConfig_TriggerConfig_Trigger&&) noexcept;
+  TraceConfig_TriggerConfig_Trigger& operator=(TraceConfig_TriggerConfig_Trigger&&);
+  TraceConfig_TriggerConfig_Trigger(const TraceConfig_TriggerConfig_Trigger&);
+  TraceConfig_TriggerConfig_Trigger& operator=(const TraceConfig_TriggerConfig_Trigger&);
+  bool operator==(const TraceConfig_TriggerConfig_Trigger&) const;
+  bool operator!=(const TraceConfig_TriggerConfig_Trigger& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name() const { return _has_field_[1]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
+
+  bool has_producer_name_regex() const { return _has_field_[2]; }
+  const std::string& producer_name_regex() const { return producer_name_regex_; }
+  void set_producer_name_regex(const std::string& value) { producer_name_regex_ = value; _has_field_.set(2); }
+
+  bool has_stop_delay_ms() const { return _has_field_[3]; }
+  uint32_t stop_delay_ms() const { return stop_delay_ms_; }
+  void set_stop_delay_ms(uint32_t value) { stop_delay_ms_ = value; _has_field_.set(3); }
+
+  bool has_max_per_24_h() const { return _has_field_[4]; }
+  uint32_t max_per_24_h() const { return max_per_24_h_; }
+  void set_max_per_24_h(uint32_t value) { max_per_24_h_ = value; _has_field_.set(4); }
+
+  bool has_skip_probability() const { return _has_field_[5]; }
+  double skip_probability() const { return skip_probability_; }
+  void set_skip_probability(double value) { skip_probability_ = value; _has_field_.set(5); }
+
+ private:
+  std::string name_{};
+  std::string producer_name_regex_{};
+  uint32_t stop_delay_ms_{};
+  uint32_t max_per_24_h_{};
+  double skip_probability_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<6> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TraceConfig_GuardrailOverrides : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kMaxUploadPerDayBytesFieldNumber = 1,
+    kMaxTracingBufferSizeKbFieldNumber = 2,
+  };
+
+  TraceConfig_GuardrailOverrides();
+  ~TraceConfig_GuardrailOverrides() override;
+  TraceConfig_GuardrailOverrides(TraceConfig_GuardrailOverrides&&) noexcept;
+  TraceConfig_GuardrailOverrides& operator=(TraceConfig_GuardrailOverrides&&);
+  TraceConfig_GuardrailOverrides(const TraceConfig_GuardrailOverrides&);
+  TraceConfig_GuardrailOverrides& operator=(const TraceConfig_GuardrailOverrides&);
+  bool operator==(const TraceConfig_GuardrailOverrides&) const;
+  bool operator!=(const TraceConfig_GuardrailOverrides& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_max_upload_per_day_bytes() const { return _has_field_[1]; }
+  uint64_t max_upload_per_day_bytes() const { return max_upload_per_day_bytes_; }
+  void set_max_upload_per_day_bytes(uint64_t value) { max_upload_per_day_bytes_ = value; _has_field_.set(1); }
+
+  bool has_max_tracing_buffer_size_kb() const { return _has_field_[2]; }
+  uint32_t max_tracing_buffer_size_kb() const { return max_tracing_buffer_size_kb_; }
+  void set_max_tracing_buffer_size_kb(uint32_t value) { max_tracing_buffer_size_kb_ = value; _has_field_.set(2); }
+
+ private:
+  uint64_t max_upload_per_day_bytes_{};
+  uint32_t max_tracing_buffer_size_kb_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TraceConfig_StatsdMetadata : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kTriggeringAlertIdFieldNumber = 1,
+    kTriggeringConfigUidFieldNumber = 2,
+    kTriggeringConfigIdFieldNumber = 3,
+    kTriggeringSubscriptionIdFieldNumber = 4,
+  };
+
+  TraceConfig_StatsdMetadata();
+  ~TraceConfig_StatsdMetadata() override;
+  TraceConfig_StatsdMetadata(TraceConfig_StatsdMetadata&&) noexcept;
+  TraceConfig_StatsdMetadata& operator=(TraceConfig_StatsdMetadata&&);
+  TraceConfig_StatsdMetadata(const TraceConfig_StatsdMetadata&);
+  TraceConfig_StatsdMetadata& operator=(const TraceConfig_StatsdMetadata&);
+  bool operator==(const TraceConfig_StatsdMetadata&) const;
+  bool operator!=(const TraceConfig_StatsdMetadata& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_triggering_alert_id() const { return _has_field_[1]; }
+  int64_t triggering_alert_id() const { return triggering_alert_id_; }
+  void set_triggering_alert_id(int64_t value) { triggering_alert_id_ = value; _has_field_.set(1); }
+
+  bool has_triggering_config_uid() const { return _has_field_[2]; }
+  int32_t triggering_config_uid() const { return triggering_config_uid_; }
+  void set_triggering_config_uid(int32_t value) { triggering_config_uid_ = value; _has_field_.set(2); }
+
+  bool has_triggering_config_id() const { return _has_field_[3]; }
+  int64_t triggering_config_id() const { return triggering_config_id_; }
+  void set_triggering_config_id(int64_t value) { triggering_config_id_ = value; _has_field_.set(3); }
+
+  bool has_triggering_subscription_id() const { return _has_field_[4]; }
+  int64_t triggering_subscription_id() const { return triggering_subscription_id_; }
+  void set_triggering_subscription_id(int64_t value) { triggering_subscription_id_ = value; _has_field_.set(4); }
+
+ private:
+  int64_t triggering_alert_id_{};
+  int32_t triggering_config_uid_{};
+  int64_t triggering_config_id_{};
+  int64_t triggering_subscription_id_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<5> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TraceConfig_ProducerConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kProducerNameFieldNumber = 1,
+    kShmSizeKbFieldNumber = 2,
+    kPageSizeKbFieldNumber = 3,
+  };
+
+  TraceConfig_ProducerConfig();
+  ~TraceConfig_ProducerConfig() override;
+  TraceConfig_ProducerConfig(TraceConfig_ProducerConfig&&) noexcept;
+  TraceConfig_ProducerConfig& operator=(TraceConfig_ProducerConfig&&);
+  TraceConfig_ProducerConfig(const TraceConfig_ProducerConfig&);
+  TraceConfig_ProducerConfig& operator=(const TraceConfig_ProducerConfig&);
+  bool operator==(const TraceConfig_ProducerConfig&) const;
+  bool operator!=(const TraceConfig_ProducerConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_producer_name() const { return _has_field_[1]; }
+  const std::string& producer_name() const { return producer_name_; }
+  void set_producer_name(const std::string& value) { producer_name_ = value; _has_field_.set(1); }
+
+  bool has_shm_size_kb() const { return _has_field_[2]; }
+  uint32_t shm_size_kb() const { return shm_size_kb_; }
+  void set_shm_size_kb(uint32_t value) { shm_size_kb_ = value; _has_field_.set(2); }
+
+  bool has_page_size_kb() const { return _has_field_[3]; }
+  uint32_t page_size_kb() const { return page_size_kb_; }
+  void set_page_size_kb(uint32_t value) { page_size_kb_ = value; _has_field_.set(3); }
+
+ private:
+  std::string producer_name_{};
+  uint32_t shm_size_kb_{};
+  uint32_t page_size_kb_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TraceConfig_BuiltinDataSource : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDisableClockSnapshottingFieldNumber = 1,
+    kDisableTraceConfigFieldNumber = 2,
+    kDisableSystemInfoFieldNumber = 3,
+    kDisableServiceEventsFieldNumber = 4,
+    kPrimaryTraceClockFieldNumber = 5,
+    kSnapshotIntervalMsFieldNumber = 6,
+    kPreferSuspendClockForSnapshotFieldNumber = 7,
+    kDisableChunkUsageHistogramsFieldNumber = 8,
+  };
+
+  TraceConfig_BuiltinDataSource();
+  ~TraceConfig_BuiltinDataSource() override;
+  TraceConfig_BuiltinDataSource(TraceConfig_BuiltinDataSource&&) noexcept;
+  TraceConfig_BuiltinDataSource& operator=(TraceConfig_BuiltinDataSource&&);
+  TraceConfig_BuiltinDataSource(const TraceConfig_BuiltinDataSource&);
+  TraceConfig_BuiltinDataSource& operator=(const TraceConfig_BuiltinDataSource&);
+  bool operator==(const TraceConfig_BuiltinDataSource&) const;
+  bool operator!=(const TraceConfig_BuiltinDataSource& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_disable_clock_snapshotting() const { return _has_field_[1]; }
+  bool disable_clock_snapshotting() const { return disable_clock_snapshotting_; }
+  void set_disable_clock_snapshotting(bool value) { disable_clock_snapshotting_ = value; _has_field_.set(1); }
+
+  bool has_disable_trace_config() const { return _has_field_[2]; }
+  bool disable_trace_config() const { return disable_trace_config_; }
+  void set_disable_trace_config(bool value) { disable_trace_config_ = value; _has_field_.set(2); }
+
+  bool has_disable_system_info() const { return _has_field_[3]; }
+  bool disable_system_info() const { return disable_system_info_; }
+  void set_disable_system_info(bool value) { disable_system_info_ = value; _has_field_.set(3); }
+
+  bool has_disable_service_events() const { return _has_field_[4]; }
+  bool disable_service_events() const { return disable_service_events_; }
+  void set_disable_service_events(bool value) { disable_service_events_ = value; _has_field_.set(4); }
+
+  bool has_primary_trace_clock() const { return _has_field_[5]; }
+  BuiltinClock primary_trace_clock() const { return primary_trace_clock_; }
+  void set_primary_trace_clock(BuiltinClock value) { primary_trace_clock_ = value; _has_field_.set(5); }
+
+  bool has_snapshot_interval_ms() const { return _has_field_[6]; }
+  uint32_t snapshot_interval_ms() const { return snapshot_interval_ms_; }
+  void set_snapshot_interval_ms(uint32_t value) { snapshot_interval_ms_ = value; _has_field_.set(6); }
+
+  bool has_prefer_suspend_clock_for_snapshot() const { return _has_field_[7]; }
+  bool prefer_suspend_clock_for_snapshot() const { return prefer_suspend_clock_for_snapshot_; }
+  void set_prefer_suspend_clock_for_snapshot(bool value) { prefer_suspend_clock_for_snapshot_ = value; _has_field_.set(7); }
+
+  bool has_disable_chunk_usage_histograms() const { return _has_field_[8]; }
+  bool disable_chunk_usage_histograms() const { return disable_chunk_usage_histograms_; }
+  void set_disable_chunk_usage_histograms(bool value) { disable_chunk_usage_histograms_ = value; _has_field_.set(8); }
+
+ private:
+  bool disable_clock_snapshotting_{};
+  bool disable_trace_config_{};
+  bool disable_system_info_{};
+  bool disable_service_events_{};
+  BuiltinClock primary_trace_clock_{};
+  uint32_t snapshot_interval_ms_{};
+  bool prefer_suspend_clock_for_snapshot_{};
+  bool disable_chunk_usage_histograms_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<9> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TraceConfig_DataSource : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kConfigFieldNumber = 1,
+    kProducerNameFilterFieldNumber = 2,
+    kProducerNameRegexFilterFieldNumber = 3,
+  };
+
+  TraceConfig_DataSource();
+  ~TraceConfig_DataSource() override;
+  TraceConfig_DataSource(TraceConfig_DataSource&&) noexcept;
+  TraceConfig_DataSource& operator=(TraceConfig_DataSource&&);
+  TraceConfig_DataSource(const TraceConfig_DataSource&);
+  TraceConfig_DataSource& operator=(const TraceConfig_DataSource&);
+  bool operator==(const TraceConfig_DataSource&) const;
+  bool operator!=(const TraceConfig_DataSource& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_config() const { return _has_field_[1]; }
+  const DataSourceConfig& config() const { return *config_; }
+  DataSourceConfig* mutable_config() { _has_field_.set(1); return config_.get(); }
+
+  const std::vector<std::string>& producer_name_filter() const { return producer_name_filter_; }
+  std::vector<std::string>* mutable_producer_name_filter() { return &producer_name_filter_; }
+  int producer_name_filter_size() const { return static_cast<int>(producer_name_filter_.size()); }
+  void clear_producer_name_filter() { producer_name_filter_.clear(); }
+  void add_producer_name_filter(std::string value) { producer_name_filter_.emplace_back(value); }
+  std::string* add_producer_name_filter() { producer_name_filter_.emplace_back(); return &producer_name_filter_.back(); }
+
+  const std::vector<std::string>& producer_name_regex_filter() const { return producer_name_regex_filter_; }
+  std::vector<std::string>* mutable_producer_name_regex_filter() { return &producer_name_regex_filter_; }
+  int producer_name_regex_filter_size() const { return static_cast<int>(producer_name_regex_filter_.size()); }
+  void clear_producer_name_regex_filter() { producer_name_regex_filter_.clear(); }
+  void add_producer_name_regex_filter(std::string value) { producer_name_regex_filter_.emplace_back(value); }
+  std::string* add_producer_name_regex_filter() { producer_name_regex_filter_.emplace_back(); return &producer_name_regex_filter_.back(); }
+
+ private:
+  ::protozero::CopyablePtr<DataSourceConfig> config_;
+  std::vector<std::string> producer_name_filter_;
+  std::vector<std::string> producer_name_regex_filter_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TraceConfig_BufferConfig : public ::protozero::CppMessageObj {
+ public:
+  using FillPolicy = TraceConfig_BufferConfig_FillPolicy;
+  static constexpr auto UNSPECIFIED = TraceConfig_BufferConfig_FillPolicy_UNSPECIFIED;
+  static constexpr auto RING_BUFFER = TraceConfig_BufferConfig_FillPolicy_RING_BUFFER;
+  static constexpr auto DISCARD = TraceConfig_BufferConfig_FillPolicy_DISCARD;
+  static constexpr auto FillPolicy_MIN = TraceConfig_BufferConfig_FillPolicy_UNSPECIFIED;
+  static constexpr auto FillPolicy_MAX = TraceConfig_BufferConfig_FillPolicy_DISCARD;
+  enum FieldNumbers {
+    kSizeKbFieldNumber = 1,
+    kFillPolicyFieldNumber = 4,
+    kTransferOnCloneFieldNumber = 5,
+    kClearBeforeCloneFieldNumber = 6,
+  };
+
+  TraceConfig_BufferConfig();
+  ~TraceConfig_BufferConfig() override;
+  TraceConfig_BufferConfig(TraceConfig_BufferConfig&&) noexcept;
+  TraceConfig_BufferConfig& operator=(TraceConfig_BufferConfig&&);
+  TraceConfig_BufferConfig(const TraceConfig_BufferConfig&);
+  TraceConfig_BufferConfig& operator=(const TraceConfig_BufferConfig&);
+  bool operator==(const TraceConfig_BufferConfig&) const;
+  bool operator!=(const TraceConfig_BufferConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_size_kb() const { return _has_field_[1]; }
+  uint32_t size_kb() const { return size_kb_; }
+  void set_size_kb(uint32_t value) { size_kb_ = value; _has_field_.set(1); }
+
+  bool has_fill_policy() const { return _has_field_[4]; }
+  TraceConfig_BufferConfig_FillPolicy fill_policy() const { return fill_policy_; }
+  void set_fill_policy(TraceConfig_BufferConfig_FillPolicy value) { fill_policy_ = value; _has_field_.set(4); }
+
+  bool has_transfer_on_clone() const { return _has_field_[5]; }
+  bool transfer_on_clone() const { return transfer_on_clone_; }
+  void set_transfer_on_clone(bool value) { transfer_on_clone_ = value; _has_field_.set(5); }
+
+  bool has_clear_before_clone() const { return _has_field_[6]; }
+  bool clear_before_clone() const { return clear_before_clone_; }
+  void set_clear_before_clone(bool value) { clear_before_clone_ = value; _has_field_.set(6); }
+
+ private:
+  uint32_t size_kb_{};
+  TraceConfig_BufferConfig_FillPolicy fill_policy_{};
+  bool transfer_on_clone_{};
+  bool clear_before_clone_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<7> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TRACE_CONFIG_PROTO_CPP_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_CORE_TRACE_CONFIG_H_
+#define INCLUDE_PERFETTO_TRACING_CORE_TRACE_CONFIG_H_
+
+// Creates the aliases in the ::perfetto namespace, doing things like:
+// using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
+// See comments in forward_decls.h for the historical reasons of this
+// indirection layer.
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/config/trace_config.gen.h"
+
+namespace perfetto {
+
+inline TraceConfig::TriggerConfig::TriggerMode GetTriggerMode(
+    const TraceConfig& cfg) {
+  auto mode = cfg.trigger_config().trigger_mode();
+  if (cfg.trigger_config().use_clone_snapshot_if_available())
+    mode = TraceConfig::TriggerConfig::CLONE_SNAPSHOT;
+  return mode;
+}
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_CORE_TRACE_CONFIG_H_
+// gen_amalgamated begin header: include/perfetto/tracing/data_source.h
+// gen_amalgamated begin header: include/perfetto/tracing/core/flush_flags.h
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_CORE_FLUSH_FLAGS_H_
+#define INCLUDE_PERFETTO_TRACING_CORE_FLUSH_FLAGS_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace perfetto {
+
+// This class is a wrapper around the uint64_t flags that are sent across the
+// tracing protocol whenenver a flush occurs. It helps determining the reason
+// and initiator of the flush.
+// NOTE: the values here are part of the tracing protocol ABI. Do not renumber.
+class FlushFlags {
+ public:
+  enum class Initiator : uint64_t {
+    // DO NOT RENUMBER, ABI.
+    kUnknown = 0,
+    kTraced = 1,
+    kPerfettoCmd = 2,
+    kConsumerSdk = 3,
+    kMax,
+  };
+
+  enum class Reason : uint64_t {
+    // DO NOT RENUMBER, ABI.
+    kUnknown = 0,
+    kPeriodic = 1,
+    kTraceStop = 2,
+    kTraceClone = 3,
+    kExplicit = 4,
+    kMax,
+  };
+
+  enum class CloneTarget : uint64_t {
+    // DO NOT RENUMBER, ABI.
+    kUnknown = 0,
+    kBugreport = 1,
+    kMax,
+  };
+
+  explicit FlushFlags(uint64_t flags = 0) : flags_(flags) {}
+  FlushFlags(Initiator i, Reason r, CloneTarget c = CloneTarget::kUnknown)
+      : flags_((static_cast<uint64_t>(i) << kInitiatorShift) |
+               (static_cast<uint64_t>(r) << kReasonShift) |
+               (static_cast<uint64_t>(c) << kCloneTargetShift)) {}
+
+  bool operator==(const FlushFlags& o) const { return flags_ == o.flags_; }
+  bool operator!=(const FlushFlags& o) const { return !(*this == o); }
+
+  Initiator initiator() const {
+    // Due to version mismatch we might see a value from the future that we
+    // didn't know yet. If that happens, short ciruit to kUnknown.
+    static_assert(
+        uint64_t(Initiator::kMax) - 1 <= (kInitiatorMask >> kInitiatorShift),
+        "enum out of range");
+    const uint64_t value = (flags_ & kInitiatorMask) >> kInitiatorShift;
+    return value < uint64_t(Initiator::kMax) ? Initiator(value)
+                                             : Initiator::kUnknown;
+  }
+
+  Reason reason() const {
+    static_assert(uint64_t(Reason::kMax) - 1 <= (kReasonMask >> kReasonShift),
+                  "enum out of range");
+    const uint64_t value = (flags_ & kReasonMask) >> kReasonShift;
+    return value < uint64_t(Reason::kMax) ? Reason(value) : Reason::kUnknown;
+  }
+
+  CloneTarget clone_target() const {
+    static_assert(uint64_t(CloneTarget::kMax) - 1 <=
+                      (kCloneTargetMask >> kCloneTargetShift),
+                  "enum out of range");
+    const uint64_t value = (flags_ & kCloneTargetMask) >> kCloneTargetShift;
+    return value < uint64_t(CloneTarget::kMax) ? CloneTarget(value)
+                                               : CloneTarget::kUnknown;
+  }
+
+  uint64_t flags() const { return flags_; }
+
+ private:
+  // DO NOT CHANGE, ABI.
+  static constexpr uint64_t kReasonMask = 0xF;
+  static constexpr uint64_t kReasonShift = 0;
+  static constexpr uint64_t kInitiatorMask = 0xF0;
+  static constexpr uint64_t kInitiatorShift = 4;
+  static constexpr uint64_t kCloneTargetMask = 0xF00;
+  static constexpr uint64_t kCloneTargetShift = 8;
+
+  uint64_t flags_ = 0;
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_CORE_FLUSH_FLAGS_H_
+// gen_amalgamated begin header: include/perfetto/tracing/internal/data_source_type.h
+// gen_amalgamated begin header: include/perfetto/tracing/internal/tracing_muxer.h
+// gen_amalgamated begin header: include/perfetto/tracing/internal/tracing_tls.h
+// gen_amalgamated begin header: include/perfetto/tracing/platform.h
+// gen_amalgamated begin header: include/perfetto/base/proc_utils.h
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_BASE_PROC_UTILS_H_
+#define INCLUDE_PERFETTO_BASE_PROC_UTILS_H_
+
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+extern "C" {
+// Prototype extracted from the Windows SDK to avoid including windows.h.
+__declspec(dllimport) unsigned long __stdcall GetCurrentProcessId();
+}
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+#include <zircon/process.h>
+#include <zircon/types.h>
+#else
+#include <unistd.h>
+#endif
+
+namespace perfetto {
+namespace base {
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+using PlatformProcessId = zx_handle_t;
+inline PlatformProcessId GetProcessId() {
+  return zx_process_self();
+}
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+using PlatformProcessId = uint64_t;
+inline PlatformProcessId GetProcessId() {
+  return static_cast<uint64_t>(GetCurrentProcessId());
+}
+#else
+using PlatformProcessId = pid_t;
+inline PlatformProcessId GetProcessId() {
+  return getpid();
+}
+#endif
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_BASE_PROC_UTILS_H_
+// gen_amalgamated begin header: include/perfetto/base/thread_utils.h
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_BASE_THREAD_UTILS_H_
+#define INCLUDE_PERFETTO_BASE_THREAD_UTILS_H_
+
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+extern "C" {
+// Prototype extracted from the Windows SDK to avoid including windows.h.
+__declspec(dllimport) unsigned long __stdcall GetCurrentThreadId();
+}
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+#include <zircon/types.h>
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <unistd.h>
+#else
+#include <pthread.h>
+#endif
+
+namespace perfetto {
+namespace base {
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+using PlatformThreadId = pid_t;
+inline PlatformThreadId GetThreadId() {
+  return gettid();
+}
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX)
+using PlatformThreadId = pid_t;
+inline PlatformThreadId GetThreadId() {
+  return static_cast<pid_t>(syscall(__NR_gettid));
+}
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+using PlatformThreadId = zx_koid_t;
+// Not inlined because the result is cached internally.
+PERFETTO_EXPORT_COMPONENT PlatformThreadId GetThreadId();
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+using PlatformThreadId = uint64_t;
+inline PlatformThreadId GetThreadId() {
+  uint64_t tid;
+  pthread_threadid_np(nullptr, &tid);
+  return tid;
+}
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+using PlatformThreadId = uint64_t;
+inline PlatformThreadId GetThreadId() {
+  return static_cast<uint64_t>(GetCurrentThreadId());
+}
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
+using PlatformThreadId = pid_t;
+inline PlatformThreadId GetThreadId() {
+  return reinterpret_cast<int32_t>(pthread_self());
+}
+#else  // Default to pthreads in case no OS is set.
+using PlatformThreadId = pthread_t;
+inline PlatformThreadId GetThreadId() {
+  return pthread_self();
+}
+#endif
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_BASE_THREAD_UTILS_H_
+// gen_amalgamated begin header: include/perfetto/tracing/tracing.h
+// gen_amalgamated begin header: include/perfetto/tracing/backend_type.h
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_BACKEND_TYPE_H_
+#define INCLUDE_PERFETTO_TRACING_BACKEND_TYPE_H_
+
+#include <stdint.h>
+
+namespace perfetto {
+
+enum BackendType : uint32_t {
+  kUnspecifiedBackend = 0,
+
+  // Connects to a previously-initialized perfetto tracing backend for
+  // in-process. If the in-process backend has not been previously initialized
+  // it will do so and create the tracing service on a dedicated thread.
+  kInProcessBackend = 1 << 0,
+
+  // Connects to the system tracing service (e.g. on Linux/Android/Mac uses a
+  // named UNIX socket).
+  kSystemBackend = 1 << 1,
+
+  // Used to provide a custom IPC transport to connect to the service.
+  // TracingInitArgs::custom_backend must be non-null and point to an
+  // indefinitely lived instance.
+  kCustomBackend = 1 << 2,
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_BACKEND_TYPE_H_
+// gen_amalgamated begin header: include/perfetto/tracing/internal/in_process_tracing_backend.h
+// gen_amalgamated begin header: include/perfetto/tracing/tracing_backend.h
+// gen_amalgamated begin header: include/perfetto/base/platform_handle.h
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_BASE_PLATFORM_HANDLE_H_
+#define INCLUDE_PERFETTO_BASE_PLATFORM_HANDLE_H_
+
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+namespace perfetto {
+namespace base {
+
+// PlatformHandle should be used only for types that are HANDLE(s) in Windows.
+// It should NOT be used to blanket-replace "int fd" in the codebase.
+// Windows has two types of "handles", which, in UNIX-land, both map to int:
+// 1. File handles returned by the posix-compatibility API like _open().
+//    These are just int(s) and should stay such, because all the posix-like API
+//    in Windows.h take an int, not a HANDLE.
+// 2. Handles returned by old-school WINAPI like CreateFile, CreateEvent etc.
+//    These are proper HANDLE(s). PlatformHandle should be used here.
+//
+// On Windows, sockets have their own type (SOCKET) which is neither a HANDLE
+// nor an int. However Windows SOCKET(s) can have an event HANDLE attached
+// to them (which in Perfetto is a PlatformHandle), and that can be used in
+// WaitForMultipleObjects, hence in base::TaskRunner.AddFileDescriptorWatch().
+// On POSIX OSes, a SocketHandle is really just an int (a file descriptor).
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+// Windows.h typedefs HANDLE to void*, and SOCKET to uintptr_t. We use their
+// types to avoid leaking Windows.h through our headers.
+using PlatformHandle = void*;
+using SocketHandle = uintptr_t;
+
+// On Windows both nullptr and 0xffff... (INVALID_HANDLE_VALUE) are invalid.
+struct PlatformHandleChecker {
+  static inline bool IsValid(PlatformHandle h) {
+    return h && h != reinterpret_cast<PlatformHandle>(-1);
+  }
+};
+#else
+using PlatformHandle = int;
+using SocketHandle = int;
+struct PlatformHandleChecker {
+  static inline bool IsValid(PlatformHandle h) { return h >= 0; }
+};
+#endif
+
+// The definition of this lives in base/file_utils.cc (to avoid creating an
+// extra build edge for a one liner). This is really an alias for close() (UNIX)
+// CloseHandle() (Windows). THe indirection layer is just to avoid leaking
+// system headers like Windows.h through perfetto headers.
+// Thre return value is always UNIX-style: 0 on success, -1 on failure.
+int ClosePlatformHandle(PlatformHandle);
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_BASE_PLATFORM_HANDLE_H_
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_TRACING_BACKEND_H_
+#define INCLUDE_PERFETTO_TRACING_TRACING_BACKEND_H_
+
+#include <functional>
+#include <memory>
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
+
+// The embedder can (but doesn't have to) extend the TracingBackend class and
+// pass as an argument to Tracing::Initialize(kCustomBackend) to override the
+// way to reach the service. This is for peculiar cases where the embedder has
+// a multi-process architecture and wants to override the IPC transport. The
+// real use-case for this at the time of writing is chromium (+ Mojo IPC).
+// Extending this class requires depending on the full set of perfetto headers
+// (not just /public/). Contact the team before doing so as the non-public
+// headers are not guaranteed to be API stable.
+
+namespace perfetto {
+
+namespace base {
+class TaskRunner;
+}
+
+// These classes are declared in headers outside of /public/.
+class Consumer;
+class ConsumerEndpoint;
+class Producer;
+class ProducerEndpoint;
+
+using CreateSocketCallback = std::function<void(base::SocketHandle)>;
+using CreateSocketAsync = void (*)(CreateSocketCallback);
+
+// Responsible for connecting to the producer.
+class PERFETTO_EXPORT_COMPONENT TracingProducerBackend {
+ public:
+  virtual ~TracingProducerBackend();
+
+  // Connects a Producer instance and obtains a ProducerEndpoint, which is
+  // essentially a 1:1 channel between one Producer and the Service.
+  // To disconnect just destroy the returned endpoint object. It is safe to
+  // destroy the Producer once Producer::OnDisconnect() has been invoked.
+  struct ConnectProducerArgs {
+    std::string producer_name;
+
+    // The Producer object that will receive calls like Start/StopDataSource().
+    // The caller has to guarantee that this object is valid as long as the
+    // returned ProducerEndpoint is alive.
+    Producer* producer = nullptr;
+
+    // The task runner where the Producer methods will be called onto.
+    // The caller has to guarantee that the passed TaskRunner is valid as long
+    // as the returned ProducerEndpoint is alive.
+    ::perfetto::base::TaskRunner* task_runner = nullptr;
+
+    // These get propagated from TracingInitArgs and are optionally provided by
+    // the client when calling Tracing::Initialize().
+    uint32_t shmem_size_hint_bytes = 0;
+    uint32_t shmem_page_size_hint_bytes = 0;
+
+    // If true, the backend should allocate a shared memory buffer and provide
+    // it to the service when connecting.
+    // It's used in startup tracing.
+    bool use_producer_provided_smb = false;
+
+    // If set, the producer will call this function to create and connect to a
+    // socket. See the corresponding field in TracingInitArgs for more info.
+    CreateSocketAsync create_socket_async = nullptr;
+  };
+
+  virtual std::unique_ptr<ProducerEndpoint> ConnectProducer(
+      const ConnectProducerArgs&) = 0;
+};
+
+// Responsible for connecting to the consumer.
+class PERFETTO_EXPORT_COMPONENT TracingConsumerBackend {
+ public:
+  virtual ~TracingConsumerBackend();
+
+  // As above, for the Consumer-side.
+  struct ConnectConsumerArgs {
+    // The Consumer object that will receive calls like OnTracingDisabled(),
+    // OnTraceData().
+    Consumer* consumer{};
+
+    // The task runner where the Consumer methods will be called onto.
+    ::perfetto::base::TaskRunner* task_runner{};
+  };
+  virtual std::unique_ptr<ConsumerEndpoint> ConnectConsumer(
+      const ConnectConsumerArgs&) = 0;
+};
+
+class PERFETTO_EXPORT_COMPONENT TracingBackend : public TracingProducerBackend,
+                                                 public TracingConsumerBackend {
+ public:
+  ~TracingBackend() override;
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_TRACING_BACKEND_H_
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_IN_PROCESS_TRACING_BACKEND_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_IN_PROCESS_TRACING_BACKEND_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/tracing_backend.h"
+
+namespace perfetto {
+
+namespace base {
+class TaskRunner;
+}
+
+class Producer;
+class TracingService;
+
+namespace internal {
+
+// A built-in implementation of TracingBackend that creates a tracing service
+// instance in-process. Instantiated when the embedder calls
+// Tracing::Initialize(kInProcessBackend). Solves most in-app-only tracing
+// use-cases.
+class PERFETTO_EXPORT_COMPONENT InProcessTracingBackend
+    : public TracingBackend {
+ public:
+  static TracingBackend* GetInstance();
+
+  ~InProcessTracingBackend() override;
+
+  // TracingBackend implementation.
+  std::unique_ptr<ProducerEndpoint> ConnectProducer(
+      const ConnectProducerArgs&) override;
+  std::unique_ptr<ConsumerEndpoint> ConnectConsumer(
+      const ConnectConsumerArgs&) override;
+
+ private:
+  InProcessTracingBackend();
+  TracingService* GetOrCreateService(base::TaskRunner*);
+
+  std::unique_ptr<TracingService> service_;
+};
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_IN_PROCESS_TRACING_BACKEND_H_
+// gen_amalgamated begin header: include/perfetto/tracing/internal/system_tracing_backend.h
+// gen_amalgamated begin header: include/perfetto/tracing/default_socket.h
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_DEFAULT_SOCKET_H_
+#define INCLUDE_PERFETTO_TRACING_DEFAULT_SOCKET_H_
+
+#include <string>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+
+PERFETTO_EXPORT_COMPONENT const char* GetConsumerSocket();
+// This function is used for tokenize the |producer_socket_names| string into
+// multiple producer socket names.
+PERFETTO_EXPORT_COMPONENT std::vector<std::string> TokenizeProducerSockets(
+    const char* producer_socket_names);
+PERFETTO_EXPORT_COMPONENT const char* GetProducerSocket();
+
+// Optionally returns the relay socket name (nullable). The relay socket is used
+// for forwarding the IPC messages between the local producers and the remote
+// tracing service.
+PERFETTO_EXPORT_COMPONENT const char* GetRelaySocket();
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_DEFAULT_SOCKET_H_
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_SYSTEM_TRACING_BACKEND_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_SYSTEM_TRACING_BACKEND_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/default_socket.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/tracing_backend.h"
+
+namespace perfetto {
+
+namespace base {
+class TaskRunner;
+}
+
+class Producer;
+
+// Built-in implementations of TracingProducerBackend and TracingConsumerBackend
+// that connect to the system tracing daemon (traced) via a UNIX socket using
+// the perfetto built-in proto-based IPC mechanism. Instantiated when the
+// embedder calls Tracing::Initialize(kSystemBackend). They allow to get
+// app-traces fused together with system traces, useful to correlate on the
+// timeline system events (e.g. scheduling slices from the kernel) with in-app
+// events.
+namespace internal {
+
+// Producer backend
+class PERFETTO_EXPORT_COMPONENT SystemProducerTracingBackend
+    : public TracingProducerBackend {
+ public:
+  static TracingProducerBackend* GetInstance();
+
+  std::unique_ptr<ProducerEndpoint> ConnectProducer(
+      const ConnectProducerArgs&) override;
+
+ private:
+  SystemProducerTracingBackend();
+};
+
+// Consumer backend
+class PERFETTO_EXPORT_COMPONENT SystemConsumerTracingBackend
+    : public TracingConsumerBackend {
+ public:
+  static TracingConsumerBackend* GetInstance();
+
+  std::unique_ptr<ConsumerEndpoint> ConnectConsumer(
+      const ConnectConsumerArgs&) override;
+
+ private:
+  SystemConsumerTracingBackend();
+};
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_SYSTEM_TRACING_BACKEND_H_
+// gen_amalgamated begin header: include/perfetto/tracing/tracing_policy.h
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_TRACING_POLICY_H_
+#define INCLUDE_PERFETTO_TRACING_TRACING_POLICY_H_
+
+#include <functional>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/backend_type.h"
+
+namespace perfetto {
+
+// Applies policy decisions, such as allowing or denying connections, when
+// certain tracing SDK events occur. All methods are called on an internal
+// perfetto thread.
+class PERFETTO_EXPORT_COMPONENT TracingPolicy {
+ public:
+  virtual ~TracingPolicy();
+
+  // Called when the current process attempts to connect a new consumer to the
+  // backend of |backend_type| to check if the connection should be allowed. Its
+  // implementation should execute |result_callback| with the result of the
+  // check (synchronuosly or asynchronously on any thread). If the result is
+  // false, the consumer connection is aborted. Chrome uses this to restrict
+  // creating (system) tracing sessions based on an enterprise policy.
+  struct ShouldAllowConsumerSessionArgs {
+    BackendType backend_type;
+    std::function<void(bool /*allow*/)> result_callback;
+  };
+  virtual void ShouldAllowConsumerSession(
+      const ShouldAllowConsumerSessionArgs&) = 0;
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_TRACING_POLICY_H_
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_TRACING_H_
+#define INCLUDE_PERFETTO_TRACING_TRACING_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <functional>
+#include <memory>
+#include <string>
+#include <tuple>
+#include <utility>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/backend_type.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/in_process_tracing_backend.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/system_tracing_backend.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/tracing_policy.h"
+
+namespace perfetto {
+
+namespace internal {
+class TracingMuxerImpl;
+}
+
+class TracingBackend;
+class Platform;
+class StartupTracingSession;  // Declared below.
+class TracingSession;         // Declared below.
+
+struct TracingError {
+  enum ErrorCode : uint32_t {
+    // Peer disconnection.
+    kDisconnected = 1,
+
+    // The Start() method failed. This is typically because errors in the passed
+    // TraceConfig. More details are available in |message|.
+    kTracingFailed = 2,
+  };
+
+  ErrorCode code;
+  std::string message;
+
+  TracingError(ErrorCode cd, std::string msg)
+      : code(cd), message(std::move(msg)) {
+    PERFETTO_CHECK(!message.empty());
+  }
+};
+
+using LogLev = ::perfetto::base::LogLev;
+using LogMessageCallbackArgs = ::perfetto::base::LogMessageCallbackArgs;
+using LogMessageCallback = ::perfetto::base::LogMessageCallback;
+
+struct TracingInitArgs {
+  uint32_t backends = 0;                     // One or more BackendTypes.
+  TracingBackend* custom_backend = nullptr;  // [Optional].
+
+  // [Optional] Platform implementation. It allows the embedder to take control
+  // of platform-specific bits like thread creation and TLS slot handling. If
+  // not set it will use Platform::GetDefaultPlatform().
+  Platform* platform = nullptr;
+
+  // [Optional] Tune the size of the shared memory buffer between the current
+  // process and the service backend(s). This is a trade-off between memory
+  // footprint and the ability to sustain bursts of trace writes (see comments
+  // in shared_memory_abi.h).
+  // If set, the value must be a multiple of 4KB. The value can be ignored if
+  // larger than kMaxShmSize (32MB) or not a multiple of 4KB.
+  uint32_t shmem_size_hint_kb = 0;
+
+  // [Optional] Specifies the preferred size of each page in the shmem buffer.
+  // This is a trade-off between IPC overhead and fragmentation/efficiency of
+  // the shmem buffer in presence of multiple writer threads.
+  // Must be one of [4, 8, 16, 32].
+  uint32_t shmem_page_size_hint_kb = 0;
+
+  // [Optional] The length of the period during which shared-memory-buffer
+  // chunks that have been filled with data are accumulated (batched) on the
+  // producer side, before the service is notified of them over an out-of-band
+  // IPC call. If, while this period lasts, the shared memory buffer gets too
+  // full, the IPC call will be sent immediately. The value of this parameter is
+  // a trade-off between IPC traffic overhead and the ability to sustain bursts
+  // of trace writes. The higher the value, the more chunks will be batched and
+  // the less buffer space will be available to hide the latency of the service,
+  // and vice versa. For more details, see the SetBatchCommitsDuration method in
+  // shared_memory_arbiter.h.
+  //
+  // Note: With the default value of 0ms, batching still happens but with a zero
+  // delay, i.e. commits will be sent to the service at the next opportunity.
+  uint32_t shmem_batch_commits_duration_ms = 0;
+
+  // [Optional] Enables direct producer-side patching of chunks that have not
+  // yet been committed to the service. This flag will only have an effect
+  // if the service supports direct patching, otherwise it will be ignored.
+  bool shmem_direct_patching_enabled = false;
+
+  // [Optional] If set, the policy object is notified when certain SDK events
+  // occur and may apply policy decisions, such as denying connections. The
+  // embedder is responsible for ensuring the object remains alive for the
+  // lifetime of the process.
+  TracingPolicy* tracing_policy = nullptr;
+
+  // [Optional] If set, log messages generated by perfetto are passed to this
+  // callback instead of being logged directly.
+  LogMessageCallback log_message_callback = nullptr;
+
+  // When this flag is set to false, it overrides
+  // `DataSource::kSupportsMultipleInstances` for all the data sources.
+  // As a result when a tracing session is already running and if we attempt to
+  // start another session, it will fail to start the data source which were
+  // already active.
+  bool supports_multiple_data_source_instances = true;
+
+  // If this flag is set the default clock for taking timestamps is overridden
+  // with CLOCK_MONOTONIC (for use in Chrome).
+  bool use_monotonic_clock = false;
+
+  // If this flag is set the default clock for taking timestamps is overridden
+  // with CLOCK_MONOTONIC_RAW on platforms that support it.
+  bool use_monotonic_raw_clock = false;
+
+  // This flag can be set to false in order to avoid enabling the system
+  // consumer in Tracing::Initialize(), so that the linker can remove the unused
+  // consumer IPC implementation to reduce binary size. This setting only has an
+  // effect if kSystemBackend is specified in |backends|. When this option is
+  // false, Tracing::NewTrace() will instatiate the system backend only if
+  // explicitly specified as kSystemBackend: kUndefinedBackend will consider
+  // only already instantiated backends.
+  bool enable_system_consumer = true;
+
+  // When true, sets disallow_merging_with_system_tracks in TrackDescriptor,
+  // making sure that Trace Processor doesn't merge track event and system
+  // event tracks for the same thread.
+  bool disallow_merging_with_system_tracks = false;
+
+  // If set, this function will be called by the producer client to create a
+  // socket for connection to the system service. The function takes one
+  // argument: a callback that takes an open file descriptor. The function
+  // should create a socket with the name defined by
+  // perfetto::GetProducerSocket(), connect to it, and return the corresponding
+  // descriptor via the callback.
+  // This is intended for the use-case where a process being traced is run
+  // inside a sandbox and can't create sockets directly.
+  // Not yet supported for consumer connections currently.
+  CreateSocketAsync create_socket_async = nullptr;
+
+ protected:
+  friend class Tracing;
+  friend class internal::TracingMuxerImpl;
+
+  using BackendFactoryFunction = TracingBackend* (*)();
+  using ProducerBackendFactoryFunction = TracingProducerBackend* (*)();
+  using ConsumerBackendFactoryFunction = TracingConsumerBackend* (*)();
+
+  BackendFactoryFunction in_process_backend_factory_ = nullptr;
+  ProducerBackendFactoryFunction system_producer_backend_factory_ = nullptr;
+  ConsumerBackendFactoryFunction system_consumer_backend_factory_ = nullptr;
+  bool dcheck_is_on_ = PERFETTO_DCHECK_IS_ON();
+};
+
+// The entry-point for using perfetto.
+class PERFETTO_EXPORT_COMPONENT Tracing {
+ public:
+  // Initializes Perfetto with the given backends in the calling process and/or
+  // with a user-provided backend. It's possible to call this function more than
+  // once to initialize different backends. If a backend was already initialized
+  // the call will have no effect on it. All the members of `args` will be
+  // ignored in subsequent calls, except those require to initialize new
+  // backends (`backends`, `enable_system_consumer`, `shmem_size_hint_kb`,
+  // `shmem_page_size_hint_kb` and `shmem_batch_commits_duration_ms`).
+  static inline void Initialize(const TracingInitArgs& args)
+      PERFETTO_ALWAYS_INLINE {
+    TracingInitArgs args_copy(args);
+    // This code is inlined to allow dead-code elimination for unused backends.
+    // This saves ~200 KB when not using the in-process backend (b/148198993).
+    // The logic behind it is the following:
+    // Nothing other than the code below references the two GetInstance()
+    // methods. From a linker-graph viewpoint, those GetInstance() pull in many
+    // other pieces of the codebase (e.g. InProcessTracingBackend pulls the
+    // whole TracingServiceImpl, SystemTracingBackend pulls the whole //ipc
+    // layer). Due to the inline, the compiler can see through the code and
+    // realize that some branches are always not taken. When that happens, no
+    // reference to the backends' GetInstance() is emitted and that allows the
+    // linker GC to get rid of the entire set of dependencies.
+    if (args.backends & kInProcessBackend) {
+      args_copy.in_process_backend_factory_ =
+          &internal::InProcessTracingBackend::GetInstance;
+    }
+    if (args.backends & kSystemBackend) {
+      args_copy.system_producer_backend_factory_ =
+          &internal::SystemProducerTracingBackend::GetInstance;
+      if (args.enable_system_consumer) {
+        args_copy.system_consumer_backend_factory_ =
+            &internal::SystemConsumerTracingBackend::GetInstance;
+      }
+    }
+    InitializeInternal(args_copy);
+  }
+
+  // Checks if tracing has been initialized by calling |Initialize|.
+  static bool IsInitialized();
+
+  // Start a new tracing session using the given tracing backend. Use
+  // |kUnspecifiedBackend| to select an available backend automatically.
+  static PERFETTO_ALWAYS_INLINE inline std::unique_ptr<TracingSession> NewTrace(
+      BackendType backend = kUnspecifiedBackend);
+
+  // Shut down Perfetto, releasing any allocated OS resources (threads, files,
+  // sockets, etc.). Note that Perfetto cannot be reinitialized again in the
+  // same process[1]. Instead, this function is meant for shutting down all
+  // Perfetto-related code so that it can be safely unloaded, e.g., with
+  // dlclose().
+  //
+  // It is only safe to call this function when all threads recording trace
+  // events have been terminated or otherwise guaranteed to not make any further
+  // calls into Perfetto.
+  //
+  // [1] Unless static data is also cleared through other means.
+  static void Shutdown();
+
+  // Uninitialize Perfetto. Only exposed for testing scenarios where it can be
+  // guaranteed that no tracing sessions or other operations are happening when
+  // this call is made.
+  static void ResetForTesting();
+
+  // Start a new startup tracing session in the current process. Startup tracing
+  // can be used in anticipation of a session that will be started by the
+  // specified backend in the near future. The data source configs in the
+  // supplied TraceConfig have to (mostly) match those in the config that will
+  // later be provided by the backend.
+  // Learn more about config matching at ComputeStartupConfigHash.
+  //
+  // Note that startup tracing requires that either:
+  //  (a) the service backend already has an SMB set up, or
+  //  (b) the service backend to support producer-provided SMBs if the backend
+  //      is not yet connected or no SMB has been set up yet
+  //      (See `use_producer_provided_smb`). If necessary, the
+  //      client library will briefly disconnect and reconnect the backend to
+  //      supply an SMB to the backend. If the service does not accept the SMB,
+  //      startup tracing will be aborted, but the service may still start the
+  //      corresponding tracing session later.
+  //
+  // Startup tracing is NOT supported with the in-process backend. For this
+  // backend, you can just start a regular tracing session and block until it is
+  // set up instead.
+  //
+  // The client library will start the data sources instances specified in the
+  // config with a placeholder target buffer. Once the backend starts a matching
+  // tracing session, the session will resume as normal. If no matching session
+  // is started after a timeout (or the backend doesn't accept the
+  // producer-provided SMB), the startup tracing session will be aborted
+  // and the data source instances stopped.
+  struct OnStartupTracingSetupCallbackArgs {
+    int num_data_sources_started;
+  };
+  struct SetupStartupTracingOpts {
+    BackendType backend = kUnspecifiedBackend;
+    uint32_t timeout_ms = 10000;
+
+    // If set, this callback is executed (on an internal Perfetto thread) when
+    // startup tracing was set up.
+    std::function<void(OnStartupTracingSetupCallbackArgs)> on_setup;
+
+    // If set, this callback is executed (on an internal Perfetto thread) if any
+    // data sources were aborted, e.g. due to exceeding the timeout or as a
+    // response to Abort().
+    std::function<void()> on_aborted;
+
+    // If set, this callback is executed (on an internal Perfetto thread) after
+    // all data sources were adopted by a tracing session initiated by the
+    // backend.
+    std::function<void()> on_adopted;
+  };
+
+  static std::unique_ptr<StartupTracingSession> SetupStartupTracing(
+      const TraceConfig& config,
+      SetupStartupTracingOpts);
+
+  // Blocking version of above method, so callers can ensure that tracing is
+  // active before proceeding with app startup. Calls into
+  // DataSource::Trace() or trace macros right after this method are written
+  // into the startup session.
+  static std::unique_ptr<StartupTracingSession> SetupStartupTracingBlocking(
+      const TraceConfig& config,
+      SetupStartupTracingOpts);
+
+  // Informs the tracing services to activate any of these triggers if any
+  // tracing session was waiting for them.
+  //
+  // Sends the trigger signal to all the initialized backends that are currently
+  // connected and that connect in the next `ttl_ms` milliseconds (but
+  // returns immediately anyway).
+  static void ActivateTriggers(const std::vector<std::string>& triggers,
+                               uint32_t ttl_ms);
+
+ private:
+  static void InitializeInternal(const TracingInitArgs&);
+  static std::unique_ptr<TracingSession> NewTraceInternal(
+      BackendType,
+      TracingConsumerBackend* (*system_backend_factory)());
+
+  Tracing() = delete;
+};
+
+class PERFETTO_EXPORT_COMPONENT TracingSession {
+ public:
+  virtual ~TracingSession();
+
+  // Configure the session passing the trace config.
+  // If a writable file handle is given through |fd|, the trace will
+  // automatically written to that file. Otherwise you should call ReadTrace()
+  // to retrieve the trace data. This call does not take ownership of |fd|.
+  // TODO(primiano): add an error callback.
+  virtual void Setup(const TraceConfig&, int fd = -1) = 0;
+
+  // Enable tracing asynchronously. Use SetOnStartCallback() to get a
+  // notification when the session has fully started.
+  virtual void Start() = 0;
+
+  // Enable tracing and block until tracing has started. Note that if data
+  // sources are registered after this call was initiated, the call may return
+  // before the additional data sources have started. Also, if other producers
+  // (e.g., with system-wide tracing) have registered data sources without start
+  // notification support, this call may return before those data sources have
+  // started.
+  virtual void StartBlocking() = 0;
+
+  // This callback will be invoked when all data sources have acknowledged that
+  // tracing has started. This callback will be invoked on an internal perfetto
+  // thread.
+  virtual void SetOnStartCallback(std::function<void()>) = 0;
+
+  // This callback can be used to get a notification when some error occurred
+  // (e.g., peer disconnection). Error type will be passed as an argument. This
+  // callback will be invoked on an internal perfetto thread.
+  virtual void SetOnErrorCallback(std::function<void(TracingError)>) = 0;
+
+  // Issues a flush request, asking all data sources to ack the request, within
+  // the specified timeout. A "flush" is a fence to ensure visibility of data in
+  // the async tracing pipeline. It guarantees that all data written before the
+  // Flush() call will be visible in the trace buffer and hence by the
+  // ReadTrace() / ReadTraceBlocking() methods.
+  // Args:
+  //  callback: will be invoked on an internal perfetto thread when all data
+  //    sources have acked, or the timeout is reached. The bool argument
+  //    will be true if all data sources acked within the timeout, false if
+  //    the timeout was hit or some other error occurred (e.g. the tracing
+  //    session wasn't started or ended).
+  //  timeout_ms: how much time the service will wait for data source acks. If
+  //    0, the global timeout specified in the TraceConfig (flush_timeout_ms)
+  //    will be used. If flush_timeout_ms is also unspecified, a default value
+  //    of 5s will be used.
+  // Known issues:
+  //    Because flushing is still based on service-side scraping, the very last
+  //    trace packet for each data source thread will not be visible. Fixing
+  //    this requires either propagating the Flush() to the data sources or
+  //    changing the order of atomic operations in the service (b/162206162).
+  //    Until then, a workaround is to make sure to call
+  //    DataSource::Trace([](TraceContext ctx) { ctx.Flush(); }) just before
+  //    stopping, on each thread where DataSource::Trace has been previously
+  //    called.
+  virtual void Flush(std::function<void(bool)>, uint32_t timeout_ms = 0) = 0;
+
+  // Blocking version of Flush(). Waits until all data sources have acked and
+  // returns the success/failure status.
+  bool FlushBlocking(uint32_t timeout_ms = 0);
+
+  // Disable tracing asynchronously.
+  // Use SetOnStopCallback() to get a notification when the tracing session is
+  // fully stopped and all data sources have acked.
+  virtual void Stop() = 0;
+
+  // Disable tracing and block until tracing has stopped.
+  virtual void StopBlocking() = 0;
+
+  // This callback will be invoked when tracing is disabled.
+  // This can happen either when explicitly calling TracingSession.Stop() or
+  // when the trace reaches its |duration_ms| time limit.
+  // This callback will be invoked on an internal perfetto thread.
+  virtual void SetOnStopCallback(std::function<void()>) = 0;
+
+  // Changes the TraceConfig for an active tracing session. The session must
+  // have been configured and started before. Note that the tracing service
+  // only supports changing a subset of TraceConfig fields,
+  // see ConsumerEndpoint::ChangeTraceConfig().
+  virtual void ChangeTraceConfig(const TraceConfig&) = 0;
+
+  // Struct passed as argument to the callback passed to ReadTrace().
+  // [data, size] is guaranteed to contain 1 or more full trace packets, which
+  // can be decoded using trace.proto. No partial or truncated packets are
+  // exposed. If the trace is empty this returns a zero-sized nullptr with
+  // |has_more| == true to signal EOF.
+  // This callback will be invoked on an internal perfetto thread.
+  struct ReadTraceCallbackArgs {
+    const char* data = nullptr;
+    size_t size = 0;
+
+    // When false, this will be the last invocation of the callback for this
+    // read cycle.
+    bool has_more = false;
+  };
+
+  // Reads back the trace data (raw protobuf-encoded bytes) asynchronously.
+  // Can be called at any point during the trace, typically but not necessarily,
+  // after stopping. If this is called before the end of the trace (i.e. before
+  // Stop() / StopBlocking()), in almost all cases you need to call
+  // Flush() / FlushBlocking() before Read(). This is to guarantee that tracing
+  // data in-flight in the data sources is committed into the tracing buffers
+  // before reading them.
+  // Reading the trace data is a destructive operation w.r.t. contents of the
+  // trace buffer and is not idempotent.
+  // A single ReadTrace() call can yield >1 callback invocations, until
+  // |has_more| is false.
+  using ReadTraceCallback = std::function<void(ReadTraceCallbackArgs)>;
+  virtual void ReadTrace(ReadTraceCallback) = 0;
+
+  // Synchronous version of ReadTrace(). It blocks the calling thread until all
+  // the trace contents are read. This is slow and inefficient (involves more
+  // copies) and is mainly intended for testing.
+  std::vector<char> ReadTraceBlocking();
+
+  // Struct passed as an argument to the callback for GetTraceStats(). Contains
+  // statistics about the tracing session.
+  struct GetTraceStatsCallbackArgs {
+    // Whether or not querying statistics succeeded.
+    bool success = false;
+    // Serialized TraceStats protobuf message. To decode:
+    //
+    //   perfetto::protos::gen::TraceStats trace_stats;
+    //   trace_stats.ParseFromArray(args.trace_stats_data.data(),
+    //                              args.trace_stats_data.size());
+    //
+    std::vector<uint8_t> trace_stats_data;
+  };
+
+  // Requests a snapshot of statistical data for this tracing session. Only one
+  // query may be active at a time. This callback will be invoked on an internal
+  // perfetto thread.
+  using GetTraceStatsCallback = std::function<void(GetTraceStatsCallbackArgs)>;
+  virtual void GetTraceStats(GetTraceStatsCallback) = 0;
+
+  // Synchronous version of GetTraceStats() for convenience.
+  GetTraceStatsCallbackArgs GetTraceStatsBlocking();
+
+  // Struct passed as an argument to the callback for QueryServiceState().
+  // Contains information about registered data sources.
+  struct QueryServiceStateCallbackArgs {
+    // Whether or not getting the service state succeeded.
+    bool success = false;
+    // Serialized TracingServiceState protobuf message. To decode:
+    //
+    //   perfetto::protos::gen::TracingServiceState state;
+    //   state.ParseFromArray(args.service_state_data.data(),
+    //                        args.service_state_data.size());
+    //
+    std::vector<uint8_t> service_state_data;
+  };
+
+  // Requests a snapshot of the tracing service state for this session. Only one
+  // request per session may be active at a time. This callback will be invoked
+  // on an internal perfetto thread.
+  using QueryServiceStateCallback =
+      std::function<void(QueryServiceStateCallbackArgs)>;
+  virtual void QueryServiceState(QueryServiceStateCallback) = 0;
+
+  // Synchronous version of QueryServiceState() for convenience.
+  QueryServiceStateCallbackArgs QueryServiceStateBlocking();
+};
+
+class PERFETTO_EXPORT_COMPONENT StartupTracingSession {
+ public:
+  // Note that destroying the StartupTracingSession object will not abort the
+  // startup session automatically. Call Abort() explicitly to do so.
+  virtual ~StartupTracingSession();
+
+  // Abort any active but still unbound data source instances that belong to
+  // this startup tracing session. Does not affect data source instances that
+  // were already bound to a service-controlled session.
+  virtual void Abort() = 0;
+
+  // Same as above, but blocks the current thread until aborted.
+  // Note some of the internal (non observable from public APIs) cleanup might
+  // be done even after this method returns.
+  virtual void AbortBlocking() = 0;
+};
+
+PERFETTO_ALWAYS_INLINE inline std::unique_ptr<TracingSession>
+Tracing::NewTrace(BackendType backend) {
+  // This code is inlined to allow dead-code elimination for unused consumer
+  // implementation. The logic behind it is the following:
+  // Nothing other than the code below references the GetInstance() method
+  // below. From a linker-graph viewpoint, those GetInstance() pull in many
+  // other pieces of the codebase (ConsumerOnlySystemTracingBackend pulls
+  // ConsumerIPCClient). Due to the inline, the compiler can see through the
+  // code and realize that some branches are always not taken. When that
+  // happens, no reference to the backends' GetInstance() is emitted and that
+  // allows the linker GC to get rid of the entire set of dependencies.
+  TracingConsumerBackend* (*system_backend_factory)();
+  system_backend_factory = nullptr;
+  // In case PERFETTO_IPC is disabled, a fake system backend is used, which
+  // always panics. NewTrace(kSystemBackend) should fail if PERFETTO_IPC is
+  // diabled, not panic.
+#if PERFETTO_BUILDFLAG(PERFETTO_IPC)
+  if (backend & kSystemBackend) {
+    system_backend_factory =
+        &internal::SystemConsumerTracingBackend::GetInstance;
+  }
+#endif
+  return NewTraceInternal(backend, system_backend_factory);
+}
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_TRACING_H_
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_PLATFORM_H_
+#define INCLUDE_PERFETTO_TRACING_PLATFORM_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <functional>
+#include <memory>
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/proc_utils.h"
+// gen_amalgamated expanded: #include "perfetto/base/thread_utils.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/tracing.h"
+
+namespace perfetto {
+
+namespace base {
+class TaskRunner;
+}  // namespace base
+
+// This abstract class is used to abstract dependencies on platform-specific
+// primitives that cannot be implemented by the perfetto codebase and must be
+// provided or overridden by the embedder.
+// This is, for instance, for cases where we want to use some particular
+// base:: class in Chrome and provide instead POSIX fallbacks for other
+// embedders.
+
+// Base class for thread-local objects. This is to get a basic object vtable and
+// delegate destruction to the embedder. See Platform::CreateThreadLocalObject.
+class PERFETTO_EXPORT_COMPONENT PlatformThreadLocalObject {
+ public:
+  // Implemented by perfetto internal code. The embedder must call this when
+  // implementing GetOrCreateThreadLocalObject() to create an instance for the
+  // first time on each thread.
+  static std::unique_ptr<PlatformThreadLocalObject> CreateInstance();
+  virtual ~PlatformThreadLocalObject();
+};
+
+class PERFETTO_EXPORT_COMPONENT Platform {
+ public:
+  // Embedders can use this unless they have custom needs (e.g. Chrome wanting
+  // to use its own base class for TLS).
+  static Platform* GetDefaultPlatform();
+
+  // Embedders can call this to set process ID in those cases where getpid()
+  // returns incorrect values (e.g. for sandboxed processes in Chromium).
+  // Should only be called once, before tracing has been initialized.
+  static void SetCurrentProcessId(base::PlatformProcessId process_id) {
+    PERFETTO_CHECK(!process_id_);
+    PERFETTO_DCHECK(!Tracing::IsInitialized());
+    process_id_ = process_id;
+  }
+
+  // Returns process ID previously set by SetCurrentProcessId, or the process
+  // ID provided by the OS if no custom ID was provided.
+  static base::PlatformProcessId GetCurrentProcessId() {
+    if (process_id_)
+      return process_id_;
+    return base::GetProcessId();
+  }
+
+  virtual ~Platform();
+
+  // Creates a thread-local object. The embedder must:
+  // - Create an instance per-thread calling ThreadLocalObject::CreateInstance.
+  // - Own the lifetime of the returned object as long as the thread is alive.
+  // - Destroy it when the thread exits.
+  // Perfetto requires only one thread-local object overall (obviously, one
+  // instance per-thread) from the embedder.
+  using ThreadLocalObject = ::perfetto::PlatformThreadLocalObject;
+  virtual ThreadLocalObject* GetOrCreateThreadLocalObject() = 0;
+
+  // Creates a sequenced task runner. The easiest implementation is to create
+  // a new thread (e.g. use base::ThreadTaskRunner) but this can also be
+  // implemented in some more clever way (e.g. using chromiums's scheduler).
+  struct CreateTaskRunnerArgs {
+    // Optional. Sets the name to the newly created task runner. In the default
+    // PosixPlatform implementation this causes a pthread_setname_np(). This is
+    // only for ease of debugging, it does not affect the tracing behavior.
+    std::string name_for_debugging;
+  };
+  virtual std::unique_ptr<base::TaskRunner> CreateTaskRunner(
+      const CreateTaskRunnerArgs&) = 0;
+
+  // Used to derive the producer name. Mostly relevant when using the
+  // kSystemBackend mode. It can be an arbitrary string when using the
+  // in-process mode.
+  virtual std::string GetCurrentProcessName() = 0;
+
+  // Tear down any persistent platform state (e.g., TLS variables). The platform
+  // interface must not be used after calling this function.
+  virtual void Shutdown();
+
+  // Returns the thread ID provided by the OS by default. Chromium uses
+  // different thread IDs on some platforms, so it needs the ability to
+  // override this method.
+  virtual base::PlatformThreadId GetCurrentThreadId();
+
+ private:
+  static base::PlatformProcessId process_id_;
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_PLATFORM_H_
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_TRACING_TLS_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_TRACING_TLS_H_
+
+#include <array>
+#include <memory>
+
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/data_source_internal.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/platform.h"
+
+namespace perfetto {
+
+class TraceWriterBase;
+
+namespace internal {
+
+// Organization of the thread-local storage
+// ----------------------------------------
+// First of all, remember the cardinality of the problem: at any point in time
+// there are M data sources registered (i.e. number of subclasses of DataSource)
+// and up to N concurrent instances for each data source, so up to M * N total
+// data source instances around.
+// Each data source instance can be accessed by T threads (no upper bound).
+// We can safely put hard limits both to M and N (i.e. say that we support at
+// most 32 data source types per process and up to 8 concurrent instances).
+//
+// We want to make it so from the Platform viewpoint, we use only one global
+// TLS object, so T instances in total, one per thread, regardless of M and N.
+// This allows to deal with at-thread-exit destruction only in one place, rather
+// than N, M or M * N.
+//
+// Visually:
+//                     [    Thread 1   ] [    Thread 2   ] [    Thread T   ]
+//                     +---------------+ +---------------+ +---------------+
+// Data source Foo     |               | |               | |               |
+//  Instance 1         |     TLS       | |     TLS       | |     TLS       |
+//  Instance 2         |    Object     | |    Object     | |    Object     |
+//  Instance 3         |               | |               | |               |
+//                     |               | |               | |               |
+// Data source Bar     |               | |               | |               |
+//  Instance 1         |               | |               | |               |
+//  Instance 2         |               | |               | |               |
+//                     +---------------+ +---------------+ +---------------+
+//
+// Each TLS Object is organized as an array of M DataSourceThreadLocalState.
+// Each DSTLS itself is an array of up to N per-instance objects.
+// The only per-instance object for now is the TraceWriter.
+// So for each data source, for each instance, for each thread we keep one
+// TraceWriter.
+// The lookup is O(1): Given the TLS object, the TraceWriter is just tls[M][N].
+class TracingTLS : public Platform::ThreadLocalObject {
+ public:
+  ~TracingTLS() override;
+
+  // This is checked against TraceMuxerImpl's global generation counter to
+  // handle destruction of TraceWriter(s) that belong to data sources that
+  // have been stopped. When the two numbers diverge, a scan of all the
+  // thread-local TraceWriter(s) is issued.
+  uint32_t generation = 0;
+
+  // This flag is true while this thread is inside a trace point for any data
+  // source or in other delicate parts of the tracing machinery during which we
+  // should not try to trace. Used to prevent unexpected re-entrancy.
+  // This flag is also load-bearing when handling re-entrancy during thread-exit
+  // handlers. See comment in TracingTLS::~TracingTLS().
+  bool is_in_trace_point = false;
+
+  // Used inside a trace point (only one trace point per thread can be active at
+  // any time) to cache the instances bitmap.
+  uint32_t cached_instances = 0;
+
+  // By default all data source instances have independent thread-local state
+  // (see above).
+  std::array<DataSourceThreadLocalState, kMaxDataSources> data_sources_tls{};
+
+  // Track event data sources, however, share the same thread-local state in
+  // order to be able to share trace writers and interning state across all
+  // track event categories.
+  DataSourceThreadLocalState track_event_tls{};
+};
+
+struct ScopedReentrancyAnnotator {
+  ScopedReentrancyAnnotator(TracingTLS& root_tls) : root_tls_(root_tls) {
+    PERFETTO_DCHECK(!root_tls_.is_in_trace_point);
+    root_tls_.is_in_trace_point = true;
+  }
+  ~ScopedReentrancyAnnotator() { root_tls_.is_in_trace_point = false; }
+
+ private:
+  TracingTLS& root_tls_;
+};
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_TRACING_TLS_H_
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_TRACING_MUXER_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_TRACING_MUXER_H_
+
+#include <atomic>
+#include <memory>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/interceptor.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_tls.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/platform.h"
+namespace perfetto {
+
+class DataSourceBase;
+class TraceWriterBase;
+struct TracingInitArgs;
+class TracingSession;
+
+namespace internal {
+
+struct DataSourceParams {
+  bool supports_multiple_instances;
+  bool requires_callbacks_under_lock;
+};
+
+struct DataSourceStaticState;
+
+// This class acts as a bridge between the public API methods and the
+// TracingBackend(s). It exposes a simplified view of the world to the API
+// methods, so that they don't have to care about the multiplicity of backends.
+// It handles all the bookkeeping to map data source instances and trace writers
+// to the various backends.
+// See tracing_muxer_impl.h for the full picture. This class contains only the
+// fewer fields and methods that need to be exposed to public/ headers. Fields
+// and methods that are required to implement them should go into
+// src/tracing/internal/tracing_muxer_impl.h instead: that one can pull in
+// perfetto headers outside of public, this one cannot.
+class PERFETTO_EXPORT_COMPONENT TracingMuxer {
+ public:
+  static TracingMuxer* Get() { return instance_; }
+
+  virtual ~TracingMuxer();
+
+  TracingTLS* GetOrCreateTracingTLS() {
+    return static_cast<TracingTLS*>(platform_->GetOrCreateThreadLocalObject());
+  }
+
+  // This method can fail and return false if trying to register more than
+  // kMaxDataSources types.
+  using DataSourceFactory = std::function<std::unique_ptr<DataSourceBase>()>;
+  virtual bool RegisterDataSource(const DataSourceDescriptor&,
+                                  DataSourceFactory,
+                                  DataSourceParams,
+                                  bool no_flush,
+                                  DataSourceStaticState*) = 0;
+
+  // Updates the DataSourceDescriptor for the DataSource.
+  virtual void UpdateDataSourceDescriptor(const DataSourceDescriptor&,
+                                          const DataSourceStaticState*) = 0;
+
+  // It identifies the right backend and forwards the call to it.
+  // The returned TraceWriter must be used within the same sequence (for most
+  // projects this means "same thread"). Alternatively the client needs to take
+  // care of using synchronization primitives to prevent concurrent accesses.
+  virtual std::unique_ptr<TraceWriterBase> CreateTraceWriter(
+      DataSourceStaticState*,
+      uint32_t data_source_instance_index,
+      DataSourceState*,
+      BufferExhaustedPolicy buffer_exhausted_policy) = 0;
+
+  virtual void DestroyStoppedTraceWritersForCurrentThread() = 0;
+
+  uint32_t generation(std::memory_order ord) { return generation_.load(ord); }
+
+  using InterceptorFactory = std::function<std::unique_ptr<InterceptorBase>()>;
+  virtual void RegisterInterceptor(const InterceptorDescriptor&,
+                                   InterceptorFactory,
+                                   InterceptorBase::TLSFactory,
+                                   InterceptorBase::TracePacketCallback) = 0;
+
+  // Informs the tracing services to activate any of these triggers if any
+  // tracing session was waiting for them.
+  //
+  // Sends the trigger signal to all the initialized backends that are currently
+  // connected and that connect in the next `ttl_ms` milliseconds (but returns
+  // immediately anyway).
+  virtual void ActivateTriggers(const std::vector<std::string>&,
+                                uint32_t ttl_ms) = 0;
+
+  base::PlatformThreadId GetCurrentThreadId() {
+    return platform_->GetCurrentThreadId();
+  }
+
+ protected:
+  explicit TracingMuxer(Platform* platform) : platform_(platform) {}
+
+  static TracingMuxer* instance_;
+  Platform* const platform_ = nullptr;
+
+  // Incremented every time a data source is destroyed. See tracing_tls.h.
+  std::atomic<uint32_t> generation_{};
+};
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_TRACING_MUXER_H_
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_DATA_SOURCE_TYPE_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_DATA_SOURCE_TYPE_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/data_source_internal.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_muxer.h"
+
+namespace perfetto {
+namespace internal {
+
+// Represents a data source type (not an instance).
+//
+// All the static state of a DataSource<T> lives here (including
+// DataSourceStaticState).
+//
+// The C shared library API wrapper cannot use DataSource<T>, because it needs
+// to create new data source types at runtime, so it uses this directly.
+//
+// The main reason why this intermediate class exist is to decouple the
+// DataSourceStaticState from the specific DataSource<T>. The C API cannot
+// dynamically create template instances and it needs a way to decouple those at
+// runtime.
+class PERFETTO_EXPORT_COMPONENT DataSourceType {
+ public:
+  // Function pointer type used to create custom per instance thread local
+  // state.
+  using CreateCustomTlsFn =
+      DataSourceInstanceThreadLocalState::ObjectWithDeleter (*)(
+          DataSourceInstanceThreadLocalState* tls_inst,
+          uint32_t instance_index,
+          void* user_arg);
+  // Function pointer type used to create custom per instance thread local
+  // incremental state (which might be cleared periodically by the tracing
+  // service).
+  using CreateIncrementalStateFn =
+      DataSourceInstanceThreadLocalState::ObjectWithDeleter (*)(
+          DataSourceInstanceThreadLocalState* tls_inst,
+          uint32_t instance_index,
+          void* user_arg);
+
+  // Registers the data source type with the central tracing muxer.
+  // * `descriptor` is the data source protobuf descriptor.
+  // * `factory` is a std::function used to create instances of the data source
+  //   type.
+  // * `buffer_exhausted_policy` specifies what to do when the shared memory
+  //   buffer runs out of chunks.
+  // * `create_custom_tls_fn` and `create_incremental_state_fn` are function
+  //   pointers called to create custom state. They will receive `user_arg` as
+  //   an extra param.
+  bool Register(const DataSourceDescriptor& descriptor,
+                TracingMuxer::DataSourceFactory factory,
+                internal::DataSourceParams params,
+                BufferExhaustedPolicy buffer_exhausted_policy,
+                bool no_flush,
+                CreateCustomTlsFn create_custom_tls_fn,
+                CreateIncrementalStateFn create_incremental_state_fn,
+                void* user_arg) {
+    buffer_exhausted_policy_ = buffer_exhausted_policy;
+    create_custom_tls_fn_ = create_custom_tls_fn;
+    create_incremental_state_fn_ = create_incremental_state_fn;
+    user_arg_ = user_arg;
+    auto* tracing_impl = TracingMuxer::Get();
+    return tracing_impl->RegisterDataSource(descriptor, factory, params,
+                                            no_flush, &state_);
+  }
+
+  // Updates the data source type descriptor.
+  void UpdateDescriptor(const DataSourceDescriptor& descriptor) {
+    auto* tracing_impl = TracingMuxer::Get();
+    tracing_impl->UpdateDataSourceDescriptor(descriptor, &state_);
+  }
+
+  // The beginning of a trace point.
+  //
+  // `tls_state` must point to a thread local variable that caches a pointer to
+  // an internal per data source type thread local state.
+  //
+  // `instances` must point to a copy of the current active instances for the
+  // data source type.
+  //
+  // `DataSourceTraits` can be used to customize the thread local storage used
+  // for the data source type.
+  //
+  // `TracePointTraits` and `trace_point_data` are customization point for
+  // getting the active instances bitmap.
+  //
+  // If this returns false, the trace point must be skipped.
+  template <typename DataSourceTraits, typename TracePointTraits>
+  bool TracePrologue(
+      DataSourceThreadLocalState** tls_state,
+      uint32_t* instances,
+      typename TracePointTraits::TracePointData trace_point_data) {
+    // See tracing_muxer.h for the structure of the TLS.
+    if (PERFETTO_UNLIKELY(!*tls_state)) {
+      *tls_state = GetOrCreateDataSourceTLS<DataSourceTraits>();
+      // If the TLS hasn't been obtained yet, it's possible that this thread
+      // hasn't observed the initialization of global state like the muxer yet.
+      // To ensure that the thread "sees" the effects of such initialization,
+      // we have to reload |instances| with an acquire fence, ensuring that any
+      // initialization performed before instances was updated is visible
+      // in this thread.
+      *instances &= TracePointTraits::GetActiveInstances(trace_point_data)
+                        ->load(std::memory_order_acquire);
+      if (!*instances)
+        return false;
+    }
+    auto* tracing_impl = TracingMuxer::Get();
+
+    // Avoid re-entering the trace point recursively.
+    if (PERFETTO_UNLIKELY((*tls_state)->root_tls->is_in_trace_point))
+      return false;
+
+    (*tls_state)->root_tls->is_in_trace_point = true;
+
+    // TracingTLS::generation is a global monotonic counter that is incremented
+    // every time a tracing session is stopped. We use that as a signal to force
+    // a slow-path garbage collection of all the trace writers for the current
+    // thread and to destroy the ones that belong to tracing sessions that have
+    // ended. This is to avoid having too many TraceWriter instances alive, each
+    // holding onto one chunk of the shared memory buffer.
+    // Rationale why memory_order_relaxed should be fine:
+    // - The TraceWriter object that we use is always constructed and destructed
+    //   on the current thread. There is no risk of accessing a half-initialized
+    //   TraceWriter (which would be really bad).
+    // - In the worst case, in the case of a race on the generation check, we
+    //   might end up using a TraceWriter for the same data source that belongs
+    //   to a stopped session. This is not really wrong, as we don't give any
+    //   guarantee on the global atomicity of the stop. In the worst case the
+    //   service will reject the data commit if this arrives too late.
+
+    if (PERFETTO_UNLIKELY(
+            (*tls_state)->root_tls->generation !=
+            tracing_impl->generation(std::memory_order_relaxed))) {
+      // Will update root_tls->generation.
+      tracing_impl->DestroyStoppedTraceWritersForCurrentThread();
+    }
+
+    return true;
+  }
+
+  // Must be called at the ending of a trace point that was not skipped.
+  void TraceEpilogue(DataSourceThreadLocalState* tls_state) {
+    tls_state->root_tls->is_in_trace_point = false;
+  }
+
+  struct InstancesIterator {
+    // A bitmap of the currenly active instances.
+    uint32_t cached_instances;
+    // The current instance index.
+    uint32_t i;
+    // The current instance. If this is `nullptr`, the iteration is over.
+    DataSourceInstanceThreadLocalState* instance;
+  };
+
+  // Returns an iterator to the active instances of this data source type.
+  //
+  // `cached_instances` is a copy of the bitmap of the active instances for this
+  // data source type (usually just a copy of ValidInstances(), but can be
+  // customized).
+  //
+  // `tls_state` is the thread local pointer obtained from TracePrologue.
+  //
+  // `TracePointTraits` and `trace_point_data` are customization point for
+  // getting the active instances bitmap.
+  template <typename TracePointTraits>
+  InstancesIterator BeginIteration(
+      uint32_t cached_instances,
+      DataSourceThreadLocalState* tls_state,
+      typename TracePointTraits::TracePointData trace_point_data) {
+    InstancesIterator it{};
+    it.cached_instances = cached_instances;
+    FirstActiveInstance<TracePointTraits>(&it, tls_state, trace_point_data);
+    return it;
+  }
+
+  // Advances `*iterator` to point to the next active instance of this data
+  // source type.
+  //
+  // `tls_state` is the thread local pointer obtained from TracePrologue.
+  //
+  // `TracePointTraits` and `trace_point_data` are customization point for
+  // getting the active instances bitmap.
+  template <typename TracePointTraits>
+  void NextIteration(
+      InstancesIterator* iterator,
+      DataSourceThreadLocalState* tls_state,
+      typename TracePointTraits::TracePointData trace_point_data) {
+    iterator->i++;
+    FirstActiveInstance<TracePointTraits>(iterator, tls_state,
+                                          trace_point_data);
+  }
+
+  void* GetIncrementalState(
+      internal::DataSourceInstanceThreadLocalState* tls_inst,
+      uint32_t instance_index) {
+    // Recreate incremental state data if it has been reset by the service.
+    if (tls_inst->incremental_state_generation !=
+        static_state()->incremental_state_generation.load(
+            std::memory_order_relaxed)) {
+      tls_inst->incremental_state.reset();
+      CreateIncrementalState(tls_inst, instance_index);
+    }
+    return tls_inst->incremental_state.get();
+  }
+
+  std::atomic<uint32_t>* valid_instances() { return &state_.valid_instances; }
+
+  DataSourceStaticState* static_state() { return &state_; }
+
+ private:
+  void CreateIncrementalState(
+      internal::DataSourceInstanceThreadLocalState* tls_inst,
+      uint32_t instance_index) {
+    PERFETTO_DCHECK(create_incremental_state_fn_ != nullptr);
+    tls_inst->incremental_state =
+        create_incremental_state_fn_(tls_inst, instance_index, user_arg_);
+    tls_inst->incremental_state_generation =
+        static_state()->incremental_state_generation.load(
+            std::memory_order_relaxed);
+  }
+
+  void PopulateTlsInst(DataSourceInstanceThreadLocalState* tls_inst,
+                       DataSourceState* instance_state,
+                       uint32_t instance_index);
+
+  // Advances `*iterator` to the first active instance whose index is greater or
+  // equal than `iterator->i`.
+  template <typename TracePointTraits>
+  void FirstActiveInstance(
+      InstancesIterator* iterator,
+      DataSourceThreadLocalState* tls_state,
+      typename TracePointTraits::TracePointData trace_point_data) {
+    iterator->instance = nullptr;
+    for (; iterator->i < kMaxDataSourceInstances; iterator->i++) {
+      DataSourceState* instance_state =
+          state_.TryGetCached(iterator->cached_instances, iterator->i);
+      if (!instance_state)
+        continue;
+      // Even if we passed the check above, the DataSourceInstance might be
+      // still destroyed concurrently while this code runs. The code below is
+      // designed to deal with such race, as follows:
+      // - We don't access the user-defined data source instance state. The only
+      //   bits of state we use are |backend_id| and |buffer_id|.
+      // - Beyond those two integers, we access only the TraceWriter here. The
+      //   TraceWriter is always safe because it lives on the TLS.
+      // - |instance_state| is backed by static storage, so the pointer is
+      //   always valid, even after the data source instance is destroyed.
+      // - In the case of a race-on-destruction, we'll still see the latest
+      //   backend_id and buffer_id and in the worst case keep trying writing
+      //   into the tracing shared memory buffer after stopped. But this isn't
+      //   really any worse than the case of the stop IPC being delayed by the
+      //   kernel scheduler. The tracing service is robust against data commit
+      //   attemps made after tracing is stopped.
+      // There is a theoretical race that would case the wrong behavior w.r.t
+      // writing data in the wrong buffer, but it's so rare that we ignore it:
+      // if the data source is stopped and started kMaxDataSourceInstances
+      // times (so that the same id is recycled) while we are in this function,
+      // we might end up reusing the old data source's backend_id and buffer_id
+      // for the new one, because we don't see the generation change past this
+      // point. But stopping and starting tracing (even once) takes so much
+      // handshaking to make this extremely unrealistic.
+
+      auto& tls_inst = tls_state->per_instance[iterator->i];
+      if (PERFETTO_UNLIKELY(!tls_inst.trace_writer)) {
+        // Here we need an acquire barrier, which matches the release-store made
+        // by TracingMuxerImpl::SetupDataSource(), to ensure that the backend_id
+        // and buffer_id are consistent.
+        iterator->cached_instances &=
+            TracePointTraits::GetActiveInstances(trace_point_data)
+                ->load(std::memory_order_acquire);
+        instance_state =
+            state_.TryGetCached(iterator->cached_instances, iterator->i);
+        if (!instance_state || !instance_state->trace_lambda_enabled.load(
+                                   std::memory_order_relaxed))
+          continue;
+        PopulateTlsInst(&tls_inst, instance_state, iterator->i);
+      }
+      iterator->instance = &tls_inst;
+      break;
+    }
+  }
+
+  // Note that the returned object is one per-thread per-data-source-type, NOT
+  // per data-source *instance*.
+  template <typename DataSourceTraits>
+  DataSourceThreadLocalState* GetOrCreateDataSourceTLS() {
+    auto* tracing_impl = TracingMuxer::Get();
+    TracingTLS* root_tls = tracing_impl->GetOrCreateTracingTLS();
+    DataSourceThreadLocalState* ds_tls =
+        DataSourceTraits::GetDataSourceTLS(&state_, root_tls);
+    // We keep re-initializing as the initialization is idempotent and not worth
+    // the code for extra checks. Also, ds_tls->static_state might point to
+    // another data source if ResetForTesting() has been used.
+    ds_tls->static_state = &state_;
+    assert(!ds_tls->root_tls || ds_tls->root_tls == root_tls);
+    ds_tls->root_tls = root_tls;
+    return ds_tls;
+  }
+
+  DataSourceStaticState state_;
+  BufferExhaustedPolicy buffer_exhausted_policy_{};
+  CreateCustomTlsFn create_custom_tls_fn_ = nullptr;
+  CreateIncrementalStateFn create_incremental_state_fn_ = nullptr;
+  // User defined pointer that carries extra content for the fn_ callbacks
+  // above. Only used in the C shared library.
+  void* user_arg_ = nullptr;
+};
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_DATA_SOURCE_TYPE_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/trace_packet.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACE_PACKET_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACE_PACKET_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class AndroidCameraFrameEvent;
+class AndroidCameraSessionStats;
+class AndroidEnergyEstimationBreakdown;
+class AndroidGameInterventionList;
+class AndroidInputEvent;
+class AndroidLogPacket;
+class AndroidSystemProperty;
+class BatteryCounters;
+class ChromeBenchmarkMetadata;
+class ChromeEventBundle;
+class ChromeMetadataPacket;
+class ChromeTrigger;
+class ClockSnapshot;
+class CpuInfo;
+class DeobfuscationMapping;
+class EntityStateResidency;
+class EtwTraceEventBundle;
+class ExtensionDescriptor;
+class FrameTimelineEvent;
+class FtraceEventBundle;
+class FtraceStats;
+class GpuCounterEvent;
+class GpuLog;
+class GpuMemTotalEvent;
+class GpuRenderStageEvent;
+class GraphicsFrameEvent;
+class HeapGraph;
+class InitialDisplayState;
+class InodeFileMap;
+class InternedData;
+class LayersSnapshotProto;
+class MemoryTrackerSnapshot;
+class ModuleSymbols;
+class NetworkPacketBundle;
+class NetworkPacketEvent;
+class PackagesList;
+class PerfSample;
+class PerfettoMetatrace;
+class PixelModemEvents;
+class PixelModemTokenDatabase;
+class PowerRails;
+class ProcessDescriptor;
+class ProcessStats;
+class ProcessTree;
+class ProfilePacket;
+class ProfiledFrameSymbols;
+class ProtoLogMessage;
+class ProtoLogViewerConfig;
+class RemoteClockSync;
+class ShellHandlerMappings;
+class ShellTransition;
+class SmapsPacket;
+class StatsdAtom;
+class StreamingAllocation;
+class StreamingFree;
+class StreamingProfilePacket;
+class SysStats;
+class SystemInfo;
+class TestEvent;
+class ThreadDescriptor;
+class TraceConfig;
+class TracePacketDefaults;
+class TraceStats;
+class TraceUuid;
+class TracingServiceEvent;
+class TrackDescriptor;
+class TrackEvent;
+class TrackEventRangeOfInterest;
+class TransactionTraceEntry;
+class TranslationTable;
+class Trigger;
+class UiState;
+class V8CodeMove;
+class V8InternalCode;
+class V8JsCode;
+class V8RegExpCode;
+class V8WasmCode;
+class VulkanApiEvent;
+class VulkanMemoryEvent;
+class WinscopeExtensions;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_TracePacket {
+enum SequenceFlags : int32_t {
+  SEQ_UNSPECIFIED = 0,
+  SEQ_INCREMENTAL_STATE_CLEARED = 1,
+  SEQ_NEEDS_INCREMENTAL_STATE = 2,
+};
+} // namespace perfetto_pbzero_enum_TracePacket
+using TracePacket_SequenceFlags = perfetto_pbzero_enum_TracePacket::SequenceFlags;
+
+
+constexpr TracePacket_SequenceFlags TracePacket_SequenceFlags_MIN = TracePacket_SequenceFlags::SEQ_UNSPECIFIED;
+constexpr TracePacket_SequenceFlags TracePacket_SequenceFlags_MAX = TracePacket_SequenceFlags::SEQ_NEEDS_INCREMENTAL_STATE;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* TracePacket_SequenceFlags_Name(::perfetto::protos::pbzero::TracePacket_SequenceFlags value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::TracePacket_SequenceFlags::SEQ_UNSPECIFIED:
+    return "SEQ_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::TracePacket_SequenceFlags::SEQ_INCREMENTAL_STATE_CLEARED:
+    return "SEQ_INCREMENTAL_STATE_CLEARED";
+
+  case ::perfetto::protos::pbzero::TracePacket_SequenceFlags::SEQ_NEEDS_INCREMENTAL_STATE:
+    return "SEQ_NEEDS_INCREMENTAL_STATE";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class TracePacket_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/900, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TracePacket_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TracePacket_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TracePacket_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_timestamp() const { return at<8>().valid(); }
+  uint64_t timestamp() const { return at<8>().as_uint64(); }
+  bool has_timestamp_clock_id() const { return at<58>().valid(); }
+  uint32_t timestamp_clock_id() const { return at<58>().as_uint32(); }
+  bool has_process_tree() const { return at<2>().valid(); }
+  ::protozero::ConstBytes process_tree() const { return at<2>().as_bytes(); }
+  bool has_process_stats() const { return at<9>().valid(); }
+  ::protozero::ConstBytes process_stats() const { return at<9>().as_bytes(); }
+  bool has_inode_file_map() const { return at<4>().valid(); }
+  ::protozero::ConstBytes inode_file_map() const { return at<4>().as_bytes(); }
+  bool has_chrome_events() const { return at<5>().valid(); }
+  ::protozero::ConstBytes chrome_events() const { return at<5>().as_bytes(); }
+  bool has_clock_snapshot() const { return at<6>().valid(); }
+  ::protozero::ConstBytes clock_snapshot() const { return at<6>().as_bytes(); }
+  bool has_sys_stats() const { return at<7>().valid(); }
+  ::protozero::ConstBytes sys_stats() const { return at<7>().as_bytes(); }
+  bool has_track_event() const { return at<11>().valid(); }
+  ::protozero::ConstBytes track_event() const { return at<11>().as_bytes(); }
+  bool has_trace_uuid() const { return at<89>().valid(); }
+  ::protozero::ConstBytes trace_uuid() const { return at<89>().as_bytes(); }
+  bool has_trace_config() const { return at<33>().valid(); }
+  ::protozero::ConstBytes trace_config() const { return at<33>().as_bytes(); }
+  bool has_ftrace_stats() const { return at<34>().valid(); }
+  ::protozero::ConstBytes ftrace_stats() const { return at<34>().as_bytes(); }
+  bool has_trace_stats() const { return at<35>().valid(); }
+  ::protozero::ConstBytes trace_stats() const { return at<35>().as_bytes(); }
+  bool has_profile_packet() const { return at<37>().valid(); }
+  ::protozero::ConstBytes profile_packet() const { return at<37>().as_bytes(); }
+  bool has_streaming_allocation() const { return at<74>().valid(); }
+  ::protozero::ConstBytes streaming_allocation() const { return at<74>().as_bytes(); }
+  bool has_streaming_free() const { return at<75>().valid(); }
+  ::protozero::ConstBytes streaming_free() const { return at<75>().as_bytes(); }
+  bool has_battery() const { return at<38>().valid(); }
+  ::protozero::ConstBytes battery() const { return at<38>().as_bytes(); }
+  bool has_power_rails() const { return at<40>().valid(); }
+  ::protozero::ConstBytes power_rails() const { return at<40>().as_bytes(); }
+  bool has_android_log() const { return at<39>().valid(); }
+  ::protozero::ConstBytes android_log() const { return at<39>().as_bytes(); }
+  bool has_system_info() const { return at<45>().valid(); }
+  ::protozero::ConstBytes system_info() const { return at<45>().as_bytes(); }
+  bool has_trigger() const { return at<46>().valid(); }
+  ::protozero::ConstBytes trigger() const { return at<46>().as_bytes(); }
+  bool has_chrome_trigger() const { return at<109>().valid(); }
+  ::protozero::ConstBytes chrome_trigger() const { return at<109>().as_bytes(); }
+  bool has_packages_list() const { return at<47>().valid(); }
+  ::protozero::ConstBytes packages_list() const { return at<47>().as_bytes(); }
+  bool has_chrome_benchmark_metadata() const { return at<48>().valid(); }
+  ::protozero::ConstBytes chrome_benchmark_metadata() const { return at<48>().as_bytes(); }
+  bool has_perfetto_metatrace() const { return at<49>().valid(); }
+  ::protozero::ConstBytes perfetto_metatrace() const { return at<49>().as_bytes(); }
+  bool has_chrome_metadata() const { return at<51>().valid(); }
+  ::protozero::ConstBytes chrome_metadata() const { return at<51>().as_bytes(); }
+  bool has_gpu_counter_event() const { return at<52>().valid(); }
+  ::protozero::ConstBytes gpu_counter_event() const { return at<52>().as_bytes(); }
+  bool has_gpu_render_stage_event() const { return at<53>().valid(); }
+  ::protozero::ConstBytes gpu_render_stage_event() const { return at<53>().as_bytes(); }
+  bool has_streaming_profile_packet() const { return at<54>().valid(); }
+  ::protozero::ConstBytes streaming_profile_packet() const { return at<54>().as_bytes(); }
+  bool has_heap_graph() const { return at<56>().valid(); }
+  ::protozero::ConstBytes heap_graph() const { return at<56>().as_bytes(); }
+  bool has_graphics_frame_event() const { return at<57>().valid(); }
+  ::protozero::ConstBytes graphics_frame_event() const { return at<57>().as_bytes(); }
+  bool has_vulkan_memory_event() const { return at<62>().valid(); }
+  ::protozero::ConstBytes vulkan_memory_event() const { return at<62>().as_bytes(); }
+  bool has_gpu_log() const { return at<63>().valid(); }
+  ::protozero::ConstBytes gpu_log() const { return at<63>().as_bytes(); }
+  bool has_vulkan_api_event() const { return at<65>().valid(); }
+  ::protozero::ConstBytes vulkan_api_event() const { return at<65>().as_bytes(); }
+  bool has_perf_sample() const { return at<66>().valid(); }
+  ::protozero::ConstBytes perf_sample() const { return at<66>().as_bytes(); }
+  bool has_cpu_info() const { return at<67>().valid(); }
+  ::protozero::ConstBytes cpu_info() const { return at<67>().as_bytes(); }
+  bool has_smaps_packet() const { return at<68>().valid(); }
+  ::protozero::ConstBytes smaps_packet() const { return at<68>().as_bytes(); }
+  bool has_service_event() const { return at<69>().valid(); }
+  ::protozero::ConstBytes service_event() const { return at<69>().as_bytes(); }
+  bool has_initial_display_state() const { return at<70>().valid(); }
+  ::protozero::ConstBytes initial_display_state() const { return at<70>().as_bytes(); }
+  bool has_gpu_mem_total_event() const { return at<71>().valid(); }
+  ::protozero::ConstBytes gpu_mem_total_event() const { return at<71>().as_bytes(); }
+  bool has_memory_tracker_snapshot() const { return at<73>().valid(); }
+  ::protozero::ConstBytes memory_tracker_snapshot() const { return at<73>().as_bytes(); }
+  bool has_frame_timeline_event() const { return at<76>().valid(); }
+  ::protozero::ConstBytes frame_timeline_event() const { return at<76>().as_bytes(); }
+  bool has_android_energy_estimation_breakdown() const { return at<77>().valid(); }
+  ::protozero::ConstBytes android_energy_estimation_breakdown() const { return at<77>().as_bytes(); }
+  bool has_ui_state() const { return at<78>().valid(); }
+  ::protozero::ConstBytes ui_state() const { return at<78>().as_bytes(); }
+  bool has_android_camera_frame_event() const { return at<80>().valid(); }
+  ::protozero::ConstBytes android_camera_frame_event() const { return at<80>().as_bytes(); }
+  bool has_android_camera_session_stats() const { return at<81>().valid(); }
+  ::protozero::ConstBytes android_camera_session_stats() const { return at<81>().as_bytes(); }
+  bool has_translation_table() const { return at<82>().valid(); }
+  ::protozero::ConstBytes translation_table() const { return at<82>().as_bytes(); }
+  bool has_android_game_intervention_list() const { return at<83>().valid(); }
+  ::protozero::ConstBytes android_game_intervention_list() const { return at<83>().as_bytes(); }
+  bool has_statsd_atom() const { return at<84>().valid(); }
+  ::protozero::ConstBytes statsd_atom() const { return at<84>().as_bytes(); }
+  bool has_android_system_property() const { return at<86>().valid(); }
+  ::protozero::ConstBytes android_system_property() const { return at<86>().as_bytes(); }
+  bool has_entity_state_residency() const { return at<91>().valid(); }
+  ::protozero::ConstBytes entity_state_residency() const { return at<91>().as_bytes(); }
+  bool has_profiled_frame_symbols() const { return at<55>().valid(); }
+  ::protozero::ConstBytes profiled_frame_symbols() const { return at<55>().as_bytes(); }
+  bool has_module_symbols() const { return at<61>().valid(); }
+  ::protozero::ConstBytes module_symbols() const { return at<61>().as_bytes(); }
+  bool has_deobfuscation_mapping() const { return at<64>().valid(); }
+  ::protozero::ConstBytes deobfuscation_mapping() const { return at<64>().as_bytes(); }
+  bool has_track_descriptor() const { return at<60>().valid(); }
+  ::protozero::ConstBytes track_descriptor() const { return at<60>().as_bytes(); }
+  bool has_process_descriptor() const { return at<43>().valid(); }
+  ::protozero::ConstBytes process_descriptor() const { return at<43>().as_bytes(); }
+  bool has_thread_descriptor() const { return at<44>().valid(); }
+  ::protozero::ConstBytes thread_descriptor() const { return at<44>().as_bytes(); }
+  bool has_ftrace_events() const { return at<1>().valid(); }
+  ::protozero::ConstBytes ftrace_events() const { return at<1>().as_bytes(); }
+  bool has_synchronization_marker() const { return at<36>().valid(); }
+  ::protozero::ConstBytes synchronization_marker() const { return at<36>().as_bytes(); }
+  bool has_compressed_packets() const { return at<50>().valid(); }
+  ::protozero::ConstBytes compressed_packets() const { return at<50>().as_bytes(); }
+  bool has_extension_descriptor() const { return at<72>().valid(); }
+  ::protozero::ConstBytes extension_descriptor() const { return at<72>().as_bytes(); }
+  bool has_network_packet() const { return at<88>().valid(); }
+  ::protozero::ConstBytes network_packet() const { return at<88>().as_bytes(); }
+  bool has_network_packet_bundle() const { return at<92>().valid(); }
+  ::protozero::ConstBytes network_packet_bundle() const { return at<92>().as_bytes(); }
+  bool has_track_event_range_of_interest() const { return at<90>().valid(); }
+  ::protozero::ConstBytes track_event_range_of_interest() const { return at<90>().as_bytes(); }
+  bool has_surfaceflinger_layers_snapshot() const { return at<93>().valid(); }
+  ::protozero::ConstBytes surfaceflinger_layers_snapshot() const { return at<93>().as_bytes(); }
+  bool has_surfaceflinger_transactions() const { return at<94>().valid(); }
+  ::protozero::ConstBytes surfaceflinger_transactions() const { return at<94>().as_bytes(); }
+  bool has_shell_transition() const { return at<96>().valid(); }
+  ::protozero::ConstBytes shell_transition() const { return at<96>().as_bytes(); }
+  bool has_shell_handler_mappings() const { return at<97>().valid(); }
+  ::protozero::ConstBytes shell_handler_mappings() const { return at<97>().as_bytes(); }
+  bool has_protolog_message() const { return at<104>().valid(); }
+  ::protozero::ConstBytes protolog_message() const { return at<104>().as_bytes(); }
+  bool has_protolog_viewer_config() const { return at<105>().valid(); }
+  ::protozero::ConstBytes protolog_viewer_config() const { return at<105>().as_bytes(); }
+  bool has_winscope_extensions() const { return at<112>().valid(); }
+  ::protozero::ConstBytes winscope_extensions() const { return at<112>().as_bytes(); }
+  bool has_etw_events() const { return at<95>().valid(); }
+  ::protozero::ConstBytes etw_events() const { return at<95>().as_bytes(); }
+  bool has_v8_js_code() const { return at<99>().valid(); }
+  ::protozero::ConstBytes v8_js_code() const { return at<99>().as_bytes(); }
+  bool has_v8_internal_code() const { return at<100>().valid(); }
+  ::protozero::ConstBytes v8_internal_code() const { return at<100>().as_bytes(); }
+  bool has_v8_wasm_code() const { return at<101>().valid(); }
+  ::protozero::ConstBytes v8_wasm_code() const { return at<101>().as_bytes(); }
+  bool has_v8_reg_exp_code() const { return at<102>().valid(); }
+  ::protozero::ConstBytes v8_reg_exp_code() const { return at<102>().as_bytes(); }
+  bool has_v8_code_move() const { return at<103>().valid(); }
+  ::protozero::ConstBytes v8_code_move() const { return at<103>().as_bytes(); }
+  bool has_android_input_event() const { return at<106>().valid(); }
+  ::protozero::ConstBytes android_input_event() const { return at<106>().as_bytes(); }
+  bool has_remote_clock_sync() const { return at<107>().valid(); }
+  ::protozero::ConstBytes remote_clock_sync() const { return at<107>().as_bytes(); }
+  bool has_pixel_modem_events() const { return at<110>().valid(); }
+  ::protozero::ConstBytes pixel_modem_events() const { return at<110>().as_bytes(); }
+  bool has_pixel_modem_token_database() const { return at<111>().valid(); }
+  ::protozero::ConstBytes pixel_modem_token_database() const { return at<111>().as_bytes(); }
+  bool has_for_testing() const { return at<900>().valid(); }
+  ::protozero::ConstBytes for_testing() const { return at<900>().as_bytes(); }
+  bool has_trusted_uid() const { return at<3>().valid(); }
+  int32_t trusted_uid() const { return at<3>().as_int32(); }
+  bool has_trusted_packet_sequence_id() const { return at<10>().valid(); }
+  uint32_t trusted_packet_sequence_id() const { return at<10>().as_uint32(); }
+  bool has_trusted_pid() const { return at<79>().valid(); }
+  int32_t trusted_pid() const { return at<79>().as_int32(); }
+  bool has_interned_data() const { return at<12>().valid(); }
+  ::protozero::ConstBytes interned_data() const { return at<12>().as_bytes(); }
+  bool has_sequence_flags() const { return at<13>().valid(); }
+  uint32_t sequence_flags() const { return at<13>().as_uint32(); }
+  bool has_incremental_state_cleared() const { return at<41>().valid(); }
+  bool incremental_state_cleared() const { return at<41>().as_bool(); }
+  bool has_trace_packet_defaults() const { return at<59>().valid(); }
+  ::protozero::ConstBytes trace_packet_defaults() const { return at<59>().as_bytes(); }
+  bool has_previous_packet_dropped() const { return at<42>().valid(); }
+  bool previous_packet_dropped() const { return at<42>().as_bool(); }
+  bool has_first_packet_on_sequence() const { return at<87>().valid(); }
+  bool first_packet_on_sequence() const { return at<87>().as_bool(); }
+  bool has_machine_id() const { return at<98>().valid(); }
+  uint32_t machine_id() const { return at<98>().as_uint32(); }
+};
+
+class TracePacket : public ::protozero::Message {
+ public:
+  using Decoder = TracePacket_Decoder;
+  enum : int32_t {
+    kTimestampFieldNumber = 8,
+    kTimestampClockIdFieldNumber = 58,
+    kProcessTreeFieldNumber = 2,
+    kProcessStatsFieldNumber = 9,
+    kInodeFileMapFieldNumber = 4,
+    kChromeEventsFieldNumber = 5,
+    kClockSnapshotFieldNumber = 6,
+    kSysStatsFieldNumber = 7,
+    kTrackEventFieldNumber = 11,
+    kTraceUuidFieldNumber = 89,
+    kTraceConfigFieldNumber = 33,
+    kFtraceStatsFieldNumber = 34,
+    kTraceStatsFieldNumber = 35,
+    kProfilePacketFieldNumber = 37,
+    kStreamingAllocationFieldNumber = 74,
+    kStreamingFreeFieldNumber = 75,
+    kBatteryFieldNumber = 38,
+    kPowerRailsFieldNumber = 40,
+    kAndroidLogFieldNumber = 39,
+    kSystemInfoFieldNumber = 45,
+    kTriggerFieldNumber = 46,
+    kChromeTriggerFieldNumber = 109,
+    kPackagesListFieldNumber = 47,
+    kChromeBenchmarkMetadataFieldNumber = 48,
+    kPerfettoMetatraceFieldNumber = 49,
+    kChromeMetadataFieldNumber = 51,
+    kGpuCounterEventFieldNumber = 52,
+    kGpuRenderStageEventFieldNumber = 53,
+    kStreamingProfilePacketFieldNumber = 54,
+    kHeapGraphFieldNumber = 56,
+    kGraphicsFrameEventFieldNumber = 57,
+    kVulkanMemoryEventFieldNumber = 62,
+    kGpuLogFieldNumber = 63,
+    kVulkanApiEventFieldNumber = 65,
+    kPerfSampleFieldNumber = 66,
+    kCpuInfoFieldNumber = 67,
+    kSmapsPacketFieldNumber = 68,
+    kServiceEventFieldNumber = 69,
+    kInitialDisplayStateFieldNumber = 70,
+    kGpuMemTotalEventFieldNumber = 71,
+    kMemoryTrackerSnapshotFieldNumber = 73,
+    kFrameTimelineEventFieldNumber = 76,
+    kAndroidEnergyEstimationBreakdownFieldNumber = 77,
+    kUiStateFieldNumber = 78,
+    kAndroidCameraFrameEventFieldNumber = 80,
+    kAndroidCameraSessionStatsFieldNumber = 81,
+    kTranslationTableFieldNumber = 82,
+    kAndroidGameInterventionListFieldNumber = 83,
+    kStatsdAtomFieldNumber = 84,
+    kAndroidSystemPropertyFieldNumber = 86,
+    kEntityStateResidencyFieldNumber = 91,
+    kProfiledFrameSymbolsFieldNumber = 55,
+    kModuleSymbolsFieldNumber = 61,
+    kDeobfuscationMappingFieldNumber = 64,
+    kTrackDescriptorFieldNumber = 60,
+    kProcessDescriptorFieldNumber = 43,
+    kThreadDescriptorFieldNumber = 44,
+    kFtraceEventsFieldNumber = 1,
+    kSynchronizationMarkerFieldNumber = 36,
+    kCompressedPacketsFieldNumber = 50,
+    kExtensionDescriptorFieldNumber = 72,
+    kNetworkPacketFieldNumber = 88,
+    kNetworkPacketBundleFieldNumber = 92,
+    kTrackEventRangeOfInterestFieldNumber = 90,
+    kSurfaceflingerLayersSnapshotFieldNumber = 93,
+    kSurfaceflingerTransactionsFieldNumber = 94,
+    kShellTransitionFieldNumber = 96,
+    kShellHandlerMappingsFieldNumber = 97,
+    kProtologMessageFieldNumber = 104,
+    kProtologViewerConfigFieldNumber = 105,
+    kWinscopeExtensionsFieldNumber = 112,
+    kEtwEventsFieldNumber = 95,
+    kV8JsCodeFieldNumber = 99,
+    kV8InternalCodeFieldNumber = 100,
+    kV8WasmCodeFieldNumber = 101,
+    kV8RegExpCodeFieldNumber = 102,
+    kV8CodeMoveFieldNumber = 103,
+    kAndroidInputEventFieldNumber = 106,
+    kRemoteClockSyncFieldNumber = 107,
+    kPixelModemEventsFieldNumber = 110,
+    kPixelModemTokenDatabaseFieldNumber = 111,
+    kForTestingFieldNumber = 900,
+    kTrustedUidFieldNumber = 3,
+    kTrustedPacketSequenceIdFieldNumber = 10,
+    kTrustedPidFieldNumber = 79,
+    kInternedDataFieldNumber = 12,
+    kSequenceFlagsFieldNumber = 13,
+    kIncrementalStateClearedFieldNumber = 41,
+    kTracePacketDefaultsFieldNumber = 59,
+    kPreviousPacketDroppedFieldNumber = 42,
+    kFirstPacketOnSequenceFieldNumber = 87,
+    kMachineIdFieldNumber = 98,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TracePacket"; }
+
+
+  using SequenceFlags = ::perfetto::protos::pbzero::TracePacket_SequenceFlags;
+  static inline const char* SequenceFlags_Name(SequenceFlags value) {
+    return ::perfetto::protos::pbzero::TracePacket_SequenceFlags_Name(value);
+  }
+  static inline const SequenceFlags SEQ_UNSPECIFIED = SequenceFlags::SEQ_UNSPECIFIED;
+  static inline const SequenceFlags SEQ_INCREMENTAL_STATE_CLEARED = SequenceFlags::SEQ_INCREMENTAL_STATE_CLEARED;
+  static inline const SequenceFlags SEQ_NEEDS_INCREMENTAL_STATE = SequenceFlags::SEQ_NEEDS_INCREMENTAL_STATE;
+
+  using FieldMetadata_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TracePacket>;
+
+  static constexpr FieldMetadata_Timestamp kTimestamp{};
+  void set_timestamp(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timestamp::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_TimestampClockId =
+    ::protozero::proto_utils::FieldMetadata<
+      58,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TracePacket>;
+
+  static constexpr FieldMetadata_TimestampClockId kTimestampClockId{};
+  void set_timestamp_clock_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimestampClockId::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_ProcessTree =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProcessTree,
+      TracePacket>;
+
+  static constexpr FieldMetadata_ProcessTree kProcessTree{};
+  template <typename T = ProcessTree> T* set_process_tree() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_ProcessStats =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProcessStats,
+      TracePacket>;
+
+  static constexpr FieldMetadata_ProcessStats kProcessStats{};
+  template <typename T = ProcessStats> T* set_process_stats() {
+    return BeginNestedMessage<T>(9);
+  }
+
+
+  using FieldMetadata_InodeFileMap =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InodeFileMap,
+      TracePacket>;
+
+  static constexpr FieldMetadata_InodeFileMap kInodeFileMap{};
+  template <typename T = InodeFileMap> T* set_inode_file_map() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_ChromeEvents =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeEventBundle,
+      TracePacket>;
+
+  static constexpr FieldMetadata_ChromeEvents kChromeEvents{};
+  template <typename T = ChromeEventBundle> T* set_chrome_events() {
+    return BeginNestedMessage<T>(5);
+  }
+
+
+  using FieldMetadata_ClockSnapshot =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ClockSnapshot,
+      TracePacket>;
+
+  static constexpr FieldMetadata_ClockSnapshot kClockSnapshot{};
+  template <typename T = ClockSnapshot> T* set_clock_snapshot() {
+    return BeginNestedMessage<T>(6);
+  }
+
+
+  using FieldMetadata_SysStats =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SysStats,
+      TracePacket>;
+
+  static constexpr FieldMetadata_SysStats kSysStats{};
+  template <typename T = SysStats> T* set_sys_stats() {
+    return BeginNestedMessage<T>(7);
+  }
+
+
+  using FieldMetadata_TrackEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrackEvent,
+      TracePacket>;
+
+  static constexpr FieldMetadata_TrackEvent kTrackEvent{};
+  template <typename T = TrackEvent> T* set_track_event() {
+    return BeginNestedMessage<T>(11);
+  }
+
+
+  using FieldMetadata_TraceUuid =
+    ::protozero::proto_utils::FieldMetadata<
+      89,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceUuid,
+      TracePacket>;
+
+  static constexpr FieldMetadata_TraceUuid kTraceUuid{};
+  template <typename T = TraceUuid> T* set_trace_uuid() {
+    return BeginNestedMessage<T>(89);
+  }
+
+
+  using FieldMetadata_TraceConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      33,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceConfig,
+      TracePacket>;
+
+  static constexpr FieldMetadata_TraceConfig kTraceConfig{};
+  template <typename T = TraceConfig> T* set_trace_config() {
+    return BeginNestedMessage<T>(33);
+  }
+
+
+  using FieldMetadata_FtraceStats =
+    ::protozero::proto_utils::FieldMetadata<
+      34,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FtraceStats,
+      TracePacket>;
+
+  static constexpr FieldMetadata_FtraceStats kFtraceStats{};
+  template <typename T = FtraceStats> T* set_ftrace_stats() {
+    return BeginNestedMessage<T>(34);
+  }
+
+
+  using FieldMetadata_TraceStats =
+    ::protozero::proto_utils::FieldMetadata<
+      35,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceStats,
+      TracePacket>;
+
+  static constexpr FieldMetadata_TraceStats kTraceStats{};
+  template <typename T = TraceStats> T* set_trace_stats() {
+    return BeginNestedMessage<T>(35);
+  }
+
+
+  using FieldMetadata_ProfilePacket =
+    ::protozero::proto_utils::FieldMetadata<
+      37,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProfilePacket,
+      TracePacket>;
+
+  static constexpr FieldMetadata_ProfilePacket kProfilePacket{};
+  template <typename T = ProfilePacket> T* set_profile_packet() {
+    return BeginNestedMessage<T>(37);
+  }
+
+
+  using FieldMetadata_StreamingAllocation =
+    ::protozero::proto_utils::FieldMetadata<
+      74,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      StreamingAllocation,
+      TracePacket>;
+
+  static constexpr FieldMetadata_StreamingAllocation kStreamingAllocation{};
+  template <typename T = StreamingAllocation> T* set_streaming_allocation() {
+    return BeginNestedMessage<T>(74);
+  }
+
+
+  using FieldMetadata_StreamingFree =
+    ::protozero::proto_utils::FieldMetadata<
+      75,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      StreamingFree,
+      TracePacket>;
+
+  static constexpr FieldMetadata_StreamingFree kStreamingFree{};
+  template <typename T = StreamingFree> T* set_streaming_free() {
+    return BeginNestedMessage<T>(75);
+  }
+
+
+  using FieldMetadata_Battery =
+    ::protozero::proto_utils::FieldMetadata<
+      38,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BatteryCounters,
+      TracePacket>;
+
+  static constexpr FieldMetadata_Battery kBattery{};
+  template <typename T = BatteryCounters> T* set_battery() {
+    return BeginNestedMessage<T>(38);
+  }
+
+
+  using FieldMetadata_PowerRails =
+    ::protozero::proto_utils::FieldMetadata<
+      40,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PowerRails,
+      TracePacket>;
+
+  static constexpr FieldMetadata_PowerRails kPowerRails{};
+  template <typename T = PowerRails> T* set_power_rails() {
+    return BeginNestedMessage<T>(40);
+  }
+
+
+  using FieldMetadata_AndroidLog =
+    ::protozero::proto_utils::FieldMetadata<
+      39,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidLogPacket,
+      TracePacket>;
+
+  static constexpr FieldMetadata_AndroidLog kAndroidLog{};
+  template <typename T = AndroidLogPacket> T* set_android_log() {
+    return BeginNestedMessage<T>(39);
+  }
+
+
+  using FieldMetadata_SystemInfo =
+    ::protozero::proto_utils::FieldMetadata<
+      45,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SystemInfo,
+      TracePacket>;
+
+  static constexpr FieldMetadata_SystemInfo kSystemInfo{};
+  template <typename T = SystemInfo> T* set_system_info() {
+    return BeginNestedMessage<T>(45);
+  }
+
+
+  using FieldMetadata_Trigger =
+    ::protozero::proto_utils::FieldMetadata<
+      46,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Trigger,
+      TracePacket>;
+
+  static constexpr FieldMetadata_Trigger kTrigger{};
+  template <typename T = Trigger> T* set_trigger() {
+    return BeginNestedMessage<T>(46);
+  }
+
+
+  using FieldMetadata_ChromeTrigger =
+    ::protozero::proto_utils::FieldMetadata<
+      109,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeTrigger,
+      TracePacket>;
+
+  static constexpr FieldMetadata_ChromeTrigger kChromeTrigger{};
+  template <typename T = ChromeTrigger> T* set_chrome_trigger() {
+    return BeginNestedMessage<T>(109);
+  }
+
+
+  using FieldMetadata_PackagesList =
+    ::protozero::proto_utils::FieldMetadata<
+      47,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PackagesList,
+      TracePacket>;
+
+  static constexpr FieldMetadata_PackagesList kPackagesList{};
+  template <typename T = PackagesList> T* set_packages_list() {
+    return BeginNestedMessage<T>(47);
+  }
+
+
+  using FieldMetadata_ChromeBenchmarkMetadata =
+    ::protozero::proto_utils::FieldMetadata<
+      48,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeBenchmarkMetadata,
+      TracePacket>;
+
+  static constexpr FieldMetadata_ChromeBenchmarkMetadata kChromeBenchmarkMetadata{};
+  template <typename T = ChromeBenchmarkMetadata> T* set_chrome_benchmark_metadata() {
+    return BeginNestedMessage<T>(48);
+  }
+
+
+  using FieldMetadata_PerfettoMetatrace =
+    ::protozero::proto_utils::FieldMetadata<
+      49,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PerfettoMetatrace,
+      TracePacket>;
+
+  static constexpr FieldMetadata_PerfettoMetatrace kPerfettoMetatrace{};
+  template <typename T = PerfettoMetatrace> T* set_perfetto_metatrace() {
+    return BeginNestedMessage<T>(49);
+  }
+
+
+  using FieldMetadata_ChromeMetadata =
+    ::protozero::proto_utils::FieldMetadata<
+      51,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeMetadataPacket,
+      TracePacket>;
+
+  static constexpr FieldMetadata_ChromeMetadata kChromeMetadata{};
+  template <typename T = ChromeMetadataPacket> T* set_chrome_metadata() {
+    return BeginNestedMessage<T>(51);
+  }
+
+
+  using FieldMetadata_GpuCounterEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      52,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuCounterEvent,
+      TracePacket>;
+
+  static constexpr FieldMetadata_GpuCounterEvent kGpuCounterEvent{};
+  template <typename T = GpuCounterEvent> T* set_gpu_counter_event() {
+    return BeginNestedMessage<T>(52);
+  }
+
+
+  using FieldMetadata_GpuRenderStageEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      53,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuRenderStageEvent,
+      TracePacket>;
+
+  static constexpr FieldMetadata_GpuRenderStageEvent kGpuRenderStageEvent{};
+  template <typename T = GpuRenderStageEvent> T* set_gpu_render_stage_event() {
+    return BeginNestedMessage<T>(53);
+  }
+
+
+  using FieldMetadata_StreamingProfilePacket =
+    ::protozero::proto_utils::FieldMetadata<
+      54,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      StreamingProfilePacket,
+      TracePacket>;
+
+  static constexpr FieldMetadata_StreamingProfilePacket kStreamingProfilePacket{};
+  template <typename T = StreamingProfilePacket> T* set_streaming_profile_packet() {
+    return BeginNestedMessage<T>(54);
+  }
+
+
+  using FieldMetadata_HeapGraph =
+    ::protozero::proto_utils::FieldMetadata<
+      56,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      HeapGraph,
+      TracePacket>;
+
+  static constexpr FieldMetadata_HeapGraph kHeapGraph{};
+  template <typename T = HeapGraph> T* set_heap_graph() {
+    return BeginNestedMessage<T>(56);
+  }
+
+
+  using FieldMetadata_GraphicsFrameEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      57,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GraphicsFrameEvent,
+      TracePacket>;
+
+  static constexpr FieldMetadata_GraphicsFrameEvent kGraphicsFrameEvent{};
+  template <typename T = GraphicsFrameEvent> T* set_graphics_frame_event() {
+    return BeginNestedMessage<T>(57);
+  }
+
+
+  using FieldMetadata_VulkanMemoryEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      62,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      VulkanMemoryEvent,
+      TracePacket>;
+
+  static constexpr FieldMetadata_VulkanMemoryEvent kVulkanMemoryEvent{};
+  template <typename T = VulkanMemoryEvent> T* set_vulkan_memory_event() {
+    return BeginNestedMessage<T>(62);
+  }
+
+
+  using FieldMetadata_GpuLog =
+    ::protozero::proto_utils::FieldMetadata<
+      63,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuLog,
+      TracePacket>;
+
+  static constexpr FieldMetadata_GpuLog kGpuLog{};
+  template <typename T = GpuLog> T* set_gpu_log() {
+    return BeginNestedMessage<T>(63);
+  }
+
+
+  using FieldMetadata_VulkanApiEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      65,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      VulkanApiEvent,
+      TracePacket>;
+
+  static constexpr FieldMetadata_VulkanApiEvent kVulkanApiEvent{};
+  template <typename T = VulkanApiEvent> T* set_vulkan_api_event() {
+    return BeginNestedMessage<T>(65);
+  }
+
+
+  using FieldMetadata_PerfSample =
+    ::protozero::proto_utils::FieldMetadata<
+      66,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PerfSample,
+      TracePacket>;
+
+  static constexpr FieldMetadata_PerfSample kPerfSample{};
+  template <typename T = PerfSample> T* set_perf_sample() {
+    return BeginNestedMessage<T>(66);
+  }
+
+
+  using FieldMetadata_CpuInfo =
+    ::protozero::proto_utils::FieldMetadata<
+      67,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CpuInfo,
+      TracePacket>;
+
+  static constexpr FieldMetadata_CpuInfo kCpuInfo{};
+  template <typename T = CpuInfo> T* set_cpu_info() {
+    return BeginNestedMessage<T>(67);
+  }
+
+
+  using FieldMetadata_SmapsPacket =
+    ::protozero::proto_utils::FieldMetadata<
+      68,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SmapsPacket,
+      TracePacket>;
+
+  static constexpr FieldMetadata_SmapsPacket kSmapsPacket{};
+  template <typename T = SmapsPacket> T* set_smaps_packet() {
+    return BeginNestedMessage<T>(68);
+  }
+
+
+  using FieldMetadata_ServiceEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      69,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TracingServiceEvent,
+      TracePacket>;
+
+  static constexpr FieldMetadata_ServiceEvent kServiceEvent{};
+  template <typename T = TracingServiceEvent> T* set_service_event() {
+    return BeginNestedMessage<T>(69);
+  }
+
+
+  using FieldMetadata_InitialDisplayState =
+    ::protozero::proto_utils::FieldMetadata<
+      70,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InitialDisplayState,
+      TracePacket>;
+
+  static constexpr FieldMetadata_InitialDisplayState kInitialDisplayState{};
+  template <typename T = InitialDisplayState> T* set_initial_display_state() {
+    return BeginNestedMessage<T>(70);
+  }
+
+
+  using FieldMetadata_GpuMemTotalEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      71,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuMemTotalEvent,
+      TracePacket>;
+
+  static constexpr FieldMetadata_GpuMemTotalEvent kGpuMemTotalEvent{};
+  template <typename T = GpuMemTotalEvent> T* set_gpu_mem_total_event() {
+    return BeginNestedMessage<T>(71);
+  }
+
+
+  using FieldMetadata_MemoryTrackerSnapshot =
+    ::protozero::proto_utils::FieldMetadata<
+      73,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MemoryTrackerSnapshot,
+      TracePacket>;
+
+  static constexpr FieldMetadata_MemoryTrackerSnapshot kMemoryTrackerSnapshot{};
+  template <typename T = MemoryTrackerSnapshot> T* set_memory_tracker_snapshot() {
+    return BeginNestedMessage<T>(73);
+  }
+
+
+  using FieldMetadata_FrameTimelineEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      76,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FrameTimelineEvent,
+      TracePacket>;
+
+  static constexpr FieldMetadata_FrameTimelineEvent kFrameTimelineEvent{};
+  template <typename T = FrameTimelineEvent> T* set_frame_timeline_event() {
+    return BeginNestedMessage<T>(76);
+  }
+
+
+  using FieldMetadata_AndroidEnergyEstimationBreakdown =
+    ::protozero::proto_utils::FieldMetadata<
+      77,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidEnergyEstimationBreakdown,
+      TracePacket>;
+
+  static constexpr FieldMetadata_AndroidEnergyEstimationBreakdown kAndroidEnergyEstimationBreakdown{};
+  template <typename T = AndroidEnergyEstimationBreakdown> T* set_android_energy_estimation_breakdown() {
+    return BeginNestedMessage<T>(77);
+  }
+
+
+  using FieldMetadata_UiState =
+    ::protozero::proto_utils::FieldMetadata<
+      78,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      UiState,
+      TracePacket>;
+
+  static constexpr FieldMetadata_UiState kUiState{};
+  template <typename T = UiState> T* set_ui_state() {
+    return BeginNestedMessage<T>(78);
+  }
+
+
+  using FieldMetadata_AndroidCameraFrameEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      80,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidCameraFrameEvent,
+      TracePacket>;
+
+  static constexpr FieldMetadata_AndroidCameraFrameEvent kAndroidCameraFrameEvent{};
+  template <typename T = AndroidCameraFrameEvent> T* set_android_camera_frame_event() {
+    return BeginNestedMessage<T>(80);
+  }
+
+
+  using FieldMetadata_AndroidCameraSessionStats =
+    ::protozero::proto_utils::FieldMetadata<
+      81,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidCameraSessionStats,
+      TracePacket>;
+
+  static constexpr FieldMetadata_AndroidCameraSessionStats kAndroidCameraSessionStats{};
+  template <typename T = AndroidCameraSessionStats> T* set_android_camera_session_stats() {
+    return BeginNestedMessage<T>(81);
+  }
+
+
+  using FieldMetadata_TranslationTable =
+    ::protozero::proto_utils::FieldMetadata<
+      82,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TranslationTable,
+      TracePacket>;
+
+  static constexpr FieldMetadata_TranslationTable kTranslationTable{};
+  template <typename T = TranslationTable> T* set_translation_table() {
+    return BeginNestedMessage<T>(82);
+  }
+
+
+  using FieldMetadata_AndroidGameInterventionList =
+    ::protozero::proto_utils::FieldMetadata<
+      83,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidGameInterventionList,
+      TracePacket>;
+
+  static constexpr FieldMetadata_AndroidGameInterventionList kAndroidGameInterventionList{};
+  template <typename T = AndroidGameInterventionList> T* set_android_game_intervention_list() {
+    return BeginNestedMessage<T>(83);
+  }
+
+
+  using FieldMetadata_StatsdAtom =
+    ::protozero::proto_utils::FieldMetadata<
+      84,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      StatsdAtom,
+      TracePacket>;
+
+  static constexpr FieldMetadata_StatsdAtom kStatsdAtom{};
+  template <typename T = StatsdAtom> T* set_statsd_atom() {
+    return BeginNestedMessage<T>(84);
+  }
+
+
+  using FieldMetadata_AndroidSystemProperty =
+    ::protozero::proto_utils::FieldMetadata<
+      86,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidSystemProperty,
+      TracePacket>;
+
+  static constexpr FieldMetadata_AndroidSystemProperty kAndroidSystemProperty{};
+  template <typename T = AndroidSystemProperty> T* set_android_system_property() {
+    return BeginNestedMessage<T>(86);
+  }
+
+
+  using FieldMetadata_EntityStateResidency =
+    ::protozero::proto_utils::FieldMetadata<
+      91,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      EntityStateResidency,
+      TracePacket>;
+
+  static constexpr FieldMetadata_EntityStateResidency kEntityStateResidency{};
+  template <typename T = EntityStateResidency> T* set_entity_state_residency() {
+    return BeginNestedMessage<T>(91);
+  }
+
+
+  using FieldMetadata_ProfiledFrameSymbols =
+    ::protozero::proto_utils::FieldMetadata<
+      55,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProfiledFrameSymbols,
+      TracePacket>;
+
+  static constexpr FieldMetadata_ProfiledFrameSymbols kProfiledFrameSymbols{};
+  template <typename T = ProfiledFrameSymbols> T* set_profiled_frame_symbols() {
+    return BeginNestedMessage<T>(55);
+  }
+
+
+  using FieldMetadata_ModuleSymbols =
+    ::protozero::proto_utils::FieldMetadata<
+      61,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ModuleSymbols,
+      TracePacket>;
+
+  static constexpr FieldMetadata_ModuleSymbols kModuleSymbols{};
+  template <typename T = ModuleSymbols> T* set_module_symbols() {
+    return BeginNestedMessage<T>(61);
+  }
+
+
+  using FieldMetadata_DeobfuscationMapping =
+    ::protozero::proto_utils::FieldMetadata<
+      64,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DeobfuscationMapping,
+      TracePacket>;
+
+  static constexpr FieldMetadata_DeobfuscationMapping kDeobfuscationMapping{};
+  template <typename T = DeobfuscationMapping> T* set_deobfuscation_mapping() {
+    return BeginNestedMessage<T>(64);
+  }
+
+
+  using FieldMetadata_TrackDescriptor =
+    ::protozero::proto_utils::FieldMetadata<
+      60,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrackDescriptor,
+      TracePacket>;
+
+  static constexpr FieldMetadata_TrackDescriptor kTrackDescriptor{};
+  template <typename T = TrackDescriptor> T* set_track_descriptor() {
+    return BeginNestedMessage<T>(60);
+  }
+
+
+  using FieldMetadata_ProcessDescriptor =
+    ::protozero::proto_utils::FieldMetadata<
+      43,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProcessDescriptor,
+      TracePacket>;
+
+  static constexpr FieldMetadata_ProcessDescriptor kProcessDescriptor{};
+  template <typename T = ProcessDescriptor> T* set_process_descriptor() {
+    return BeginNestedMessage<T>(43);
+  }
+
+
+  using FieldMetadata_ThreadDescriptor =
+    ::protozero::proto_utils::FieldMetadata<
+      44,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ThreadDescriptor,
+      TracePacket>;
+
+  static constexpr FieldMetadata_ThreadDescriptor kThreadDescriptor{};
+  template <typename T = ThreadDescriptor> T* set_thread_descriptor() {
+    return BeginNestedMessage<T>(44);
+  }
+
+
+  using FieldMetadata_FtraceEvents =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FtraceEventBundle,
+      TracePacket>;
+
+  static constexpr FieldMetadata_FtraceEvents kFtraceEvents{};
+  template <typename T = FtraceEventBundle> T* set_ftrace_events() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_SynchronizationMarker =
+    ::protozero::proto_utils::FieldMetadata<
+      36,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      TracePacket>;
+
+  static constexpr FieldMetadata_SynchronizationMarker kSynchronizationMarker{};
+  void set_synchronization_marker(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_SynchronizationMarker::kFieldId, data, size);
+  }
+  void set_synchronization_marker(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_SynchronizationMarker::kFieldId, bytes.data, bytes.size);
+  }
+  void set_synchronization_marker(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_SynchronizationMarker::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);
+  }
+
+  using FieldMetadata_CompressedPackets =
+    ::protozero::proto_utils::FieldMetadata<
+      50,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      TracePacket>;
+
+  static constexpr FieldMetadata_CompressedPackets kCompressedPackets{};
+  void set_compressed_packets(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_CompressedPackets::kFieldId, data, size);
+  }
+  void set_compressed_packets(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_CompressedPackets::kFieldId, bytes.data, bytes.size);
+  }
+  void set_compressed_packets(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_CompressedPackets::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);
+  }
+
+  using FieldMetadata_ExtensionDescriptor =
+    ::protozero::proto_utils::FieldMetadata<
+      72,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ExtensionDescriptor,
+      TracePacket>;
+
+  static constexpr FieldMetadata_ExtensionDescriptor kExtensionDescriptor{};
+  template <typename T = ExtensionDescriptor> T* set_extension_descriptor() {
+    return BeginNestedMessage<T>(72);
+  }
+
+
+  using FieldMetadata_NetworkPacket =
+    ::protozero::proto_utils::FieldMetadata<
+      88,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      NetworkPacketEvent,
+      TracePacket>;
+
+  static constexpr FieldMetadata_NetworkPacket kNetworkPacket{};
+  template <typename T = NetworkPacketEvent> T* set_network_packet() {
+    return BeginNestedMessage<T>(88);
+  }
+
+
+  using FieldMetadata_NetworkPacketBundle =
+    ::protozero::proto_utils::FieldMetadata<
+      92,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      NetworkPacketBundle,
+      TracePacket>;
+
+  static constexpr FieldMetadata_NetworkPacketBundle kNetworkPacketBundle{};
+  template <typename T = NetworkPacketBundle> T* set_network_packet_bundle() {
+    return BeginNestedMessage<T>(92);
+  }
+
+
+  using FieldMetadata_TrackEventRangeOfInterest =
+    ::protozero::proto_utils::FieldMetadata<
+      90,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrackEventRangeOfInterest,
+      TracePacket>;
+
+  static constexpr FieldMetadata_TrackEventRangeOfInterest kTrackEventRangeOfInterest{};
+  template <typename T = TrackEventRangeOfInterest> T* set_track_event_range_of_interest() {
+    return BeginNestedMessage<T>(90);
+  }
+
+
+  using FieldMetadata_SurfaceflingerLayersSnapshot =
+    ::protozero::proto_utils::FieldMetadata<
+      93,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      LayersSnapshotProto,
+      TracePacket>;
+
+  static constexpr FieldMetadata_SurfaceflingerLayersSnapshot kSurfaceflingerLayersSnapshot{};
+  template <typename T = LayersSnapshotProto> T* set_surfaceflinger_layers_snapshot() {
+    return BeginNestedMessage<T>(93);
+  }
+
+
+  using FieldMetadata_SurfaceflingerTransactions =
+    ::protozero::proto_utils::FieldMetadata<
+      94,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TransactionTraceEntry,
+      TracePacket>;
+
+  static constexpr FieldMetadata_SurfaceflingerTransactions kSurfaceflingerTransactions{};
+  template <typename T = TransactionTraceEntry> T* set_surfaceflinger_transactions() {
+    return BeginNestedMessage<T>(94);
+  }
+
+
+  using FieldMetadata_ShellTransition =
+    ::protozero::proto_utils::FieldMetadata<
+      96,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ShellTransition,
+      TracePacket>;
+
+  static constexpr FieldMetadata_ShellTransition kShellTransition{};
+  template <typename T = ShellTransition> T* set_shell_transition() {
+    return BeginNestedMessage<T>(96);
+  }
+
+
+  using FieldMetadata_ShellHandlerMappings =
+    ::protozero::proto_utils::FieldMetadata<
+      97,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ShellHandlerMappings,
+      TracePacket>;
+
+  static constexpr FieldMetadata_ShellHandlerMappings kShellHandlerMappings{};
+  template <typename T = ShellHandlerMappings> T* set_shell_handler_mappings() {
+    return BeginNestedMessage<T>(97);
+  }
+
+
+  using FieldMetadata_ProtologMessage =
+    ::protozero::proto_utils::FieldMetadata<
+      104,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProtoLogMessage,
+      TracePacket>;
+
+  static constexpr FieldMetadata_ProtologMessage kProtologMessage{};
+  template <typename T = ProtoLogMessage> T* set_protolog_message() {
+    return BeginNestedMessage<T>(104);
+  }
+
+
+  using FieldMetadata_ProtologViewerConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      105,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProtoLogViewerConfig,
+      TracePacket>;
+
+  static constexpr FieldMetadata_ProtologViewerConfig kProtologViewerConfig{};
+  template <typename T = ProtoLogViewerConfig> T* set_protolog_viewer_config() {
+    return BeginNestedMessage<T>(105);
+  }
+
+
+  using FieldMetadata_WinscopeExtensions =
+    ::protozero::proto_utils::FieldMetadata<
+      112,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      WinscopeExtensions,
+      TracePacket>;
+
+  static constexpr FieldMetadata_WinscopeExtensions kWinscopeExtensions{};
+  template <typename T = WinscopeExtensions> T* set_winscope_extensions() {
+    return BeginNestedMessage<T>(112);
+  }
+
+
+  using FieldMetadata_EtwEvents =
+    ::protozero::proto_utils::FieldMetadata<
+      95,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      EtwTraceEventBundle,
+      TracePacket>;
+
+  static constexpr FieldMetadata_EtwEvents kEtwEvents{};
+  template <typename T = EtwTraceEventBundle> T* set_etw_events() {
+    return BeginNestedMessage<T>(95);
+  }
+
+
+  using FieldMetadata_V8JsCode =
+    ::protozero::proto_utils::FieldMetadata<
+      99,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      V8JsCode,
+      TracePacket>;
+
+  static constexpr FieldMetadata_V8JsCode kV8JsCode{};
+  template <typename T = V8JsCode> T* set_v8_js_code() {
+    return BeginNestedMessage<T>(99);
+  }
+
+
+  using FieldMetadata_V8InternalCode =
+    ::protozero::proto_utils::FieldMetadata<
+      100,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      V8InternalCode,
+      TracePacket>;
+
+  static constexpr FieldMetadata_V8InternalCode kV8InternalCode{};
+  template <typename T = V8InternalCode> T* set_v8_internal_code() {
+    return BeginNestedMessage<T>(100);
+  }
+
+
+  using FieldMetadata_V8WasmCode =
+    ::protozero::proto_utils::FieldMetadata<
+      101,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      V8WasmCode,
+      TracePacket>;
+
+  static constexpr FieldMetadata_V8WasmCode kV8WasmCode{};
+  template <typename T = V8WasmCode> T* set_v8_wasm_code() {
+    return BeginNestedMessage<T>(101);
+  }
+
+
+  using FieldMetadata_V8RegExpCode =
+    ::protozero::proto_utils::FieldMetadata<
+      102,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      V8RegExpCode,
+      TracePacket>;
+
+  static constexpr FieldMetadata_V8RegExpCode kV8RegExpCode{};
+  template <typename T = V8RegExpCode> T* set_v8_reg_exp_code() {
+    return BeginNestedMessage<T>(102);
+  }
+
+
+  using FieldMetadata_V8CodeMove =
+    ::protozero::proto_utils::FieldMetadata<
+      103,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      V8CodeMove,
+      TracePacket>;
+
+  static constexpr FieldMetadata_V8CodeMove kV8CodeMove{};
+  template <typename T = V8CodeMove> T* set_v8_code_move() {
+    return BeginNestedMessage<T>(103);
+  }
+
+
+  using FieldMetadata_AndroidInputEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      106,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidInputEvent,
+      TracePacket>;
+
+  static constexpr FieldMetadata_AndroidInputEvent kAndroidInputEvent{};
+  template <typename T = AndroidInputEvent> T* set_android_input_event() {
+    return BeginNestedMessage<T>(106);
+  }
+
+
+  using FieldMetadata_RemoteClockSync =
+    ::protozero::proto_utils::FieldMetadata<
+      107,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RemoteClockSync,
+      TracePacket>;
+
+  static constexpr FieldMetadata_RemoteClockSync kRemoteClockSync{};
+  template <typename T = RemoteClockSync> T* set_remote_clock_sync() {
+    return BeginNestedMessage<T>(107);
+  }
+
+
+  using FieldMetadata_PixelModemEvents =
+    ::protozero::proto_utils::FieldMetadata<
+      110,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PixelModemEvents,
+      TracePacket>;
+
+  static constexpr FieldMetadata_PixelModemEvents kPixelModemEvents{};
+  template <typename T = PixelModemEvents> T* set_pixel_modem_events() {
+    return BeginNestedMessage<T>(110);
+  }
+
+
+  using FieldMetadata_PixelModemTokenDatabase =
+    ::protozero::proto_utils::FieldMetadata<
+      111,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PixelModemTokenDatabase,
+      TracePacket>;
+
+  static constexpr FieldMetadata_PixelModemTokenDatabase kPixelModemTokenDatabase{};
+  template <typename T = PixelModemTokenDatabase> T* set_pixel_modem_token_database() {
+    return BeginNestedMessage<T>(111);
+  }
+
+
+  using FieldMetadata_ForTesting =
+    ::protozero::proto_utils::FieldMetadata<
+      900,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TestEvent,
+      TracePacket>;
+
+  static constexpr FieldMetadata_ForTesting kForTesting{};
+  template <typename T = TestEvent> T* set_for_testing() {
+    return BeginNestedMessage<T>(900);
+  }
+
+
+  using FieldMetadata_TrustedUid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TracePacket>;
+
+  static constexpr FieldMetadata_TrustedUid kTrustedUid{};
+  void set_trusted_uid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TrustedUid::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_TrustedPacketSequenceId =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TracePacket>;
+
+  static constexpr FieldMetadata_TrustedPacketSequenceId kTrustedPacketSequenceId{};
+  void set_trusted_packet_sequence_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TrustedPacketSequenceId::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_TrustedPid =
+    ::protozero::proto_utils::FieldMetadata<
+      79,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TracePacket>;
+
+  static constexpr FieldMetadata_TrustedPid kTrustedPid{};
+  void set_trusted_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TrustedPid::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_InternedData =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InternedData,
+      TracePacket>;
+
+  static constexpr FieldMetadata_InternedData kInternedData{};
+  template <typename T = InternedData> T* set_interned_data() {
+    return BeginNestedMessage<T>(12);
+  }
+
+
+  using FieldMetadata_SequenceFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TracePacket>;
+
+  static constexpr FieldMetadata_SequenceFlags kSequenceFlags{};
+  void set_sequence_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SequenceFlags::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_IncrementalStateCleared =
+    ::protozero::proto_utils::FieldMetadata<
+      41,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TracePacket>;
+
+  static constexpr FieldMetadata_IncrementalStateCleared kIncrementalStateCleared{};
+  void set_incremental_state_cleared(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IncrementalStateCleared::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_TracePacketDefaults =
+    ::protozero::proto_utils::FieldMetadata<
+      59,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TracePacketDefaults,
+      TracePacket>;
+
+  static constexpr FieldMetadata_TracePacketDefaults kTracePacketDefaults{};
+  template <typename T = TracePacketDefaults> T* set_trace_packet_defaults() {
+    return BeginNestedMessage<T>(59);
+  }
+
+
+  using FieldMetadata_PreviousPacketDropped =
+    ::protozero::proto_utils::FieldMetadata<
+      42,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TracePacket>;
+
+  static constexpr FieldMetadata_PreviousPacketDropped kPreviousPacketDropped{};
+  void set_previous_packet_dropped(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_PreviousPacketDropped::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_FirstPacketOnSequence =
+    ::protozero::proto_utils::FieldMetadata<
+      87,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TracePacket>;
+
+  static constexpr FieldMetadata_FirstPacketOnSequence kFirstPacketOnSequence{};
+  void set_first_packet_on_sequence(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_FirstPacketOnSequence::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_MachineId =
+    ::protozero::proto_utils::FieldMetadata<
+      98,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TracePacket>;
+
+  static constexpr FieldMetadata_MachineId kMachineId{};
+  void set_machine_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MachineId::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_DATA_SOURCE_H_
+#define INCLUDE_PERFETTO_TRACING_DATA_SOURCE_H_
+
+// This header contains the key class (DataSource) that a producer app should
+// override in order to create a custom data source that gets tracing Start/Stop
+// notifications and emits tracing data.
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <array>
+#include <atomic>
+#include <functional>
+#include <memory>
+#include <mutex>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/buffer_exhausted_policy.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/flush_flags.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/data_source_internal.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/data_source_type.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_muxer.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/locked_handle.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
+
+// DEPRECATED: Instead of using this macro, prefer specifying symbol linkage
+// attributes explicitly using the `_WITH_ATTRS` macro variants (e.g.,
+// PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS_WITH_ATTRS). This avoids
+// potential macro definition collisions between two libraries using Perfetto.
+//
+// PERFETTO_COMPONENT_EXPORT is used to mark symbols in Perfetto's headers
+// (typically templates) that are defined by the user outside of Perfetto and
+// should be made visible outside the current module. (e.g., in Chrome's
+// component build).
+#if !defined(PERFETTO_COMPONENT_EXPORT)
+#if PERFETTO_BUILDFLAG(PERFETTO_COMPILER_MSVC)
+// Workaround for C4003: not enough arguments for function-like macro invocation
+// 'PERFETTO_INTERNAL_DECLARE_TRACK_EVENT_DATA_SOURCE'
+#define PERFETTO_COMPONENT_EXPORT __declspec()
+#else
+#define PERFETTO_COMPONENT_EXPORT
+#endif
+#endif
+
+namespace perfetto {
+namespace internal {
+class TracingMuxerImpl;
+class TrackEventCategoryRegistry;
+template <typename, const internal::TrackEventCategoryRegistry*>
+class TrackEventDataSource;
+}  // namespace internal
+
+namespace shlib {
+class TrackEvent;
+}  // namespace shlib
+
+namespace test {
+class DataSourceInternalForTest;
+}  // namespace test
+
+// Base class with the virtual methods to get start/stop notifications.
+// Embedders are supposed to derive the templated version below, not this one.
+class PERFETTO_EXPORT_COMPONENT DataSourceBase {
+ public:
+  virtual ~DataSourceBase();
+
+  // TODO(primiano): change the const& args below to be pointers instead. It
+  // makes it more awkward to handle output arguments and require mutable(s).
+  // This requires synchronizing a breaking API change for existing embedders.
+
+  // OnSetup() is invoked when tracing is configured. In most cases this happens
+  // just before starting the trace. In the case of deferred start (see
+  // deferred_start in trace_config.proto) start might happen later.
+  //
+  // Can be called from any thread.
+  class SetupArgs {
+   public:
+    // This is valid only within the scope of the OnSetup() call and must not
+    // be retained.
+    const DataSourceConfig* config = nullptr;
+
+    // Backend type.
+    BackendType backend_type = kUnspecifiedBackend;
+
+    // The index of this data source instance (0..kMaxDataSourceInstances - 1).
+    uint32_t internal_instance_index = 0;
+  };
+  virtual void OnSetup(const SetupArgs&);
+
+  class StartArgs {
+   public:
+    // The index of this data source instance (0..kMaxDataSourceInstances - 1).
+    uint32_t internal_instance_index = 0;
+  };
+  // Invoked after tracing is actually started.
+  //
+  // Can be called from any thread.
+  virtual void OnStart(const StartArgs&);
+
+  class PERFETTO_EXPORT_COMPONENT StopArgs {
+   public:
+    virtual ~StopArgs();
+
+    // HandleAsynchronously() can optionally be called to defer the tracing
+    // session stop and write tracing data just before stopping.
+    // This function returns a closure that must be invoked after the last
+    // trace events have been emitted. The returned closure can be called from
+    // any thread. The caller also needs to explicitly call TraceContext.Flush()
+    // from the last Trace() lambda invocation because no other implicit flushes
+    // will happen after the stop signal.
+    // When this function is called, the tracing service will defer the stop of
+    // the tracing session until the returned closure is invoked.
+    // However, the caller cannot hang onto this closure for too long. The
+    // tracing service will forcefully stop the tracing session without waiting
+    // for pending producers after TraceConfig.data_source_stop_timeout_ms
+    // (default: 5s, can be overridden by Consumers when starting a trace).
+    // If the closure is called after this timeout an error will be logged and
+    // the trace data emitted will not be present in the trace. No other
+    // functional side effects (e.g. crashes or corruptions) will happen. In
+    // other words, it is fine to accidentally hold onto this closure for too
+    // long but, if that happens, some tracing data will be lost.
+    virtual std::function<void()> HandleStopAsynchronously() const = 0;
+
+    // The index of this data source instance (0..kMaxDataSourceInstances - 1).
+    uint32_t internal_instance_index = 0;
+  };
+  // Invoked before tracing is stopped.
+  //
+  // Can be called from any thread. Blocking this for too long it's not a good
+  // idea and can cause deadlocks. Use HandleAsynchronously() to postpone
+  // disabling the data source instance.
+  virtual void OnStop(const StopArgs&);
+
+  class ClearIncrementalStateArgs {
+   public:
+    // The index of this data source instance (0..kMaxDataSourceInstances - 1).
+    uint32_t internal_instance_index = 0;
+  };
+  // Invoked before marking the thread local per-instance incremental state
+  // outdated.
+  //
+  // Can be called from any thread.
+  virtual void WillClearIncrementalState(const ClearIncrementalStateArgs&);
+
+  class FlushArgs {
+   public:
+    virtual ~FlushArgs();
+
+    // HandleFlushAsynchronously() can be called to postpone acknowledging the
+    // flush request. This function returns a closure that must be invoked after
+    // the flush request has been processed. The returned closure can be called
+    // from any thread.
+    virtual std::function<void()> HandleFlushAsynchronously() const = 0;
+
+    // The index of this data source instance (0..kMaxDataSourceInstances - 1).
+    uint32_t internal_instance_index = 0;
+
+    // The reason and initiator of the flush. See flush_flags.h .
+    FlushFlags flush_flags;
+  };
+  // Called when the tracing service requests a Flush. Users can override this
+  // to tell other threads to flush their TraceContext for this data source
+  // (the library cannot execute code on all the threads on its own).
+  //
+  // Can be called from any thread. Blocking this for too long it's not a good
+  // idea and can cause deadlocks. Use HandleAsynchronously() to postpone
+  // sending the flush acknowledgement to the service.
+  virtual void OnFlush(const FlushArgs&);
+
+  // Determines whether a startup session can be adopted by a service-initiated
+  // tracing session (i.e. whether their configs are compatible).
+  virtual bool CanAdoptStartupSession(const DataSourceConfig& startup_config,
+                                      const DataSourceConfig& service_config);
+};
+
+struct DefaultDataSourceTraits {
+  // |IncrementalStateType| can optionally be used store custom per-sequence
+  // incremental data (e.g., interning tables).
+  using IncrementalStateType = void;
+  // |TlsStateType| can optionally be used to store custom per-sequence
+  // session data, which is not reset when incremental state is cleared
+  // (e.g. configuration options).
+  using TlsStateType = void;
+
+  // Allows overriding what type of thread-local state configuration the data
+  // source uses. By default every data source gets independent thread-local
+  // state, which means every instance uses separate trace writers and
+  // incremental state even on the same thread. Some data sources (most notably
+  // the track event data source) want to share trace writers and incremental
+  // state on the same thread.
+  static internal::DataSourceThreadLocalState* GetDataSourceTLS(
+      internal::DataSourceStaticState* static_state,
+      internal::TracingTLS* root_tls) {
+    auto* ds_tls = &root_tls->data_sources_tls[static_state->index];
+    // ds_tls->static_state can be:
+    // * nullptr
+    // * equal to static_state
+    // * equal to the static state of a different data source, in tests (when
+    //   ResetForTesting() has been used)
+    // In any case, there's no need to do anything, the caller will reinitialize
+    // static_state.
+    return ds_tls;
+  }
+};
+
+// Holds the type for a DataSource. Accessed by the static Trace() method
+// fastpaths. This allows redefinitions under a component where a component
+// specific export macro is used.
+// Due to C2086 (redefinition) error on MSVC/clang-cl, internal::DataSourceType
+// can't be a static data member. To avoid explicit specialization after
+// instantiation error, type() needs to be in a template helper class that's
+// instantiated independently from DataSource. See b/280777748.
+template <typename DerivedDataSource,
+          typename DataSourceTraits = DefaultDataSourceTraits>
+struct DataSourceHelper {
+  static internal::DataSourceType& type() {
+    static perfetto::internal::DataSourceType type_;
+    return type_;
+  }
+};
+
+// Templated base class meant to be derived by embedders to create a custom data
+// source. DerivedDataSource must be the type of the derived class itself, e.g.:
+// class MyDataSource : public DataSource<MyDataSource> {...}.
+//
+// |DataSourceTraits| allows customizing the behavior of the data source. See
+// |DefaultDataSourceTraits|.
+template <typename DerivedDataSource,
+          typename DataSourceTraits = DefaultDataSourceTraits>
+class DataSource : public DataSourceBase {
+  struct DefaultTracePointTraits;
+  using Helper = DataSourceHelper<DerivedDataSource, DataSourceTraits>;
+
+ public:
+  // The BufferExhaustedPolicy to use for TraceWriters of this DataSource.
+  // Override this in your DataSource class to change the default, which is to
+  // drop data on shared memory overruns.
+  constexpr static BufferExhaustedPolicy kBufferExhaustedPolicy =
+      BufferExhaustedPolicy::kDrop;
+
+  // When this flag is false, we cannot have multiple instances of this data
+  // source. When a data source is already active and if we attempt
+  // to start another instance of that data source (via another tracing
+  // session), it will fail to start the second instance of data source.
+  static constexpr bool kSupportsMultipleInstances = true;
+
+  // When this flag is true, DataSource callbacks (OnSetup, OnStart, etc.) are
+  // called under the lock (the same that is used in GetDataSourceLocked
+  // function). This is not recommended because it can lead to deadlocks, but
+  // it was the default behavior for a long time and some embedders rely on it
+  // to protect concurrent access to the DataSource members. So we keep the
+  // "true" value as the default.
+  static constexpr bool kRequiresCallbacksUnderLock = true;
+
+  // Argument passed to the lambda function passed to Trace() (below).
+  class TraceContext {
+   public:
+    using TracePacketHandle =
+        ::protozero::MessageHandle<::perfetto::protos::pbzero::TracePacket>;
+
+    TraceContext(TraceContext&&) noexcept = default;
+    ~TraceContext() {
+      // If the data source is being intercepted, flush the trace writer after
+      // each trace point to make sure the interceptor sees the data right away.
+      if (PERFETTO_UNLIKELY(tls_inst_->is_intercepted))
+        Flush();
+    }
+
+    // Adds an empty trace packet to the trace to ensure that the service can
+    // safely read the last event from the trace buffer.
+    // See PERFETTO_INTERNAL_ADD_EMPTY_EVENT macros for context.
+    void AddEmptyTracePacket() {
+      // If nothing was written since the last empty packet, there's nothing to
+      // scrape, so adding more empty packets serves no purpose.
+      if (tls_inst_->trace_writer->written() ==
+          tls_inst_->last_empty_packet_position) {
+        return;
+      }
+      tls_inst_->trace_writer->NewTracePacket();
+      tls_inst_->last_empty_packet_position =
+          tls_inst_->trace_writer->written();
+    }
+
+    TracePacketHandle NewTracePacket() {
+      return tls_inst_->trace_writer->NewTracePacket();
+    }
+
+    // Forces a commit of the thread-local tracing data written so far to the
+    // service. This is almost never required (tracing data is periodically
+    // committed as trace pages are filled up) and has a non-negligible
+    // performance hit (requires an IPC + refresh of the current thread-local
+    // chunk). The only case when this should be used is when handling OnStop()
+    // asynchronously, to ensure sure that the data is committed before the
+    // Stop timeout expires.
+    // The TracePacketHandle obtained by the last NewTracePacket() call must be
+    // finalized before calling Flush() (either implicitly by going out of scope
+    // or by explicitly calling Finalize()).
+    // |cb| is an optional callback. When non-null it will request the
+    // service to ACK the flush and will be invoked on an internal thread after
+    // the service has  acknowledged it. The callback might be NEVER INVOKED if
+    // the service crashes or the IPC connection is dropped.
+    void Flush(std::function<void()> cb = {}) {
+      tls_inst_->trace_writer->Flush(cb);
+    }
+
+    // Returns the number of bytes written on the current thread by the current
+    // data-source since its creation.
+    // This can be useful for splitting protos that might grow very large.
+    uint64_t written() { return tls_inst_->trace_writer->written(); }
+
+    // Returns a RAII handle to access the data source instance, guaranteeing
+    // that it won't be deleted on another thread (because of trace stopping)
+    // while accessing it from within the Trace() lambda.
+    // The returned handle can be invalid (nullptr) if tracing is stopped
+    // immediately before calling this. The caller is supposed to check for its
+    // validity before using it. After checking, the handle is guaranteed to
+    // remain valid until the handle goes out of scope.
+    LockedHandle<DerivedDataSource> GetDataSourceLocked() const {
+      auto* internal_state =
+          Helper::type().static_state()->TryGet(instance_index_);
+      if (!internal_state)
+        return LockedHandle<DerivedDataSource>();
+      std::unique_lock<std::recursive_mutex> lock(internal_state->lock);
+      return LockedHandle<DerivedDataSource>(
+          std::move(lock),
+          static_cast<DerivedDataSource*>(internal_state->data_source.get()));
+    }
+
+    // Post-condition: returned ptr will be non-null.
+    typename DataSourceTraits::TlsStateType* GetCustomTlsState() {
+      PERFETTO_DCHECK(tls_inst_->data_source_custom_tls);
+      return reinterpret_cast<typename DataSourceTraits::TlsStateType*>(
+          tls_inst_->data_source_custom_tls.get());
+    }
+
+    typename DataSourceTraits::IncrementalStateType* GetIncrementalState() {
+      return static_cast<typename DataSourceTraits::IncrementalStateType*>(
+          Helper::type().GetIncrementalState(tls_inst_, instance_index_));
+    }
+
+   private:
+    friend class DataSource;
+    template <typename, const internal::TrackEventCategoryRegistry*>
+    friend class internal::TrackEventDataSource;
+    TraceContext(internal::DataSourceInstanceThreadLocalState* tls_inst,
+                 uint32_t instance_index)
+        : tls_inst_(tls_inst), instance_index_(instance_index) {}
+    TraceContext(const TraceContext&) = delete;
+    TraceContext& operator=(const TraceContext&) = delete;
+
+    internal::DataSourceInstanceThreadLocalState* const tls_inst_;
+    uint32_t const instance_index_;
+  };
+
+  // The main tracing method. Tracing code should call this passing a lambda as
+  // argument, with the following signature: void(TraceContext).
+  // The lambda will be called synchronously (i.e., always before Trace()
+  // returns) only if tracing is enabled and the data source has been enabled in
+  // the tracing config.
+  // The lambda can be called more than once per Trace() call, in the case of
+  // concurrent tracing sessions (or even if the data source is instantiated
+  // twice within the same trace config).
+  template <typename Lambda>
+  static void Trace(Lambda tracing_fn) {
+    CallIfEnabled<DefaultTracePointTraits>([&tracing_fn](uint32_t instances) {
+      TraceWithInstances<DefaultTracePointTraits>(instances,
+                                                  std::move(tracing_fn));
+    });
+  }
+
+  // An efficient trace point guard for checking if this data source is active.
+  // |callback| is a function which will only be called if there are active
+  // instances. It is given an instance state parameter, which should be passed
+  // to TraceWithInstances() to actually record trace data.
+  template <typename Traits = DefaultTracePointTraits, typename Callback>
+  static void CallIfEnabled(Callback callback,
+                            typename Traits::TracePointData trace_point_data =
+                                {}) PERFETTO_ALWAYS_INLINE {
+    // |instances| is a per-class bitmap that tells:
+    // 1. If the data source is enabled at all.
+    // 2. The index of the slot within
+    //    internal::DataSourceStaticState::instances that holds the instance
+    //    state. In turn this allows to map the data source to the tracing
+    //    session and buffers.
+    // memory_order_relaxed is okay because:
+    // - |instances| is re-read with an acquire barrier below if this succeeds.
+    // - The code between this point and the acquire-load is based on static
+    //    storage which has indefinite lifetime.
+    uint32_t instances = Traits::GetActiveInstances(trace_point_data)
+                             ->load(std::memory_order_relaxed);
+
+    // This is the tracing fast-path. Bail out immediately if tracing is not
+    // enabled (or tracing is enabled but not for this data source).
+    if (PERFETTO_LIKELY(!instances))
+      return;
+    callback(instances);
+  }
+
+  // The "lower half" of a trace point which actually performs tracing after
+  // this data source has been determined to be active.
+  // |instances| must be the instance state value retrieved through
+  // CallIfEnabled().
+  // |tracing_fn| will be called to record trace data as in Trace().
+  //
+  // |trace_point_data| is an optional parameter given to |Traits::
+  // GetActiveInstances| to make it possible to use custom storage for
+  // the data source enabled state. This is, for example, used by TrackEvent to
+  // implement per-tracing category enabled states.
+  template <typename Traits = DefaultTracePointTraits, typename Lambda>
+  static void TraceWithInstances(
+      uint32_t cached_instances,
+      Lambda tracing_fn,
+      typename Traits::TracePointData trace_point_data = {}) {
+    PERFETTO_DCHECK(cached_instances);
+
+    if (!Helper::type().template TracePrologue<DataSourceTraits, Traits>(
+            &tls_state_, &cached_instances, trace_point_data)) {
+      return;
+    }
+
+    for (internal::DataSourceType::InstancesIterator it =
+             Helper::type().template BeginIteration<Traits>(
+                 cached_instances, tls_state_, trace_point_data);
+         it.instance; Helper::type().template NextIteration<Traits>(
+             &it, tls_state_, trace_point_data)) {
+      tracing_fn(TraceContext(it.instance, it.i));
+    }
+
+    Helper::type().TraceEpilogue(tls_state_);
+  }
+
+  // Registers the data source on all tracing backends, including ones that
+  // connect after the registration. Doing so enables the data source to receive
+  // Setup/Start/Stop notifications and makes the Trace() method work when
+  // tracing is enabled and the data source is selected.
+  // This must be called after Tracing::Initialize().
+  // Can return false to signal failure if attemping to register more than
+  // kMaxDataSources (32) data sources types or if tracing hasn't been
+  // initialized.
+  // The optional |constructor_args| will be passed to the data source when it
+  // is constructed.
+  template <class... Args>
+  static bool Register(const DataSourceDescriptor& descriptor,
+                       const Args&... constructor_args) {
+    // Silences -Wunused-variable warning in case the trace method is not used
+    // by the translation unit that declares the data source.
+    (void)tls_state_;
+
+    auto factory = [constructor_args...]() {
+      return std::unique_ptr<DataSourceBase>(
+          new DerivedDataSource(constructor_args...));
+    };
+    constexpr bool no_flush =
+        std::is_same_v<decltype(&DerivedDataSource::OnFlush),
+                       decltype(&DataSourceBase::OnFlush)>;
+    internal::DataSourceParams params{
+        DerivedDataSource::kSupportsMultipleInstances,
+        DerivedDataSource::kRequiresCallbacksUnderLock};
+    return Helper::type().Register(
+        descriptor, factory, params, DerivedDataSource::kBufferExhaustedPolicy,
+        no_flush,
+        GetCreateTlsFn(
+            static_cast<typename DataSourceTraits::TlsStateType*>(nullptr)),
+        GetCreateIncrementalStateFn(
+            static_cast<typename DataSourceTraits::IncrementalStateType*>(
+                nullptr)),
+        nullptr);
+  }
+
+  // Updates the data source descriptor.
+  static void UpdateDescriptor(const DataSourceDescriptor& descriptor) {
+    Helper::type().UpdateDescriptor(descriptor);
+  }
+
+ private:
+  friend ::perfetto::test::DataSourceInternalForTest;
+  friend ::perfetto::shlib::TrackEvent;
+  // Traits for customizing the behavior of a specific trace point.
+  struct DefaultTracePointTraits {
+    // By default, every call to DataSource::Trace() will record trace events
+    // for every active instance of that data source. A single trace point can,
+    // however, use a custom set of enable flags for more fine grained control
+    // of when that trace point is active.
+    //
+    // DANGER: when doing this, the data source must use the appropriate memory
+    // fences when changing the state of the bitmap.
+    //
+    // |TraceWithInstances| may be optionally given an additional parameter for
+    // looking up the enable flags. That parameter is passed as |TracePointData|
+    // to |GetActiveInstances|. This is, for example, used by TrackEvent to
+    // implement per-category enabled states.
+    struct TracePointData {};
+    static constexpr std::atomic<uint32_t>* GetActiveInstances(TracePointData) {
+      return Helper::type().valid_instances();
+    }
+  };
+
+  template <typename T>
+  static internal::DataSourceInstanceThreadLocalState::ObjectWithDeleter
+  CreateIncrementalState(internal::DataSourceInstanceThreadLocalState*,
+                         uint32_t,
+                         void*) {
+    return internal::DataSourceInstanceThreadLocalState::ObjectWithDeleter(
+        reinterpret_cast<void*>(new T()),
+        [](void* p) { delete reinterpret_cast<T*>(p); });
+  }
+
+  // The second parameter here is used to specialize the case where there is no
+  // incremental state type.
+  template <typename T>
+  static internal::DataSourceType::CreateIncrementalStateFn
+  GetCreateIncrementalStateFn(const T*) {
+    return &CreateIncrementalState<T>;
+  }
+
+  static internal::DataSourceType::CreateIncrementalStateFn
+  GetCreateIncrementalStateFn(const void*) {
+    return nullptr;
+  }
+
+  template <typename T>
+  static internal::DataSourceInstanceThreadLocalState::ObjectWithDeleter
+  CreateDataSourceCustomTls(
+      internal::DataSourceInstanceThreadLocalState* tls_inst,
+      uint32_t instance_index,
+      void*) {
+    return internal::DataSourceInstanceThreadLocalState::ObjectWithDeleter(
+        reinterpret_cast<void*>(new T(TraceContext(tls_inst, instance_index))),
+        [](void* p) { delete reinterpret_cast<T*>(p); });
+  }
+
+  // The second parameter here is used to specialize the case where there is no
+  // tls state type.
+  template <typename T>
+  static internal::DataSourceType::CreateCustomTlsFn GetCreateTlsFn(const T*) {
+    return &CreateDataSourceCustomTls<T>;
+  }
+
+  static internal::DataSourceType::CreateCustomTlsFn GetCreateTlsFn(
+      const void*) {
+    return nullptr;
+  }
+
+  // This TLS object is a cached raw pointer and has deliberately no destructor.
+  // The Platform implementation is supposed to create and manage the lifetime
+  // of the Platform::ThreadLocalObject and take care of destroying it.
+  // This is because non-POD thread_local variables have subtleties (global
+  // destructors) that we need to defer to the embedder. In chromium's platform
+  // implementation, for instance, the tls slot is implemented using
+  // chromium's base::ThreadLocalStorage.
+  static thread_local internal::DataSourceThreadLocalState* tls_state_;
+};
+
+// static
+template <typename T, typename D>
+thread_local internal::DataSourceThreadLocalState* DataSource<T, D>::tls_state_;
+
+}  // namespace perfetto
+
+// If placed at the end of a macro declaration, eats the semicolon at the end of
+// the macro invocation (e.g., "MACRO(...);") to avoid warnings about extra
+// semicolons.
+#define PERFETTO_INTERNAL_SWALLOW_SEMICOLON() \
+  extern int perfetto_internal_unused
+
+// This macro must be used once for each data source next to the data source's
+// declaration.
+#define PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS(...)  \
+  PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS_WITH_ATTRS( \
+      PERFETTO_COMPONENT_EXPORT, __VA_ARGS__)
+
+// Similar to `PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS` but it also takes
+// custom attributes, which are useful when DataSource is defined in a component
+// where a component specific export macro is used.
+#define PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS_WITH_ATTRS(attrs, ...) \
+  template <>                                                              \
+  attrs perfetto::internal::DataSourceType&                                \
+  perfetto::DataSourceHelper<__VA_ARGS__>::type()
+
+// This macro must be used once for each data source in one source file to
+// allocate static storage for the data source's static state.
+#define PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(...)  \
+  PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS_WITH_ATTRS( \
+      PERFETTO_COMPONENT_EXPORT, __VA_ARGS__)
+
+// Similar to `PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS` but it also takes
+// custom attributes, which are useful when DataSource is defined in a component
+// where a component specific export macro is used.
+#define PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS_WITH_ATTRS(attrs, ...) \
+  template <>                                                             \
+  perfetto::internal::DataSourceType&                                     \
+  perfetto::DataSourceHelper<__VA_ARGS__>::type() {                       \
+    static perfetto::internal::DataSourceType type_;                      \
+    return type_;                                                         \
+  }                                                                       \
+  PERFETTO_INTERNAL_SWALLOW_SEMICOLON()
+
+#endif  // INCLUDE_PERFETTO_TRACING_DATA_SOURCE_H_
+// gen_amalgamated begin header: include/perfetto/tracing/track_event.h
+// gen_amalgamated begin header: include/perfetto/tracing/internal/track_event_data_source.h
+// gen_amalgamated begin header: include/perfetto/base/template_util.h
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_BASE_TEMPLATE_UTIL_H_
+#define INCLUDE_PERFETTO_BASE_TEMPLATE_UTIL_H_
+
+#include <cstddef>
+#include <type_traits>
+
+namespace perfetto {
+namespace base {
+
+// Helper to express preferences in an overload set. If more than one overload
+// is available for a given set of parameters the overload with the higher
+// priority will be chosen.
+template <size_t I>
+struct priority_tag : priority_tag<I - 1> {};
+
+template <>
+struct priority_tag<0> {};
+
+// enable_if_t is an implementation of std::enable_if_t from C++14.
+//
+// Specification:
+// https://en.cppreference.com/w/cpp/types/enable_if
+template <bool B, class T = void>
+using enable_if_t = typename std::enable_if<B, T>::type;
+
+// decay_t is an implementation of std::decay_t from C++14.
+//
+// Specification:
+// https://en.cppreference.com/w/cpp/types/decay
+template <class T>
+using decay_t = typename std::decay<T>::type;
+
+// remove_cvref is an implementation of std::remove_cvref from
+// C++20.
+//
+// Specification:
+// https://en.cppreference.com/w/cpp/types/remove_cvref
+
+template <class T>
+struct remove_cvref {
+  using type = typename std::remove_cv<typename std::remove_cv<
+      typename std::remove_reference<T>::type>::type>::type;
+};
+template <class T>
+using remove_cvref_t = typename remove_cvref<T>::type;
+
+// Check if a given type is a specialization of a given template:
+// is_specialization<T, std::vector>::value.
+
+template <typename Type, template <typename...> class Template>
+struct is_specialization : std::false_type {};
+
+template <template <typename...> class Ref, typename... Args>
+struct is_specialization<Ref<Args...>, Ref> : std::true_type {};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_BASE_TEMPLATE_UTIL_H_
+// gen_amalgamated begin header: include/perfetto/tracing/event_context.h
+// gen_amalgamated begin header: include/perfetto/tracing/internal/track_event_internal.h
+// gen_amalgamated begin header: include/perfetto/base/flat_set.h
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_BASE_FLAT_SET_H_
+#define INCLUDE_PERFETTO_BASE_FLAT_SET_H_
+
+#include <algorithm>
+#include <vector>
+
+// A vector-based set::set-like container.
+// It's more cache friendly than std::*set and performs for cases where:
+// 1. A high number of dupes is expected (e.g. pid tracking in ftrace).
+// 2. The working set is small (hundreds of elements).
+
+// Performance characteristics (for uniformly random insertion order):
+// - For smaller insertions (up to ~500), it outperforms both std::set<int> and
+//   std::unordered_set<int> by ~3x.
+// - Up until 4k insertions, it is always faster than std::set<int>.
+// - unordered_set<int> is faster with more than 2k insertions.
+// - unordered_set, however, it's less memory efficient and has more caveats
+//   (see chromium's base/containers/README.md).
+//
+// See flat_set_benchmark.cc and the charts in go/perfetto-int-set-benchmark.
+
+namespace perfetto {
+namespace base {
+
+template <typename T>
+class FlatSet {
+ public:
+  using value_type = T;
+  using const_pointer = const T*;
+  using iterator = typename std::vector<T>::iterator;
+  using const_iterator = typename std::vector<T>::const_iterator;
+
+  FlatSet() = default;
+
+  // Mainly for tests. Deliberately not marked as "explicit".
+  FlatSet(std::initializer_list<T> initial) : entries_(initial) {
+    std::sort(entries_.begin(), entries_.end());
+    entries_.erase(std::unique(entries_.begin(), entries_.end()),
+                   entries_.end());
+  }
+
+  const_iterator find(T value) const {
+    auto entries_end = entries_.end();
+    auto it = std::lower_bound(entries_.begin(), entries_end, value);
+    return (it != entries_end && *it == value) ? it : entries_end;
+  }
+
+  size_t count(T value) const { return find(value) == entries_.end() ? 0 : 1; }
+
+  std::pair<iterator, bool> insert(T value) {
+    auto entries_end = entries_.end();
+    auto it = std::lower_bound(entries_.begin(), entries_end, value);
+    if (it != entries_end && *it == value)
+      return std::make_pair(it, false);
+    // If the value is not found |it| is either end() or the next item strictly
+    // greater than |value|. In both cases we want to insert just before that.
+    it = entries_.insert(it, std::move(value));
+    return std::make_pair(it, true);
+  }
+
+  size_t erase(T value) {
+    auto it = find(value);
+    if (it == entries_.end())
+      return 0;
+    entries_.erase(it);
+    return 1;
+  }
+
+  void clear() { entries_.clear(); }
+
+  bool empty() const { return entries_.empty(); }
+  void reserve(size_t n) { entries_.reserve(n); }
+  size_t size() const { return entries_.size(); }
+  const_iterator begin() const { return entries_.begin(); }
+  const_iterator end() const { return entries_.end(); }
+
+ private:
+  std::vector<T> entries_;
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_BASE_FLAT_SET_H_
+// gen_amalgamated begin header: include/perfetto/protozero/scattered_heap_buffer.h
+// gen_amalgamated begin header: include/perfetto/protozero/root_message.h
+// gen_amalgamated begin header: include/perfetto/protozero/message_arena.h
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_PROTOZERO_MESSAGE_ARENA_H_
+#define INCLUDE_PERFETTO_PROTOZERO_MESSAGE_ARENA_H_
+
+#include <stdint.h>
+
+#include <forward_list>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+
+namespace protozero {
+
+class Message;
+
+// Object allocator for fixed-sized protozero::Message objects.
+// It's a simple bump-pointer allocator which leverages the stack-alike
+// usage pattern of protozero nested messages. It avoids hitting the system
+// allocator in most cases, by reusing the same block, and falls back on
+// allocating new blocks only when using deeply nested messages (which are
+// extremely rare).
+// This is used by RootMessage<T> to handle the storage for root-level messages.
+class PERFETTO_EXPORT_COMPONENT MessageArena {
+ public:
+  MessageArena();
+  ~MessageArena();
+
+  // Strictly no copies or moves as this is used to hand out pointers.
+  MessageArena(const MessageArena&) = delete;
+  MessageArena& operator=(const MessageArena&) = delete;
+  MessageArena(MessageArena&&) = delete;
+  MessageArena& operator=(MessageArena&&) = delete;
+
+  // Allocates a new Message object.
+  Message* NewMessage();
+
+  // Deletes the last message allocated. The |msg| argument is used only for
+  // DCHECKs, it MUST be the pointer obtained by the last NewMessage() call.
+  void DeleteLastMessage(Message* msg) {
+    PERFETTO_DCHECK(!blocks_.empty() && blocks_.front().entries > 0);
+    PERFETTO_DCHECK(&blocks_.front().storage[blocks_.front().entries - 1] ==
+                    static_cast<void*>(msg));
+    DeleteLastMessageInternal();
+  }
+
+  // Resets the state of the arena, clearing up all but one block. This is used
+  // to avoid leaking outstanding unfinished sub-messages while recycling the
+  // RootMessage object (this is extremely rare due to the RAII scoped handles
+  // but could happen if some client does some overly clever std::move() trick).
+  void Reset() {
+    PERFETTO_DCHECK(!blocks_.empty());
+    blocks_.resize(1);
+    auto& block = blocks_.front();
+    block.entries = 0;
+    PERFETTO_ASAN_POISON(block.storage, sizeof(block.storage));
+  }
+
+ private:
+  void DeleteLastMessageInternal();
+
+  struct Block {
+    static constexpr size_t kCapacity = 16;
+
+    Block() { PERFETTO_ASAN_POISON(storage, sizeof(storage)); }
+
+    std::aligned_storage<sizeof(Message), alignof(Message)>::type
+        storage[kCapacity];
+    uint32_t entries = 0;  // # Message entries used (<= kCapacity).
+  };
+
+  // blocks are used to hand out pointers and must not be moved. Hence why
+  // std::list rather than std::vector.
+  std::forward_list<Block> blocks_;
+};
+
+}  // namespace protozero
+
+#endif  // INCLUDE_PERFETTO_PROTOZERO_MESSAGE_ARENA_H_
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_PROTOZERO_ROOT_MESSAGE_H_
+#define INCLUDE_PERFETTO_PROTOZERO_ROOT_MESSAGE_H_
+
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message_arena.h"
+
+namespace protozero {
+
+// Helper class to hand out messages using the default MessageArena.
+// Usage:
+// RootMessage<perfetto::protos::zero::MyMessage> msg;
+// msg.Reset(stream_writer);
+// msg.set_foo(...);
+// auto* nested = msg.set_nested();
+template <typename T = Message>
+class RootMessage : public T {
+ public:
+  RootMessage() { T::Reset(nullptr, &root_arena_); }
+
+  // Disallow copy and move.
+  RootMessage(const RootMessage&) = delete;
+  RootMessage& operator=(const RootMessage&) = delete;
+  RootMessage(RootMessage&&) = delete;
+  RootMessage& operator=(RootMessage&&) = delete;
+
+  void Reset(ScatteredStreamWriter* writer) {
+    root_arena_.Reset();
+    Message::Reset(writer, &root_arena_);
+  }
+
+ private:
+  MessageArena root_arena_;
+};
+
+}  // namespace protozero
+
+#endif  // INCLUDE_PERFETTO_PROTOZERO_ROOT_MESSAGE_H_
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_PROTOZERO_SCATTERED_HEAP_BUFFER_H_
+#define INCLUDE_PERFETTO_PROTOZERO_SCATTERED_HEAP_BUFFER_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/root_message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
+
+namespace protozero {
+
+class Message;
+
+class PERFETTO_EXPORT_COMPONENT ScatteredHeapBuffer
+    : public protozero::ScatteredStreamWriter::Delegate {
+ public:
+  class PERFETTO_EXPORT_COMPONENT Slice {
+   public:
+    Slice();
+    explicit Slice(size_t size);
+    Slice(Slice&& slice) noexcept;
+    ~Slice();
+    Slice& operator=(Slice&&);
+
+    inline protozero::ContiguousMemoryRange GetTotalRange() const {
+      return {buffer_.get(), buffer_.get() + size_};
+    }
+
+    inline protozero::ContiguousMemoryRange GetUsedRange() const {
+      return {buffer_.get(), buffer_.get() + size_ - unused_bytes_};
+    }
+
+    uint8_t* start() const { return buffer_.get(); }
+    size_t size() const { return size_; }
+    size_t unused_bytes() const { return unused_bytes_; }
+    void set_unused_bytes(size_t unused_bytes) {
+      PERFETTO_DCHECK(unused_bytes_ <= size_);
+      unused_bytes_ = unused_bytes;
+    }
+
+    void Clear();
+
+   private:
+    std::unique_ptr<uint8_t[]> buffer_;
+    size_t size_;
+    size_t unused_bytes_;
+  };
+
+  ScatteredHeapBuffer(size_t initial_slice_size_bytes = 128,
+                      size_t maximum_slice_size_bytes = 128 * 1024);
+  ~ScatteredHeapBuffer() override;
+
+  // protozero::ScatteredStreamWriter::Delegate implementation.
+  protozero::ContiguousMemoryRange GetNewBuffer() override;
+
+  // Return the slices backing this buffer, adjusted for the number of bytes the
+  // writer has written.
+  const std::vector<Slice>& GetSlices();
+
+  // Stitch all the slices into a single contiguous buffer.
+  std::vector<uint8_t> StitchSlices();
+
+  // Note that the returned ranges point back to this buffer and thus cannot
+  // outlive it.
+  std::vector<protozero::ContiguousMemoryRange> GetRanges();
+
+  // Note that size of the last slice isn't updated to reflect the number of
+  // bytes written by the trace writer.
+  const std::vector<Slice>& slices() const { return slices_; }
+
+  void set_writer(protozero::ScatteredStreamWriter* writer) {
+    writer_ = writer;
+  }
+
+  // Update unused_bytes() of the current |Slice| based on the writer's state.
+  void AdjustUsedSizeOfCurrentSlice();
+
+  // Returns the total size the slices occupy in heap memory (including unused).
+  size_t GetTotalSize();
+
+  // Reset the contents of this buffer but retain one slice allocation (if it
+  // exists) to be reused for future writes.
+  void Reset();
+
+ private:
+  size_t next_slice_size_;
+  const size_t maximum_slice_size_;
+  protozero::ScatteredStreamWriter* writer_ = nullptr;
+  std::vector<Slice> slices_;
+
+  // Used to keep an allocated slice around after this buffer is reset.
+  Slice cached_slice_;
+};
+
+// Helper function to create heap-based protozero messages in one line.
+// Useful when manually serializing a protozero message (primarily in
+// tests/utilities). So instead of the following:
+//   protozero::MyMessage msg;
+//   protozero::ScatteredHeapBuffer shb;
+//   protozero::ScatteredStreamWriter writer(&shb);
+//   shb.set_writer(&writer);
+//   msg.Reset(&writer);
+//   ...
+// You can write:
+//   protozero::HeapBuffered<protozero::MyMessage> msg;
+//   msg->set_stuff(...);
+//   msg.SerializeAsString();
+template <typename T = ::protozero::Message>
+class HeapBuffered {
+ public:
+  HeapBuffered() : HeapBuffered(4096, 4096) {}
+  HeapBuffered(size_t initial_slice_size_bytes, size_t maximum_slice_size_bytes)
+      : shb_(initial_slice_size_bytes, maximum_slice_size_bytes),
+        writer_(&shb_) {
+    shb_.set_writer(&writer_);
+    msg_.Reset(&writer_);
+  }
+
+  // This can't be neither copied nor moved because Message hands out pointers
+  // to itself when creating submessages.
+  HeapBuffered(const HeapBuffered&) = delete;
+  HeapBuffered& operator=(const HeapBuffered&) = delete;
+  HeapBuffered(HeapBuffered&&) = delete;
+  HeapBuffered& operator=(HeapBuffered&&) = delete;
+
+  T* get() { return &msg_; }
+  T* operator->() { return &msg_; }
+
+  bool empty() const { return shb_.slices().empty(); }
+
+  std::vector<uint8_t> SerializeAsArray() {
+    msg_.Finalize();
+    return shb_.StitchSlices();
+  }
+
+  std::string SerializeAsString() {
+    auto vec = SerializeAsArray();
+    return std::string(reinterpret_cast<const char*>(vec.data()), vec.size());
+  }
+
+  std::vector<protozero::ContiguousMemoryRange> GetRanges() {
+    msg_.Finalize();
+    return shb_.GetRanges();
+  }
+
+  const std::vector<ScatteredHeapBuffer::Slice>& GetSlices() {
+    msg_.Finalize();
+    return shb_.GetSlices();
+  }
+
+  void Reset() {
+    shb_.Reset();
+    writer_.Reset(protozero::ContiguousMemoryRange{});
+    msg_.Reset(&writer_);
+    PERFETTO_DCHECK(empty());
+  }
+
+ private:
+  ScatteredHeapBuffer shb_;
+  ScatteredStreamWriter writer_;
+  RootMessage<T> msg_;
+};
+
+}  // namespace protozero
+
+#endif  // INCLUDE_PERFETTO_PROTOZERO_SCATTERED_HEAP_BUFFER_H_
+// gen_amalgamated begin header: include/perfetto/tracing/debug_annotation.h
+// gen_amalgamated begin header: include/perfetto/tracing/traced_value_forward.h
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_TRACED_VALUE_FORWARD_H_
+#define INCLUDE_PERFETTO_TRACING_TRACED_VALUE_FORWARD_H_
+
+namespace perfetto {
+
+class TracedValue;
+class TracedArray;
+class TracedDictionary;
+template <typename MessageType>
+class TracedProto;
+
+template <typename T>
+void WriteIntoTracedValue(TracedValue context, T&& value);
+template <typename MessageType, typename T>
+void WriteIntoTracedProto(TracedProto<MessageType> context, T&& value);
+
+template <typename T, class = void>
+struct TraceFormatTraits;
+
+// Helpers to check whether a given type T can be written into a TracedValue /
+// TracedProto<MessageType>.
+//
+// Intended to be used for types like smart pointers, who should support
+// WriteIntoTrace only iff their inner type supports being written into
+// a TracedValue.
+//
+// template <typename T>
+// class SmartPtr {
+//   ...
+//
+//   // Note: |Check| is needed to ensure that using
+//   SmartPtr<ClassWhichDoesNotSupportTracedValue> does not generate a
+//   compilation error.
+//
+//   template <typename Check=void>
+//   typename check_traced_value_support<T, Check>::value
+//   WriteIntoTrace(perfetto::TracedValue context) const {
+//      WriteIntoTracedValue(std::move(context), *ptr_);
+//   }
+//
+//   template <typename MessageType>
+//   typename check_traced_value_support<T, MessageType>::value
+//   WriteIntoTrace(perfetto::TracedProto<MessageType> message) const {
+//      WriteIntoTracedProto(std::move(message), *ptr_);
+//   }
+// };
+template <typename T, typename ResultType = void, typename = void>
+struct check_traced_value_support;
+
+template <typename MessageType,
+          typename T,
+          typename ResultType = void,
+          typename = void>
+struct check_traced_proto_support;
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_TRACED_VALUE_FORWARD_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/debug_annotation.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_DEBUG_ANNOTATION_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_DEBUG_ANNOTATION_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class DebugAnnotation;
+class DebugAnnotation_NestedValue;
+namespace perfetto_pbzero_enum_DebugAnnotation_NestedValue {
+enum NestedType : int32_t;
+}  // namespace perfetto_pbzero_enum_DebugAnnotation_NestedValue
+using DebugAnnotation_NestedValue_NestedType = perfetto_pbzero_enum_DebugAnnotation_NestedValue::NestedType;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_DebugAnnotation_NestedValue {
+enum NestedType : int32_t {
+  UNSPECIFIED = 0,
+  DICT = 1,
+  ARRAY = 2,
+};
+} // namespace perfetto_pbzero_enum_DebugAnnotation_NestedValue
+using DebugAnnotation_NestedValue_NestedType = perfetto_pbzero_enum_DebugAnnotation_NestedValue::NestedType;
+
+
+constexpr DebugAnnotation_NestedValue_NestedType DebugAnnotation_NestedValue_NestedType_MIN = DebugAnnotation_NestedValue_NestedType::UNSPECIFIED;
+constexpr DebugAnnotation_NestedValue_NestedType DebugAnnotation_NestedValue_NestedType_MAX = DebugAnnotation_NestedValue_NestedType::ARRAY;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* DebugAnnotation_NestedValue_NestedType_Name(::perfetto::protos::pbzero::DebugAnnotation_NestedValue_NestedType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::DebugAnnotation_NestedValue_NestedType::UNSPECIFIED:
+    return "UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::DebugAnnotation_NestedValue_NestedType::DICT:
+    return "DICT";
+
+  case ::perfetto::protos::pbzero::DebugAnnotation_NestedValue_NestedType::ARRAY:
+    return "ARRAY";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class DebugAnnotationValueTypeName_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DebugAnnotationValueTypeName_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DebugAnnotationValueTypeName_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DebugAnnotationValueTypeName_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+};
+
+class DebugAnnotationValueTypeName : public ::protozero::Message {
+ public:
+  using Decoder = DebugAnnotationValueTypeName_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kNameFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DebugAnnotationValueTypeName"; }
+
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DebugAnnotationValueTypeName>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DebugAnnotationValueTypeName>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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);
+  }
+};
+
+class DebugAnnotationName_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DebugAnnotationName_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DebugAnnotationName_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DebugAnnotationName_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+};
+
+class DebugAnnotationName : public ::protozero::Message {
+ public:
+  using Decoder = DebugAnnotationName_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kNameFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DebugAnnotationName"; }
+
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DebugAnnotationName>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DebugAnnotationName>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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);
+  }
+};
+
+class DebugAnnotation_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/17, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  DebugAnnotation_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DebugAnnotation_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DebugAnnotation_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name_iid() const { return at<1>().valid(); }
+  uint64_t name_iid() const { return at<1>().as_uint64(); }
+  bool has_name() const { return at<10>().valid(); }
+  ::protozero::ConstChars name() const { return at<10>().as_string(); }
+  bool has_bool_value() const { return at<2>().valid(); }
+  bool bool_value() const { return at<2>().as_bool(); }
+  bool has_uint_value() const { return at<3>().valid(); }
+  uint64_t uint_value() const { return at<3>().as_uint64(); }
+  bool has_int_value() const { return at<4>().valid(); }
+  int64_t int_value() const { return at<4>().as_int64(); }
+  bool has_double_value() const { return at<5>().valid(); }
+  double double_value() const { return at<5>().as_double(); }
+  bool has_pointer_value() const { return at<7>().valid(); }
+  uint64_t pointer_value() const { return at<7>().as_uint64(); }
+  bool has_nested_value() const { return at<8>().valid(); }
+  ::protozero::ConstBytes nested_value() const { return at<8>().as_bytes(); }
+  bool has_legacy_json_value() const { return at<9>().valid(); }
+  ::protozero::ConstChars legacy_json_value() const { return at<9>().as_string(); }
+  bool has_string_value() const { return at<6>().valid(); }
+  ::protozero::ConstChars string_value() const { return at<6>().as_string(); }
+  bool has_string_value_iid() const { return at<17>().valid(); }
+  uint64_t string_value_iid() const { return at<17>().as_uint64(); }
+  bool has_proto_type_name() const { return at<16>().valid(); }
+  ::protozero::ConstChars proto_type_name() const { return at<16>().as_string(); }
+  bool has_proto_type_name_iid() const { return at<13>().valid(); }
+  uint64_t proto_type_name_iid() const { return at<13>().as_uint64(); }
+  bool has_proto_value() const { return at<14>().valid(); }
+  ::protozero::ConstBytes proto_value() const { return at<14>().as_bytes(); }
+  bool has_dict_entries() const { return at<11>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> dict_entries() const { return GetRepeated<::protozero::ConstBytes>(11); }
+  bool has_array_values() const { return at<12>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> array_values() const { return GetRepeated<::protozero::ConstBytes>(12); }
+};
+
+class DebugAnnotation : public ::protozero::Message {
+ public:
+  using Decoder = DebugAnnotation_Decoder;
+  enum : int32_t {
+    kNameIidFieldNumber = 1,
+    kNameFieldNumber = 10,
+    kBoolValueFieldNumber = 2,
+    kUintValueFieldNumber = 3,
+    kIntValueFieldNumber = 4,
+    kDoubleValueFieldNumber = 5,
+    kPointerValueFieldNumber = 7,
+    kNestedValueFieldNumber = 8,
+    kLegacyJsonValueFieldNumber = 9,
+    kStringValueFieldNumber = 6,
+    kStringValueIidFieldNumber = 17,
+    kProtoTypeNameFieldNumber = 16,
+    kProtoTypeNameIidFieldNumber = 13,
+    kProtoValueFieldNumber = 14,
+    kDictEntriesFieldNumber = 11,
+    kArrayValuesFieldNumber = 12,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DebugAnnotation"; }
+
+  using NestedValue = ::perfetto::protos::pbzero::DebugAnnotation_NestedValue;
+
+  using FieldMetadata_NameIid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DebugAnnotation>;
+
+  static constexpr FieldMetadata_NameIid kNameIid{};
+  void set_name_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NameIid::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DebugAnnotation>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_BoolValue =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      DebugAnnotation>;
+
+  static constexpr FieldMetadata_BoolValue kBoolValue{};
+  void set_bool_value(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_BoolValue::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_UintValue =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DebugAnnotation>;
+
+  static constexpr FieldMetadata_UintValue kUintValue{};
+  void set_uint_value(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UintValue::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_IntValue =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      DebugAnnotation>;
+
+  static constexpr FieldMetadata_IntValue kIntValue{};
+  void set_int_value(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IntValue::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_DoubleValue =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      DebugAnnotation>;
+
+  static constexpr FieldMetadata_DoubleValue kDoubleValue{};
+  void set_double_value(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_DoubleValue::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);
+  }
+
+  using FieldMetadata_PointerValue =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DebugAnnotation>;
+
+  static constexpr FieldMetadata_PointerValue kPointerValue{};
+  void set_pointer_value(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PointerValue::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_NestedValue =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DebugAnnotation_NestedValue,
+      DebugAnnotation>;
+
+  static constexpr FieldMetadata_NestedValue kNestedValue{};
+  template <typename T = DebugAnnotation_NestedValue> T* set_nested_value() {
+    return BeginNestedMessage<T>(8);
+  }
+
+
+  using FieldMetadata_LegacyJsonValue =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DebugAnnotation>;
+
+  static constexpr FieldMetadata_LegacyJsonValue kLegacyJsonValue{};
+  void set_legacy_json_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_LegacyJsonValue::kFieldId, data, size);
+  }
+  void set_legacy_json_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_LegacyJsonValue::kFieldId, chars.data, chars.size);
+  }
+  void set_legacy_json_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_LegacyJsonValue::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_StringValue =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DebugAnnotation>;
+
+  static constexpr FieldMetadata_StringValue kStringValue{};
+  void set_string_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_StringValue::kFieldId, data, size);
+  }
+  void set_string_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_StringValue::kFieldId, chars.data, chars.size);
+  }
+  void set_string_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_StringValue::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_StringValueIid =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DebugAnnotation>;
+
+  static constexpr FieldMetadata_StringValueIid kStringValueIid{};
+  void set_string_value_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StringValueIid::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_ProtoTypeName =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DebugAnnotation>;
+
+  static constexpr FieldMetadata_ProtoTypeName kProtoTypeName{};
+  void set_proto_type_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ProtoTypeName::kFieldId, data, size);
+  }
+  void set_proto_type_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ProtoTypeName::kFieldId, chars.data, chars.size);
+  }
+  void set_proto_type_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProtoTypeName::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_ProtoTypeNameIid =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DebugAnnotation>;
+
+  static constexpr FieldMetadata_ProtoTypeNameIid kProtoTypeNameIid{};
+  void set_proto_type_name_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProtoTypeNameIid::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_ProtoValue =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      DebugAnnotation>;
+
+  static constexpr FieldMetadata_ProtoValue kProtoValue{};
+  void set_proto_value(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_ProtoValue::kFieldId, data, size);
+  }
+  void set_proto_value(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_ProtoValue::kFieldId, bytes.data, bytes.size);
+  }
+  void set_proto_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProtoValue::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);
+  }
+
+  using FieldMetadata_DictEntries =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DebugAnnotation,
+      DebugAnnotation>;
+
+  static constexpr FieldMetadata_DictEntries kDictEntries{};
+  template <typename T = DebugAnnotation> T* add_dict_entries() {
+    return BeginNestedMessage<T>(11);
+  }
+
+
+  using FieldMetadata_ArrayValues =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DebugAnnotation,
+      DebugAnnotation>;
+
+  static constexpr FieldMetadata_ArrayValues kArrayValues{};
+  template <typename T = DebugAnnotation> T* add_array_values() {
+    return BeginNestedMessage<T>(12);
+  }
+
+};
+
+class DebugAnnotation_NestedValue_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  DebugAnnotation_NestedValue_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DebugAnnotation_NestedValue_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DebugAnnotation_NestedValue_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_nested_type() const { return at<1>().valid(); }
+  int32_t nested_type() const { return at<1>().as_int32(); }
+  bool has_dict_keys() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> dict_keys() const { return GetRepeated<::protozero::ConstChars>(2); }
+  bool has_dict_values() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> dict_values() const { return GetRepeated<::protozero::ConstBytes>(3); }
+  bool has_array_values() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> array_values() const { return GetRepeated<::protozero::ConstBytes>(4); }
+  bool has_int_value() const { return at<5>().valid(); }
+  int64_t int_value() const { return at<5>().as_int64(); }
+  bool has_double_value() const { return at<6>().valid(); }
+  double double_value() const { return at<6>().as_double(); }
+  bool has_bool_value() const { return at<7>().valid(); }
+  bool bool_value() const { return at<7>().as_bool(); }
+  bool has_string_value() const { return at<8>().valid(); }
+  ::protozero::ConstChars string_value() const { return at<8>().as_string(); }
+};
+
+class DebugAnnotation_NestedValue : public ::protozero::Message {
+ public:
+  using Decoder = DebugAnnotation_NestedValue_Decoder;
+  enum : int32_t {
+    kNestedTypeFieldNumber = 1,
+    kDictKeysFieldNumber = 2,
+    kDictValuesFieldNumber = 3,
+    kArrayValuesFieldNumber = 4,
+    kIntValueFieldNumber = 5,
+    kDoubleValueFieldNumber = 6,
+    kBoolValueFieldNumber = 7,
+    kStringValueFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DebugAnnotation.NestedValue"; }
+
+
+  using NestedType = ::perfetto::protos::pbzero::DebugAnnotation_NestedValue_NestedType;
+  static inline const char* NestedType_Name(NestedType value) {
+    return ::perfetto::protos::pbzero::DebugAnnotation_NestedValue_NestedType_Name(value);
+  }
+  static inline const NestedType UNSPECIFIED = NestedType::UNSPECIFIED;
+  static inline const NestedType DICT = NestedType::DICT;
+  static inline const NestedType ARRAY = NestedType::ARRAY;
+
+  using FieldMetadata_NestedType =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      DebugAnnotation_NestedValue_NestedType,
+      DebugAnnotation_NestedValue>;
+
+  static constexpr FieldMetadata_NestedType kNestedType{};
+  void set_nested_type(DebugAnnotation_NestedValue_NestedType value) {
+    static constexpr uint32_t field_id = FieldMetadata_NestedType::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_DictKeys =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DebugAnnotation_NestedValue>;
+
+  static constexpr FieldMetadata_DictKeys kDictKeys{};
+  void add_dict_keys(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DictKeys::kFieldId, data, size);
+  }
+  void add_dict_keys(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_DictKeys::kFieldId, chars.data, chars.size);
+  }
+  void add_dict_keys(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_DictKeys::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_DictValues =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DebugAnnotation_NestedValue,
+      DebugAnnotation_NestedValue>;
+
+  static constexpr FieldMetadata_DictValues kDictValues{};
+  template <typename T = DebugAnnotation_NestedValue> T* add_dict_values() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_ArrayValues =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DebugAnnotation_NestedValue,
+      DebugAnnotation_NestedValue>;
+
+  static constexpr FieldMetadata_ArrayValues kArrayValues{};
+  template <typename T = DebugAnnotation_NestedValue> T* add_array_values() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_IntValue =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      DebugAnnotation_NestedValue>;
+
+  static constexpr FieldMetadata_IntValue kIntValue{};
+  void set_int_value(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IntValue::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_DoubleValue =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      DebugAnnotation_NestedValue>;
+
+  static constexpr FieldMetadata_DoubleValue kDoubleValue{};
+  void set_double_value(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_DoubleValue::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);
+  }
+
+  using FieldMetadata_BoolValue =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      DebugAnnotation_NestedValue>;
+
+  static constexpr FieldMetadata_BoolValue kBoolValue{};
+  void set_bool_value(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_BoolValue::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_StringValue =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DebugAnnotation_NestedValue>;
+
+  static constexpr FieldMetadata_StringValue kStringValue{};
+  void set_string_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_StringValue::kFieldId, data, size);
+  }
+  void set_string_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_StringValue::kFieldId, chars.data, chars.size);
+  }
+  void set_string_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_StringValue::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_DEBUG_ANNOTATION_H_
+#define INCLUDE_PERFETTO_TRACING_DEBUG_ANNOTATION_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/traced_value_forward.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
+
+#include <stdint.h>
+
+#include <memory>
+#include <string>
+
+namespace {
+// std::underlying_type can't be used with non-enum types, so we need this
+// indirection.
+template <typename T, bool = std::is_enum<T>::value>
+struct safe_underlying_type {
+  using type = typename std::underlying_type<T>::type;
+};
+
+template <typename T>
+struct safe_underlying_type<T, false> {
+  using type = T;
+};
+}  // namespace
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class DebugAnnotation;
+}  // namespace pbzero
+}  // namespace protos
+
+// A base class for custom track event debug annotations.
+class PERFETTO_EXPORT_COMPONENT DebugAnnotation {
+ public:
+  DebugAnnotation() = default;
+  virtual ~DebugAnnotation();
+
+  // Called to write the contents of the debug annotation into the trace.
+  virtual void Add(protos::pbzero::DebugAnnotation*) const = 0;
+
+  void WriteIntoTracedValue(TracedValue context) const;
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_DEBUG_ANNOTATION_H_
+// gen_amalgamated begin header: include/perfetto/tracing/traced_value.h
+// gen_amalgamated begin header: include/perfetto/tracing/internal/checked_scope.h
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_CHECKED_SCOPE_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_CHECKED_SCOPE_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+
+namespace perfetto {
+namespace internal {
+
+#if PERFETTO_DCHECK_IS_ON()
+
+// Checker to ensure that despite multiple scopes being present, only the active
+// one is being accessed. Rules:
+// - Only an active scope can create inner scopes. When this happens, it stops
+// being active and the inner scope becomes active instead.
+// - Only an active scope can be destroyed. When this happens, its parent scope
+// becomes active.
+class PERFETTO_EXPORT_COMPONENT CheckedScope {
+ public:
+  explicit CheckedScope(CheckedScope* parent_scope);
+  ~CheckedScope();
+  CheckedScope(CheckedScope&&);
+  CheckedScope& operator=(CheckedScope&&);
+  CheckedScope(const CheckedScope&) = delete;
+  CheckedScope& operator=(const CheckedScope&) = delete;
+
+  void Reset();
+
+  CheckedScope* parent_scope() const { return parent_scope_; }
+  bool is_active() const { return is_active_; }
+
+ private:
+  void set_is_active(bool is_active) { is_active_ = is_active; }
+
+  bool is_active_ = true;
+  CheckedScope* parent_scope_;
+
+  bool deleted_ = false;
+};
+
+#else
+
+// Dummy for cases when DCHECK is not enabled. Methods are marked constexpr to
+// ensure that the compiler can inline and optimise them away.
+class CheckedScope {
+ public:
+  inline explicit CheckedScope(CheckedScope*) {}
+  inline ~CheckedScope() {}
+
+  CheckedScope(const CheckedScope&) = delete;
+  CheckedScope& operator=(const CheckedScope&) = delete;
+
+  CheckedScope(CheckedScope&&) = default;
+  CheckedScope& operator=(CheckedScope&&) = default;
+
+  inline void Reset() {}
+
+  inline CheckedScope* parent_scope() const { return nullptr; }
+  inline bool is_active() const { return true; }
+};
+
+#endif  // PERFETTO_DCHECK_IS_ON()
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_CHECKED_SCOPE_H_
+// gen_amalgamated begin header: include/perfetto/tracing/string_helpers.h
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_STRING_HELPERS_H_
+#define INCLUDE_PERFETTO_TRACING_STRING_HELPERS_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+
+#include <cstddef>
+#include <string>
+
+namespace perfetto {
+
+// A wrapper for marking strings that can't be determined to be static at build
+// time, but are in fact static.
+class PERFETTO_EXPORT_COMPONENT StaticString {
+ public:
+  // Implicit constructor for string literals.
+  template <size_t N>
+  constexpr StaticString(const char (&str)[N]) : value(str) {}
+
+  // Implicit constructor for null strings.
+  constexpr StaticString(std::nullptr_t) : value(nullptr) {}
+
+  constexpr explicit StaticString(const char* str) : value(str) {}
+
+  const char* value;
+};
+
+// A explicit wrapper for marking strings as dynamic to ensure that perfetto
+// doesn't try to cache the pointer value.
+class PERFETTO_EXPORT_COMPONENT DynamicString {
+ public:
+  explicit DynamicString(const std::string& str)
+      : value(str.data()), length(str.length()) {}
+  explicit DynamicString(const char* str) : value(str) {
+    PERFETTO_DCHECK(str);
+    length = strlen(str);
+  }
+  DynamicString(const char* str, size_t len) : value(str), length(len) {}
+
+  const char* value;
+  size_t length;
+};
+
+namespace internal {
+
+template <size_t N>
+constexpr const char* GetStaticString(const char (&string)[N]) {
+  return string;
+}
+
+constexpr std::nullptr_t GetStaticString(std::nullptr_t) {
+  return nullptr;
+}
+
+constexpr const char* GetStaticString(perfetto::StaticString string) {
+  return string.value;
+}
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_STRING_HELPERS_H_
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_TRACED_VALUE_H_
+#define INCLUDE_PERFETTO_TRACING_TRACED_VALUE_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/template_util.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/checked_scope.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/string_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/traced_value_forward.h"
+
+#include <memory>
+#include <string>
+#include <string_view>
+#include <type_traits>
+#include <utility>
+
+namespace perfetto {
+
+namespace protos {
+namespace pbzero {
+class DebugAnnotation;
+}
+}  // namespace protos
+
+class DebugAnnotation;
+class EventContext;
+
+// These classes provide a JSON-inspired way to write structed data into traces.
+//
+// Each TracedValue can be consumed exactly once to write a value into a trace
+// using one of the Write* methods.
+//
+// Write* methods fall into two categories:
+// - Primitive types (int, string, bool, double, etc): they just write the
+//   provided value, consuming the TracedValue in the process.
+// - Complex types (arrays and dicts): they consume the TracedValue and
+//   return a corresponding scoped object (TracedArray or TracedDictionary).
+//   This scope then can be used to write multiple items into the container:
+//   TracedArray::AppendItem and TracedDictionary::AddItem return a new
+//   TracedValue which then can be used to write an element of the
+//   dictionary or array.
+//
+// To define how a custom class should be written into the trace, users should
+// define one of the two following functions:
+// - Foo::WriteIntoTrace(TracedValue) const
+//   (preferred for code which depends on perfetto directly)
+// - perfetto::TraceFormatTraits<T>::WriteIntoTrace(
+//       TracedValue, const T&);
+//   (should be used if T is defined in a library which doesn't know anything
+//   about tracing).
+//
+//
+// After defining a conversion method, the object can be used directly as a
+// TRACE_EVENT argument:
+//
+// Foo foo;
+// TRACE_EVENT("cat", "Event", "arg", foo);
+//
+// Examples:
+//
+// TRACE_EVENT("cat", "event", "params", [&](perfetto::TracedValue context)
+// {
+//   auto dict = std::move(context).WriteDictionary();
+//   dict->Add("param1", param1);
+//   dict->Add("param2", param2);
+//   ...
+//   dict->Add("paramN", paramN);
+//
+//   {
+//     auto inner_array = dict->AddArray("inner");
+//     inner_array->Append(value1);
+//     inner_array->Append(value2);
+//   }
+// });
+//
+// template <typename T>
+// TraceFormatTraits<std::optional<T>>::WriteIntoTrace(
+//    TracedValue context, const std::optional<T>& value) {
+//  if (!value) {
+//    std::move(context).WritePointer(nullptr);
+//    return;
+//  }
+//  perfetto::WriteIntoTrace(std::move(context), *value);
+// }
+//
+// template <typename T>
+// TraceFormatTraits<std::vector<T>>::WriteIntoTrace(
+//    TracedValue context, const std::array<T>& value) {
+//  auto array = std::move(context).WriteArray();
+//  for (const auto& item: value) {
+//    array_scope.Append(item);
+//  }
+// }
+//
+// class Foo {
+//   void WriteIntoTrace(TracedValue context) const {
+//     auto dict = std::move(context).WriteDictionary();
+//     dict->Set("key", 42);
+//     dict->Set("foo", "bar");
+//     dict->Set("member", member_);
+//   }
+// }
+namespace internal {
+// TODO(altimin): Currently EventContext can be null due the need to support
+// TracedValue-based serialisation with the Chrome's TraceLog. After this is
+// gone, the second parameter should be changed to EventContext&.
+PERFETTO_EXPORT_COMPONENT TracedValue
+CreateTracedValueFromProto(protos::pbzero::DebugAnnotation*,
+                           EventContext* = nullptr);
+}
+
+class PERFETTO_EXPORT_COMPONENT TracedValue {
+ public:
+  TracedValue(const TracedValue&) = delete;
+  TracedValue& operator=(const TracedValue&) = delete;
+  TracedValue& operator=(TracedValue&&) = delete;
+  TracedValue(TracedValue&&);
+  ~TracedValue();
+
+  // TracedValue represents a context into which a single value can be written
+  // (either by writing it directly for primitive types, or by creating a
+  // TracedArray or TracedDictionary for the complex types). This is enforced
+  // by allowing Write* methods to be called only on rvalue references.
+
+  void WriteInt64(int64_t value) &&;
+  void WriteUInt64(uint64_t value) &&;
+  void WriteDouble(double value) &&;
+  void WriteBoolean(bool value) &&;
+  void WriteString(const char*) &&;
+  void WriteString(const char*, size_t len) &&;
+  void WriteString(const std::string&) &&;
+  void WriteString(std::string_view) &&;
+  void WritePointer(const void* value) &&;
+  template <typename MessageType>
+  TracedProto<MessageType> WriteProto() &&;
+
+  // Rules for writing nested dictionaries and arrays:
+  // - Only one scope (TracedArray, TracedDictionary or TracedValue) can be
+  // active at the same time. It's only allowed to call methods on the active
+  // scope.
+  // - When a scope creates a nested scope, the new scope becomes active.
+  // - When a scope is destroyed, its parent scope becomes active again.
+  //
+  // Typically users will have to create a scope only at the beginning of a
+  // conversion function and this scope should be destroyed at the end of it.
+  // TracedArray::Append and TracedDictionary::Add create, write and complete
+  // inner scopes automatically.
+
+  // Scope which allows multiple values to be appended.
+  TracedArray WriteArray() && PERFETTO_WARN_UNUSED_RESULT;
+
+  // Scope which allows multiple key-value pairs to be added.
+  TracedDictionary WriteDictionary() && PERFETTO_WARN_UNUSED_RESULT;
+
+ private:
+  friend class TracedArray;
+  friend class TracedDictionary;
+  friend TracedValue internal::CreateTracedValueFromProto(
+      protos::pbzero::DebugAnnotation*,
+      EventContext*);
+
+  static TracedValue CreateFromProto(protos::pbzero::DebugAnnotation* proto,
+                                     EventContext* event_context = nullptr);
+
+  inline TracedValue(protos::pbzero::DebugAnnotation* annotation,
+                     EventContext* event_context,
+                     internal::CheckedScope* parent_scope)
+      : annotation_(annotation),
+        event_context_(event_context),
+        checked_scope_(parent_scope) {}
+
+  protozero::Message* WriteProtoInternal(const char* name);
+
+  // Temporary support for perfetto::DebugAnnotation C++ class before it's going
+  // to be replaced by TracedValue.
+  // TODO(altimin): Convert v8 to use TracedValue directly and delete it.
+  friend class DebugAnnotation;
+
+  protos::pbzero::DebugAnnotation* const annotation_ = nullptr;
+  EventContext* const event_context_ = nullptr;
+
+  internal::CheckedScope checked_scope_;
+};
+
+template <typename MessageType>
+TracedProto<MessageType> TracedValue::WriteProto() && {
+  return TracedProto<MessageType>(
+      static_cast<MessageType*>(WriteProtoInternal(MessageType::GetName())),
+      event_context_);
+}
+
+class PERFETTO_EXPORT_COMPONENT TracedArray {
+ public:
+  // implicit
+  TracedArray(TracedValue);
+
+  TracedArray(const TracedArray&) = delete;
+  TracedArray& operator=(const TracedArray&) = delete;
+  TracedArray& operator=(TracedArray&&) = delete;
+  TracedArray(TracedArray&&) = default;
+  ~TracedArray() = default;
+
+  TracedValue AppendItem();
+
+  template <typename T>
+  void Append(T&& value) {
+    WriteIntoTracedValue(AppendItem(), std::forward<T>(value));
+  }
+
+  TracedDictionary AppendDictionary() PERFETTO_WARN_UNUSED_RESULT;
+  TracedArray AppendArray();
+
+ private:
+  friend class TracedValue;
+
+  inline TracedArray(protos::pbzero::DebugAnnotation* annotation,
+                     EventContext* event_context,
+                     internal::CheckedScope* parent_scope)
+      : annotation_(annotation),
+        event_context_(event_context),
+        checked_scope_(parent_scope) {}
+
+  protos::pbzero::DebugAnnotation* annotation_;
+  EventContext* const event_context_;
+
+  internal::CheckedScope checked_scope_;
+};
+
+class PERFETTO_EXPORT_COMPONENT TracedDictionary {
+ public:
+  // implicit
+  TracedDictionary(TracedValue);
+
+  TracedDictionary(const TracedDictionary&) = delete;
+  TracedDictionary& operator=(const TracedDictionary&) = delete;
+  TracedDictionary& operator=(TracedDictionary&&) = delete;
+  TracedDictionary(TracedDictionary&&) = default;
+  ~TracedDictionary() = default;
+
+  // There are two paths for writing dictionary keys: fast path for writing
+  // compile-time const, whose pointer is remains valid during the entire
+  // runtime of the program and the slow path for dynamic strings, which need to
+  // be copied.
+  // In the most common case, a string literal can be passed to `Add`/`AddItem`.
+  // In other cases, either StaticString or DynamicString declarations are
+  // needed.
+
+  TracedValue AddItem(StaticString key);
+  TracedValue AddItem(DynamicString key);
+
+  template <typename T>
+  void Add(StaticString key, T&& value) {
+    WriteIntoTracedValue(AddItem(key), std::forward<T>(value));
+  }
+
+  template <typename T>
+  void Add(DynamicString key, T&& value) {
+    WriteIntoTracedValue(AddItem(key), std::forward<T>(value));
+  }
+
+  TracedDictionary AddDictionary(StaticString key);
+  TracedDictionary AddDictionary(DynamicString key);
+  TracedArray AddArray(StaticString key);
+  TracedArray AddArray(DynamicString key);
+
+ private:
+  friend class TracedValue;
+  template <typename T>
+  friend class TracedProto;
+
+  // Create a |TracedDictionary| which will populate the given field of the
+  // given |message|.
+  template <typename MessageType, typename FieldMetadata>
+  inline TracedDictionary(MessageType* message,
+                          FieldMetadata,
+                          EventContext* event_context,
+                          internal::CheckedScope* parent_scope)
+      : message_(message),
+        field_id_(FieldMetadata::kFieldId),
+        event_context_(event_context),
+        checked_scope_(parent_scope) {
+    static_assert(std::is_base_of<protozero::Message, MessageType>::value,
+                  "Message should be a subclass of protozero::Message");
+    static_assert(std::is_base_of<protozero::proto_utils::FieldMetadataBase,
+                                  FieldMetadata>::value,
+                  "FieldMetadata should be a subclass of FieldMetadataBase");
+    static_assert(
+        std::is_same<typename FieldMetadata::message_type, MessageType>::value,
+        "Field does not belong to this message");
+    static_assert(
+        std::is_same<typename FieldMetadata::cpp_field_type,
+                     ::perfetto::protos::pbzero::DebugAnnotation>::value,
+        "Field should be of DebugAnnotation type");
+    static_assert(
+        FieldMetadata::kRepetitionType ==
+            protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+        "Field should be non-packed repeated");
+  }
+
+  protozero::Message* const message_;
+  const uint32_t field_id_;
+  EventContext* event_context_;
+
+  internal::CheckedScope checked_scope_;
+};
+
+namespace internal {
+
+// SFINAE helpers for finding a right overload to convert a given class to
+// trace-friendly form, ordered from most to least preferred.
+
+constexpr int kMaxWriteImplPriority = 4;
+
+// If T has WriteIntoTracedValue member function, call it.
+template <typename T>
+decltype(std::declval<T>().WriteIntoTracedValue(std::declval<TracedValue>()),
+         void())
+WriteImpl(base::priority_tag<4>, TracedValue context, T&& value) {
+  value.WriteIntoTracedValue(std::move(context));
+}
+
+// If T has WriteIntoTrace member function, call it.
+template <typename T>
+decltype(std::declval<T>().WriteIntoTrace(std::declval<TracedValue>()), void())
+WriteImpl(base::priority_tag<4>, TracedValue context, T&& value) {
+  value.WriteIntoTrace(std::move(context));
+}
+
+// If perfetto::TraceFormatTraits<T>::WriteIntoTracedValue(TracedValue, const
+// T&) is available, use it.
+template <typename T>
+decltype(TraceFormatTraits<base::remove_cvref_t<T>>::WriteIntoTracedValue(
+             std::declval<TracedValue>(),
+             std::declval<T>()),
+         void())
+WriteImpl(base::priority_tag<3>, TracedValue context, T&& value) {
+  TraceFormatTraits<base::remove_cvref_t<T>>::WriteIntoTracedValue(
+      std::move(context), std::forward<T>(value));
+}
+
+// If perfetto::TraceFormatTraits<T>::WriteIntoTrace(TracedValue, const T&)
+// is available, use it.
+template <typename T>
+decltype(TraceFormatTraits<base::remove_cvref_t<T>>::WriteIntoTrace(
+             std::declval<TracedValue>(),
+             std::declval<T>()),
+         void())
+WriteImpl(base::priority_tag<3>, TracedValue context, T&& value) {
+  TraceFormatTraits<base::remove_cvref_t<T>>::WriteIntoTrace(
+      std::move(context), std::forward<T>(value));
+}
+
+// If T has operator(), which takes TracedValue, use it.
+// Very useful for lambda resolutions.
+template <typename T>
+decltype(std::declval<T>()(std::declval<TracedValue>()), void())
+WriteImpl(base::priority_tag<2>, TracedValue context, T&& value) {
+  std::forward<T>(value)(std::move(context));
+}
+
+// If T is a container and its elements have tracing support, use it.
+//
+// Note: a reference to T should be passed to std::begin, otherwise
+// for non-reference types const T& will be passed to std::begin, losing
+// support for non-const WriteIntoTracedValue methods.
+template <typename T>
+typename check_traced_value_support<
+    decltype(*std::begin(std::declval<T&>()))>::type
+WriteImpl(base::priority_tag<1>, TracedValue context, T&& value) {
+  auto array = std::move(context).WriteArray();
+  for (auto&& item : value) {
+    array.Append(item);
+  }
+}
+
+// std::underlying_type can't be used with non-enum types, so we need this
+// indirection.
+template <typename T, bool = std::is_enum<T>::value>
+struct safe_underlying_type {
+  using type = typename std::underlying_type<T>::type;
+};
+
+template <typename T>
+struct safe_underlying_type<T, false> {
+  using type = T;
+};
+
+template <typename T>
+struct is_incomplete_type {
+  static constexpr bool value = sizeof(T) != 0;
+};
+
+// sizeof is not available for const char[], but it's still not considered to be
+// an incomplete type for our purposes as the size can be determined at runtime
+// due to strings being null-terminated.
+template <>
+struct is_incomplete_type<const char[]> {
+  static constexpr bool value = true;
+};
+
+}  // namespace internal
+
+// Helper template to determine if a given type can be passed to
+// perfetto::WriteIntoTracedValue. These templates will fail to resolve if the
+// class does not have it support, so they are useful in SFINAE and in producing
+// helpful compiler results.
+template <typename T, class Result = void>
+using check_traced_value_support_t = decltype(
+    internal::WriteImpl(
+        std::declval<base::priority_tag<internal::kMaxWriteImplPriority>>(),
+        std::declval<TracedValue>(),
+        std::declval<T>()),
+    std::declval<Result>());
+
+// check_traced_value_support<T, V>::type is defined (and equal to V) iff T
+// supports being passed to WriteIntoTracedValue. See the comment in
+// traced_value_forward.h for more details.
+template <typename T, class Result>
+struct check_traced_value_support<T,
+                                  Result,
+                                  check_traced_value_support_t<T, Result>> {
+  static_assert(
+      internal::is_incomplete_type<T>::value,
+      "perfetto::TracedValue should not be used with incomplete types");
+
+  static constexpr bool value = true;
+  using type = Result;
+};
+
+namespace internal {
+
+// Helper class to check if a given type can be passed to
+// perfetto::WriteIntoTracedValue. This template will always resolve (with
+// |value| being set to either true or false depending on presence of the
+// support, so this macro is useful in the situation when you want to e.g. OR
+// the result with some other conditions.
+//
+// In this case, compiler will not give you the full deduction chain, so, for
+// example, use check_traced_value_support for writing positive static_asserts
+// and has_traced_value_support for writing negative.
+template <typename T>
+class has_traced_value_support {
+  using Yes = char[1];
+  using No = char[2];
+
+  template <typename V>
+  static Yes& check_support(check_traced_value_support_t<V, int>);
+  template <typename V>
+  static No& check_support(...);
+
+ public:
+  static constexpr bool value = sizeof(Yes) == sizeof(check_support<T>(0));
+};
+
+}  // namespace internal
+
+template <typename T>
+void WriteIntoTracedValue(TracedValue context, T&& value) {
+  // TODO(altimin): Add a URL to documentation and a list of common failure
+  // patterns.
+  static_assert(
+      internal::has_traced_value_support<T>::value,
+      "The provided type (passed to TRACE_EVENT argument / TracedArray::Append "
+      "/ TracedDictionary::Add) does not support being written in a trace "
+      "format. Please see the comment in traced_value.h for more details.");
+
+  // Should be kept in sync with check_traced_value_support_t!
+  internal::WriteImpl(base::priority_tag<internal::kMaxWriteImplPriority>(),
+                      std::move(context), std::forward<T>(value));
+}
+
+// Helpers to write a given value into TracedValue even if the given type
+// doesn't support conversion (in which case the provided fallback should be
+// used). Useful for automatically generating conversions for autogenerated
+// code, but otherwise shouldn't be used as non-autogenerated code is expected
+// to define WriteIntoTracedValue convertor.
+// See WriteWithFallback test in traced_value_unittest.cc for a concrete
+// example.
+template <typename T>
+typename std::enable_if<internal::has_traced_value_support<T>::value>::type
+WriteIntoTracedValueWithFallback(TracedValue context,
+                                 T&& value,
+                                 const std::string&) {
+  WriteIntoTracedValue(std::move(context), std::forward<T>(value));
+}
+
+template <typename T>
+typename std::enable_if<!internal::has_traced_value_support<T>::value>::type
+WriteIntoTracedValueWithFallback(TracedValue context,
+                                 T&&,
+                                 const std::string& fallback) {
+  std::move(context).WriteString(fallback);
+}
+
+// TraceFormatTraits implementations for primitive types.
+
+// Specialisation for signed integer types (note: it excludes enums, which have
+// their own explicit specialisation).
+template <typename T>
+struct TraceFormatTraits<
+    T,
+    typename std::enable_if<std::is_integral<T>::value &&
+                            !std::is_same<T, bool>::value &&
+                            std::is_signed<T>::value>::type> {
+  inline static void WriteIntoTrace(TracedValue context, T value) {
+    std::move(context).WriteInt64(value);
+  }
+};
+
+// Specialisation for unsigned integer types (note: it excludes enums, which
+// have their own explicit specialisation).
+template <typename T>
+struct TraceFormatTraits<
+    T,
+    typename std::enable_if<std::is_integral<T>::value &&
+                            !std::is_same<T, bool>::value &&
+                            std::is_unsigned<T>::value>::type> {
+  inline static void WriteIntoTrace(TracedValue context, T value) {
+    std::move(context).WriteUInt64(value);
+  }
+};
+
+// Specialisation for bools.
+template <>
+struct TraceFormatTraits<bool> {
+  inline static void WriteIntoTrace(TracedValue context, bool value) {
+    std::move(context).WriteBoolean(value);
+  }
+};
+
+// Specialisation for floating point values.
+template <typename T>
+struct TraceFormatTraits<
+    T,
+    typename std::enable_if<std::is_floating_point<T>::value>::type> {
+  inline static void WriteIntoTrace(TracedValue context, T value) {
+    std::move(context).WriteDouble(static_cast<double>(value));
+  }
+};
+
+// Specialisation for signed enums.
+template <typename T>
+struct TraceFormatTraits<
+    T,
+    typename std::enable_if<
+        std::is_enum<T>::value &&
+        std::is_signed<
+            typename internal::safe_underlying_type<T>::type>::value>::type> {
+  inline static void WriteIntoTrace(TracedValue context, T value) {
+    std::move(context).WriteInt64(static_cast<int64_t>(value));
+  }
+};
+
+// Specialisation for unsigned enums.
+template <typename T>
+struct TraceFormatTraits<
+    T,
+    typename std::enable_if<
+        std::is_enum<T>::value &&
+        std::is_unsigned<
+            typename internal::safe_underlying_type<T>::type>::value>::type> {
+  inline static void WriteIntoTrace(TracedValue context, T value) {
+    std::move(context).WriteUInt64(static_cast<uint64_t>(value));
+  }
+};
+
+// Specialisations for C-style strings.
+template <>
+struct TraceFormatTraits<const char*> {
+  inline static void WriteIntoTrace(TracedValue context, const char* value) {
+    std::move(context).WriteString(value);
+  }
+};
+
+template <>
+struct TraceFormatTraits<char[]> {
+  inline static void WriteIntoTrace(TracedValue context, const char value[]) {
+    std::move(context).WriteString(value);
+  }
+};
+
+template <size_t N>
+struct TraceFormatTraits<char[N]> {
+  inline static void WriteIntoTrace(TracedValue context, const char value[N]) {
+    std::move(context).WriteString(value);
+  }
+};
+
+// Specialization for Perfetto strings.
+template <>
+struct TraceFormatTraits<perfetto::StaticString> {
+  inline static void WriteIntoTrace(TracedValue context,
+                                    perfetto::StaticString str) {
+    std::move(context).WriteString(str.value);
+  }
+};
+
+template <>
+struct TraceFormatTraits<perfetto::DynamicString> {
+  inline static void WriteIntoTrace(TracedValue context,
+                                    perfetto::DynamicString str) {
+    std::move(context).WriteString(str.value, str.length);
+  }
+};
+
+// Specialisation for C++ strings.
+template <>
+struct TraceFormatTraits<std::string> {
+  inline static void WriteIntoTrace(TracedValue context,
+                                    const std::string& value) {
+    std::move(context).WriteString(value);
+  }
+};
+
+// Specialisation for C++ string_views.
+template <>
+struct TraceFormatTraits<std::string_view> {
+  inline static void WriteIntoTrace(TracedValue context,
+                                    std::string_view value) {
+    std::move(context).WriteString(value);
+  }
+};
+
+// Specialisation for (const) void*, which writes the pointer value.
+template <>
+struct TraceFormatTraits<void*> {
+  inline static void WriteIntoTrace(TracedValue context, void* value) {
+    std::move(context).WritePointer(value);
+  }
+};
+
+template <>
+struct TraceFormatTraits<const void*> {
+  inline static void WriteIntoTrace(TracedValue context, const void* value) {
+    std::move(context).WritePointer(value);
+  }
+};
+
+// Specialisation for std::unique_ptr<>, which writes either nullptr or the
+// object it points to.
+template <typename T>
+struct TraceFormatTraits<std::unique_ptr<T>, check_traced_value_support_t<T>> {
+  inline static void WriteIntoTrace(TracedValue context,
+                                    const std::unique_ptr<T>& value) {
+    ::perfetto::WriteIntoTracedValue(std::move(context), value.get());
+  }
+
+  template <typename MessageType>
+  inline static void WriteIntoTrace(TracedProto<MessageType> message,
+                                    const std::unique_ptr<T>& value) {
+    ::perfetto::WriteIntoTracedProto(std::move(message), value.get());
+  }
+};
+
+// Specialisation for raw pointer, which writes either nullptr or the object it
+// points to.
+template <typename T>
+struct TraceFormatTraits<T*, check_traced_value_support_t<T>> {
+  inline static void WriteIntoTrace(TracedValue context, T* value) {
+    if (!value) {
+      std::move(context).WritePointer(nullptr);
+      return;
+    }
+    ::perfetto::WriteIntoTracedValue(std::move(context), *value);
+  }
+
+  template <typename MessageType>
+  inline static void WriteIntoTrace(TracedProto<MessageType> message,
+                                    T* value) {
+    if (!value) {
+      // Start the message, but do not write anything. TraceProcessor will emit
+      // a NULL value.
+      return;
+    }
+
+    ::perfetto::WriteIntoTracedProto(std::move(message), *value);
+  }
+};
+
+// Specialisation for nullptr.
+template <>
+struct TraceFormatTraits<std::nullptr_t> {
+  inline static void WriteIntoTrace(TracedValue context, std::nullptr_t) {
+    std::move(context).WritePointer(nullptr);
+  }
+
+  template <typename MessageType>
+  inline static void WriteIntoTrace(TracedProto<MessageType>, std::nullptr_t) {
+    // Start the message, but do not write anything. TraceProcessor will emit a
+    // NULL value.
+  }
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_TRACED_VALUE_H_
+// gen_amalgamated begin header: include/perfetto/tracing/track.h
+// gen_amalgamated begin header: include/perfetto/tracing/internal/fnv1a.h
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_FNV1A_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_FNV1A_H_
+
+#include <cstddef>
+#include <cstdint>
+
+namespace perfetto {
+namespace internal {
+
+// Constexpr functions to compute a 64-bit hash of the input data. The algorithm
+// used is FNV-1a as it is fast and easy to implement and has relatively few
+// collisions.
+//
+// WARNING: This hash function should not be used for any cryptographic purpose.
+
+static constexpr uint64_t kFnv1a64OffsetBasis = 0xcbf29ce484222325;
+static constexpr uint64_t kFnv1a64Prime = 0x100000001b3;
+
+static constexpr inline uint64_t Fnv1a(const char* s) {
+  uint64_t ret = kFnv1a64OffsetBasis;
+  for (; *s; s++) {
+    ret = ret ^ static_cast<uint8_t>(*s);
+    ret *= kFnv1a64Prime;
+  }
+  return ret;
+}
+
+static constexpr inline uint64_t Fnv1a(const void* data, size_t size) {
+  uint64_t ret = kFnv1a64OffsetBasis;
+  const uint8_t* s = static_cast<const uint8_t*>(data);
+  for (size_t i = 0; i < size; i++) {
+    ret = ret ^ s[i];
+    ret *= kFnv1a64Prime;
+  }
+  return ret;
+}
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_FNV1A_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/counter_descriptor.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_COUNTER_DESCRIPTOR_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_COUNTER_DESCRIPTOR_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class CounterDescriptor;
+enum CounterDescriptor_BuiltinCounterType : int;
+enum CounterDescriptor_Unit : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum CounterDescriptor_BuiltinCounterType : int {
+  CounterDescriptor_BuiltinCounterType_COUNTER_UNSPECIFIED = 0,
+  CounterDescriptor_BuiltinCounterType_COUNTER_THREAD_TIME_NS = 1,
+  CounterDescriptor_BuiltinCounterType_COUNTER_THREAD_INSTRUCTION_COUNT = 2,
+};
+enum CounterDescriptor_Unit : int {
+  CounterDescriptor_Unit_UNIT_UNSPECIFIED = 0,
+  CounterDescriptor_Unit_UNIT_TIME_NS = 1,
+  CounterDescriptor_Unit_UNIT_COUNT = 2,
+  CounterDescriptor_Unit_UNIT_SIZE_BYTES = 3,
+};
+
+class PERFETTO_EXPORT_COMPONENT CounterDescriptor : public ::protozero::CppMessageObj {
+ public:
+  using BuiltinCounterType = CounterDescriptor_BuiltinCounterType;
+  static constexpr auto COUNTER_UNSPECIFIED = CounterDescriptor_BuiltinCounterType_COUNTER_UNSPECIFIED;
+  static constexpr auto COUNTER_THREAD_TIME_NS = CounterDescriptor_BuiltinCounterType_COUNTER_THREAD_TIME_NS;
+  static constexpr auto COUNTER_THREAD_INSTRUCTION_COUNT = CounterDescriptor_BuiltinCounterType_COUNTER_THREAD_INSTRUCTION_COUNT;
+  static constexpr auto BuiltinCounterType_MIN = CounterDescriptor_BuiltinCounterType_COUNTER_UNSPECIFIED;
+  static constexpr auto BuiltinCounterType_MAX = CounterDescriptor_BuiltinCounterType_COUNTER_THREAD_INSTRUCTION_COUNT;
+  using Unit = CounterDescriptor_Unit;
+  static constexpr auto UNIT_UNSPECIFIED = CounterDescriptor_Unit_UNIT_UNSPECIFIED;
+  static constexpr auto UNIT_TIME_NS = CounterDescriptor_Unit_UNIT_TIME_NS;
+  static constexpr auto UNIT_COUNT = CounterDescriptor_Unit_UNIT_COUNT;
+  static constexpr auto UNIT_SIZE_BYTES = CounterDescriptor_Unit_UNIT_SIZE_BYTES;
+  static constexpr auto Unit_MIN = CounterDescriptor_Unit_UNIT_UNSPECIFIED;
+  static constexpr auto Unit_MAX = CounterDescriptor_Unit_UNIT_SIZE_BYTES;
+  enum FieldNumbers {
+    kTypeFieldNumber = 1,
+    kCategoriesFieldNumber = 2,
+    kUnitFieldNumber = 3,
+    kUnitNameFieldNumber = 6,
+    kUnitMultiplierFieldNumber = 4,
+    kIsIncrementalFieldNumber = 5,
+  };
+
+  CounterDescriptor();
+  ~CounterDescriptor() override;
+  CounterDescriptor(CounterDescriptor&&) noexcept;
+  CounterDescriptor& operator=(CounterDescriptor&&);
+  CounterDescriptor(const CounterDescriptor&);
+  CounterDescriptor& operator=(const CounterDescriptor&);
+  bool operator==(const CounterDescriptor&) const;
+  bool operator!=(const CounterDescriptor& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_type() const { return _has_field_[1]; }
+  CounterDescriptor_BuiltinCounterType type() const { return type_; }
+  void set_type(CounterDescriptor_BuiltinCounterType value) { type_ = value; _has_field_.set(1); }
+
+  const std::vector<std::string>& categories() const { return categories_; }
+  std::vector<std::string>* mutable_categories() { return &categories_; }
+  int categories_size() const { return static_cast<int>(categories_.size()); }
+  void clear_categories() { categories_.clear(); }
+  void add_categories(std::string value) { categories_.emplace_back(value); }
+  std::string* add_categories() { categories_.emplace_back(); return &categories_.back(); }
+
+  bool has_unit() const { return _has_field_[3]; }
+  CounterDescriptor_Unit unit() const { return unit_; }
+  void set_unit(CounterDescriptor_Unit value) { unit_ = value; _has_field_.set(3); }
+
+  bool has_unit_name() const { return _has_field_[6]; }
+  const std::string& unit_name() const { return unit_name_; }
+  void set_unit_name(const std::string& value) { unit_name_ = value; _has_field_.set(6); }
+
+  bool has_unit_multiplier() const { return _has_field_[4]; }
+  int64_t unit_multiplier() const { return unit_multiplier_; }
+  void set_unit_multiplier(int64_t value) { unit_multiplier_ = value; _has_field_.set(4); }
+
+  bool has_is_incremental() const { return _has_field_[5]; }
+  bool is_incremental() const { return is_incremental_; }
+  void set_is_incremental(bool value) { is_incremental_ = value; _has_field_.set(5); }
+
+ private:
+  CounterDescriptor_BuiltinCounterType type_{};
+  std::vector<std::string> categories_;
+  CounterDescriptor_Unit unit_{};
+  std::string unit_name_{};
+  int64_t unit_multiplier_{};
+  bool is_incremental_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<7> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_COUNTER_DESCRIPTOR_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/counter_descriptor.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_COUNTER_DESCRIPTOR_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_COUNTER_DESCRIPTOR_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+namespace perfetto_pbzero_enum_CounterDescriptor {
+enum BuiltinCounterType : int32_t;
+}  // namespace perfetto_pbzero_enum_CounterDescriptor
+using CounterDescriptor_BuiltinCounterType = perfetto_pbzero_enum_CounterDescriptor::BuiltinCounterType;
+namespace perfetto_pbzero_enum_CounterDescriptor {
+enum Unit : int32_t;
+}  // namespace perfetto_pbzero_enum_CounterDescriptor
+using CounterDescriptor_Unit = perfetto_pbzero_enum_CounterDescriptor::Unit;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_CounterDescriptor {
+enum BuiltinCounterType : int32_t {
+  COUNTER_UNSPECIFIED = 0,
+  COUNTER_THREAD_TIME_NS = 1,
+  COUNTER_THREAD_INSTRUCTION_COUNT = 2,
+};
+} // namespace perfetto_pbzero_enum_CounterDescriptor
+using CounterDescriptor_BuiltinCounterType = perfetto_pbzero_enum_CounterDescriptor::BuiltinCounterType;
+
+
+constexpr CounterDescriptor_BuiltinCounterType CounterDescriptor_BuiltinCounterType_MIN = CounterDescriptor_BuiltinCounterType::COUNTER_UNSPECIFIED;
+constexpr CounterDescriptor_BuiltinCounterType CounterDescriptor_BuiltinCounterType_MAX = CounterDescriptor_BuiltinCounterType::COUNTER_THREAD_INSTRUCTION_COUNT;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* CounterDescriptor_BuiltinCounterType_Name(::perfetto::protos::pbzero::CounterDescriptor_BuiltinCounterType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::CounterDescriptor_BuiltinCounterType::COUNTER_UNSPECIFIED:
+    return "COUNTER_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::CounterDescriptor_BuiltinCounterType::COUNTER_THREAD_TIME_NS:
+    return "COUNTER_THREAD_TIME_NS";
+
+  case ::perfetto::protos::pbzero::CounterDescriptor_BuiltinCounterType::COUNTER_THREAD_INSTRUCTION_COUNT:
+    return "COUNTER_THREAD_INSTRUCTION_COUNT";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_CounterDescriptor {
+enum Unit : int32_t {
+  UNIT_UNSPECIFIED = 0,
+  UNIT_TIME_NS = 1,
+  UNIT_COUNT = 2,
+  UNIT_SIZE_BYTES = 3,
+};
+} // namespace perfetto_pbzero_enum_CounterDescriptor
+using CounterDescriptor_Unit = perfetto_pbzero_enum_CounterDescriptor::Unit;
+
+
+constexpr CounterDescriptor_Unit CounterDescriptor_Unit_MIN = CounterDescriptor_Unit::UNIT_UNSPECIFIED;
+constexpr CounterDescriptor_Unit CounterDescriptor_Unit_MAX = CounterDescriptor_Unit::UNIT_SIZE_BYTES;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* CounterDescriptor_Unit_Name(::perfetto::protos::pbzero::CounterDescriptor_Unit value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::CounterDescriptor_Unit::UNIT_UNSPECIFIED:
+    return "UNIT_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::CounterDescriptor_Unit::UNIT_TIME_NS:
+    return "UNIT_TIME_NS";
+
+  case ::perfetto::protos::pbzero::CounterDescriptor_Unit::UNIT_COUNT:
+    return "UNIT_COUNT";
+
+  case ::perfetto::protos::pbzero::CounterDescriptor_Unit::UNIT_SIZE_BYTES:
+    return "UNIT_SIZE_BYTES";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class CounterDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  CounterDescriptor_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CounterDescriptor_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CounterDescriptor_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_type() const { return at<1>().valid(); }
+  int32_t type() const { return at<1>().as_int32(); }
+  bool has_categories() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> categories() const { return GetRepeated<::protozero::ConstChars>(2); }
+  bool has_unit() const { return at<3>().valid(); }
+  int32_t unit() const { return at<3>().as_int32(); }
+  bool has_unit_name() const { return at<6>().valid(); }
+  ::protozero::ConstChars unit_name() const { return at<6>().as_string(); }
+  bool has_unit_multiplier() const { return at<4>().valid(); }
+  int64_t unit_multiplier() const { return at<4>().as_int64(); }
+  bool has_is_incremental() const { return at<5>().valid(); }
+  bool is_incremental() const { return at<5>().as_bool(); }
+};
+
+class CounterDescriptor : public ::protozero::Message {
+ public:
+  using Decoder = CounterDescriptor_Decoder;
+  enum : int32_t {
+    kTypeFieldNumber = 1,
+    kCategoriesFieldNumber = 2,
+    kUnitFieldNumber = 3,
+    kUnitNameFieldNumber = 6,
+    kUnitMultiplierFieldNumber = 4,
+    kIsIncrementalFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CounterDescriptor"; }
+
+
+  using BuiltinCounterType = ::perfetto::protos::pbzero::CounterDescriptor_BuiltinCounterType;
+  static inline const char* BuiltinCounterType_Name(BuiltinCounterType value) {
+    return ::perfetto::protos::pbzero::CounterDescriptor_BuiltinCounterType_Name(value);
+  }
+
+  using Unit = ::perfetto::protos::pbzero::CounterDescriptor_Unit;
+  static inline const char* Unit_Name(Unit value) {
+    return ::perfetto::protos::pbzero::CounterDescriptor_Unit_Name(value);
+  }
+  static inline const BuiltinCounterType COUNTER_UNSPECIFIED = BuiltinCounterType::COUNTER_UNSPECIFIED;
+  static inline const BuiltinCounterType COUNTER_THREAD_TIME_NS = BuiltinCounterType::COUNTER_THREAD_TIME_NS;
+  static inline const BuiltinCounterType COUNTER_THREAD_INSTRUCTION_COUNT = BuiltinCounterType::COUNTER_THREAD_INSTRUCTION_COUNT;
+  static inline const Unit UNIT_UNSPECIFIED = Unit::UNIT_UNSPECIFIED;
+  static inline const Unit UNIT_TIME_NS = Unit::UNIT_TIME_NS;
+  static inline const Unit UNIT_COUNT = Unit::UNIT_COUNT;
+  static inline const Unit UNIT_SIZE_BYTES = Unit::UNIT_SIZE_BYTES;
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      CounterDescriptor_BuiltinCounterType,
+      CounterDescriptor>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(CounterDescriptor_BuiltinCounterType value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::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_Categories =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CounterDescriptor>;
+
+  static constexpr FieldMetadata_Categories kCategories{};
+  void add_categories(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Categories::kFieldId, data, size);
+  }
+  void add_categories(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Categories::kFieldId, chars.data, chars.size);
+  }
+  void add_categories(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Categories::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_Unit =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      CounterDescriptor_Unit,
+      CounterDescriptor>;
+
+  static constexpr FieldMetadata_Unit kUnit{};
+  void set_unit(CounterDescriptor_Unit value) {
+    static constexpr uint32_t field_id = FieldMetadata_Unit::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_UnitName =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CounterDescriptor>;
+
+  static constexpr FieldMetadata_UnitName kUnitName{};
+  void set_unit_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_UnitName::kFieldId, data, size);
+  }
+  void set_unit_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_UnitName::kFieldId, chars.data, chars.size);
+  }
+  void set_unit_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_UnitName::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_UnitMultiplier =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      CounterDescriptor>;
+
+  static constexpr FieldMetadata_UnitMultiplier kUnitMultiplier{};
+  void set_unit_multiplier(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UnitMultiplier::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_IsIncremental =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      CounterDescriptor>;
+
+  static constexpr FieldMetadata_IsIncremental kIsIncremental{};
+  void set_is_incremental(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsIncremental::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/track_descriptor.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TRACK_DESCRIPTOR_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TRACK_DESCRIPTOR_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class TrackDescriptor;
+class CounterDescriptor;
+class ChromeThreadDescriptor;
+class ThreadDescriptor;
+class ChromeProcessDescriptor;
+class ProcessDescriptor;
+enum CounterDescriptor_BuiltinCounterType : int;
+enum CounterDescriptor_Unit : int;
+enum ChromeThreadDescriptor_ThreadType : int;
+enum ThreadDescriptor_ChromeThreadType : int;
+enum ChromeProcessDescriptor_ProcessType : int;
+enum ProcessDescriptor_ChromeProcessType : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT TrackDescriptor : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kUuidFieldNumber = 1,
+    kParentUuidFieldNumber = 5,
+    kNameFieldNumber = 2,
+    kProcessFieldNumber = 3,
+    kChromeProcessFieldNumber = 6,
+    kThreadFieldNumber = 4,
+    kChromeThreadFieldNumber = 7,
+    kCounterFieldNumber = 8,
+    kDisallowMergingWithSystemTracksFieldNumber = 9,
+  };
+
+  TrackDescriptor();
+  ~TrackDescriptor() override;
+  TrackDescriptor(TrackDescriptor&&) noexcept;
+  TrackDescriptor& operator=(TrackDescriptor&&);
+  TrackDescriptor(const TrackDescriptor&);
+  TrackDescriptor& operator=(const TrackDescriptor&);
+  bool operator==(const TrackDescriptor&) const;
+  bool operator!=(const TrackDescriptor& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_uuid() const { return _has_field_[1]; }
+  uint64_t uuid() const { return uuid_; }
+  void set_uuid(uint64_t value) { uuid_ = value; _has_field_.set(1); }
+
+  bool has_parent_uuid() const { return _has_field_[5]; }
+  uint64_t parent_uuid() const { return parent_uuid_; }
+  void set_parent_uuid(uint64_t value) { parent_uuid_ = value; _has_field_.set(5); }
+
+  bool has_name() const { return _has_field_[2]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
+
+  bool has_process() const { return _has_field_[3]; }
+  const ProcessDescriptor& process() const { return *process_; }
+  ProcessDescriptor* mutable_process() { _has_field_.set(3); return process_.get(); }
+
+  bool has_chrome_process() const { return _has_field_[6]; }
+  const ChromeProcessDescriptor& chrome_process() const { return *chrome_process_; }
+  ChromeProcessDescriptor* mutable_chrome_process() { _has_field_.set(6); return chrome_process_.get(); }
+
+  bool has_thread() const { return _has_field_[4]; }
+  const ThreadDescriptor& thread() const { return *thread_; }
+  ThreadDescriptor* mutable_thread() { _has_field_.set(4); return thread_.get(); }
+
+  bool has_chrome_thread() const { return _has_field_[7]; }
+  const ChromeThreadDescriptor& chrome_thread() const { return *chrome_thread_; }
+  ChromeThreadDescriptor* mutable_chrome_thread() { _has_field_.set(7); return chrome_thread_.get(); }
+
+  bool has_counter() const { return _has_field_[8]; }
+  const CounterDescriptor& counter() const { return *counter_; }
+  CounterDescriptor* mutable_counter() { _has_field_.set(8); return counter_.get(); }
+
+  bool has_disallow_merging_with_system_tracks() const { return _has_field_[9]; }
+  bool disallow_merging_with_system_tracks() const { return disallow_merging_with_system_tracks_; }
+  void set_disallow_merging_with_system_tracks(bool value) { disallow_merging_with_system_tracks_ = value; _has_field_.set(9); }
+
+ private:
+  uint64_t uuid_{};
+  uint64_t parent_uuid_{};
+  std::string name_{};
+  ::protozero::CopyablePtr<ProcessDescriptor> process_;
+  ::protozero::CopyablePtr<ChromeProcessDescriptor> chrome_process_;
+  ::protozero::CopyablePtr<ThreadDescriptor> thread_;
+  ::protozero::CopyablePtr<ChromeThreadDescriptor> chrome_thread_;
+  ::protozero::CopyablePtr<CounterDescriptor> counter_;
+  bool disallow_merging_with_system_tracks_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<10> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TRACK_DESCRIPTOR_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/track_descriptor.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TRACK_DESCRIPTOR_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TRACK_DESCRIPTOR_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class ChromeProcessDescriptor;
+class ChromeThreadDescriptor;
+class CounterDescriptor;
+class ProcessDescriptor;
+class ThreadDescriptor;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class TrackDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrackDescriptor_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrackDescriptor_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrackDescriptor_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_uuid() const { return at<1>().valid(); }
+  uint64_t uuid() const { return at<1>().as_uint64(); }
+  bool has_parent_uuid() const { return at<5>().valid(); }
+  uint64_t parent_uuid() const { return at<5>().as_uint64(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+  bool has_process() const { return at<3>().valid(); }
+  ::protozero::ConstBytes process() const { return at<3>().as_bytes(); }
+  bool has_chrome_process() const { return at<6>().valid(); }
+  ::protozero::ConstBytes chrome_process() const { return at<6>().as_bytes(); }
+  bool has_thread() const { return at<4>().valid(); }
+  ::protozero::ConstBytes thread() const { return at<4>().as_bytes(); }
+  bool has_chrome_thread() const { return at<7>().valid(); }
+  ::protozero::ConstBytes chrome_thread() const { return at<7>().as_bytes(); }
+  bool has_counter() const { return at<8>().valid(); }
+  ::protozero::ConstBytes counter() const { return at<8>().as_bytes(); }
+  bool has_disallow_merging_with_system_tracks() const { return at<9>().valid(); }
+  bool disallow_merging_with_system_tracks() const { return at<9>().as_bool(); }
+};
+
+class TrackDescriptor : public ::protozero::Message {
+ public:
+  using Decoder = TrackDescriptor_Decoder;
+  enum : int32_t {
+    kUuidFieldNumber = 1,
+    kParentUuidFieldNumber = 5,
+    kNameFieldNumber = 2,
+    kProcessFieldNumber = 3,
+    kChromeProcessFieldNumber = 6,
+    kThreadFieldNumber = 4,
+    kChromeThreadFieldNumber = 7,
+    kCounterFieldNumber = 8,
+    kDisallowMergingWithSystemTracksFieldNumber = 9,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrackDescriptor"; }
+
+
+  using FieldMetadata_Uuid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackDescriptor>;
+
+  static constexpr FieldMetadata_Uuid kUuid{};
+  void set_uuid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Uuid::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_ParentUuid =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackDescriptor>;
+
+  static constexpr FieldMetadata_ParentUuid kParentUuid{};
+  void set_parent_uuid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ParentUuid::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrackDescriptor>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Process =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProcessDescriptor,
+      TrackDescriptor>;
+
+  static constexpr FieldMetadata_Process kProcess{};
+  template <typename T = ProcessDescriptor> T* set_process() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_ChromeProcess =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeProcessDescriptor,
+      TrackDescriptor>;
+
+  static constexpr FieldMetadata_ChromeProcess kChromeProcess{};
+  template <typename T = ChromeProcessDescriptor> T* set_chrome_process() {
+    return BeginNestedMessage<T>(6);
+  }
+
+
+  using FieldMetadata_Thread =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ThreadDescriptor,
+      TrackDescriptor>;
+
+  static constexpr FieldMetadata_Thread kThread{};
+  template <typename T = ThreadDescriptor> T* set_thread() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_ChromeThread =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeThreadDescriptor,
+      TrackDescriptor>;
+
+  static constexpr FieldMetadata_ChromeThread kChromeThread{};
+  template <typename T = ChromeThreadDescriptor> T* set_chrome_thread() {
+    return BeginNestedMessage<T>(7);
+  }
+
+
+  using FieldMetadata_Counter =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CounterDescriptor,
+      TrackDescriptor>;
+
+  static constexpr FieldMetadata_Counter kCounter{};
+  template <typename T = CounterDescriptor> T* set_counter() {
+    return BeginNestedMessage<T>(8);
+  }
+
+
+  using FieldMetadata_DisallowMergingWithSystemTracks =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TrackDescriptor>;
+
+  static constexpr FieldMetadata_DisallowMergingWithSystemTracks kDisallowMergingWithSystemTracks{};
+  void set_disallow_merging_with_system_tracks(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DisallowMergingWithSystemTracks::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_TRACK_H_
+#define INCLUDE_PERFETTO_TRACING_TRACK_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/proc_utils.h"
+// gen_amalgamated expanded: #include "perfetto/base/thread_utils.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/fnv1a.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_muxer.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/platform.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/counter_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/counter_descriptor.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_descriptor.pbzero.h"
+
+#include <stdint.h>
+#include <map>
+#include <mutex>
+
+namespace perfetto {
+namespace internal {
+class TrackRegistry;
+}
+class Flow;
+class TerminatingFlow;
+
+// Track events are recorded on a timeline track, which maintains the relative
+// time ordering of all events on that track. Each thread has its own default
+// track (ThreadTrack), which is by default where all track events are written.
+// Thread tracks are grouped under their hosting process (ProcessTrack).
+
+// Events which aren't strictly scoped to a thread or a process, or don't
+// correspond to synchronous code execution on a thread can use a custom
+// track (Track, ThreadTrack or ProcessTrack). A Track object can also
+// optionally be parented to a thread or a process.
+//
+// A track is represented by a uuid, which must be unique across the entire
+// recorded trace.
+//
+// For example, to record an event that begins and ends on different threads,
+// use a matching id to tie the begin and end events together:
+//
+//   TRACE_EVENT_BEGIN("category", "AsyncEvent", perfetto::Track(8086));
+//   ...
+//   TRACE_EVENT_END("category", perfetto::Track(8086));
+//
+// Tracks can also be annotated with metadata:
+//
+//   auto desc = track.Serialize();
+//   desc.set_name("MyTrack");
+//   perfetto::TrackEvent::SetTrackDescriptor(track, desc);
+//
+// Threads and processes can also be named in a similar way, e.g.:
+//
+//   auto desc = perfetto::ProcessTrack::Current().Serialize();
+//   desc.mutable_process()->set_process_name("MyProcess");
+//   perfetto::TrackEvent::SetTrackDescriptor(
+//       perfetto::ProcessTrack::Current(), desc);
+//
+// The metadata remains valid between tracing sessions. To free up data for a
+// track, call EraseTrackDescriptor:
+//
+//   perfetto::TrackEvent::EraseTrackDescriptor(track);
+//
+struct PERFETTO_EXPORT_COMPONENT Track {
+  const uint64_t uuid;
+  const uint64_t parent_uuid;
+  constexpr Track() : uuid(0), parent_uuid(0) {}
+
+  // Construct a track with identifier |id|, optionally parented under |parent|.
+  // If no parent is specified, the track's parent is the current process's
+  // track.
+  //
+  // To minimize the chances for accidental id collisions across processes, the
+  // track's effective uuid is generated by xorring |id| with a random,
+  // per-process cookie.
+  explicit constexpr Track(uint64_t id, Track parent = MakeProcessTrack())
+      : uuid(id ^ parent.uuid), parent_uuid(parent.uuid) {}
+
+  explicit operator bool() const { return uuid; }
+  void Serialize(protos::pbzero::TrackDescriptor*) const;
+  protos::gen::TrackDescriptor Serialize() const;
+
+  // Construct a global track with identifier |id|.
+  //
+  // Beware: the globally unique |id| should be chosen carefully to avoid
+  // accidental clashes with track identifiers emitted by other producers.
+  static Track Global(uint64_t id) { return Track(id, Track()); }
+
+  // Construct a track using |ptr| as identifier.
+  static Track FromPointer(const void* ptr, Track parent = MakeProcessTrack()) {
+    // Using pointers as global TrackIds isn't supported as pointers are
+    // per-proccess and the same pointer value can be used in different
+    // processes. If you hit this check but are providing no |parent| track,
+    // verify that Tracing::Initialize() was called for the current process.
+    PERFETTO_DCHECK(parent.uuid != Track().uuid);
+
+    return Track(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(ptr)),
+                 parent);
+  }
+
+  // Construct a track using |ptr| as identifier within thread-scope.
+  // Shorthand for `Track::FromPointer(ptr, ThreadTrack::Current())`
+  // Usage: TRACE_EVENT_BEGIN("...", "...", perfetto::Track::ThreadScoped(this))
+  static Track ThreadScoped(
+      const void* ptr,
+      Track parent = MakeThreadTrack(base::GetThreadId())) {
+    return Track::FromPointer(ptr, parent);
+  }
+
+ protected:
+  constexpr Track(uint64_t uuid_, uint64_t parent_uuid_)
+      : uuid(uuid_), parent_uuid(parent_uuid_) {}
+
+  static Track MakeThreadTrack(base::PlatformThreadId tid) {
+    // If tid were 0 here (which is an invalid tid), we would create a thread
+    // track with a uuid that conflicts with the corresponding ProcessTrack.
+    PERFETTO_DCHECK(tid != 0);
+    return Track(static_cast<uint64_t>(tid), MakeProcessTrack());
+  }
+
+  static Track MakeProcessTrack() { return Track(process_uuid, Track()); }
+
+  static constexpr inline uint64_t CompileTimeHash(const char* string) {
+    return internal::Fnv1a(string);
+  }
+
+ private:
+  friend class internal::TrackRegistry;
+  friend class Flow;
+  friend class TerminatingFlow;
+  static uint64_t process_uuid;
+};
+
+// A process track represents events that describe the state of the entire
+// application (e.g., counter events). Currently a ProcessTrack can only
+// represent the current process.
+struct PERFETTO_EXPORT_COMPONENT ProcessTrack : public Track {
+  const base::PlatformProcessId pid;
+
+  static ProcessTrack Current() { return ProcessTrack(); }
+
+  void Serialize(protos::pbzero::TrackDescriptor*) const;
+  protos::gen::TrackDescriptor Serialize() const;
+
+ private:
+  ProcessTrack()
+      : Track(MakeProcessTrack()), pid(Platform::GetCurrentProcessId()) {}
+};
+
+// A thread track is associated with a specific thread of execution. Currently
+// only threads in the current process can be referenced.
+struct PERFETTO_EXPORT_COMPONENT ThreadTrack : public Track {
+  const base::PlatformProcessId pid;
+  const base::PlatformThreadId tid;
+  bool disallow_merging_with_system_tracks = false;
+
+  static ThreadTrack Current();
+
+  // Represents a thread in the current process.
+  static ThreadTrack ForThread(base::PlatformThreadId tid_);
+
+  void Serialize(protos::pbzero::TrackDescriptor*) const;
+  protos::gen::TrackDescriptor Serialize() const;
+
+ private:
+  explicit ThreadTrack(base::PlatformThreadId tid_,
+                       bool disallow_merging_with_system_tracks_)
+      : Track(MakeThreadTrack(tid_)),
+        pid(ProcessTrack::Current().pid),
+        tid(tid_),
+        disallow_merging_with_system_tracks(
+            disallow_merging_with_system_tracks_) {}
+};
+
+// A track for recording counter values with the TRACE_COUNTER macro. Counter
+// tracks can optionally be given units and other metadata. See
+// /protos/perfetto/trace/track_event/counter_descriptor.proto for details.
+class PERFETTO_EXPORT_COMPONENT CounterTrack : public Track {
+  // A random value mixed into counter track uuids to avoid collisions with
+  // other types of tracks.
+  static constexpr uint64_t kCounterMagic = 0xb1a4a67d7970839eul;
+
+ public:
+  using Unit = perfetto::protos::pbzero::CounterDescriptor::Unit;
+  using CounterType =
+      perfetto::protos::gen::CounterDescriptor::BuiltinCounterType;
+
+  // |name| must outlive this object.
+  constexpr explicit CounterTrack(const char* name,
+                                  Track parent = MakeProcessTrack())
+      : Track(internal::Fnv1a(name) ^ kCounterMagic, parent),
+        name_(name),
+        category_(nullptr) {}
+
+  // |unit_name| is a free-form description of the unit used by this counter. It
+  // must outlive this object.
+  constexpr CounterTrack(const char* name,
+                         const char* unit_name,
+                         Track parent = MakeProcessTrack())
+      : Track(internal::Fnv1a(name) ^ kCounterMagic, parent),
+        name_(name),
+        category_(nullptr),
+        unit_name_(unit_name) {}
+
+  constexpr CounterTrack(const char* name,
+                         Unit unit,
+                         Track parent = MakeProcessTrack())
+      : Track(internal::Fnv1a(name) ^ kCounterMagic, parent),
+        name_(name),
+        category_(nullptr),
+        unit_(unit) {}
+
+  static constexpr CounterTrack Global(const char* name,
+                                       const char* unit_name) {
+    return CounterTrack(name, unit_name, Track());
+  }
+
+  static constexpr CounterTrack Global(const char* name, Unit unit) {
+    return CounterTrack(name, unit, Track());
+  }
+
+  static constexpr CounterTrack Global(const char* name) {
+    return Global(name, nullptr);
+  }
+
+  constexpr CounterTrack set_unit(Unit unit) const {
+    return CounterTrack(uuid, parent_uuid, name_, category_, unit, unit_name_,
+                        unit_multiplier_, is_incremental_, type_);
+  }
+
+  constexpr CounterTrack set_type(CounterType type) const {
+    return CounterTrack(uuid, parent_uuid, name_, category_, unit_, unit_name_,
+                        unit_multiplier_, is_incremental_, type);
+  }
+
+  constexpr CounterTrack set_unit_name(const char* unit_name) const {
+    return CounterTrack(uuid, parent_uuid, name_, category_, unit_, unit_name,
+                        unit_multiplier_, is_incremental_, type_);
+  }
+
+  constexpr CounterTrack set_unit_multiplier(int64_t unit_multiplier) const {
+    return CounterTrack(uuid, parent_uuid, name_, category_, unit_, unit_name_,
+                        unit_multiplier, is_incremental_, type_);
+  }
+
+  constexpr CounterTrack set_category(const char* category) const {
+    return CounterTrack(uuid, parent_uuid, name_, category, unit_, unit_name_,
+                        unit_multiplier_, is_incremental_, type_);
+  }
+
+  constexpr CounterTrack set_is_incremental(bool is_incremental = true) const {
+    return CounterTrack(uuid, parent_uuid, name_, category_, unit_, unit_name_,
+                        unit_multiplier_, is_incremental, type_);
+  }
+
+  constexpr bool is_incremental() const { return is_incremental_; }
+
+  void Serialize(protos::pbzero::TrackDescriptor*) const;
+  protos::gen::TrackDescriptor Serialize() const;
+
+ private:
+  constexpr CounterTrack(uint64_t uuid_,
+                         uint64_t parent_uuid_,
+                         const char* name,
+                         const char* category,
+                         Unit unit,
+                         const char* unit_name,
+                         int64_t unit_multiplier,
+                         bool is_incremental,
+                         CounterType type)
+      : Track(uuid_, parent_uuid_),
+        name_(name),
+        category_(category),
+        unit_(unit),
+        unit_name_(unit_name),
+        unit_multiplier_(unit_multiplier),
+        is_incremental_(is_incremental),
+        type_(type) {}
+
+  const char* const name_;
+  const char* const category_;
+  Unit unit_ = perfetto::protos::pbzero::CounterDescriptor::UNIT_UNSPECIFIED;
+  const char* const unit_name_ = nullptr;
+  int64_t unit_multiplier_ = 1;
+  const bool is_incremental_ = false;
+  CounterType type_ =
+      perfetto::protos::gen::CounterDescriptor::COUNTER_UNSPECIFIED;
+};
+
+namespace internal {
+
+// Keeps a map of uuids to serialized track descriptors and provides a
+// thread-safe way to read and write them. Each trace writer keeps a TLS set of
+// the tracks it has seen (see TrackEventIncrementalState). In the common case,
+// this registry is not consulted (and no locks are taken). However when a new
+// track is seen, this registry is used to write either 1) the default
+// descriptor for that track (see *Track::Serialize) or 2) a serialized
+// descriptor stored in the registry which may have additional metadata (e.g.,
+// track name).
+// TODO(eseckler): Remove PERFETTO_EXPORT_COMPONENT once Chromium no longer
+// calls TrackRegistry::InitializeInstance() directly.
+class PERFETTO_EXPORT_COMPONENT TrackRegistry {
+ public:
+  using SerializedTrackDescriptor = std::string;
+
+  TrackRegistry();
+  ~TrackRegistry();
+
+  static void InitializeInstance();
+  static void ResetForTesting();
+  static uint64_t ComputeProcessUuid();
+  static TrackRegistry* Get() { return instance_; }
+
+  void EraseTrack(Track);
+
+  // Store metadata for |track| in the registry. |fill_function| is called
+  // synchronously to record additional properties for the track.
+  template <typename TrackType>
+  void UpdateTrack(
+      const TrackType& track,
+      std::function<void(protos::pbzero::TrackDescriptor*)> fill_function) {
+    UpdateTrackImpl(track, [&](protos::pbzero::TrackDescriptor* desc) {
+      track.Serialize(desc);
+      fill_function(desc);
+    });
+  }
+
+  // This variant lets the user supply a serialized track descriptor directly.
+  void UpdateTrack(Track, const std::string& serialized_desc);
+
+  // If |track| exists in the registry, write out the serialized track
+  // descriptor for it into |packet|. Otherwise just the ephemeral track object
+  // is serialized without any additional metadata.
+  template <typename TrackType>
+  void SerializeTrack(
+      const TrackType& track,
+      protozero::MessageHandle<protos::pbzero::TracePacket> packet) {
+    // If the track has extra metadata (recorded with UpdateTrack), it will be
+    // found in the registry. To minimize the time the lock is held, make a copy
+    // of the data held in the registry and write it outside the lock.
+    std::string desc_copy;
+    {
+      std::lock_guard<std::mutex> lock(mutex_);
+      const auto& it = tracks_.find(track.uuid);
+      if (it != tracks_.end()) {
+        desc_copy = it->second;
+        PERFETTO_DCHECK(!desc_copy.empty());
+      }
+    }
+    if (!desc_copy.empty()) {
+      WriteTrackDescriptor(std::move(desc_copy), std::move(packet));
+    } else {
+      // Otherwise we just write the basic descriptor for this type of track
+      // (e.g., just uuid, no name).
+      track.Serialize(packet->set_track_descriptor());
+    }
+  }
+
+  static void WriteTrackDescriptor(
+      const SerializedTrackDescriptor& desc,
+      protozero::MessageHandle<protos::pbzero::TracePacket> packet);
+
+ private:
+  void UpdateTrackImpl(
+      Track,
+      std::function<void(protos::pbzero::TrackDescriptor*)> fill_function);
+
+  std::mutex mutex_;
+  std::map<uint64_t /* uuid */, SerializedTrackDescriptor> tracks_;
+
+  static TrackRegistry* instance_;
+};
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_TRACK_H_
+// gen_amalgamated begin header: gen/protos/perfetto/common/builtin_clock.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_BUILTIN_CLOCK_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_BUILTIN_CLOCK_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+enum BuiltinClock : int32_t {
+  BUILTIN_CLOCK_UNKNOWN = 0,
+  BUILTIN_CLOCK_REALTIME = 1,
+  BUILTIN_CLOCK_REALTIME_COARSE = 2,
+  BUILTIN_CLOCK_MONOTONIC = 3,
+  BUILTIN_CLOCK_MONOTONIC_COARSE = 4,
+  BUILTIN_CLOCK_MONOTONIC_RAW = 5,
+  BUILTIN_CLOCK_BOOTTIME = 6,
+  BUILTIN_CLOCK_TSC = 9,
+  BUILTIN_CLOCK_MAX_ID = 63,
+};
+
+constexpr BuiltinClock BuiltinClock_MIN = BuiltinClock::BUILTIN_CLOCK_UNKNOWN;
+constexpr BuiltinClock BuiltinClock_MAX = BuiltinClock::BUILTIN_CLOCK_MAX_ID;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* BuiltinClock_Name(::perfetto::protos::pbzero::BuiltinClock value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::BuiltinClock::BUILTIN_CLOCK_UNKNOWN:
+    return "BUILTIN_CLOCK_UNKNOWN";
+
+  case ::perfetto::protos::pbzero::BuiltinClock::BUILTIN_CLOCK_REALTIME:
+    return "BUILTIN_CLOCK_REALTIME";
+
+  case ::perfetto::protos::pbzero::BuiltinClock::BUILTIN_CLOCK_REALTIME_COARSE:
+    return "BUILTIN_CLOCK_REALTIME_COARSE";
+
+  case ::perfetto::protos::pbzero::BuiltinClock::BUILTIN_CLOCK_MONOTONIC:
+    return "BUILTIN_CLOCK_MONOTONIC";
+
+  case ::perfetto::protos::pbzero::BuiltinClock::BUILTIN_CLOCK_MONOTONIC_COARSE:
+    return "BUILTIN_CLOCK_MONOTONIC_COARSE";
+
+  case ::perfetto::protos::pbzero::BuiltinClock::BUILTIN_CLOCK_MONOTONIC_RAW:
+    return "BUILTIN_CLOCK_MONOTONIC_RAW";
+
+  case ::perfetto::protos::pbzero::BuiltinClock::BUILTIN_CLOCK_BOOTTIME:
+    return "BUILTIN_CLOCK_BOOTTIME";
+
+  case ::perfetto::protos::pbzero::BuiltinClock::BUILTIN_CLOCK_TSC:
+    return "BUILTIN_CLOCK_TSC";
+
+  case ::perfetto::protos::pbzero::BuiltinClock::BUILTIN_CLOCK_MAX_ID:
+    return "BUILTIN_CLOCK_MAX_ID";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/interned_data/interned_data.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_INTERNED_DATA_INTERNED_DATA_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_INTERNED_DATA_INTERNED_DATA_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class Callstack;
+class DebugAnnotationName;
+class DebugAnnotationValueTypeName;
+class EventCategory;
+class EventName;
+class Frame;
+class HistogramName;
+class InternedGpuRenderStageSpecification;
+class InternedGraphicsContext;
+class InternedString;
+class InternedV8Isolate;
+class InternedV8JsFunction;
+class InternedV8JsScript;
+class InternedV8String;
+class InternedV8WasmScript;
+class LogMessageBody;
+class Mapping;
+class NetworkPacketContext;
+class ProfiledFrameSymbols;
+class SourceLocation;
+class UnsymbolizedSourceLocation;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class InternedData_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/37, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  InternedData_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit InternedData_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit InternedData_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_event_categories() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> event_categories() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_event_names() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> event_names() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_debug_annotation_names() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> debug_annotation_names() const { return GetRepeated<::protozero::ConstBytes>(3); }
+  bool has_debug_annotation_value_type_names() const { return at<27>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> debug_annotation_value_type_names() const { return GetRepeated<::protozero::ConstBytes>(27); }
+  bool has_source_locations() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> source_locations() const { return GetRepeated<::protozero::ConstBytes>(4); }
+  bool has_unsymbolized_source_locations() const { return at<28>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> unsymbolized_source_locations() const { return GetRepeated<::protozero::ConstBytes>(28); }
+  bool has_log_message_body() const { return at<20>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> log_message_body() const { return GetRepeated<::protozero::ConstBytes>(20); }
+  bool has_histogram_names() const { return at<25>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> histogram_names() const { return GetRepeated<::protozero::ConstBytes>(25); }
+  bool has_build_ids() const { return at<16>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> build_ids() const { return GetRepeated<::protozero::ConstBytes>(16); }
+  bool has_mapping_paths() const { return at<17>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> mapping_paths() const { return GetRepeated<::protozero::ConstBytes>(17); }
+  bool has_source_paths() const { return at<18>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> source_paths() const { return GetRepeated<::protozero::ConstBytes>(18); }
+  bool has_function_names() const { return at<5>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> function_names() const { return GetRepeated<::protozero::ConstBytes>(5); }
+  bool has_profiled_frame_symbols() const { return at<21>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> profiled_frame_symbols() const { return GetRepeated<::protozero::ConstBytes>(21); }
+  bool has_mappings() const { return at<19>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> mappings() const { return GetRepeated<::protozero::ConstBytes>(19); }
+  bool has_frames() const { return at<6>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> frames() const { return GetRepeated<::protozero::ConstBytes>(6); }
+  bool has_callstacks() const { return at<7>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> callstacks() const { return GetRepeated<::protozero::ConstBytes>(7); }
+  bool has_vulkan_memory_keys() const { return at<22>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> vulkan_memory_keys() const { return GetRepeated<::protozero::ConstBytes>(22); }
+  bool has_graphics_contexts() const { return at<23>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> graphics_contexts() const { return GetRepeated<::protozero::ConstBytes>(23); }
+  bool has_gpu_specifications() const { return at<24>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> gpu_specifications() const { return GetRepeated<::protozero::ConstBytes>(24); }
+  bool has_kernel_symbols() const { return at<26>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> kernel_symbols() const { return GetRepeated<::protozero::ConstBytes>(26); }
+  bool has_debug_annotation_string_values() const { return at<29>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> debug_annotation_string_values() const { return GetRepeated<::protozero::ConstBytes>(29); }
+  bool has_packet_context() const { return at<30>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> packet_context() const { return GetRepeated<::protozero::ConstBytes>(30); }
+  bool has_v8_js_function_name() const { return at<31>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> v8_js_function_name() const { return GetRepeated<::protozero::ConstBytes>(31); }
+  bool has_v8_js_function() const { return at<32>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> v8_js_function() const { return GetRepeated<::protozero::ConstBytes>(32); }
+  bool has_v8_js_script() const { return at<33>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> v8_js_script() const { return GetRepeated<::protozero::ConstBytes>(33); }
+  bool has_v8_wasm_script() const { return at<34>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> v8_wasm_script() const { return GetRepeated<::protozero::ConstBytes>(34); }
+  bool has_v8_isolate() const { return at<35>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> v8_isolate() const { return GetRepeated<::protozero::ConstBytes>(35); }
+  bool has_protolog_string_args() const { return at<36>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> protolog_string_args() const { return GetRepeated<::protozero::ConstBytes>(36); }
+  bool has_protolog_stacktrace() const { return at<37>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> protolog_stacktrace() const { return GetRepeated<::protozero::ConstBytes>(37); }
+};
+
+class InternedData : public ::protozero::Message {
+ public:
+  using Decoder = InternedData_Decoder;
+  enum : int32_t {
+    kEventCategoriesFieldNumber = 1,
+    kEventNamesFieldNumber = 2,
+    kDebugAnnotationNamesFieldNumber = 3,
+    kDebugAnnotationValueTypeNamesFieldNumber = 27,
+    kSourceLocationsFieldNumber = 4,
+    kUnsymbolizedSourceLocationsFieldNumber = 28,
+    kLogMessageBodyFieldNumber = 20,
+    kHistogramNamesFieldNumber = 25,
+    kBuildIdsFieldNumber = 16,
+    kMappingPathsFieldNumber = 17,
+    kSourcePathsFieldNumber = 18,
+    kFunctionNamesFieldNumber = 5,
+    kProfiledFrameSymbolsFieldNumber = 21,
+    kMappingsFieldNumber = 19,
+    kFramesFieldNumber = 6,
+    kCallstacksFieldNumber = 7,
+    kVulkanMemoryKeysFieldNumber = 22,
+    kGraphicsContextsFieldNumber = 23,
+    kGpuSpecificationsFieldNumber = 24,
+    kKernelSymbolsFieldNumber = 26,
+    kDebugAnnotationStringValuesFieldNumber = 29,
+    kPacketContextFieldNumber = 30,
+    kV8JsFunctionNameFieldNumber = 31,
+    kV8JsFunctionFieldNumber = 32,
+    kV8JsScriptFieldNumber = 33,
+    kV8WasmScriptFieldNumber = 34,
+    kV8IsolateFieldNumber = 35,
+    kProtologStringArgsFieldNumber = 36,
+    kProtologStacktraceFieldNumber = 37,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.InternedData"; }
+
+
+  using FieldMetadata_EventCategories =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      EventCategory,
+      InternedData>;
+
+  static constexpr FieldMetadata_EventCategories kEventCategories{};
+  template <typename T = EventCategory> T* add_event_categories() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_EventNames =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      EventName,
+      InternedData>;
+
+  static constexpr FieldMetadata_EventNames kEventNames{};
+  template <typename T = EventName> T* add_event_names() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_DebugAnnotationNames =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DebugAnnotationName,
+      InternedData>;
+
+  static constexpr FieldMetadata_DebugAnnotationNames kDebugAnnotationNames{};
+  template <typename T = DebugAnnotationName> T* add_debug_annotation_names() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_DebugAnnotationValueTypeNames =
+    ::protozero::proto_utils::FieldMetadata<
+      27,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DebugAnnotationValueTypeName,
+      InternedData>;
+
+  static constexpr FieldMetadata_DebugAnnotationValueTypeNames kDebugAnnotationValueTypeNames{};
+  template <typename T = DebugAnnotationValueTypeName> T* add_debug_annotation_value_type_names() {
+    return BeginNestedMessage<T>(27);
+  }
+
+
+  using FieldMetadata_SourceLocations =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SourceLocation,
+      InternedData>;
+
+  static constexpr FieldMetadata_SourceLocations kSourceLocations{};
+  template <typename T = SourceLocation> T* add_source_locations() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_UnsymbolizedSourceLocations =
+    ::protozero::proto_utils::FieldMetadata<
+      28,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      UnsymbolizedSourceLocation,
+      InternedData>;
+
+  static constexpr FieldMetadata_UnsymbolizedSourceLocations kUnsymbolizedSourceLocations{};
+  template <typename T = UnsymbolizedSourceLocation> T* add_unsymbolized_source_locations() {
+    return BeginNestedMessage<T>(28);
+  }
+
+
+  using FieldMetadata_LogMessageBody =
+    ::protozero::proto_utils::FieldMetadata<
+      20,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      LogMessageBody,
+      InternedData>;
+
+  static constexpr FieldMetadata_LogMessageBody kLogMessageBody{};
+  template <typename T = LogMessageBody> T* add_log_message_body() {
+    return BeginNestedMessage<T>(20);
+  }
+
+
+  using FieldMetadata_HistogramNames =
+    ::protozero::proto_utils::FieldMetadata<
+      25,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      HistogramName,
+      InternedData>;
+
+  static constexpr FieldMetadata_HistogramNames kHistogramNames{};
+  template <typename T = HistogramName> T* add_histogram_names() {
+    return BeginNestedMessage<T>(25);
+  }
+
+
+  using FieldMetadata_BuildIds =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InternedString,
+      InternedData>;
+
+  static constexpr FieldMetadata_BuildIds kBuildIds{};
+  template <typename T = InternedString> T* add_build_ids() {
+    return BeginNestedMessage<T>(16);
+  }
+
+
+  using FieldMetadata_MappingPaths =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InternedString,
+      InternedData>;
+
+  static constexpr FieldMetadata_MappingPaths kMappingPaths{};
+  template <typename T = InternedString> T* add_mapping_paths() {
+    return BeginNestedMessage<T>(17);
+  }
+
+
+  using FieldMetadata_SourcePaths =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InternedString,
+      InternedData>;
+
+  static constexpr FieldMetadata_SourcePaths kSourcePaths{};
+  template <typename T = InternedString> T* add_source_paths() {
+    return BeginNestedMessage<T>(18);
+  }
+
+
+  using FieldMetadata_FunctionNames =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InternedString,
+      InternedData>;
+
+  static constexpr FieldMetadata_FunctionNames kFunctionNames{};
+  template <typename T = InternedString> T* add_function_names() {
+    return BeginNestedMessage<T>(5);
+  }
+
+
+  using FieldMetadata_ProfiledFrameSymbols =
+    ::protozero::proto_utils::FieldMetadata<
+      21,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProfiledFrameSymbols,
+      InternedData>;
+
+  static constexpr FieldMetadata_ProfiledFrameSymbols kProfiledFrameSymbols{};
+  template <typename T = ProfiledFrameSymbols> T* add_profiled_frame_symbols() {
+    return BeginNestedMessage<T>(21);
+  }
+
+
+  using FieldMetadata_Mappings =
+    ::protozero::proto_utils::FieldMetadata<
+      19,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Mapping,
+      InternedData>;
+
+  static constexpr FieldMetadata_Mappings kMappings{};
+  template <typename T = Mapping> T* add_mappings() {
+    return BeginNestedMessage<T>(19);
+  }
+
+
+  using FieldMetadata_Frames =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Frame,
+      InternedData>;
+
+  static constexpr FieldMetadata_Frames kFrames{};
+  template <typename T = Frame> T* add_frames() {
+    return BeginNestedMessage<T>(6);
+  }
+
+
+  using FieldMetadata_Callstacks =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Callstack,
+      InternedData>;
+
+  static constexpr FieldMetadata_Callstacks kCallstacks{};
+  template <typename T = Callstack> T* add_callstacks() {
+    return BeginNestedMessage<T>(7);
+  }
+
+
+  using FieldMetadata_VulkanMemoryKeys =
+    ::protozero::proto_utils::FieldMetadata<
+      22,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InternedString,
+      InternedData>;
+
+  static constexpr FieldMetadata_VulkanMemoryKeys kVulkanMemoryKeys{};
+  template <typename T = InternedString> T* add_vulkan_memory_keys() {
+    return BeginNestedMessage<T>(22);
+  }
+
+
+  using FieldMetadata_GraphicsContexts =
+    ::protozero::proto_utils::FieldMetadata<
+      23,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InternedGraphicsContext,
+      InternedData>;
+
+  static constexpr FieldMetadata_GraphicsContexts kGraphicsContexts{};
+  template <typename T = InternedGraphicsContext> T* add_graphics_contexts() {
+    return BeginNestedMessage<T>(23);
+  }
+
+
+  using FieldMetadata_GpuSpecifications =
+    ::protozero::proto_utils::FieldMetadata<
+      24,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InternedGpuRenderStageSpecification,
+      InternedData>;
+
+  static constexpr FieldMetadata_GpuSpecifications kGpuSpecifications{};
+  template <typename T = InternedGpuRenderStageSpecification> T* add_gpu_specifications() {
+    return BeginNestedMessage<T>(24);
+  }
+
+
+  using FieldMetadata_KernelSymbols =
+    ::protozero::proto_utils::FieldMetadata<
+      26,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InternedString,
+      InternedData>;
+
+  static constexpr FieldMetadata_KernelSymbols kKernelSymbols{};
+  template <typename T = InternedString> T* add_kernel_symbols() {
+    return BeginNestedMessage<T>(26);
+  }
+
+
+  using FieldMetadata_DebugAnnotationStringValues =
+    ::protozero::proto_utils::FieldMetadata<
+      29,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InternedString,
+      InternedData>;
+
+  static constexpr FieldMetadata_DebugAnnotationStringValues kDebugAnnotationStringValues{};
+  template <typename T = InternedString> T* add_debug_annotation_string_values() {
+    return BeginNestedMessage<T>(29);
+  }
+
+
+  using FieldMetadata_PacketContext =
+    ::protozero::proto_utils::FieldMetadata<
+      30,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      NetworkPacketContext,
+      InternedData>;
+
+  static constexpr FieldMetadata_PacketContext kPacketContext{};
+  template <typename T = NetworkPacketContext> T* add_packet_context() {
+    return BeginNestedMessage<T>(30);
+  }
+
+
+  using FieldMetadata_V8JsFunctionName =
+    ::protozero::proto_utils::FieldMetadata<
+      31,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InternedV8String,
+      InternedData>;
+
+  static constexpr FieldMetadata_V8JsFunctionName kV8JsFunctionName{};
+  template <typename T = InternedV8String> T* add_v8_js_function_name() {
+    return BeginNestedMessage<T>(31);
+  }
+
+
+  using FieldMetadata_V8JsFunction =
+    ::protozero::proto_utils::FieldMetadata<
+      32,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InternedV8JsFunction,
+      InternedData>;
+
+  static constexpr FieldMetadata_V8JsFunction kV8JsFunction{};
+  template <typename T = InternedV8JsFunction> T* add_v8_js_function() {
+    return BeginNestedMessage<T>(32);
+  }
+
+
+  using FieldMetadata_V8JsScript =
+    ::protozero::proto_utils::FieldMetadata<
+      33,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InternedV8JsScript,
+      InternedData>;
+
+  static constexpr FieldMetadata_V8JsScript kV8JsScript{};
+  template <typename T = InternedV8JsScript> T* add_v8_js_script() {
+    return BeginNestedMessage<T>(33);
+  }
+
+
+  using FieldMetadata_V8WasmScript =
+    ::protozero::proto_utils::FieldMetadata<
+      34,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InternedV8WasmScript,
+      InternedData>;
+
+  static constexpr FieldMetadata_V8WasmScript kV8WasmScript{};
+  template <typename T = InternedV8WasmScript> T* add_v8_wasm_script() {
+    return BeginNestedMessage<T>(34);
+  }
+
+
+  using FieldMetadata_V8Isolate =
+    ::protozero::proto_utils::FieldMetadata<
+      35,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InternedV8Isolate,
+      InternedData>;
+
+  static constexpr FieldMetadata_V8Isolate kV8Isolate{};
+  template <typename T = InternedV8Isolate> T* add_v8_isolate() {
+    return BeginNestedMessage<T>(35);
+  }
+
+
+  using FieldMetadata_ProtologStringArgs =
+    ::protozero::proto_utils::FieldMetadata<
+      36,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InternedString,
+      InternedData>;
+
+  static constexpr FieldMetadata_ProtologStringArgs kProtologStringArgs{};
+  template <typename T = InternedString> T* add_protolog_string_args() {
+    return BeginNestedMessage<T>(36);
+  }
+
+
+  using FieldMetadata_ProtologStacktrace =
+    ::protozero::proto_utils::FieldMetadata<
+      37,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InternedString,
+      InternedData>;
+
+  static constexpr FieldMetadata_ProtologStacktrace kProtologStacktrace{};
+  template <typename T = InternedString> T* add_protolog_stacktrace() {
+    return BeginNestedMessage<T>(37);
+  }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_INTERNAL_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_INTERNAL_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/flat_set.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/data_source.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/debug_annotation.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/traced_value.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_event.pbzero.h"
+
+#include <unordered_map>
+
+namespace perfetto {
+
+// Represents a point in time for the clock specified by |clock_id|.
+struct TraceTimestamp {
+  // Clock IDs have the following semantic:
+  // [1, 63]:    Builtin types, see BuiltinClock from
+  //             ../common/builtin_clock.proto.
+  // [64, 127]:  User-defined clocks. These clocks are sequence-scoped. They
+  //             are only valid within the same |trusted_packet_sequence_id|
+  //             (i.e. only for TracePacket(s) emitted by the same TraceWriter
+  //             that emitted the clock snapshot).
+  // [128, MAX]: Reserved for future use. The idea is to allow global clock
+  //             IDs and setting this ID to hash(full_clock_name) & ~127.
+  // Learn more: `clock_snapshot.proto`
+  uint32_t clock_id;
+  uint64_t value;
+};
+
+class EventContext;
+class TrackEventSessionObserver;
+struct Category;
+struct TraceTimestamp;
+namespace protos {
+namespace gen {
+class TrackEventConfig;
+}  // namespace gen
+namespace pbzero {
+class DebugAnnotation;
+}  // namespace pbzero
+}  // namespace protos
+
+// A callback interface for observing track event tracing sessions starting and
+// stopping. See TrackEvent::{Add,Remove}SessionObserver. Note that all methods
+// will be called on an internal Perfetto thread.
+class PERFETTO_EXPORT_COMPONENT TrackEventSessionObserver {
+ public:
+  virtual ~TrackEventSessionObserver();
+  // Called when a track event tracing session is configured. Note tracing isn't
+  // active yet, so track events emitted here won't be recorded. See
+  // DataSourceBase::OnSetup.
+  virtual void OnSetup(const DataSourceBase::SetupArgs&);
+  // Called when a track event tracing session is started. It is possible to
+  // emit track events from this callback.
+  virtual void OnStart(const DataSourceBase::StartArgs&);
+  // Called when a track event tracing session is stopped. It is still possible
+  // to emit track events from this callback.
+  virtual void OnStop(const DataSourceBase::StopArgs&);
+  // Called when tracing muxer requests to clear incremental state.
+  virtual void WillClearIncrementalState(
+      const DataSourceBase::ClearIncrementalStateArgs&);
+};
+
+// A class that the embedder can store arbitrary data user data per thread.
+class PERFETTO_EXPORT_COMPONENT TrackEventTlsStateUserData {
+ public:
+  TrackEventTlsStateUserData() = default;
+  // Not clonable.
+  TrackEventTlsStateUserData(const TrackEventTlsStateUserData&) = delete;
+  TrackEventTlsStateUserData& operator=(const TrackEventTlsStateUserData&) =
+      delete;
+
+  virtual ~TrackEventTlsStateUserData();
+};
+
+namespace internal {
+class TrackEventCategoryRegistry;
+
+class PERFETTO_EXPORT_COMPONENT BaseTrackEventInternedDataIndex {
+ public:
+  virtual ~BaseTrackEventInternedDataIndex();
+
+#if PERFETTO_DCHECK_IS_ON()
+  const char* type_id_ = nullptr;
+  const void* add_function_ptr_ = nullptr;
+#endif  // PERFETTO_DCHECK_IS_ON()
+};
+
+struct TrackEventTlsState {
+  template <typename TraceContext>
+  explicit TrackEventTlsState(const TraceContext& trace_context);
+  bool enable_thread_time_sampling = false;
+  bool filter_debug_annotations = false;
+  bool filter_dynamic_event_names = false;
+  uint64_t timestamp_unit_multiplier = 1;
+  uint32_t default_clock;
+  std::map<const void*, std::unique_ptr<TrackEventTlsStateUserData>> user_data;
+};
+
+struct TrackEventIncrementalState {
+  static constexpr size_t kMaxInternedDataFields = 32;
+
+  // Packet-sequence-scoped clock that encodes nanosecond timestamps in the
+  // domain of the clock returned by GetClockId() as delta values - see
+  // Clock::is_incremental in perfetto/trace/clock_snapshot.proto.
+  // Default unit: nanoseconds.
+  static constexpr uint32_t kClockIdIncremental = 64;
+
+  // Packet-sequence-scoped clock that encodes timestamps in the domain of the
+  // clock returned by GetClockId() with custom unit_multiplier.
+  // Default unit: nanoseconds.
+  static constexpr uint32_t kClockIdAbsolute = 65;
+
+  bool was_cleared = true;
+
+  // A heap-allocated message for storing newly seen interned data while we are
+  // in the middle of writing a track event. When a track event wants to write
+  // new interned data into the trace, it is first serialized into this message
+  // and then flushed to the real trace in EventContext when the packet ends.
+  // The message is cached here as a part of incremental state so that we can
+  // reuse the underlying buffer allocation for subsequently written interned
+  // data.
+  protozero::HeapBuffered<protos::pbzero::InternedData>
+      serialized_interned_data;
+
+  // In-memory indices for looking up interned data ids.
+  // For each intern-able field (up to a max of 32) we keep a dictionary of
+  // field-value -> interning-key. Depending on the type we either keep the full
+  // value or a hash of it (See track_event_interned_data_index.h)
+  using InternedDataIndex =
+      std::pair</* interned_data.proto field number */ size_t,
+                std::unique_ptr<BaseTrackEventInternedDataIndex>>;
+  std::array<InternedDataIndex, kMaxInternedDataFields> interned_data_indices =
+      {};
+
+  // Track uuids for which we have written descriptors into the trace. If a
+  // trace event uses a track which is not in this set, we'll write out a
+  // descriptor for it.
+  base::FlatSet<uint64_t> seen_tracks;
+
+  // Dynamically registered category names that have been encountered during
+  // this tracing session. The value in the map indicates whether the category
+  // is enabled or disabled.
+  std::unordered_map<std::string, bool> dynamic_categories;
+
+  // The latest reference timestamp that was used in a TracePacket or in a
+  // ClockSnapshot. The increment between this timestamp and the current trace
+  // time (GetTimeNs) is a value in kClockIdIncremental's domain.
+  uint64_t last_timestamp_ns = 0;
+
+  // The latest known counter values that was used in a TracePacket for each
+  // counter track. The key (uint64_t) is the uuid of counter track.
+  // The value is used for delta encoding of counter values.
+  std::unordered_map<uint64_t, int64_t> last_counter_value_per_track;
+  int64_t last_thread_time_ns = 0;
+};
+
+// The backend portion of the track event trace point implemention. Outlined to
+// a separate .cc file so it can be shared by different track event category
+// namespaces.
+class PERFETTO_EXPORT_COMPONENT TrackEventInternal {
+ public:
+  static bool Initialize(
+      const TrackEventCategoryRegistry&,
+      bool (*register_data_source)(const DataSourceDescriptor&));
+
+  static bool AddSessionObserver(const TrackEventCategoryRegistry&,
+                                 TrackEventSessionObserver*);
+  static void RemoveSessionObserver(const TrackEventCategoryRegistry&,
+                                    TrackEventSessionObserver*);
+
+  static void EnableTracing(const TrackEventCategoryRegistry& registry,
+                            const protos::gen::TrackEventConfig& config,
+                            const DataSourceBase::SetupArgs&);
+  static void OnStart(const TrackEventCategoryRegistry&,
+                      const DataSourceBase::StartArgs&);
+  static void OnStop(const TrackEventCategoryRegistry&,
+                     const DataSourceBase::StopArgs&);
+  static void DisableTracing(const TrackEventCategoryRegistry& registry,
+                             uint32_t internal_instance_index);
+  static void WillClearIncrementalState(
+      const TrackEventCategoryRegistry&,
+      const DataSourceBase::ClearIncrementalStateArgs&);
+
+  static bool IsCategoryEnabled(const TrackEventCategoryRegistry& registry,
+                                const protos::gen::TrackEventConfig& config,
+                                const Category& category);
+
+  static void WriteEventName(perfetto::DynamicString event_name,
+                             perfetto::EventContext& event_ctx,
+                             const TrackEventTlsState&);
+
+  static void WriteEventName(perfetto::StaticString event_name,
+                             perfetto::EventContext& event_ctx,
+                             const TrackEventTlsState&);
+
+  static perfetto::EventContext WriteEvent(
+      TraceWriterBase*,
+      TrackEventIncrementalState*,
+      TrackEventTlsState& tls_state,
+      const Category* category,
+      perfetto::protos::pbzero::TrackEvent::Type,
+      const TraceTimestamp& timestamp,
+      bool on_current_thread_track);
+
+  static void ResetIncrementalStateIfRequired(
+      TraceWriterBase* trace_writer,
+      TrackEventIncrementalState* incr_state,
+      const TrackEventTlsState& tls_state,
+      const TraceTimestamp& timestamp) {
+    if (incr_state->was_cleared) {
+      incr_state->was_cleared = false;
+      ResetIncrementalState(trace_writer, incr_state, tls_state, timestamp);
+    }
+  }
+
+  // TODO(altimin): Remove this method once Chrome uses
+  // EventContext::AddDebugAnnotation directly.
+  template <typename NameType, typename ValueType>
+  static void AddDebugAnnotation(perfetto::EventContext* event_ctx,
+                                 NameType&& name,
+                                 ValueType&& value) {
+    auto annotation =
+        AddDebugAnnotation(event_ctx, std::forward<NameType>(name));
+    WriteIntoTracedValue(
+        internal::CreateTracedValueFromProto(annotation, event_ctx),
+        std::forward<ValueType>(value));
+  }
+
+  // If the given track hasn't been seen by the trace writer yet, write a
+  // descriptor for it into the trace. Doesn't take a lock unless the track
+  // descriptor is new.
+  template <typename TrackType>
+  static void WriteTrackDescriptorIfNeeded(
+      const TrackType& track,
+      TraceWriterBase* trace_writer,
+      TrackEventIncrementalState* incr_state,
+      const TrackEventTlsState& tls_state,
+      const TraceTimestamp& timestamp) {
+    auto it_and_inserted = incr_state->seen_tracks.insert(track.uuid);
+    if (PERFETTO_LIKELY(!it_and_inserted.second))
+      return;
+    WriteTrackDescriptor(track, trace_writer, incr_state, tls_state, timestamp);
+  }
+
+  // Unconditionally write a track descriptor into the trace.
+  template <typename TrackType>
+  static void WriteTrackDescriptor(const TrackType& track,
+                                   TraceWriterBase* trace_writer,
+                                   TrackEventIncrementalState* incr_state,
+                                   const TrackEventTlsState& tls_state,
+                                   const TraceTimestamp& timestamp) {
+    ResetIncrementalStateIfRequired(trace_writer, incr_state, tls_state,
+                                    timestamp);
+    TrackRegistry::Get()->SerializeTrack(
+        track, NewTracePacket(trace_writer, incr_state, tls_state, timestamp));
+  }
+
+  // Get the current time in nanoseconds in the trace clock timebase.
+  static uint64_t GetTimeNs();
+
+  static TraceTimestamp GetTraceTime();
+
+  static inline protos::pbzero::BuiltinClock GetClockId() { return clock_; }
+  static inline void SetClockId(protos::pbzero::BuiltinClock clock) {
+    clock_ = clock;
+  }
+
+  static inline bool GetDisallowMergingWithSystemTracks() {
+    return disallow_merging_with_system_tracks_;
+  }
+  static inline void SetDisallowMergingWithSystemTracks(
+      bool disallow_merging_with_system_tracks) {
+    disallow_merging_with_system_tracks_ = disallow_merging_with_system_tracks;
+  }
+
+  static int GetSessionCount();
+
+  // Represents the default track for the calling thread.
+  static const Track kDefaultTrack;
+
+ private:
+  static void ResetIncrementalState(TraceWriterBase* trace_writer,
+                                    TrackEventIncrementalState* incr_state,
+                                    const TrackEventTlsState& tls_state,
+                                    const TraceTimestamp& timestamp);
+
+  static protozero::MessageHandle<protos::pbzero::TracePacket> NewTracePacket(
+      TraceWriterBase*,
+      TrackEventIncrementalState*,
+      const TrackEventTlsState& tls_state,
+      TraceTimestamp,
+      uint32_t seq_flags =
+          protos::pbzero::TracePacket::SEQ_NEEDS_INCREMENTAL_STATE);
+
+  static protos::pbzero::DebugAnnotation* AddDebugAnnotation(
+      perfetto::EventContext*,
+      const char* name);
+
+  static protos::pbzero::DebugAnnotation* AddDebugAnnotation(
+      perfetto::EventContext*,
+      perfetto::DynamicString name);
+
+  static std::atomic<int> session_count_;
+
+  static protos::pbzero::BuiltinClock clock_;
+  static bool disallow_merging_with_system_tracks_;
+};
+
+template <typename TraceContext>
+TrackEventTlsState::TrackEventTlsState(const TraceContext& trace_context) {
+  auto locked_ds = trace_context.GetDataSourceLocked();
+  bool disable_incremental_timestamps = false;
+  if (locked_ds.valid()) {
+    const auto& config = locked_ds->GetConfig();
+    disable_incremental_timestamps = config.disable_incremental_timestamps();
+    filter_debug_annotations = config.filter_debug_annotations();
+    filter_dynamic_event_names = config.filter_dynamic_event_names();
+    enable_thread_time_sampling = config.enable_thread_time_sampling();
+    if (config.has_timestamp_unit_multiplier()) {
+      timestamp_unit_multiplier = config.timestamp_unit_multiplier();
+    }
+  }
+  if (disable_incremental_timestamps) {
+    if (timestamp_unit_multiplier == 1) {
+      default_clock = static_cast<uint32_t>(TrackEventInternal::GetClockId());
+    } else {
+      default_clock = TrackEventIncrementalState::kClockIdAbsolute;
+    }
+  } else {
+    default_clock = TrackEventIncrementalState::kClockIdIncremental;
+  }
+}
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_INTERNAL_H_
+// gen_amalgamated begin header: include/perfetto/tracing/traced_proto.h
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_TRACED_PROTO_H_
+#define INCLUDE_PERFETTO_TRACING_TRACED_PROTO_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/template_util.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/traced_value.h"
+
+namespace perfetto {
+class EventContext;
+namespace internal {
+template <typename FieldMetadata,
+          bool is_message,
+          protozero::proto_utils::RepetitionType repetition_type>
+struct TypedProtoWriterImpl;
+}
+
+// A Wrapper around a protozero message to allow C++ classes to specify how it
+// should be serialised into the trace:
+//
+// class Foo {
+//  public:
+//   void WriteIntoTrace(perfetto::TracedProto<pbzero::Foo> message) {
+//     message->set_int_field(int_field_);
+//   }
+// };
+//
+// This class also exposes EventContext, e.g. to enable data interning.
+//
+// NOTE: the functionality below is not ready yet.
+// TODO(altimin): Make the interop below possible.
+// TracedProto also provides a seamless integration with writing untyped
+// values via TracedValue / TracedDictionary / TracedArray:
+//
+// - TracedValue can be converted to a TracedProto, either by calling
+//   TracedValue::WriteProto<T>() or implicitly.
+// - If a proto message has a repeating DebugAnnotation debug_annotations
+//   field, it can be filled using the TracedDictionary obtained from
+//   TracedProto::AddDebugAnnotations.
+template <typename MessageType>
+class TracedProto {
+ public:
+  // implicit
+  TracedProto(TracedValue&& value)
+      : TracedProto(std::move(value).WriteProto<MessageType>()) {}
+  ~TracedProto() = default;
+
+  TracedProto(const TracedProto&) = delete;
+  TracedProto& operator=(const TracedProto&) = delete;
+  TracedProto& operator=(TracedProto&&) = delete;
+  TracedProto(TracedProto&&) = default;
+
+  MessageType* operator->() const { return message_; }
+
+  MessageType* message() { return message_; }
+
+  // Write additional untyped values into the same context, which is useful
+  // when a given C++ class has a typed representation, but also either has
+  // members which can only be written into an untyped context (e.g. they are
+  // autogenerated) or it's desirable to have a way to quickly extend the
+  // trace representation of this class (e.g. for debugging).
+  //
+  // The usage of the returned TracedDictionary should not be interleaved with
+  // writing into |message| as this results in an inefficient proto layout. To
+  // enforce this, AddDebugAnnotations should be called on TracedProto&&, i.e.
+  // std::move(message).AddDebugAnnotations().
+  //
+  // This requires a 'repeated DebugAnnotations debug_annotations' field in
+  // MessageType.
+  template <typename Check = void>
+  TracedDictionary AddDebugAnnotations() && {
+    static_assert(
+        std::is_base_of<
+            protozero::proto_utils::FieldMetadataBase,
+            typename MessageType::FieldMetadata_DebugAnnotations>::value,
+        "This message does not have a |debug_annotations| field. Please add a"
+        "'repeated perfetto.protos.DebugAnnotation debug_annnotations = N;' "
+        "field to your message.");
+    return TracedDictionary(message_, MessageType::kDebugAnnotations, context_,
+                            nullptr);
+  }
+
+  // Start writing a single entry corresponding to the given |field| and return
+  // TracedProto should be used to populate this further.
+  // This method requires |field|'s type to be a nested message, but both
+  // repeated and non-repeated complex fields are supported.
+  template <typename FieldMetadata>
+  TracedProto<typename FieldMetadata::cpp_field_type> WriteNestedMessage(
+      FieldMetadata) {
+    static_assert(std::is_base_of<MessageType,
+                                  typename FieldMetadata::message_type>::value,
+                  "Field should belong to the current message");
+    static_assert(
+        FieldMetadata::kProtoFieldType ==
+            protozero::proto_utils::ProtoSchemaType::kMessage,
+        "AddItem() can be used only for nested message fields. To write a "
+        "primitive field, use traced_proto->set_field() or traced_proto.Set()");
+    return Wrap(
+        message_->template BeginNestedMessage<
+            typename FieldMetadata::cpp_field_type>(FieldMetadata::kFieldId));
+  }
+
+  // Write a given |value| into proto  as a new |field| of the current message.
+  // This method supports both nested messages and primitive types (i.e. int or
+  // string), but requires the |field| to be non-repeateable (i.e. optional).
+  // For repeatable fields, AppendValue or AppendFrom should be used.
+  template <typename FieldMetadata, typename ValueType>
+  void Set(FieldMetadata, ValueType&& value) {
+    static_assert(std::is_base_of<MessageType,
+                                  typename FieldMetadata::message_type>::value,
+                  "Field should belong to the current message");
+    static_assert(
+        FieldMetadata::kRepetitionType ==
+            protozero::proto_utils::RepetitionType::kNotRepeated,
+        "Set() can't be used with repeated fields due to ambiguity between "
+        "writing |value| as a single entry or treating |value| as a container "
+        "and writing all contained items as multiple entries. Please use "
+        "dedicated AppendValue() or AppendFrom() methods to differentiate "
+        "between "
+        "these two situations");
+
+    internal::TypedProtoWriterImpl<
+        FieldMetadata,
+        FieldMetadata::kProtoFieldType ==
+            protozero::proto_utils::ProtoSchemaType::kMessage,
+        protozero::proto_utils::RepetitionType::kNotRepeated>::
+        Write(*this, std::forward<ValueType>(value));
+  }
+
+  // Write a given |value| a single entry into the repeated |field| of the
+  // current message. If the field is not repeated, Set() should be used
+  // instead.
+  template <typename FieldMetadata, typename ValueType>
+  void AppendValue(FieldMetadata, ValueType&& value) {
+    static_assert(std::is_base_of<MessageType,
+                                  typename FieldMetadata::message_type>::value,
+                  "Field should belong to the current message");
+    static_assert(
+        FieldMetadata::kRepetitionType ==
+            protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+        "Append*() methods can be used only with repeated fields. "
+        "Please use Set() for non-repeated");
+
+    // Write a single value into a given repeated field by explicitly passing
+    // "kNotRepeated" to the TypedProtoWriterImpl.
+    internal::TypedProtoWriterImpl<
+        FieldMetadata,
+        FieldMetadata::kProtoFieldType ==
+            protozero::proto_utils::ProtoSchemaType::kMessage,
+        protozero::proto_utils::RepetitionType::kNotRepeated>::
+        Write(*this, std::forward<ValueType>(value));
+  }
+
+  // Write a given |value| as a set of entries into the repeated |field| of the
+  // current message. If the field is not repeated, Set() should be used
+  // instead.
+  template <typename FieldMetadata, typename ValueType>
+  void AppendFrom(FieldMetadata, ValueType&& value) {
+    static_assert(std::is_base_of<MessageType,
+                                  typename FieldMetadata::message_type>::value,
+                  "Field should belong to the current message");
+    static_assert(
+        FieldMetadata::kRepetitionType ==
+            protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+        "Append*() methods can be used only with repeated fields. "
+        "Please use Set() for non-repeated");
+
+    internal::TypedProtoWriterImpl<
+        FieldMetadata,
+        FieldMetadata::kProtoFieldType ==
+            protozero::proto_utils::ProtoSchemaType::kMessage,
+        protozero::proto_utils::RepetitionType::kRepeatedNotPacked>::
+        Write(*this, std::forward<ValueType>(value));
+  }
+
+  // Write a nested message into a field according to the provided metadata.
+  // TODO(altimin): Replace the current usages in Chrome with the functions
+  // above and make these methods private.
+  template <typename FieldMetadata>
+  TracedProto<typename FieldMetadata::cpp_field_type> WriteNestedMessage() {
+    return WriteNestedMessage(FieldMetadata());
+  }
+
+ private:
+  friend class EventContext;
+  friend class TracedValue;
+  // Allow TracedProto<Foo> to create TracedProto<Bar>.
+  template <typename T>
+  friend class TracedProto;
+
+  // Wraps a raw protozero message using the same context as the current object.
+  template <typename ChildMessageType>
+  TracedProto<ChildMessageType> Wrap(ChildMessageType* message) {
+    return TracedProto<ChildMessageType>(message, context_);
+  }
+
+  // Context might be null here when writing typed message which is
+  // nested into untyped legacy trace event macro argument.
+  // TODO(altimin): Turn this into EventContext& when this case is eliminated
+  // and expose it in public API.
+  EventContext* context() const { return context_; }
+
+  TracedProto(MessageType* message, EventContext* context)
+      : message_(message), context_(context) {}
+
+  MessageType* const message_;
+  EventContext* context_;
+};
+
+template <typename MessageType, typename ValueType>
+void WriteIntoTracedProto(TracedProto<MessageType> message, ValueType&& value);
+
+namespace internal {
+
+template <typename FieldMetadata,
+          bool is_message,
+          protozero::proto_utils::RepetitionType repetition_type>
+struct TypedProtoWriterImpl;
+
+// Simple non-repeated field.
+template <typename FieldMetadata>
+struct TypedProtoWriterImpl<
+    FieldMetadata,
+    /*is_message=*/false,
+    protozero::proto_utils::RepetitionType::kNotRepeated> {
+  template <typename Proto, typename ValueType>
+  static void Write(TracedProto<Proto>& context, ValueType&& value) {
+    protozero::internal::FieldWriter<FieldMetadata::kProtoFieldType>::Append(
+        *context.message(), FieldMetadata::kFieldId, value);
+  }
+};
+
+// Simple repeated non-packed field.
+template <typename FieldMetadata>
+struct TypedProtoWriterImpl<
+    FieldMetadata,
+    /*is_message=*/false,
+    protozero::proto_utils::RepetitionType::kRepeatedNotPacked> {
+  template <typename Proto, typename ValueType>
+  static void Write(TracedProto<Proto>& context, ValueType&& value) {
+    for (auto&& item : value) {
+      protozero::internal::FieldWriter<FieldMetadata::kProtoFieldType>::Append(
+          *context.message(), FieldMetadata::kFieldId, item);
+    }
+  }
+};
+
+// Nested repeated non-packed field.
+template <typename FieldMetadata>
+struct TypedProtoWriterImpl<
+    FieldMetadata,
+    /*is_message=*/true,
+    protozero::proto_utils::RepetitionType::kNotRepeated> {
+  template <typename Proto, typename ValueType>
+  static void Write(TracedProto<Proto>& context, ValueType&& value) {
+    WriteIntoTracedProto(context.template WriteNestedMessage<FieldMetadata>(),
+                         std::forward<ValueType>(value));
+  }
+};
+
+// Nested repeated non-packed field.
+template <typename FieldMetadata>
+struct TypedProtoWriterImpl<
+    FieldMetadata,
+    /*is_message=*/true,
+    protozero::proto_utils::RepetitionType::kRepeatedNotPacked> {
+  template <typename Proto, typename ValueType>
+  static void Write(TracedProto<Proto>& context, ValueType&& value) {
+    for (auto&& item : value) {
+      WriteIntoTracedProto(context.template WriteNestedMessage<FieldMetadata>(),
+                           item);
+    }
+  }
+};
+
+constexpr int kMaxWriteTracedProtoImplPriority = 1;
+
+// If perfetto::TraceFormatTraits<T>::WriteIntoTrace(TracedProto<MessageType>,
+// T) is available, use it.
+template <typename MessageType, typename T>
+decltype(TraceFormatTraits<base::remove_cvref_t<T>>::WriteIntoTrace(
+             std::declval<TracedProto<MessageType>>(),
+             std::declval<T>()),
+         void())
+WriteIntoTracedProtoImpl(base::priority_tag<1>,
+                         TracedProto<MessageType> message,
+                         T&& value) {
+  TraceFormatTraits<base::remove_cvref_t<T>>::WriteIntoTrace(
+      std::move(message), std::forward<T>(value));
+}
+
+// If T has WriteIntoTrace(TracedProto<MessageType>) method, use it.
+template <typename MessageType, typename T>
+decltype(
+    std::declval<T>().WriteIntoTrace(std::declval<TracedProto<MessageType>>()),
+    void())
+WriteIntoTracedProtoImpl(base::priority_tag<0>,
+                         TracedProto<MessageType> message,
+                         T&& value) {
+  value.WriteIntoTrace(std::move(message));
+}
+
+// TypedProtoWriter takes the protozero message (TracedProto<MessageType>),
+// field description (FieldMetadata) and value and writes the given value
+// into the given field of the given protozero message.
+//
+// This is primarily used for inline writing of typed messages:
+// TRACE_EVENT(..., pbzero::Message:kField, value);
+//
+// Ideally we would use a function here and not a struct, but passing template
+// arguments directly to the function (e.g. foo<void>()) isn't supported until
+// C++20, so we have to use a helper struct here.
+template <typename FieldMetadata>
+struct TypedProtoWriter {
+ private:
+  using ProtoSchemaType = protozero::proto_utils::ProtoSchemaType;
+  using RepetitionType = protozero::proto_utils::RepetitionType;
+
+  static_assert(FieldMetadata::kRepetitionType !=
+                    RepetitionType::kRepeatedPacked,
+                "writing packed fields isn't supported yet");
+
+  template <bool is_message, RepetitionType repetition_type>
+  struct Writer;
+
+ public:
+  template <typename Proto, typename ValueType>
+  static void Write(TracedProto<Proto>& context, ValueType&& value) {
+    TypedProtoWriterImpl<
+        FieldMetadata,
+        FieldMetadata::kProtoFieldType == ProtoSchemaType::kMessage,
+        FieldMetadata::kRepetitionType>::Write(context,
+                                               std::forward<ValueType>(value));
+  }
+};
+
+}  // namespace internal
+
+// Helper template to determine if a given type can be passed to
+// perfetto::WriteIntoTracedProto. These templates will fail to resolve if the
+// class does not have necesary support, so they are useful for SFINAE and for
+// producing helpful compiler error messages.
+template <typename MessageType, typename ValueType, typename Result = void>
+using check_traced_proto_support_t =
+    decltype(internal::WriteIntoTracedProtoImpl(
+        std::declval<
+            base::priority_tag<internal::kMaxWriteTracedProtoImplPriority>>(),
+        std::declval<TracedProto<MessageType>>(),
+        std::declval<ValueType>()));
+
+// check_traced_proto_support<MessageType, T, V>::type is defined (and equal to
+// V) iff T supports being passed to WriteIntoTracedProto together with
+// TracedProto<MessageType>. See the comment in traced_value_forward.h for more
+// details.
+template <typename MessageType, typename ValueType, class Result>
+struct check_traced_proto_support<
+    MessageType,
+    ValueType,
+    Result,
+    check_traced_proto_support_t<MessageType, ValueType, Result>> {
+  static constexpr bool value = true;
+  using type = Result;
+};
+
+template <typename MessageType, typename ValueType>
+void WriteIntoTracedProto(TracedProto<MessageType> message, ValueType&& value) {
+  // TODO(altimin): Add a URL to the documentation and a list of common failure
+  // patterns.
+  static_assert(
+      std::is_same<check_traced_proto_support_t<MessageType, ValueType>,
+                   void>::value,
+      "The provided type does not support being serialised into the "
+      "provided protozero message. Please see the comment in traced_proto.h "
+      "for more details.");
+
+  internal::WriteIntoTracedProtoImpl(
+      base::priority_tag<internal::kMaxWriteTracedProtoImplPriority>(),
+      std::move(message), std::forward<ValueType>(value));
+}
+
+template <typename MessageType, typename FieldMetadataType, typename ValueType>
+void WriteTracedProtoField(TracedProto<MessageType>& message,
+                           FieldMetadataType,
+                           ValueType&& value) {
+  static_assert(
+      std::is_base_of<protozero::proto_utils::FieldMetadataBase,
+                      FieldMetadataType>::value,
+      "Field name should be a protozero::internal::FieldMetadata<...>");
+  static_assert(
+      std::is_base_of<MessageType,
+                      typename FieldMetadataType::message_type>::value,
+      "Field's parent type should match the context.");
+
+  internal::TypedProtoWriter<FieldMetadataType>::Write(
+      message, std::forward<ValueType>(value));
+}
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_TRACED_PROTO_H_
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_EVENT_CONTEXT_H_
+#define INCLUDE_PERFETTO_TRACING_EVENT_CONTEXT_H_
+
+// gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_internal.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/traced_proto.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class DebugAnnotation;
+}  // namespace pbzero
+}  // namespace protos
+
+namespace internal {
+class TrackEventInternal;
+}
+
+// Allows adding custom arguments into track events. Example:
+//
+//   TRACE_EVENT_BEGIN("category", "Title",
+//                     [](perfetto::EventContext ctx) {
+//                       auto* log = ctx.event()->set_log_message();
+//                       log->set_body_iid(1234);
+//
+//                       ctx.AddDebugAnnotation("name", 1234);
+//                     });
+//
+class PERFETTO_EXPORT_COMPONENT EventContext {
+ public:
+  EventContext(EventContext&&) = default;
+
+  // For Chromium during the transition phase to the client library.
+  // TODO(eseckler): Remove once Chromium has switched to client lib entirely.
+  explicit EventContext(
+      protos::pbzero::TrackEvent* event,
+      internal::TrackEventIncrementalState* incremental_state = nullptr,
+      bool filter_debug_annotations = false)
+      : event_(event),
+        incremental_state_(incremental_state),
+        filter_debug_annotations_(filter_debug_annotations) {}
+
+  ~EventContext();
+
+  internal::TrackEventIncrementalState* GetIncrementalState() const {
+    return incremental_state_;
+  }
+
+  // Disclaimer: Experimental method, subject to change.
+  // Exposed publicly to emit some TrackEvent fields in Chromium only in local
+  // tracing. Long-term, we really shouldn't be (ab)using the
+  // filter_debug_annotation setting for this.
+  //
+  // TODO(kraskevich): Come up with a more precise name once we have more than
+  // one usecase.
+  bool ShouldFilterDebugAnnotations() const {
+    if (tls_state_) {
+      return tls_state_->filter_debug_annotations;
+    }
+    // In Chromium tls_state_ is nullptr, so we need to get this information
+    // from a separate field.
+    return filter_debug_annotations_;
+  }
+
+  // Get a TrackEvent message to write typed arguments to.
+  //
+  // event() is a template method to allow callers to specify a subclass of
+  // TrackEvent instead. Those subclasses correspond to TrackEvent message with
+  // application-specific extensions. More information in
+  // design-docs/extensions.md.
+  template <typename EventType = protos::pbzero::TrackEvent>
+  EventType* event() const {
+    // As the method does downcasting, we check that a target subclass does
+    // not add new fields.
+    static_assert(
+        sizeof(EventType) == sizeof(protos::pbzero::TrackEvent),
+        "Event type must be binary-compatible with protos::pbzero::TrackEvent");
+    return static_cast<EventType*>(event_);
+  }
+
+  // Convert a raw pointer to protozero message to TracedProto which captures
+  // the reference to this EventContext.
+  template <typename MessageType>
+  TracedProto<MessageType> Wrap(MessageType* message) {
+    static_assert(std::is_base_of<protozero::Message, MessageType>::value,
+                  "TracedProto can be used only with protozero messages");
+
+    return TracedProto<MessageType>(message, this);
+  }
+
+  // Add a new `debug_annotation` proto message and populate it from |value|
+  // using perfetto::TracedValue API. Users should generally prefer passing
+  // values directly to TRACE_EVENT (i.e. TRACE_EVENT(..., "arg", value, ...);)
+  // but in rare cases (e.g. when an argument should be written conditionally)
+  // EventContext::AddDebugAnnotation provides an explicit equivalent.
+  template <typename EventNameType, typename T>
+  void AddDebugAnnotation(EventNameType&& name, T&& value) {
+    if (tls_state_ && tls_state_->filter_debug_annotations)
+      return;
+    auto annotation = AddDebugAnnotation(std::forward<EventNameType>(name));
+    WriteIntoTracedValue(internal::CreateTracedValueFromProto(annotation, this),
+                         std::forward<T>(value));
+  }
+
+  // Read arbitrary user data that is associated with the thread-local per
+  // instance state of the track event. `key` must be non-null and unique
+  // per TrackEventTlsStateUserData subclass.
+  TrackEventTlsStateUserData* GetTlsUserData(const void* key);
+
+  // Set arbitrary user data that is associated with the thread-local per
+  // instance state of the track event. `key` must be non-null and unique
+  // per TrackEventTlsStateUserData subclass.
+  void SetTlsUserData(const void* key,
+                      std::unique_ptr<TrackEventTlsStateUserData> data);
+
+ private:
+  template <typename, size_t, typename, typename>
+  friend class TrackEventInternedDataIndex;
+  friend class internal::TrackEventInternal;
+
+  using TracePacketHandle =
+      ::protozero::MessageHandle<protos::pbzero::TracePacket>;
+
+  EventContext(TraceWriterBase* trace_writer,
+               TracePacketHandle,
+               internal::TrackEventIncrementalState*,
+               internal::TrackEventTlsState*);
+  EventContext(const EventContext&) = delete;
+
+  protos::pbzero::DebugAnnotation* AddDebugAnnotation(const char* name);
+  protos::pbzero::DebugAnnotation* AddDebugAnnotation(
+      ::perfetto::DynamicString name);
+
+  TraceWriterBase* trace_writer_ = nullptr;
+  TracePacketHandle trace_packet_;
+  protos::pbzero::TrackEvent* event_;
+  internal::TrackEventIncrementalState* incremental_state_;
+  // TODO(mohitms): Make it const-reference instead of pointer, once we
+  // are certain that it cannot be nullptr. Once we switch to client library in
+  // chrome, we can make that happen.
+  internal::TrackEventTlsState* tls_state_ = nullptr;
+  // TODO(kraskevich): Come up with a more precise name once we have more than
+  // one usecase.
+  // TODO(kraskevich): Remove once Chromium has fully switched to client lib.
+  const bool filter_debug_annotations_ = false;
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_EVENT_CONTEXT_H_
+// gen_amalgamated begin header: include/perfetto/tracing/internal/track_event_legacy.h
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_LEGACY_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_LEGACY_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/event_context.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_event.pbzero.h"
+
+#ifndef PERFETTO_ENABLE_LEGACY_TRACE_EVENTS
+#define PERFETTO_ENABLE_LEGACY_TRACE_EVENTS 0
+#endif
+
+// ----------------------------------------------------------------------------
+// Constants.
+// ----------------------------------------------------------------------------
+
+namespace perfetto {
+namespace legacy {
+
+enum TraceEventFlag {
+  kTraceEventFlagNone = 0,
+  kTraceEventFlagCopy = 1u << 0,
+  kTraceEventFlagHasId = 1u << 1,
+  kTraceEventFlagScopeOffset = 1u << 2,
+  kTraceEventFlagScopeExtra = 1u << 3,
+  kTraceEventFlagExplicitTimestamp = 1u << 4,
+  kTraceEventFlagAsyncTTS = 1u << 5,
+  kTraceEventFlagBindToEnclosing = 1u << 6,
+  kTraceEventFlagFlowIn = 1u << 7,
+  kTraceEventFlagFlowOut = 1u << 8,
+  kTraceEventFlagHasContextId = 1u << 9,
+  kTraceEventFlagHasProcessId = 1u << 10,
+  kTraceEventFlagHasLocalId = 1u << 11,
+  kTraceEventFlagHasGlobalId = 1u << 12,
+  // TODO(eseckler): Remove once we have native support for typed proto events
+  // in TRACE_EVENT macros.
+  kTraceEventFlagTypedProtoArgs = 1u << 15,
+  kTraceEventFlagJavaStringLiterals = 1u << 16,
+};
+
+enum PerfettoLegacyCurrentThreadId { kCurrentThreadId };
+
+// The following user-provided adaptors are used to serialize user-defined
+// thread id and time types into track events. For full compatibility, the user
+// should also define the following macros appropriately:
+//
+//   #define TRACE_TIME_TICKS_NOW() ...
+//   #define TRACE_TIME_NOW() ...
+
+// User-provided function to convert an abstract thread id into a thread track.
+template <typename T>
+ThreadTrack ConvertThreadId(const T&);
+
+// Built-in implementation for events referring to the current thread.
+template <>
+ThreadTrack PERFETTO_EXPORT_COMPONENT
+ConvertThreadId(const PerfettoLegacyCurrentThreadId&);
+
+}  // namespace legacy
+}  // namespace perfetto
+
+#if PERFETTO_ENABLE_LEGACY_TRACE_EVENTS
+// The following constants are defined in the global namespace, since they were
+// originally implemented as macros.
+
+// Event phases.
+static constexpr char TRACE_EVENT_PHASE_BEGIN = 'B';
+static constexpr char TRACE_EVENT_PHASE_END = 'E';
+static constexpr char TRACE_EVENT_PHASE_COMPLETE = 'X';
+static constexpr char TRACE_EVENT_PHASE_INSTANT = 'I';
+static constexpr char TRACE_EVENT_PHASE_ASYNC_BEGIN = 'S';
+static constexpr char TRACE_EVENT_PHASE_ASYNC_STEP_INTO = 'T';
+static constexpr char TRACE_EVENT_PHASE_ASYNC_STEP_PAST = 'p';
+static constexpr char TRACE_EVENT_PHASE_ASYNC_END = 'F';
+static constexpr char TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN = 'b';
+static constexpr char TRACE_EVENT_PHASE_NESTABLE_ASYNC_END = 'e';
+static constexpr char TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT = 'n';
+static constexpr char TRACE_EVENT_PHASE_FLOW_BEGIN = 's';
+static constexpr char TRACE_EVENT_PHASE_FLOW_STEP = 't';
+static constexpr char TRACE_EVENT_PHASE_FLOW_END = 'f';
+static constexpr char TRACE_EVENT_PHASE_METADATA = 'M';
+static constexpr char TRACE_EVENT_PHASE_COUNTER = 'C';
+static constexpr char TRACE_EVENT_PHASE_SAMPLE = 'P';
+static constexpr char TRACE_EVENT_PHASE_CREATE_OBJECT = 'N';
+static constexpr char TRACE_EVENT_PHASE_SNAPSHOT_OBJECT = 'O';
+static constexpr char TRACE_EVENT_PHASE_DELETE_OBJECT = 'D';
+static constexpr char TRACE_EVENT_PHASE_MEMORY_DUMP = 'v';
+static constexpr char TRACE_EVENT_PHASE_MARK = 'R';
+static constexpr char TRACE_EVENT_PHASE_CLOCK_SYNC = 'c';
+
+// Flags for changing the behavior of TRACE_EVENT_API_ADD_TRACE_EVENT.
+static constexpr uint32_t TRACE_EVENT_FLAG_NONE =
+    perfetto::legacy::kTraceEventFlagNone;
+static constexpr uint32_t TRACE_EVENT_FLAG_COPY =
+    perfetto::legacy::kTraceEventFlagCopy;
+static constexpr uint32_t TRACE_EVENT_FLAG_HAS_ID =
+    perfetto::legacy::kTraceEventFlagHasId;
+static constexpr uint32_t TRACE_EVENT_FLAG_SCOPE_OFFSET =
+    perfetto::legacy::kTraceEventFlagScopeOffset;
+static constexpr uint32_t TRACE_EVENT_FLAG_SCOPE_EXTRA =
+    perfetto::legacy::kTraceEventFlagScopeExtra;
+static constexpr uint32_t TRACE_EVENT_FLAG_EXPLICIT_TIMESTAMP =
+    perfetto::legacy::kTraceEventFlagExplicitTimestamp;
+static constexpr uint32_t TRACE_EVENT_FLAG_ASYNC_TTS =
+    perfetto::legacy::kTraceEventFlagAsyncTTS;
+static constexpr uint32_t TRACE_EVENT_FLAG_BIND_TO_ENCLOSING =
+    perfetto::legacy::kTraceEventFlagBindToEnclosing;
+static constexpr uint32_t TRACE_EVENT_FLAG_FLOW_IN =
+    perfetto::legacy::kTraceEventFlagFlowIn;
+static constexpr uint32_t TRACE_EVENT_FLAG_FLOW_OUT =
+    perfetto::legacy::kTraceEventFlagFlowOut;
+static constexpr uint32_t TRACE_EVENT_FLAG_HAS_CONTEXT_ID =
+    perfetto::legacy::kTraceEventFlagHasContextId;
+static constexpr uint32_t TRACE_EVENT_FLAG_HAS_PROCESS_ID =
+    perfetto::legacy::kTraceEventFlagHasProcessId;
+static constexpr uint32_t TRACE_EVENT_FLAG_HAS_LOCAL_ID =
+    perfetto::legacy::kTraceEventFlagHasLocalId;
+static constexpr uint32_t TRACE_EVENT_FLAG_HAS_GLOBAL_ID =
+    perfetto::legacy::kTraceEventFlagHasGlobalId;
+static constexpr uint32_t TRACE_EVENT_FLAG_TYPED_PROTO_ARGS =
+    perfetto::legacy::kTraceEventFlagTypedProtoArgs;
+static constexpr uint32_t TRACE_EVENT_FLAG_JAVA_STRING_LITERALS =
+    perfetto::legacy::kTraceEventFlagJavaStringLiterals;
+
+static constexpr uint32_t TRACE_EVENT_FLAG_SCOPE_MASK =
+    TRACE_EVENT_FLAG_SCOPE_OFFSET | TRACE_EVENT_FLAG_SCOPE_EXTRA;
+
+// Type values for identifying types in the TraceValue union.
+static constexpr uint8_t TRACE_VALUE_TYPE_BOOL = 1;
+static constexpr uint8_t TRACE_VALUE_TYPE_UINT = 2;
+static constexpr uint8_t TRACE_VALUE_TYPE_INT = 3;
+static constexpr uint8_t TRACE_VALUE_TYPE_DOUBLE = 4;
+static constexpr uint8_t TRACE_VALUE_TYPE_POINTER = 5;
+static constexpr uint8_t TRACE_VALUE_TYPE_STRING = 6;
+static constexpr uint8_t TRACE_VALUE_TYPE_COPY_STRING = 7;
+static constexpr uint8_t TRACE_VALUE_TYPE_CONVERTABLE = 8;
+static constexpr uint8_t TRACE_VALUE_TYPE_PROTO = 9;
+
+// Enum reflecting the scope of an INSTANT event. Must fit within
+// TRACE_EVENT_FLAG_SCOPE_MASK.
+static constexpr uint8_t TRACE_EVENT_SCOPE_GLOBAL = 0u << 2;
+static constexpr uint8_t TRACE_EVENT_SCOPE_PROCESS = 1u << 2;
+static constexpr uint8_t TRACE_EVENT_SCOPE_THREAD = 2u << 2;
+
+static constexpr char TRACE_EVENT_SCOPE_NAME_GLOBAL = 'g';
+static constexpr char TRACE_EVENT_SCOPE_NAME_PROCESS = 'p';
+static constexpr char TRACE_EVENT_SCOPE_NAME_THREAD = 't';
+
+#define TRACE_EVENT_API_CURRENT_THREAD_ID ::perfetto::legacy::kCurrentThreadId
+
+#endif  // PERFETTO_ENABLE_LEGACY_TRACE_EVENTS
+
+namespace perfetto {
+namespace internal {
+
+// LegacyTraceId encapsulates an ID that can either be an integer or pointer.
+class PERFETTO_EXPORT_COMPONENT LegacyTraceId {
+ public:
+  // Can be combined with WithScope.
+  class LocalId {
+   public:
+    explicit LocalId(const void* raw_id)
+        : raw_id_(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(raw_id))) {}
+    explicit LocalId(uint64_t raw_id) : raw_id_(raw_id) {}
+    uint64_t raw_id() const { return raw_id_; }
+
+   private:
+    uint64_t raw_id_;
+  };
+
+  // Can be combined with WithScope.
+  class GlobalId {
+   public:
+    explicit GlobalId(uint64_t raw_id) : raw_id_(raw_id) {}
+    uint64_t raw_id() const { return raw_id_; }
+
+   private:
+    uint64_t raw_id_;
+  };
+
+  class WithScope {
+   public:
+    WithScope(const char* scope, uint64_t raw_id)
+        : scope_(scope), raw_id_(raw_id) {}
+    WithScope(const char* scope, LocalId local_id)
+        : scope_(scope), raw_id_(local_id.raw_id()) {
+      id_flags_ = legacy::kTraceEventFlagHasLocalId;
+    }
+    WithScope(const char* scope, GlobalId global_id)
+        : scope_(scope), raw_id_(global_id.raw_id()) {
+      id_flags_ = legacy::kTraceEventFlagHasGlobalId;
+    }
+    WithScope(const char* scope, uint64_t prefix, uint64_t raw_id)
+        : scope_(scope), has_prefix_(true), prefix_(prefix), raw_id_(raw_id) {}
+    WithScope(const char* scope, uint64_t prefix, GlobalId global_id)
+        : scope_(scope),
+          has_prefix_(true),
+          prefix_(prefix),
+          raw_id_(global_id.raw_id()) {
+      id_flags_ = legacy::kTraceEventFlagHasGlobalId;
+    }
+    uint64_t raw_id() const { return raw_id_; }
+    const char* scope() const { return scope_; }
+    bool has_prefix() const { return has_prefix_; }
+    uint64_t prefix() const { return prefix_; }
+    uint32_t id_flags() const { return id_flags_; }
+
+   private:
+    const char* scope_ = nullptr;
+    bool has_prefix_ = false;
+    uint64_t prefix_;
+    uint64_t raw_id_;
+    uint32_t id_flags_ = legacy::kTraceEventFlagHasId;
+  };
+
+  explicit LegacyTraceId(const void* raw_id)
+      : raw_id_(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(raw_id))) {
+    id_flags_ = legacy::kTraceEventFlagHasLocalId;
+  }
+  explicit LegacyTraceId(uint64_t raw_id) : raw_id_(raw_id) {}
+  explicit LegacyTraceId(uint32_t raw_id) : raw_id_(raw_id) {}
+  explicit LegacyTraceId(uint16_t raw_id) : raw_id_(raw_id) {}
+  explicit LegacyTraceId(uint8_t raw_id) : raw_id_(raw_id) {}
+  explicit LegacyTraceId(int64_t raw_id)
+      : raw_id_(static_cast<uint64_t>(raw_id)) {}
+  explicit LegacyTraceId(int32_t raw_id)
+      : raw_id_(static_cast<uint64_t>(raw_id)) {}
+  explicit LegacyTraceId(int16_t raw_id)
+      : raw_id_(static_cast<uint64_t>(raw_id)) {}
+  explicit LegacyTraceId(int8_t raw_id)
+      : raw_id_(static_cast<uint64_t>(raw_id)) {}
+// Different platforms disagree on which integer types are same and which
+// are different. E.g. on Mac size_t is considered a different type from
+// uint64_t even though it has the same size and signedness.
+// Below we add overloads for those types that are known to cause ambiguity.
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+  explicit LegacyTraceId(size_t raw_id) : raw_id_(raw_id) {}
+  explicit LegacyTraceId(intptr_t raw_id)
+      : raw_id_(static_cast<uint64_t>(raw_id)) {}
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  explicit LegacyTraceId(unsigned long raw_id) : raw_id_(raw_id) {}
+#endif
+  explicit LegacyTraceId(LocalId raw_id) : raw_id_(raw_id.raw_id()) {
+    id_flags_ = legacy::kTraceEventFlagHasLocalId;
+  }
+  explicit LegacyTraceId(GlobalId raw_id) : raw_id_(raw_id.raw_id()) {
+    id_flags_ = legacy::kTraceEventFlagHasGlobalId;
+  }
+  explicit LegacyTraceId(WithScope scoped_id)
+      : scope_(scoped_id.scope()),
+        has_prefix_(scoped_id.has_prefix()),
+        prefix_(scoped_id.prefix()),
+        raw_id_(scoped_id.raw_id()),
+        id_flags_(scoped_id.id_flags()) {}
+
+  uint64_t raw_id() const { return raw_id_; }
+  const char* scope() const { return scope_; }
+  bool has_prefix() const { return has_prefix_; }
+  uint64_t prefix() const { return prefix_; }
+  uint32_t id_flags() const { return id_flags_; }
+
+  void Write(protos::pbzero::TrackEvent::LegacyEvent*,
+             uint32_t event_flags) const;
+
+ private:
+  const char* scope_ = nullptr;
+  bool has_prefix_ = false;
+  uint64_t prefix_;
+  uint64_t raw_id_;
+  uint32_t id_flags_ = legacy::kTraceEventFlagHasId;
+};
+
+#if PERFETTO_ENABLE_LEGACY_TRACE_EVENTS
+template <typename T>
+bool IsEqual(T x, T y) {
+  return x == y;
+}
+
+template <typename T, typename U>
+bool IsEqual(T, U) {
+  return false;
+}
+
+class PERFETTO_EXPORT_COMPONENT TrackEventLegacy {
+ public:
+  static constexpr protos::pbzero::TrackEvent::Type PhaseToType(char phase) {
+    // clang-format off
+    return (phase == TRACE_EVENT_PHASE_BEGIN) ?
+               protos::pbzero::TrackEvent::TYPE_SLICE_BEGIN :
+           (phase == TRACE_EVENT_PHASE_END) ?
+               protos::pbzero::TrackEvent::TYPE_SLICE_END :
+           (phase == TRACE_EVENT_PHASE_INSTANT) ?
+               protos::pbzero::TrackEvent::TYPE_INSTANT :
+           protos::pbzero::TrackEvent::TYPE_UNSPECIFIED;
+    // clang-format on
+  }
+
+  // Reduce binary size overhead by outlining most of the code for writing a
+  // legacy trace event.
+  template <typename... Args>
+  static void WriteLegacyEvent(EventContext ctx,
+                               char phase,
+                               uint32_t flags,
+                               Args&&... args) PERFETTO_NO_INLINE {
+    PERFETTO_DCHECK(!(flags & TRACE_EVENT_FLAG_HAS_PROCESS_ID));
+    AddDebugAnnotations(&ctx, std::forward<Args>(args)...);
+    if (NeedLegacyFlags(phase, flags)) {
+      auto legacy_event = ctx.event()->set_legacy_event();
+      SetLegacyFlags(legacy_event, phase, flags);
+    }
+  }
+
+  template <typename ThreadIdType, typename... Args>
+  static void WriteLegacyEventWithIdAndTid(EventContext ctx,
+                                           char phase,
+                                           uint32_t flags,
+                                           const LegacyTraceId& id,
+                                           const ThreadIdType& thread_id,
+                                           Args&&... args) PERFETTO_NO_INLINE {
+    //
+    // Overrides to consider:
+    //
+    // 1. If we have an id, we need to write {unscoped,local,global}_id and/or
+    //    bind_id.
+    // 2. If we have a thread id, we need to write track_uuid() or
+    //    {pid,tid}_override if the id represents another process.  The
+    //    conversion from |thread_id| happens in embedder code since the type is
+    //    embedder-specified.
+    // 3. If we have a timestamp, we need to write a different timestamp in the
+    //    trace packet itself and make sure TrackEvent won't write one
+    //    internally. This is already done at the call site.
+    //
+    PERFETTO_DCHECK(PhaseToType(phase) ==
+                        protos::pbzero::TrackEvent::TYPE_UNSPECIFIED ||
+                    !(flags & TRACE_EVENT_FLAG_HAS_PROCESS_ID));
+    flags |= id.id_flags();
+    AddDebugAnnotations(&ctx, std::forward<Args>(args)...);
+    if (NeedLegacyFlags(phase, flags)) {
+      auto legacy_event = ctx.event()->set_legacy_event();
+      SetLegacyFlags(legacy_event, phase, flags);
+      if (id.id_flags())
+        id.Write(legacy_event, flags);
+      if (flags & TRACE_EVENT_FLAG_HAS_PROCESS_ID) {
+        // The thread identifier actually represents a process id. Let's set an
+        // override for it.
+        int32_t pid_override =
+            static_cast<int32_t>(legacy::ConvertThreadId(thread_id).tid);
+        legacy_event->set_pid_override(pid_override);
+        legacy_event->set_tid_override(-1);
+      } else {
+        // Only synchronous phases are supported for other threads. These phases
+        // are supported in TrackEvent types and receive a track_uuid
+        // association via TrackEventDataSource::TraceForCategoryImpl().
+        PERFETTO_DCHECK(PhaseToType(phase) !=
+                            protos::pbzero::TrackEvent::TYPE_UNSPECIFIED ||
+                        IsEqual(thread_id, TRACE_EVENT_API_CURRENT_THREAD_ID) ||
+                        legacy::ConvertThreadId(thread_id).tid ==
+                            ThreadTrack::Current().tid);
+      }
+    }
+  }
+
+  // No arguments.
+  static void AddDebugAnnotations(EventContext*) {}
+
+  // N number of debug arguments.
+  template <typename ArgNameType, typename ArgType, typename... OtherArgs>
+  static void AddDebugAnnotations(EventContext* ctx,
+                                  ArgNameType&& arg_name,
+                                  ArgType&& arg_value,
+                                  OtherArgs&&... more_args) {
+    TrackEventInternal::AddDebugAnnotation(ctx,
+                                           std::forward<ArgNameType>(arg_name),
+                                           std::forward<ArgType>(arg_value));
+    AddDebugAnnotations(ctx, std::forward<OtherArgs>(more_args)...);
+  }
+
+ private:
+  static bool NeedLegacyFlags(char phase, uint32_t flags) {
+    if (PhaseToType(phase) == protos::pbzero::TrackEvent::TYPE_UNSPECIFIED)
+      return true;
+    // TODO(skyostil): Implement/deprecate:
+    // - TRACE_EVENT_FLAG_EXPLICIT_TIMESTAMP
+    // - TRACE_EVENT_FLAG_HAS_CONTEXT_ID
+    // - TRACE_EVENT_FLAG_TYPED_PROTO_ARGS
+    // - TRACE_EVENT_FLAG_JAVA_STRING_LITERALS
+    return flags &
+           (TRACE_EVENT_FLAG_HAS_ID | TRACE_EVENT_FLAG_HAS_LOCAL_ID |
+            TRACE_EVENT_FLAG_HAS_GLOBAL_ID | TRACE_EVENT_FLAG_ASYNC_TTS |
+            TRACE_EVENT_FLAG_BIND_TO_ENCLOSING | TRACE_EVENT_FLAG_FLOW_IN |
+            TRACE_EVENT_FLAG_FLOW_OUT | TRACE_EVENT_FLAG_HAS_PROCESS_ID);
+  }
+
+  static void SetLegacyFlags(
+      protos::pbzero::TrackEvent::LegacyEvent* legacy_event,
+      char phase,
+      uint32_t flags) {
+    if (PhaseToType(phase) == protos::pbzero::TrackEvent::TYPE_UNSPECIFIED)
+      legacy_event->set_phase(phase);
+    if (flags & TRACE_EVENT_FLAG_ASYNC_TTS)
+      legacy_event->set_use_async_tts(true);
+    if (flags & TRACE_EVENT_FLAG_BIND_TO_ENCLOSING)
+      legacy_event->set_bind_to_enclosing(true);
+
+    const auto kFlowIn = TRACE_EVENT_FLAG_FLOW_IN;
+    const auto kFlowOut = TRACE_EVENT_FLAG_FLOW_OUT;
+    const auto kFlowInOut = kFlowIn | kFlowOut;
+    if ((flags & kFlowInOut) == kFlowInOut) {
+      legacy_event->set_flow_direction(
+          protos::pbzero::TrackEvent::LegacyEvent::FLOW_INOUT);
+    } else if (flags & kFlowIn) {
+      legacy_event->set_flow_direction(
+          protos::pbzero::TrackEvent::LegacyEvent::FLOW_IN);
+    } else if (flags & kFlowOut) {
+      legacy_event->set_flow_direction(
+          protos::pbzero::TrackEvent::LegacyEvent::FLOW_OUT);
+    }
+  }
+};
+#endif  // PERFETTO_ENABLE_LEGACY_TRACE_EVENTS
+
+// Legacy macros allow argument values to be nullptr and convert them to the
+// "NULL" string. The following function helps mimic this behavior: it forwards
+// all types of arguments apart from a nullptr string as is, and in case of a
+// nullptr returns "NULL".
+template <typename T>
+inline T PossiblyNull(T&& value) {
+  return std::forward<T>(value);
+}
+
+inline const char* PossiblyNull(const char* name) {
+  return name ? name : "NULL";
+}
+
+inline const char* PossiblyNull(char* name) {
+  return name ? name : "NULL";
+}
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_LEGACY_H_
+// gen_amalgamated begin header: include/perfetto/tracing/internal/write_track_event_args.h
+// gen_amalgamated begin header: include/perfetto/tracing/track_event_args.h
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_TRACK_EVENT_ARGS_H_
+#define INCLUDE_PERFETTO_TRACING_TRACK_EVENT_ARGS_H_
+
+// gen_amalgamated expanded: #include "perfetto/tracing/event_context.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track.h"
+
+namespace perfetto {
+
+// A helper to add |flow_id| as a non-terminating flow id to TRACE_EVENT
+// inline: TRACE_EVENT(..., perfetto::Flow::ProcessScoped(42));
+class Flow {
+ public:
+  // |flow_id| which is local within a given process (e.g. atomic counter xor'ed
+  // with feature-specific value). This value is xor'ed with Perfetto's internal
+  // process track id to attempt to ensure that it's globally-unique.
+  static PERFETTO_ALWAYS_INLINE inline Flow ProcessScoped(uint64_t flow_id) {
+    return Global(flow_id ^ Track::process_uuid);
+  }
+
+  // Same as above, but construct an id from a pointer.
+  // NOTE: After the object is destroyed, the value of |ptr| can be reused for a
+  // different object (in particular if the object is allocated on a stack).
+  // Please ensure that you emit a trace event with the flow id of
+  // perfetto::TerminatingFlow::FromPointer(this) from the destructor of the
+  // object to avoid accidental conflicts.
+  static PERFETTO_ALWAYS_INLINE inline Flow FromPointer(void* ptr) {
+    return ProcessScoped(reinterpret_cast<uintptr_t>(ptr));
+  }
+
+  // Add the |flow_id|. The caller is responsible for ensuring that it's
+  // globally-unique (e.g. by generating a random value). This should be used
+  // only for flow events which cross the process boundary (e.g. IPCs).
+  static PERFETTO_ALWAYS_INLINE inline Flow Global(uint64_t flow_id) {
+    return Flow(flow_id);
+  }
+
+  // TODO(altimin): Remove once converting a single usage in Chromium.
+  explicit constexpr Flow(uint64_t flow_id) : flow_id_(flow_id) {}
+
+  void operator()(EventContext& ctx) const {
+    ctx.event()->add_flow_ids(flow_id_);
+  }
+
+ private:
+  uint64_t flow_id_;
+};
+
+// A helper to add a given |flow_id| as a terminating flow to TRACE_EVENT
+// inline.
+class TerminatingFlow {
+ public:
+  // See `Flow::ProcessScoped(uint64_t)`.
+  static PERFETTO_ALWAYS_INLINE inline TerminatingFlow ProcessScoped(
+      uint64_t flow_id) {
+    return Global(flow_id ^ Track::process_uuid);
+  }
+
+  // See `Flow::FromPointer(void*)`.
+  static PERFETTO_ALWAYS_INLINE inline TerminatingFlow FromPointer(void* ptr) {
+    return ProcessScoped(reinterpret_cast<uintptr_t>(ptr));
+  }
+
+  // See `Flow::Global(uint64_t)`.
+  static PERFETTO_ALWAYS_INLINE inline TerminatingFlow Global(
+      uint64_t flow_id) {
+    TerminatingFlow tf;
+    tf.flow_id_ = flow_id;
+    return tf;
+  }
+
+  void operator()(EventContext& ctx) const {
+    ctx.event()->add_terminating_flow_ids(flow_id_);
+  }
+
+ private:
+  uint64_t flow_id_;
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_TRACK_EVENT_ARGS_H_
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_WRITE_TRACK_EVENT_ARGS_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_WRITE_TRACK_EVENT_ARGS_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/event_context.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/traced_proto.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track_event_args.h"
+
+namespace perfetto {
+namespace internal {
+
+// No arguments means that we don't have to write anything.
+PERFETTO_ALWAYS_INLINE inline void WriteTrackEventArgs(EventContext) {}
+
+namespace {
+
+// A template helper for determining whether a type can be used as a track event
+// lambda, i.e., it has the signature "void(EventContext)". This is achieved by
+// checking that we can pass an EventContext value (the inner declval) into a T
+// instance (the outer declval). If this is a valid expression, the result
+// evaluates to sizeof(0), i.e., true.
+// TODO(skyostil): Replace this with std::is_convertible<std::function<...>>
+// once we have C++14.
+template <typename T>
+static constexpr bool IsValidTraceLambdaImpl(
+    typename std::enable_if<static_cast<bool>(
+        sizeof(std::declval<T>()(std::declval<EventContext>()), 0))>::type* =
+        nullptr) {
+  return true;
+}
+
+template <typename T>
+static constexpr bool IsValidTraceLambdaImpl(...) {
+  return false;
+}
+
+template <typename T>
+static constexpr bool IsValidTraceLambda() {
+  return IsValidTraceLambdaImpl<T>(nullptr);
+}
+
+template <typename T>
+static constexpr bool IsValidTraceLambdaTakingReferenceImpl(
+    typename std::enable_if<static_cast<bool>(
+        sizeof(std::declval<T>()(std::declval<EventContext&>()), 0))>::type* =
+        nullptr) {
+  return true;
+}
+
+template <typename T>
+static constexpr bool IsValidTraceLambdaTakingReferenceImpl(...) {
+  return false;
+}
+
+template <typename T>
+static constexpr bool IsValidTraceLambdaTakingReference() {
+  return IsValidTraceLambdaTakingReferenceImpl<T>(nullptr);
+}
+
+template <typename T>
+static constexpr bool IsFieldMetadataTypeImpl(
+    typename std::enable_if<
+        std::is_base_of<protozero::proto_utils::FieldMetadataBase,
+                        T>::value>::type* = nullptr) {
+  return true;
+}
+
+template <typename T>
+static constexpr bool IsFieldMetadataTypeImpl(...) {
+  return false;
+}
+
+template <typename T>
+static constexpr bool IsFieldMetadataType() {
+  return IsFieldMetadataTypeImpl<T>(nullptr);
+}
+
+}  // namespace
+
+// Write an old-style lambda taking an EventContext (without a reference)
+// as it will consume EventContext via std::move, it can only be the last
+// argument.
+template <typename ArgumentFunction,
+          typename ArgFunctionCheck = typename std::enable_if<
+              IsValidTraceLambda<ArgumentFunction>()>::type>
+PERFETTO_ALWAYS_INLINE void WriteTrackEventArgs(
+    EventContext event_ctx,
+    const ArgumentFunction& arg_function) {
+  arg_function(std::move(event_ctx));
+}
+
+// Forward-declare the specification for writing untyped arguments to ensure
+// that typed specification could recursively pick it up.
+template <typename ArgValue, typename... Args>
+PERFETTO_ALWAYS_INLINE void WriteTrackEventArgs(EventContext event_ctx,
+                                                const char* arg_name,
+                                                ArgValue&& arg_value,
+                                                Args&&... args);
+
+template <typename FieldMetadataType,
+          typename ArgValue,
+          typename... Args,
+          typename FieldMetadataTypeCheck = typename std::enable_if<
+              IsFieldMetadataType<FieldMetadataType>()>::type>
+PERFETTO_ALWAYS_INLINE void WriteTrackEventArgs(EventContext event_ctx,
+                                                FieldMetadataType field_name,
+                                                ArgValue&& arg_value,
+                                                Args&&... args);
+
+template <typename ArgumentFunction,
+          typename... Args,
+          typename ArgFunctionCheck = typename std::enable_if<
+              IsValidTraceLambdaTakingReference<ArgumentFunction>()>::type>
+PERFETTO_ALWAYS_INLINE void WriteTrackEventArgs(
+    EventContext event_ctx,
+    const ArgumentFunction& arg_function,
+    Args&&... args) {
+  // |arg_function| will capture EventContext by reference, so std::move isn't
+  // needed.
+  arg_function(event_ctx);
+
+  WriteTrackEventArgs(std::move(event_ctx), std::forward<Args>(args)...);
+}
+
+// Write one typed message and recursively write the rest of the arguments.
+template <typename FieldMetadataType,
+          typename ArgValue,
+          typename... Args,
+          typename FieldMetadataTypeCheck>
+PERFETTO_ALWAYS_INLINE void WriteTrackEventArgs(EventContext event_ctx,
+                                                FieldMetadataType field_name,
+                                                ArgValue&& arg_value,
+                                                Args&&... args) {
+  static_assert(std::is_base_of<protozero::proto_utils::FieldMetadataBase,
+                                FieldMetadataType>::value,
+                "");
+  static_assert(
+      std::is_base_of<protos::pbzero::TrackEvent,
+                      typename FieldMetadataType::message_type>::value,
+      "Only fields of TrackEvent (and TrackEvent's extensions) can "
+      "be passed to TRACE_EVENT");
+  auto track_event_proto = event_ctx.Wrap(
+      event_ctx.event<typename FieldMetadataType::message_type>());
+  WriteTracedProtoField(track_event_proto, field_name,
+                        std::forward<ArgValue>(arg_value));
+  WriteTrackEventArgs(std::move(event_ctx), std::forward<Args>(args)...);
+}
+
+// Write one debug annotation and recursively write the rest of the arguments.
+template <typename ArgValue, typename... Args>
+PERFETTO_ALWAYS_INLINE void WriteTrackEventArgs(EventContext event_ctx,
+                                                const char* arg_name,
+                                                ArgValue&& arg_value,
+                                                Args&&... args) {
+  event_ctx.AddDebugAnnotation(arg_name, std::forward<ArgValue>(arg_value));
+  WriteTrackEventArgs(std::move(event_ctx), std::forward<Args>(args)...);
+}
+
+// Write one debug annotation and recursively write the rest of the arguments.
+template <typename ArgValue, typename... Args>
+PERFETTO_ALWAYS_INLINE void WriteTrackEventArgs(EventContext event_ctx,
+                                                DynamicString arg_name,
+                                                ArgValue&& arg_value,
+                                                Args&&... args) {
+  event_ctx.AddDebugAnnotation(arg_name, std::forward<ArgValue>(arg_value));
+  WriteTrackEventArgs(std::move(event_ctx), std::forward<Args>(args)...);
+}
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_WRITE_TRACK_EVENT_ARGS_H_
+// gen_amalgamated begin header: include/perfetto/tracing/track_event_category_registry.h
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_TRACK_EVENT_CATEGORY_REGISTRY_H_
+#define INCLUDE_PERFETTO_TRACING_TRACK_EVENT_CATEGORY_REGISTRY_H_
+
+// gen_amalgamated expanded: #include "perfetto/tracing/data_source.h"
+
+#include <stddef.h>
+
+#include <atomic>
+#include <utility>
+
+namespace perfetto {
+class DynamicCategory;
+
+// A compile-time representation of a track event category. See
+// PERFETTO_DEFINE_CATEGORIES for registering your own categories.
+struct PERFETTO_EXPORT_COMPONENT Category {
+  using Tags = std::array<const char*, 4>;
+
+  const char* const name = nullptr;
+  const char* const description = nullptr;
+  const Tags tags = {};
+
+  constexpr Category(const Category&) = default;
+  constexpr explicit Category(const char* name_)
+      : name(CheckIsValidCategory(name_)),
+        name_sizes_(ComputeNameSizes(name_)) {}
+
+  constexpr Category SetDescription(const char* description_) const {
+    return Category(name, description_, tags, name_sizes_);
+  }
+
+  template <typename... Args>
+  constexpr Category SetTags(Args&&... args) const {
+    return Category(name, description, {std::forward<Args>(args)...},
+                    name_sizes_);
+  }
+
+  // A comma separated list of multiple categories to be used in a single trace
+  // point.
+  static constexpr Category Group(const char* names) {
+    return Category(names, AllowGroup{});
+  }
+
+  // Used for parsing dynamic category groups. Note that |name| and
+  // |DynamicCategory| must outlive the returned object because the category
+  // name isn't copied.
+  static Category FromDynamicCategory(const char* name);
+  static Category FromDynamicCategory(const DynamicCategory&);
+
+  constexpr bool IsGroup() const { return GetNameSize(1) > 0; }
+
+  // Returns the number of character in the category name. Not valid for
+  // category groups.
+  size_t name_size() const {
+    PERFETTO_DCHECK(!IsGroup());
+    return GetNameSize(0);
+  }
+
+  // Iterates over all the members of this category group, or just the name of
+  // the category itself if this isn't a category group. Return false from
+  // |callback| to stop iteration.
+  template <typename T>
+  void ForEachGroupMember(T callback) const {
+    const char* name_ptr = name;
+    size_t i = 0;
+    while (size_t name_size = GetNameSize(i++)) {
+      if (!callback(name_ptr, name_size))
+        break;
+      name_ptr += name_size + 1;
+    }
+  }
+
+ private:
+  static constexpr size_t kMaxGroupSize = 4;
+  using NameSizes = std::array<uint8_t, kMaxGroupSize>;
+
+  constexpr Category(const char* name_,
+                     const char* description_,
+                     Tags tags_,
+                     NameSizes name_sizes)
+      : name(name_),
+        description(description_),
+        tags(tags_),
+        name_sizes_(name_sizes) {}
+
+  enum AllowGroup {};
+  constexpr Category(const char* name_, AllowGroup)
+      : name(CheckIsValidCategoryGroup(name_)),
+        name_sizes_(ComputeNameSizes(name_)) {}
+
+  constexpr size_t GetNameSize(size_t i) const {
+    return i < name_sizes_.size() ? name_sizes_[i] : 0;
+  }
+
+  static constexpr NameSizes ComputeNameSizes(const char* s) {
+    static_assert(kMaxGroupSize == 4, "Unexpected maximum category group size");
+    return NameSizes{{static_cast<uint8_t>(GetNthNameSize(0, s, s)),
+                      static_cast<uint8_t>(GetNthNameSize(1, s, s)),
+                      static_cast<uint8_t>(GetNthNameSize(2, s, s)),
+                      static_cast<uint8_t>(GetNthNameSize(3, s, s))}};
+  }
+
+  static constexpr ptrdiff_t GetNthNameSize(int n,
+                                            const char* start,
+                                            const char* end,
+                                            int counter = 0) {
+    return (!*end || *end == ',')
+               ? ((!*end || counter == n)
+                      ? (counter == n ? end - start : 0)
+                      : GetNthNameSize(n, end + 1, end + 1, counter + 1))
+               : GetNthNameSize(n, start, end + 1, counter);
+  }
+
+  static constexpr const char* CheckIsValidCategory(const char* n) {
+    // We just replace invalid input with a nullptr here; it will trigger a
+    // static assert in TrackEventCategoryRegistry::ValidateCategories().
+    return GetNthNameSize(1, n, n) ? nullptr : n;
+  }
+
+  static constexpr const char* CheckIsValidCategoryGroup(const char* n) {
+    // Same as above: replace invalid input with nullptr.
+    return !GetNthNameSize(1, n, n) || GetNthNameSize(kMaxGroupSize, n, n)
+               ? nullptr
+               : n;
+  }
+
+  // An array of lengths of the different names associated with this category.
+  // If this category doesn't represent a group of multiple categories, only the
+  // first element is non-zero.
+  const NameSizes name_sizes_ = {};
+};
+
+// Dynamically constructed category names should marked as such through this
+// container type to make it less likely for trace points to accidentally start
+// using dynamic categories. Events with dynamic categories will always be
+// slightly more expensive than regular events, so use them sparingly.
+class PERFETTO_EXPORT_COMPONENT DynamicCategory final {
+ public:
+  explicit DynamicCategory(const std::string& name_) : name(name_) {}
+  explicit DynamicCategory(const char* name_) : name(name_) {}
+  DynamicCategory() {}
+  ~DynamicCategory() = default;
+
+  DynamicCategory(const DynamicCategory&) = default;
+  DynamicCategory& operator=(const DynamicCategory&) = delete;
+
+  DynamicCategory(DynamicCategory&&) = default;
+  DynamicCategory& operator=(DynamicCategory&&) = delete;
+
+  const std::string name;
+};
+
+namespace internal {
+
+constexpr const char* NullCategory(const char*) {
+  return nullptr;
+}
+
+perfetto::DynamicCategory NullCategory(const perfetto::DynamicCategory&);
+
+constexpr bool StringMatchesPrefix(const char* str, const char* prefix) {
+  return !*str ? !*prefix
+               : !*prefix ? true
+                          : *str != *prefix
+                                ? false
+                                : StringMatchesPrefix(str + 1, prefix + 1);
+}
+
+constexpr bool IsStringInPrefixList(const char*) {
+  return false;
+}
+
+template <typename... Args>
+constexpr bool IsStringInPrefixList(const char* str,
+                                    const char* prefix,
+                                    Args... args) {
+  return StringMatchesPrefix(str, prefix) ||
+         IsStringInPrefixList(str, std::forward<Args>(args)...);
+}
+
+// Holds all the registered categories for one category namespace. See
+// PERFETTO_DEFINE_CATEGORIES for building the registry.
+class PERFETTO_EXPORT_COMPONENT TrackEventCategoryRegistry {
+ public:
+  constexpr TrackEventCategoryRegistry(size_t category_count,
+                                       const Category* categories,
+                                       std::atomic<uint8_t>* state_storage)
+      : categories_(categories),
+        category_count_(category_count),
+        state_storage_(state_storage) {
+    static_assert(
+        sizeof(state_storage[0].load()) * 8 >= kMaxDataSourceInstances,
+        "The category state must have enough bits for all possible data source "
+        "instances");
+  }
+
+  size_t category_count() const { return category_count_; }
+
+  // Returns a category based on its index.
+  const Category* GetCategory(size_t index) const {
+    PERFETTO_DCHECK(index < category_count_);
+    return &categories_[index];
+  }
+
+  // Turn tracing on or off for the given category in a track event data source
+  // instance.
+  void EnableCategoryForInstance(size_t category_index,
+                                 uint32_t instance_index) const;
+  void DisableCategoryForInstance(size_t category_index,
+                                  uint32_t instance_index) const;
+
+  constexpr std::atomic<uint8_t>* GetCategoryState(
+      size_t category_index) const {
+    return &state_storage_[category_index];
+  }
+
+  // --------------------------------------------------------------------------
+  // Trace point support
+  // --------------------------------------------------------------------------
+  //
+  // (The following methods are used by the track event trace point
+  // implementation and typically don't need to be called by other code.)
+
+  // At compile time, turn a category name into an index into the registry.
+  // Returns kInvalidCategoryIndex if the category was not found, or
+  // kDynamicCategoryIndex if |is_dynamic| is true or a DynamicCategory was
+  // passed in.
+  static constexpr size_t kInvalidCategoryIndex = static_cast<size_t>(-1);
+  static constexpr size_t kDynamicCategoryIndex = static_cast<size_t>(-2);
+  constexpr size_t Find(const char* name, bool is_dynamic) const {
+    return CheckIsValidCategoryIndex(FindImpl(name, is_dynamic));
+  }
+
+  constexpr size_t Find(const DynamicCategory&, bool) const {
+    return kDynamicCategoryIndex;
+  }
+
+  constexpr bool ValidateCategories(size_t index = 0) const {
+    return (index == category_count_)
+               ? true
+               : IsValidCategoryName(categories_[index].name)
+                     ? ValidateCategories(index + 1)
+                     : false;
+  }
+
+ private:
+  // TODO(skyostil): Make the compile-time routines nicer with C++14.
+  constexpr size_t FindImpl(const char* name,
+                            bool is_dynamic,
+                            size_t index = 0) const {
+    return is_dynamic ? kDynamicCategoryIndex
+                      : (index == category_count_)
+                            ? kInvalidCategoryIndex
+                            : StringEq(categories_[index].name, name)
+                                  ? index
+                                  : FindImpl(name, false, index + 1);
+  }
+
+  // A compile time helper for checking that a category index is valid.
+  static constexpr size_t CheckIsValidCategoryIndex(size_t index) {
+    // Relies on PERFETTO_CHECK() (and the surrounding lambda) being a
+    // non-constexpr function, which will fail the build if the given |index| is
+    // invalid. The funny formatting here is so that clang shows the comment
+    // below as part of the error message.
+    // clang-format off
+    return index != kInvalidCategoryIndex ? index : \
+        /* Invalid category -- add it to PERFETTO_DEFINE_CATEGORIES(). */ [] {
+        PERFETTO_CHECK(
+            false &&
+            "A track event used an unknown category. Please add it to "
+            "PERFETTO_DEFINE_CATEGORIES().");
+        return kInvalidCategoryIndex;
+      }();
+    // clang-format on
+  }
+
+  static constexpr bool IsValidCategoryName(const char* name) {
+    return (!name || *name == '\"' || *name == '*' || *name == ' ')
+               ? false
+               : *name ? IsValidCategoryName(name + 1) : true;
+  }
+
+  static constexpr bool StringEq(const char* a, const char* b) {
+    return *a != *b ? false
+                    : (!*a || !*b) ? (*a == *b) : StringEq(a + 1, b + 1);
+  }
+
+  const Category* const categories_;
+  const size_t category_count_;
+  std::atomic<uint8_t>* const state_storage_;
+};
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_TRACK_EVENT_CATEGORY_REGISTRY_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/track_event/track_event_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TRACK_EVENT_TRACK_EVENT_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TRACK_EVENT_TRACK_EVENT_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class TrackEventConfig;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT TrackEventConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDisabledCategoriesFieldNumber = 1,
+    kEnabledCategoriesFieldNumber = 2,
+    kDisabledTagsFieldNumber = 3,
+    kEnabledTagsFieldNumber = 4,
+    kDisableIncrementalTimestampsFieldNumber = 5,
+    kTimestampUnitMultiplierFieldNumber = 6,
+    kFilterDebugAnnotationsFieldNumber = 7,
+    kEnableThreadTimeSamplingFieldNumber = 8,
+    kFilterDynamicEventNamesFieldNumber = 9,
+  };
+
+  TrackEventConfig();
+  ~TrackEventConfig() override;
+  TrackEventConfig(TrackEventConfig&&) noexcept;
+  TrackEventConfig& operator=(TrackEventConfig&&);
+  TrackEventConfig(const TrackEventConfig&);
+  TrackEventConfig& operator=(const TrackEventConfig&);
+  bool operator==(const TrackEventConfig&) const;
+  bool operator!=(const TrackEventConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<std::string>& disabled_categories() const { return disabled_categories_; }
+  std::vector<std::string>* mutable_disabled_categories() { return &disabled_categories_; }
+  int disabled_categories_size() const { return static_cast<int>(disabled_categories_.size()); }
+  void clear_disabled_categories() { disabled_categories_.clear(); }
+  void add_disabled_categories(std::string value) { disabled_categories_.emplace_back(value); }
+  std::string* add_disabled_categories() { disabled_categories_.emplace_back(); return &disabled_categories_.back(); }
+
+  const std::vector<std::string>& enabled_categories() const { return enabled_categories_; }
+  std::vector<std::string>* mutable_enabled_categories() { return &enabled_categories_; }
+  int enabled_categories_size() const { return static_cast<int>(enabled_categories_.size()); }
+  void clear_enabled_categories() { enabled_categories_.clear(); }
+  void add_enabled_categories(std::string value) { enabled_categories_.emplace_back(value); }
+  std::string* add_enabled_categories() { enabled_categories_.emplace_back(); return &enabled_categories_.back(); }
+
+  const std::vector<std::string>& disabled_tags() const { return disabled_tags_; }
+  std::vector<std::string>* mutable_disabled_tags() { return &disabled_tags_; }
+  int disabled_tags_size() const { return static_cast<int>(disabled_tags_.size()); }
+  void clear_disabled_tags() { disabled_tags_.clear(); }
+  void add_disabled_tags(std::string value) { disabled_tags_.emplace_back(value); }
+  std::string* add_disabled_tags() { disabled_tags_.emplace_back(); return &disabled_tags_.back(); }
+
+  const std::vector<std::string>& enabled_tags() const { return enabled_tags_; }
+  std::vector<std::string>* mutable_enabled_tags() { return &enabled_tags_; }
+  int enabled_tags_size() const { return static_cast<int>(enabled_tags_.size()); }
+  void clear_enabled_tags() { enabled_tags_.clear(); }
+  void add_enabled_tags(std::string value) { enabled_tags_.emplace_back(value); }
+  std::string* add_enabled_tags() { enabled_tags_.emplace_back(); return &enabled_tags_.back(); }
+
+  bool has_disable_incremental_timestamps() const { return _has_field_[5]; }
+  bool disable_incremental_timestamps() const { return disable_incremental_timestamps_; }
+  void set_disable_incremental_timestamps(bool value) { disable_incremental_timestamps_ = value; _has_field_.set(5); }
+
+  bool has_timestamp_unit_multiplier() const { return _has_field_[6]; }
+  uint64_t timestamp_unit_multiplier() const { return timestamp_unit_multiplier_; }
+  void set_timestamp_unit_multiplier(uint64_t value) { timestamp_unit_multiplier_ = value; _has_field_.set(6); }
+
+  bool has_filter_debug_annotations() const { return _has_field_[7]; }
+  bool filter_debug_annotations() const { return filter_debug_annotations_; }
+  void set_filter_debug_annotations(bool value) { filter_debug_annotations_ = value; _has_field_.set(7); }
+
+  bool has_enable_thread_time_sampling() const { return _has_field_[8]; }
+  bool enable_thread_time_sampling() const { return enable_thread_time_sampling_; }
+  void set_enable_thread_time_sampling(bool value) { enable_thread_time_sampling_ = value; _has_field_.set(8); }
+
+  bool has_filter_dynamic_event_names() const { return _has_field_[9]; }
+  bool filter_dynamic_event_names() const { return filter_dynamic_event_names_; }
+  void set_filter_dynamic_event_names(bool value) { filter_dynamic_event_names_ = value; _has_field_.set(9); }
+
+ private:
+  std::vector<std::string> disabled_categories_;
+  std::vector<std::string> enabled_categories_;
+  std::vector<std::string> disabled_tags_;
+  std::vector<std::string> enabled_tags_;
+  bool disable_incremental_timestamps_{};
+  uint64_t timestamp_unit_multiplier_{};
+  bool filter_debug_annotations_{};
+  bool enable_thread_time_sampling_{};
+  bool filter_dynamic_event_names_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<10> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TRACK_EVENT_TRACK_EVENT_CONFIG_PROTO_CPP_H_
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_DATA_SOURCE_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_DATA_SOURCE_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/template_util.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_config.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/data_source.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/event_context.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_internal.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_legacy.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/write_track_event_args.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track_event_category_registry.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/track_event/track_event_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_event.pbzero.h"
+
+#include <type_traits>
+
+namespace perfetto {
+
+namespace {
+
+class StopArgsImpl : public DataSourceBase::StopArgs {
+ public:
+  // HandleAsynchronously() can optionally be called to defer the tracing
+  // session stop and write track events just before stopping. This function
+  // returns a closure that must be invoked after the last track events have
+  // been emitted. The caller also needs to explicitly call
+  // TrackEvent::Flush() because no other implicit flushes will happen after
+  // the stop signal.
+  // See the comment in include/perfetto/tracing/data_source.h for more info.
+  std::function<void()> HandleStopAsynchronously() const override {
+    auto closure = std::move(async_stop_closure);
+    async_stop_closure = std::function<void()>();
+    return closure;
+  }
+
+  mutable std::function<void()> async_stop_closure;
+};
+
+}  // namespace
+
+// A function for converting an abstract timestamp into a
+// perfetto::TraceTimestamp struct. By specialising this template and defining
+// static ConvertTimestampToTraceTimeNs function in it the user can register
+// additional timestamp types. The return value should specify the
+// clock domain used by the timestamp as well as its value.
+//
+// The supported clock domains are the ones described in
+// perfetto.protos.ClockSnapshot. However, custom clock IDs (>=64) are
+// reserved for internal use by the SDK for the time being.
+// The timestamp value should be in nanoseconds regardless of the clock domain.
+template <typename T>
+struct TraceTimestampTraits;
+
+// A pass-through implementation for raw uint64_t nanosecond timestamps.
+template <>
+struct TraceTimestampTraits<uint64_t> {
+  static inline TraceTimestamp ConvertTimestampToTraceTimeNs(
+      const uint64_t& timestamp) {
+    return {static_cast<uint32_t>(internal::TrackEventInternal::GetClockId()), timestamp};
+  }
+};
+
+// A pass-through implementation for the trace timestamp structure.
+template <>
+struct TraceTimestampTraits<TraceTimestamp> {
+  static inline TraceTimestamp ConvertTimestampToTraceTimeNs(
+      const TraceTimestamp& timestamp) {
+    return timestamp;
+  }
+};
+
+namespace internal {
+namespace {
+
+// Checks if |T| is a valid track.
+template <typename T>
+static constexpr bool IsValidTrack() {
+  return std::is_convertible<T, Track>::value;
+}
+
+// Checks if |T| is a valid non-counter track.
+template <typename T>
+static constexpr bool IsValidNormalTrack() {
+  return std::is_convertible<T, Track>::value &&
+         !std::is_convertible<T, CounterTrack>::value;
+}
+
+// Because the user can use arbitrary timestamp types, we can't compare against
+// any known base type here. Instead, we check that a track or a trace lambda
+// isn't being interpreted as a timestamp.
+template <typename T,
+          typename CanBeConvertedToNsCheck = decltype(
+              ::perfetto::TraceTimestampTraits<typename base::remove_cvref_t<
+                  T>>::ConvertTimestampToTraceTimeNs(std::declval<T>())),
+          typename NotTrackCheck =
+              typename std::enable_if<!IsValidNormalTrack<T>()>::type,
+          typename NotLambdaCheck =
+              typename std::enable_if<!IsValidTraceLambda<T>()>::type>
+static constexpr bool IsValidTimestamp() {
+  return true;
+}
+
+// Taken from C++17
+template <typename...>
+using void_t = void;
+
+// Returns true iff `GetStaticString(T)` is defined OR T == DynamicString.
+template <typename T, typename = void>
+struct IsValidEventNameType
+    : std::is_same<perfetto::DynamicString, typename std::decay<T>::type> {};
+
+template <typename T>
+struct IsValidEventNameType<
+    T,
+    void_t<decltype(GetStaticString(std::declval<T>()))>> : std::true_type {};
+
+template <typename T>
+inline void ValidateEventNameType() {
+  static_assert(
+      IsValidEventNameType<T>::value,
+      "Event names must be static strings. To use dynamic event names, see "
+      "https://perfetto.dev/docs/instrumentation/"
+      "track-events#dynamic-event-names");
+}
+
+inline bool UnorderedEqual(std::vector<std::string> vec1,
+                           std::vector<std::string> vec2) {
+  std::sort(vec1.begin(), vec1.end());
+  vec1.erase(std::unique(vec1.begin(), vec1.end()), vec1.end());
+  std::sort(vec2.begin(), vec2.end());
+  vec2.erase(std::unique(vec2.begin(), vec2.end()), vec2.end());
+  return vec1 == vec2;
+}
+
+}  // namespace
+
+inline ::perfetto::DynamicString DecayEventNameType(
+    ::perfetto::DynamicString name) {
+  return name;
+}
+
+inline ::perfetto::StaticString DecayEventNameType(
+    ::perfetto::StaticString name) {
+  return name;
+}
+
+// Convert all static strings of different length to StaticString to avoid
+// unnecessary template instantiations.
+inline ::perfetto::StaticString DecayEventNameType(const char* name) {
+  return ::perfetto::StaticString{name};
+}
+
+// Traits for dynamic categories.
+template <typename CategoryType>
+struct CategoryTraits {
+  static constexpr bool kIsDynamic = true;
+  static constexpr const Category* GetStaticCategory(
+      const TrackEventCategoryRegistry*,
+      const CategoryType&) {
+    return nullptr;
+  }
+  static size_t GetStaticIndex(const CategoryType&) {
+    PERFETTO_DCHECK(false);  // Not reached.
+    return TrackEventCategoryRegistry::kDynamicCategoryIndex;
+  }
+  static DynamicCategory GetDynamicCategory(const CategoryType& category) {
+    return DynamicCategory{category};
+  }
+};
+
+// Traits for static categories.
+template <>
+struct CategoryTraits<size_t> {
+  static constexpr bool kIsDynamic = false;
+  static const Category* GetStaticCategory(
+      const TrackEventCategoryRegistry* registry,
+      size_t category_index) {
+    return registry->GetCategory(category_index);
+  }
+  static constexpr size_t GetStaticIndex(size_t category_index) {
+    return category_index;
+  }
+  static DynamicCategory GetDynamicCategory(size_t) {
+    PERFETTO_DCHECK(false);  // Not reached.
+    return DynamicCategory();
+  }
+};
+
+struct TrackEventDataSourceTraits : public perfetto::DefaultDataSourceTraits {
+  using IncrementalStateType = TrackEventIncrementalState;
+  using TlsStateType = TrackEventTlsState;
+
+  // Use a one shared TLS slot so that all track event data sources write into
+  // the same sequence and share interning dictionaries.
+  static DataSourceThreadLocalState* GetDataSourceTLS(DataSourceStaticState*,
+                                                      TracingTLS* root_tls) {
+    return &root_tls->track_event_tls;
+  }
+};
+
+// A generic track event data source which is instantiated once per track event
+// category namespace.
+template <typename DerivedDataSource,
+          const TrackEventCategoryRegistry* Registry>
+class TrackEventDataSource
+    : public DataSource<DerivedDataSource, TrackEventDataSourceTraits> {
+  using Base = DataSource<DerivedDataSource, TrackEventDataSourceTraits>;
+
+ public:
+  static constexpr bool kRequiresCallbacksUnderLock = false;
+
+  // Add or remove a session observer for this track event data source. The
+  // observer will be notified about started and stopped tracing sessions.
+  // Returns |true| if the observer was successfully added (i.e., the maximum
+  // number of observers wasn't exceeded).
+  static bool AddSessionObserver(TrackEventSessionObserver* observer) {
+    return TrackEventInternal::AddSessionObserver(*Registry, observer);
+  }
+
+  static void RemoveSessionObserver(TrackEventSessionObserver* observer) {
+    TrackEventInternal::RemoveSessionObserver(*Registry, observer);
+  }
+
+  // DataSource implementation.
+  void OnSetup(const DataSourceBase::SetupArgs& args) override {
+    auto config_raw = args.config->track_event_config_raw();
+    bool ok = config_.ParseFromArray(config_raw.data(), config_raw.size());
+    PERFETTO_DCHECK(ok);
+    TrackEventInternal::EnableTracing(*Registry, config_, args);
+  }
+
+  void OnStart(const DataSourceBase::StartArgs& args) override {
+    TrackEventInternal::OnStart(*Registry, args);
+  }
+
+  void OnStop(const DataSourceBase::StopArgs& args) override {
+    auto outer_stop_closure = args.HandleStopAsynchronously();
+    StopArgsImpl inner_stop_args{};
+    uint32_t internal_instance_index = args.internal_instance_index;
+    inner_stop_args.internal_instance_index = internal_instance_index;
+    inner_stop_args.async_stop_closure = [internal_instance_index,
+                                          outer_stop_closure] {
+      TrackEventInternal::DisableTracing(*Registry, internal_instance_index);
+      outer_stop_closure();
+    };
+
+    TrackEventInternal::OnStop(*Registry, inner_stop_args);
+
+    // If inner_stop_args.HandleStopAsynchronously() hasn't been called,
+    // run the async closure here.
+    if (inner_stop_args.async_stop_closure)
+      std::move(inner_stop_args.async_stop_closure)();
+  }
+
+  void WillClearIncrementalState(
+      const DataSourceBase::ClearIncrementalStateArgs& args) override {
+    TrackEventInternal::WillClearIncrementalState(*Registry, args);
+  }
+
+  // In Chrome, startup sessions are propagated from the browser process to
+  // child processes using command-line flags. Command-line flags can only
+  // convey the category filter and privacy settings, so we use only those
+  // to determine which startup sessions to adopt.
+  // TODO(khokhlov): After Chrome is able to propagate the entire config to the
+  // child process, we can make this comparison more strict by only clearing
+  // selected fields and comparing everything else. One specific thing to keep
+  // in mind is to clear the |convert_to_legacy_json| field, because Telemetry
+  // initiates tracing with proto format, but in some cases adopts the tracing
+  // session later via devtools which expect json format.
+  bool CanAdoptStartupSession(const DataSourceConfig& startup_config,
+                              const DataSourceConfig& service_config) override {
+    if (startup_config.track_event_config_raw().empty() ||
+        service_config.track_event_config_raw().empty()) {
+      return false;
+    }
+
+    protos::gen::TrackEventConfig startup_te_cfg;
+    startup_te_cfg.ParseFromString(startup_config.track_event_config_raw());
+    protos::gen::TrackEventConfig service_te_cfg;
+    service_te_cfg.ParseFromString(service_config.track_event_config_raw());
+
+    if (!UnorderedEqual(startup_te_cfg.enabled_categories(),
+                        service_te_cfg.enabled_categories())) {
+      return false;
+    }
+    if (!UnorderedEqual(startup_te_cfg.disabled_categories(),
+                        service_te_cfg.disabled_categories())) {
+      return false;
+    }
+    if (!UnorderedEqual(startup_te_cfg.enabled_tags(),
+                        service_te_cfg.enabled_tags())) {
+      return false;
+    }
+    if (!UnorderedEqual(startup_te_cfg.disabled_tags(),
+                        service_te_cfg.disabled_tags())) {
+      return false;
+    }
+    if (startup_te_cfg.filter_debug_annotations() !=
+        service_te_cfg.filter_debug_annotations()) {
+      return false;
+    }
+    if (startup_te_cfg.filter_dynamic_event_names() !=
+        service_te_cfg.filter_dynamic_event_names()) {
+      return false;
+    }
+
+    return true;
+  }
+
+  static void Flush() {
+    Base::template Trace([](typename Base::TraceContext ctx) { ctx.Flush(); });
+  }
+
+  // Determine if *any* tracing category is enabled.
+  static bool IsEnabled() {
+    bool enabled = false;
+    Base::template CallIfEnabled(
+        [&](uint32_t /*instances*/) { enabled = true; });
+    return enabled;
+  }
+
+  // Determine if tracing for the given static category is enabled.
+  static bool IsCategoryEnabled(size_t category_index) {
+    return Registry->GetCategoryState(category_index)
+        ->load(std::memory_order_relaxed);
+  }
+
+  // Determine if tracing for the given dynamic category is enabled.
+  static bool IsDynamicCategoryEnabled(
+      const DynamicCategory& dynamic_category) {
+    bool enabled = false;
+    Base::template Trace([&](typename Base::TraceContext ctx) {
+      enabled = enabled || IsDynamicCategoryEnabled(&ctx, dynamic_category);
+    });
+    return enabled;
+  }
+
+  // This is the inlined entrypoint for all track event trace points. It tries
+  // to be as lightweight as possible in terms of instructions and aims to
+  // compile down to an unlikely conditional jump to the actual trace writing
+  // function.
+  template <typename Callback>
+  static void CallIfCategoryEnabled(size_t category_index,
+                                    Callback callback) PERFETTO_ALWAYS_INLINE {
+    Base::template CallIfEnabled<CategoryTracePointTraits>(
+        [&callback](uint32_t instances) { callback(instances); },
+        {category_index});
+  }
+
+  // The following methods forward all arguments to TraceForCategoryBody
+  // while casting string constants to const char* and integer arguments to
+  // int64_t, uint64_t or bool.
+  template <typename CategoryType,
+            typename EventNameType,
+            typename... Arguments>
+  static void TraceForCategory(uint32_t instances,
+                               const CategoryType& category,
+                               const EventNameType& name,
+                               perfetto::protos::pbzero::TrackEvent::Type type,
+                               Arguments&&... args) PERFETTO_ALWAYS_INLINE {
+    TraceForCategoryBody(instances, DecayStrType(category), DecayStrType(name),
+                         type, DecayArgType(args)...);
+  }
+
+#if PERFETTO_ENABLE_LEGACY_TRACE_EVENTS
+  template <typename TrackType,
+            typename CategoryType,
+            typename EventNameType,
+            typename... Arguments,
+            typename TrackTypeCheck = typename std::enable_if<
+                std::is_convertible<TrackType, Track>::value>::type>
+  static void TraceForCategoryLegacy(
+      uint32_t instances,
+      const CategoryType& category,
+      const EventNameType& event_name,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      TrackType&& track,
+      char phase,
+      uint32_t flags,
+      Arguments&&... args) PERFETTO_ALWAYS_INLINE {
+    TraceForCategoryLegacyBody(instances, DecayStrType(category),
+                               DecayStrType(event_name), type, track, phase,
+                               flags, DecayArgType(args)...);
+  }
+
+  template <typename TrackType,
+            typename CategoryType,
+            typename EventNameType,
+            typename TimestampType = uint64_t,
+            typename... Arguments,
+            typename TrackTypeCheck = typename std::enable_if<
+                std::is_convertible<TrackType, Track>::value>::type,
+            typename TimestampTypeCheck = typename std::enable_if<
+                IsValidTimestamp<TimestampType>()>::type>
+  static void TraceForCategoryLegacy(
+      uint32_t instances,
+      const CategoryType& category,
+      const EventNameType& event_name,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      TrackType&& track,
+      char phase,
+      uint32_t flags,
+      TimestampType&& timestamp,
+      Arguments&&... args) PERFETTO_ALWAYS_INLINE {
+    TraceForCategoryLegacyBody(instances, DecayStrType(category),
+                               DecayStrType(event_name), type, track, phase,
+                               flags, timestamp, DecayArgType(args)...);
+  }
+
+  template <typename TrackType,
+            typename CategoryType,
+            typename EventNameType,
+            typename ThreadIdType,
+            typename LegacyIdType,
+            typename... Arguments,
+            typename TrackTypeCheck = typename std::enable_if<
+                std::is_convertible<TrackType, Track>::value>::type>
+  static void TraceForCategoryLegacyWithId(
+      uint32_t instances,
+      const CategoryType& category,
+      const EventNameType& event_name,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      TrackType&& track,
+      char phase,
+      uint32_t flags,
+      ThreadIdType thread_id,
+      LegacyIdType legacy_id,
+      Arguments&&... args) PERFETTO_ALWAYS_INLINE {
+    TraceForCategoryLegacyWithIdBody(
+        instances, DecayStrType(category), DecayStrType(event_name), type,
+        track, phase, flags, thread_id, legacy_id, DecayArgType(args)...);
+  }
+
+  template <typename TrackType,
+            typename CategoryType,
+            typename EventNameType,
+            typename ThreadIdType,
+            typename LegacyIdType,
+            typename TimestampType = uint64_t,
+            typename... Arguments,
+            typename TrackTypeCheck = typename std::enable_if<
+                std::is_convertible<TrackType, Track>::value>::type,
+            typename TimestampTypeCheck = typename std::enable_if<
+                IsValidTimestamp<TimestampType>()>::type>
+  static void TraceForCategoryLegacyWithId(
+      uint32_t instances,
+      const CategoryType& category,
+      const EventNameType& event_name,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      TrackType&& track,
+      char phase,
+      uint32_t flags,
+      ThreadIdType thread_id,
+      LegacyIdType legacy_id,
+      TimestampType&& timestamp,
+      Arguments&&... args) PERFETTO_ALWAYS_INLINE {
+    TraceForCategoryLegacyWithIdBody(instances, DecayStrType(category),
+                                     DecayStrType(event_name), type, track,
+                                     phase, flags, thread_id, legacy_id,
+                                     timestamp, DecayArgType(args)...);
+  }
+#endif
+
+  // Initialize the track event library. Should be called before tracing is
+  // enabled.
+  static bool Register() {
+    // Registration is performed out-of-line so users don't need to depend on
+    // DataSourceDescriptor C++ bindings.
+    return TrackEventInternal::Initialize(
+        *Registry,
+        [](const DataSourceDescriptor& dsd) { return Base::Register(dsd); });
+  }
+
+  // Record metadata about different types of timeline tracks. See Track.
+  static void SetTrackDescriptor(const Track& track,
+                                 const protos::gen::TrackDescriptor& desc) {
+    PERFETTO_DCHECK(track.uuid == desc.uuid());
+    TrackRegistry::Get()->UpdateTrack(track, desc.SerializeAsString());
+    Base::template Trace([&](typename Base::TraceContext ctx) {
+      TrackEventInternal::WriteTrackDescriptor(
+          track, ctx.tls_inst_->trace_writer.get(), ctx.GetIncrementalState(),
+          *ctx.GetCustomTlsState(), TrackEventInternal::GetTraceTime());
+    });
+  }
+
+  // DEPRECATED. Only kept for backwards compatibility.
+  static void SetTrackDescriptor(
+      const Track& track,
+      std::function<void(protos::pbzero::TrackDescriptor*)> callback) {
+    SetTrackDescriptorImpl(track, std::move(callback));
+  }
+
+  // DEPRECATED. Only kept for backwards compatibility.
+  static void SetProcessDescriptor(
+      std::function<void(protos::pbzero::TrackDescriptor*)> callback,
+      const ProcessTrack& track = ProcessTrack::Current()) {
+    SetTrackDescriptorImpl(std::move(track), std::move(callback));
+  }
+
+  // DEPRECATED. Only kept for backwards compatibility.
+  static void SetThreadDescriptor(
+      std::function<void(protos::pbzero::TrackDescriptor*)> callback,
+      const ThreadTrack& track = ThreadTrack::Current()) {
+    SetTrackDescriptorImpl(std::move(track), std::move(callback));
+  }
+
+  static void EraseTrackDescriptor(const Track& track) {
+    TrackRegistry::Get()->EraseTrack(track);
+  }
+
+  // Returns the current trace timestamp in nanoseconds. Note the returned
+  // timebase may vary depending on the platform, but will always match the
+  // timestamps recorded by track events (see GetTraceClockId).
+  static uint64_t GetTraceTimeNs() { return TrackEventInternal::GetTimeNs(); }
+
+  // Returns the type of clock used by GetTraceTimeNs().
+  static constexpr protos::pbzero::BuiltinClock GetTraceClockId() {
+    return TrackEventInternal::GetClockId();
+  }
+
+  const protos::gen::TrackEventConfig& GetConfig() const { return config_; }
+
+ private:
+  // The DecayStrType method is used to avoid unnecessary instantiations of
+  // templates on string constants of different sizes. Without it, strings
+  // of different lengths have different types: char[10], char[15] etc.
+  // DecayStrType forwards all types of arguments as is, with the exception
+  // of string constants which are all cast to const char*. This allows to
+  // avoid extra instantiations of TraceForCategory templates.
+  template <typename T>
+  static T&& DecayStrType(T&& t) {
+    return std::forward<T>(t);
+  }
+
+  static const char* DecayStrType(const char* t) { return t; }
+
+  // The DecayArgType method is used to avoid unnecessary instantiations of
+  // templates on:
+  // * string constants of different sizes.
+  // * primitive of different constness (or references).
+  // This avoids extra instantiations of TraceForCategory templates.
+  template <typename T>
+  static T&& DecayArgType(T&& t) {
+    return std::forward<T>(t);
+  }
+
+  static const char* DecayArgType(const char* s) { return s; }
+  static uint64_t DecayArgType(uint64_t u) { return u; }
+  static uint32_t DecayArgType(uint32_t u) { return u; }
+  static uint16_t DecayArgType(uint16_t u) { return u; }
+  static uint8_t DecayArgType(uint8_t u) { return u; }
+  static int64_t DecayArgType(int64_t i) { return i; }
+  static int32_t DecayArgType(int32_t i) { return i; }
+  static int16_t DecayArgType(int16_t i) { return i; }
+  static int8_t DecayArgType(int8_t i) { return i; }
+  static bool DecayArgType(bool b) { return b; }
+  static float DecayArgType(float f) { return f; }
+  static double DecayArgType(double f) { return f; }
+
+  // Once we've determined tracing to be enabled for this category, actually
+  // write a trace event onto this thread's default track. Outlined to avoid
+  // bloating code (mostly stack depth) at the actual trace point.
+  //
+  // The following combination of parameters is supported (in the given order):
+  // - Zero or one track,
+  // - Zero or one custom timestamp,
+  // - Arbitrary number of debug annotations.
+  // - Zero or one lambda.
+
+  // Trace point which does not take a track or timestamp.
+  template <typename CategoryType,
+            typename EventNameType,
+            typename... Arguments>
+  static void TraceForCategoryBody(
+      uint32_t instances,
+      const CategoryType& category,
+      const EventNameType& event_name,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      Arguments&&... args) PERFETTO_NO_INLINE {
+    TraceForCategoryImplNoTimestamp(instances, category, event_name, type,
+                                    TrackEventInternal::kDefaultTrack,
+                                    std::forward<Arguments>(args)...);
+  }
+
+  // Trace point which takes a track, but not timestamp.
+  // NOTE: Here track should be captured using universal reference (TrackType&&)
+  // instead of const TrackType& to ensure that the proper overload is selected
+  // (otherwise the compiler will fail to disambiguate between adding const& and
+  // parsing track as a part of Arguments...).
+  template <typename TrackType,
+            typename CategoryType,
+            typename EventNameType,
+            typename... Arguments,
+            typename TrackTypeCheck = typename std::enable_if<
+                std::is_convertible<TrackType, Track>::value>::type>
+  static void TraceForCategoryBody(
+      uint32_t instances,
+      const CategoryType& category,
+      const EventNameType& event_name,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      TrackType&& track,
+      Arguments&&... args) PERFETTO_NO_INLINE {
+    TraceForCategoryImplNoTimestamp(instances, category, event_name, type,
+                                    std::forward<TrackType>(track),
+                                    std::forward<Arguments>(args)...);
+  }
+
+  // Trace point which takes a timestamp, but not track.
+  template <typename CategoryType,
+            typename EventNameType,
+            typename TimestampType = uint64_t,
+            typename... Arguments,
+            typename TimestampTypeCheck = typename std::enable_if<
+                IsValidTimestamp<TimestampType>()>::type>
+  static void TraceForCategoryBody(
+      uint32_t instances,
+      const CategoryType& category,
+      const EventNameType& event_name,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      TimestampType&& timestamp,
+      Arguments&&... args) PERFETTO_NO_INLINE {
+    TraceForCategoryImpl(instances, category, event_name, type,
+                         TrackEventInternal::kDefaultTrack,
+                         std::forward<TimestampType>(timestamp),
+                         std::forward<Arguments>(args)...);
+  }
+
+  // Trace point which takes a timestamp and a track.
+  template <typename TrackType,
+            typename CategoryType,
+            typename EventNameType,
+            typename TimestampType = uint64_t,
+            typename... Arguments,
+            typename TrackTypeCheck = typename std::enable_if<
+                std::is_convertible<TrackType, Track>::value>::type,
+            typename TimestampTypeCheck = typename std::enable_if<
+                IsValidTimestamp<TimestampType>()>::type>
+  static void TraceForCategoryBody(
+      uint32_t instances,
+      const CategoryType& category,
+      const EventNameType& event_name,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      TrackType&& track,
+      TimestampType&& timestamp,
+      Arguments&&... args) PERFETTO_NO_INLINE {
+    TraceForCategoryImpl(instances, category, event_name, type,
+                         std::forward<TrackType>(track),
+                         std::forward<TimestampType>(timestamp),
+                         std::forward<Arguments>(args)...);
+  }
+
+  // Trace point with with a counter sample.
+  template <typename CategoryType, typename EventNameType, typename ValueType>
+  static void TraceForCategoryBody(
+      uint32_t instances,
+      const CategoryType& category,
+      const EventNameType&,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      CounterTrack track,
+      ValueType value) PERFETTO_ALWAYS_INLINE {
+    PERFETTO_DCHECK(type == perfetto::protos::pbzero::TrackEvent::TYPE_COUNTER);
+    TraceForCategory(instances, category, /*name=*/nullptr, type, track,
+                     TrackEventInternal::GetTraceTime(), value);
+  }
+
+  // Trace point with with a timestamp and a counter sample.
+  template <typename CategoryType,
+            typename EventNameType,
+            typename TimestampType = uint64_t,
+            typename TimestampTypeCheck = typename std::enable_if<
+                IsValidTimestamp<TimestampType>()>::type,
+            typename ValueType>
+  static void TraceForCategoryBody(
+      uint32_t instances,
+      const CategoryType& category,
+      const EventNameType&,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      CounterTrack track,
+      TimestampType timestamp,
+      ValueType value) PERFETTO_NO_INLINE {
+    PERFETTO_DCHECK(type == perfetto::protos::pbzero::TrackEvent::TYPE_COUNTER);
+    TraceForCategoryImpl(
+        instances, category, /*name=*/nullptr, type, track, timestamp,
+        [&](EventContext event_ctx) {
+          if (std::is_integral<ValueType>::value) {
+            int64_t value_int64 = static_cast<int64_t>(value);
+            if (track.is_incremental()) {
+              TrackEventIncrementalState* incr_state =
+                  event_ctx.GetIncrementalState();
+              PERFETTO_DCHECK(incr_state != nullptr);
+              auto prv_value =
+                  incr_state->last_counter_value_per_track[track.uuid];
+              event_ctx.event()->set_counter_value(value_int64 - prv_value);
+              prv_value = value_int64;
+              incr_state->last_counter_value_per_track[track.uuid] = prv_value;
+            } else {
+              event_ctx.event()->set_counter_value(value_int64);
+            }
+          } else {
+            event_ctx.event()->set_double_counter_value(
+                static_cast<double>(value));
+          }
+        });
+  }
+
+// Additional trace points used in legacy macros.
+// It's possible to implement legacy macros using a common TraceForCategory,
+// by supplying a lambda that sets all necessary legacy fields. But this
+// results in a binary size bloat because every trace point generates its own
+// template instantiation with its own lambda. ICF can't eliminate those as
+// each lambda captures different variables and so the code is not completely
+// identical.
+// What we do instead is define additional TraceForCategoryLegacy templates
+// that take legacy arguments directly. Their instantiations can have the same
+// binary code for at least some macro invocations and so can be successfully
+// folded by the linker.
+#if PERFETTO_ENABLE_LEGACY_TRACE_EVENTS
+  template <typename TrackType,
+            typename CategoryType,
+            typename EventNameType,
+            typename... Arguments,
+            typename TrackTypeCheck = typename std::enable_if<
+                std::is_convertible<TrackType, Track>::value>::type>
+  static void TraceForCategoryLegacyBody(
+      uint32_t instances,
+      const CategoryType& category,
+      const EventNameType& event_name,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      TrackType&& track,
+      char phase,
+      uint32_t flags,
+      Arguments&&... args) PERFETTO_NO_INLINE {
+    TraceForCategoryImplNoTimestamp(
+        instances, category, event_name, type, track,
+        [&](perfetto::EventContext ctx) PERFETTO_NO_THREAD_SAFETY_ANALYSIS {
+          using ::perfetto::internal::TrackEventLegacy;
+          TrackEventLegacy::WriteLegacyEvent(std::move(ctx), phase, flags,
+                                             args...);
+        });
+  }
+
+  template <typename TrackType,
+            typename CategoryType,
+            typename EventNameType,
+            typename TimestampType = uint64_t,
+            typename... Arguments,
+            typename TrackTypeCheck = typename std::enable_if<
+                std::is_convertible<TrackType, Track>::value>::type,
+            typename TimestampTypeCheck = typename std::enable_if<
+                IsValidTimestamp<TimestampType>()>::type>
+  static void TraceForCategoryLegacyBody(
+      uint32_t instances,
+      const CategoryType& category,
+      const EventNameType& event_name,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      TrackType&& track,
+      char phase,
+      uint32_t flags,
+      TimestampType&& timestamp,
+      Arguments&&... args) PERFETTO_NO_INLINE {
+    TraceForCategoryImpl(
+        instances, category, event_name, type, track, timestamp,
+        [&](perfetto::EventContext ctx) PERFETTO_NO_THREAD_SAFETY_ANALYSIS {
+          using ::perfetto::internal::TrackEventLegacy;
+          TrackEventLegacy::WriteLegacyEvent(std::move(ctx), phase, flags,
+                                             args...);
+        });
+  }
+
+  template <typename TrackType,
+            typename CategoryType,
+            typename EventNameType,
+            typename ThreadIdType,
+            typename LegacyIdType,
+            typename... Arguments,
+            typename TrackTypeCheck = typename std::enable_if<
+                std::is_convertible<TrackType, Track>::value>::type>
+  static void TraceForCategoryLegacyWithIdBody(
+      uint32_t instances,
+      const CategoryType& category,
+      const EventNameType& event_name,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      TrackType&& track,
+      char phase,
+      uint32_t flags,
+      ThreadIdType thread_id,
+      LegacyIdType legacy_id,
+      Arguments&&... args) PERFETTO_NO_INLINE {
+    TraceForCategoryImplNoTimestamp(
+        instances, category, event_name, type, track,
+        [&](perfetto::EventContext ctx) PERFETTO_NO_THREAD_SAFETY_ANALYSIS {
+          using ::perfetto::internal::TrackEventLegacy;
+          ::perfetto::internal::LegacyTraceId trace_id{legacy_id};
+          TrackEventLegacy::WriteLegacyEventWithIdAndTid(
+              std::move(ctx), phase, flags, trace_id, thread_id, args...);
+        });
+  }
+
+  template <typename TrackType,
+            typename CategoryType,
+            typename EventNameType,
+            typename ThreadIdType,
+            typename LegacyIdType,
+            typename TimestampType = uint64_t,
+            typename... Arguments,
+            typename TrackTypeCheck = typename std::enable_if<
+                std::is_convertible<TrackType, Track>::value>::type,
+            typename TimestampTypeCheck = typename std::enable_if<
+                IsValidTimestamp<TimestampType>()>::type>
+  static void TraceForCategoryLegacyWithIdBody(
+      uint32_t instances,
+      const CategoryType& category,
+      const EventNameType& event_name,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      TrackType&& track,
+      char phase,
+      uint32_t flags,
+      ThreadIdType thread_id,
+      LegacyIdType legacy_id,
+      TimestampType&& timestamp,
+      Arguments&&... args) PERFETTO_NO_INLINE {
+    TraceForCategoryImpl(
+        instances, category, event_name, type, track, timestamp,
+        [&](perfetto::EventContext ctx) PERFETTO_NO_THREAD_SAFETY_ANALYSIS {
+          using ::perfetto::internal::TrackEventLegacy;
+          ::perfetto::internal::LegacyTraceId trace_id{legacy_id};
+          TrackEventLegacy::WriteLegacyEventWithIdAndTid(
+              std::move(ctx), phase, flags, trace_id, thread_id, args...);
+        });
+  }
+#endif  // PERFETTO_ENABLE_LEGACY_TRACE_EVENTS
+
+  // Each category has its own enabled/disabled state, stored in the category
+  // registry.
+  struct CategoryTracePointTraits {
+    // Each trace point with a static category has an associated category index.
+    struct TracePointData {
+      size_t category_index;
+    };
+    // Called to get the enabled state bitmap of a given category.
+    // |data| is the trace point data structure given to
+    // DataSource::TraceWithInstances.
+    static constexpr std::atomic<uint8_t>* GetActiveInstances(
+        TracePointData data) {
+      return Registry->GetCategoryState(data.category_index);
+    }
+  };
+
+  template <typename CategoryType,
+            typename EventNameType,
+            typename TrackType = Track,
+            typename TrackTypeCheck =
+                typename std::enable_if<IsValidTrack<TrackType>()>::type>
+  static perfetto::EventContext WriteTrackEventImpl(
+      typename Base::TraceContext& ctx,
+      const CategoryType& category,
+      const EventNameType& event_name,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      const TrackType& track,
+      const TraceTimestamp& trace_timestamp) PERFETTO_ALWAYS_INLINE {
+    using CatTraits = CategoryTraits<CategoryType>;
+    const Category* static_category =
+        CatTraits::GetStaticCategory(Registry, category);
+
+    TrackEventTlsState& tls_state = *ctx.GetCustomTlsState();
+    TraceWriterBase* trace_writer = ctx.tls_inst_->trace_writer.get();
+    // Make sure incremental state is valid.
+    TrackEventIncrementalState* incr_state = ctx.GetIncrementalState();
+    TrackEventInternal::ResetIncrementalStateIfRequired(
+        trace_writer, incr_state, tls_state, trace_timestamp);
+
+    // Write the track descriptor before any event on the track.
+    if (track) {
+      TrackEventInternal::WriteTrackDescriptorIfNeeded(
+          track, trace_writer, incr_state, tls_state, trace_timestamp);
+    }
+
+    // Write the event itself.
+    bool on_current_thread_track =
+        (&track == &TrackEventInternal::kDefaultTrack);
+    auto event_ctx = TrackEventInternal::WriteEvent(
+        trace_writer, incr_state, tls_state, static_category, type,
+        trace_timestamp, on_current_thread_track);
+    // event name should be emitted with `TRACE_EVENT_BEGIN` macros
+    // but not with `TRACE_EVENT_END`.
+    if (type != protos::pbzero::TrackEvent::TYPE_SLICE_END) {
+      TrackEventInternal::WriteEventName(event_name, event_ctx, tls_state);
+    }
+    // Write dynamic categories (except for events that don't require
+    // categories). For counter events, the counter name (and optional
+    // category) is stored as part of the track descriptor instead being
+    // recorded with individual events.
+    if (CatTraits::kIsDynamic &&
+        type != protos::pbzero::TrackEvent::TYPE_SLICE_END &&
+        type != protos::pbzero::TrackEvent::TYPE_COUNTER) {
+      DynamicCategory dynamic_category =
+          CatTraits::GetDynamicCategory(category);
+      Category cat = Category::FromDynamicCategory(dynamic_category);
+      cat.ForEachGroupMember([&](const char* member_name, size_t name_size) {
+        event_ctx.event()->add_categories(member_name, name_size);
+        return true;
+      });
+    }
+    if (type == protos::pbzero::TrackEvent::TYPE_UNSPECIFIED) {
+      // Explicitly clear the track, so that the event is not associated
+      // with the default track, but instead uses the legacy mechanism
+      // based on the phase and pid/tid override.
+      event_ctx.event()->set_track_uuid(0);
+    } else if (!on_current_thread_track) {
+      // We emit these events using TrackDescriptors, and we cannot emit
+      // events on behalf of other processes using the TrackDescriptor
+      // format. Chrome is the only user of events with explicit process
+      // ids and currently only Chrome emits PHASE_MEMORY_DUMP events
+      // with an explicit process id, so we should be fine here.
+      // TODO(mohitms): Get rid of events with explicit process ids
+      // entirely.
+      event_ctx.event()->set_track_uuid(track.uuid);
+    }
+
+    return event_ctx;
+  }
+
+  template <typename CategoryType,
+            typename EventNameType,
+            typename TrackType = Track,
+            typename TimestampType = uint64_t,
+            typename TimestampTypeCheck = typename std::enable_if<
+                IsValidTimestamp<TimestampType>()>::type,
+            typename TrackTypeCheck =
+                typename std::enable_if<IsValidTrack<TrackType>()>::type>
+  static perfetto::EventContext WriteTrackEvent(
+      typename Base::TraceContext& ctx,
+      const CategoryType& category,
+      const EventNameType& event_name,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      const TrackType& track,
+      const TimestampType& timestamp) PERFETTO_NO_INLINE {
+    TraceTimestamp trace_timestamp = ::perfetto::TraceTimestampTraits<
+        TimestampType>::ConvertTimestampToTraceTimeNs(timestamp);
+    return WriteTrackEventImpl(ctx, category, event_name, type, track,
+                               trace_timestamp);
+  }
+
+  template <typename CategoryType,
+            typename EventNameType,
+            typename TrackType = Track,
+            typename TrackTypeCheck =
+                typename std::enable_if<IsValidTrack<TrackType>()>::type>
+  static perfetto::EventContext WriteTrackEvent(
+      typename Base::TraceContext& ctx,
+      const CategoryType& category,
+      const EventNameType& event_name,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      const TrackType& track) PERFETTO_NO_INLINE {
+    TraceTimestamp trace_timestamp = TrackEventInternal::GetTraceTime();
+    return WriteTrackEventImpl(ctx, category, event_name, type, track,
+                               trace_timestamp);
+  }
+
+  template <typename CategoryType,
+            typename EventNameType,
+            typename TrackType = Track,
+            typename TimestampType = uint64_t,
+            typename TimestampTypeCheck = typename std::enable_if<
+                IsValidTimestamp<TimestampType>()>::type,
+            typename TrackTypeCheck =
+                typename std::enable_if<IsValidTrack<TrackType>()>::type,
+            typename... Arguments>
+  static void TraceForCategoryImpl(
+      uint32_t instances,
+      const CategoryType& category,
+      const EventNameType& event_name,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      const TrackType& track,
+      const TimestampType& timestamp,
+      Arguments&&... args) PERFETTO_ALWAYS_INLINE {
+    using CatTraits = CategoryTraits<CategoryType>;
+    TraceWithInstances(
+        instances, category, [&](typename Base::TraceContext ctx) {
+          // If this category is dynamic, first check whether it's enabled.
+          if (CatTraits::kIsDynamic &&
+              !IsDynamicCategoryEnabled(
+                  &ctx, CatTraits::GetDynamicCategory(category))) {
+            return;
+          }
+
+          auto event_ctx = WriteTrackEvent(ctx, category, event_name, type,
+                                           track, timestamp);
+          WriteTrackEventArgs(std::move(event_ctx),
+                              std::forward<Arguments>(args)...);
+        });
+  }
+
+  template <typename CategoryType,
+            typename EventNameType,
+            typename TrackType = Track,
+            typename TrackTypeCheck =
+                typename std::enable_if<IsValidTrack<TrackType>()>::type,
+            typename... Arguments>
+  static void TraceForCategoryImplNoTimestamp(
+      uint32_t instances,
+      const CategoryType& category,
+      const EventNameType& event_name,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      const TrackType& track,
+      Arguments&&... args) PERFETTO_ALWAYS_INLINE {
+    using CatTraits = CategoryTraits<CategoryType>;
+    TraceWithInstances(
+        instances, category, [&](typename Base::TraceContext ctx) {
+          // If this category is dynamic, first check whether it's enabled.
+          if (CatTraits::kIsDynamic &&
+              !IsDynamicCategoryEnabled(
+                  &ctx, CatTraits::GetDynamicCategory(category))) {
+            return;
+          }
+
+          auto event_ctx =
+              WriteTrackEvent(ctx, category, event_name, type, track);
+          WriteTrackEventArgs(std::move(event_ctx),
+                              std::forward<Arguments>(args)...);
+        });
+  }
+
+  template <typename CategoryType, typename Lambda>
+  static void TraceWithInstances(uint32_t instances,
+                                 const CategoryType& category,
+                                 Lambda lambda) PERFETTO_ALWAYS_INLINE {
+    using CatTraits = CategoryTraits<CategoryType>;
+    if (CatTraits::kIsDynamic) {
+      Base::template TraceWithInstances(instances, std::move(lambda));
+    } else {
+      Base::template TraceWithInstances<CategoryTracePointTraits>(
+          instances, std::move(lambda), {CatTraits::GetStaticIndex(category)});
+    }
+  }
+
+  // Records a track descriptor into the track descriptor registry and, if we
+  // are tracing, also mirrors the descriptor into the trace.
+  template <typename TrackType>
+  static void SetTrackDescriptorImpl(
+      const TrackType& track,
+      std::function<void(protos::pbzero::TrackDescriptor*)> callback) {
+    TrackRegistry::Get()->UpdateTrack(track, std::move(callback));
+    Base::template Trace([&](typename Base::TraceContext ctx) {
+      TrackEventInternal::WriteTrackDescriptor(
+          track, ctx.tls_inst_->trace_writer.get(), ctx.GetIncrementalState(),
+          *ctx.GetCustomTlsState(), TrackEventInternal::GetTraceTime());
+    });
+  }
+
+  // Determines if the given dynamic category is enabled, first by checking the
+  // per-trace writer cache or by falling back to computing it based on the
+  // trace config for the given session.
+  static bool IsDynamicCategoryEnabled(
+      typename Base::TraceContext* ctx,
+      const DynamicCategory& dynamic_category) {
+    auto incr_state = ctx->GetIncrementalState();
+    auto it = incr_state->dynamic_categories.find(dynamic_category.name);
+    if (it == incr_state->dynamic_categories.end()) {
+      // We haven't seen this category before. Let's figure out if it's enabled.
+      // This requires grabbing a lock to read the session's trace config.
+      auto ds = ctx->GetDataSourceLocked();
+      if (!ds) {
+        return false;
+      }
+      Category category{Category::FromDynamicCategory(dynamic_category)};
+      bool enabled = TrackEventInternal::IsCategoryEnabled(
+          *Registry, ds->config_, category);
+      // TODO(skyostil): Cap the size of |dynamic_categories|.
+      incr_state->dynamic_categories[dynamic_category.name] = enabled;
+      return enabled;
+    }
+    return it->second;
+  }
+
+  // Config for the current tracing session.
+  protos::gen::TrackEventConfig config_;
+};
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_DATA_SOURCE_H_
+// gen_amalgamated begin header: include/perfetto/tracing/internal/track_event_macros.h
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_MACROS_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_MACROS_H_
+
+// This file contains underlying macros for the trace point track event
+// implementation. Perfetto API users typically don't need to use anything here
+// directly.
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_data_source.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/string_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track_event_category_registry.h"
+
+// Ignore GCC warning about a missing argument for a variadic macro parameter.
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC system_header
+#endif
+
+// Defines data structures for backing a category registry.
+//
+// Each category has one enabled/disabled bit per possible data source instance.
+// The bits are packed, i.e., each byte holds the state for instances. To
+// improve cache locality, the bits for each instance are stored separately from
+// the names of the categories:
+//
+//   byte 0                      byte 1
+//   (inst0, inst1, ..., inst7), (inst0, inst1, ..., inst7)
+//
+#define PERFETTO_INTERNAL_DECLARE_CATEGORIES(attrs, ...)                      \
+  namespace internal {                                                        \
+  constexpr ::perfetto::Category kCategories[] = {__VA_ARGS__};               \
+  constexpr size_t kCategoryCount =                                           \
+      sizeof(kCategories) / sizeof(kCategories[0]);                           \
+  /* The per-instance enable/disable state per category */                    \
+  attrs extern std::atomic<uint8_t> g_category_state_storage[kCategoryCount]; \
+  /* The category registry which mediates access to the above structures. */  \
+  /* The registry is used for two purposes: */                                \
+  /**/                                                                        \
+  /*    1) For looking up categories at build (constexpr) time. */            \
+  /*    2) For declaring the per-namespace TrackEvent data source. */         \
+  /**/                                                                        \
+  /* Because usage #1 requires a constexpr type and usage #2 requires an */   \
+  /* extern type (to avoid declaring a type based on a translation-unit */    \
+  /* variable), we need two separate copies of the registry with different */ \
+  /* storage specifiers. */                                                   \
+  /**/                                                                        \
+  /* Note that because of a Clang/Windows bug, the constexpr category */      \
+  /* registry isn't given the enabled/disabled state array. All access */     \
+  /* to the category states should therefore be done through the */           \
+  /* non-constexpr registry. See */                                           \
+  /* https://bugs.llvm.org/show_bug.cgi?id=51558 */                           \
+  /**/                                                                        \
+  /* TODO(skyostil): Unify these using a C++17 inline constexpr variable. */  \
+  constexpr ::perfetto::internal::TrackEventCategoryRegistry                  \
+      kConstExprCategoryRegistry(kCategoryCount, &kCategories[0], nullptr);   \
+  attrs extern const ::perfetto::internal::TrackEventCategoryRegistry         \
+      kCategoryRegistry;                                                      \
+  static_assert(kConstExprCategoryRegistry.ValidateCategories(),              \
+                "Invalid category names found");                              \
+  }  // namespace internal
+
+// In a .cc file, declares storage for each category's runtime state.
+#define PERFETTO_INTERNAL_CATEGORY_STORAGE(attrs)                      \
+  namespace internal {                                                 \
+  attrs std::atomic<uint8_t> g_category_state_storage[kCategoryCount]; \
+  attrs const ::perfetto::internal::TrackEventCategoryRegistry         \
+      kCategoryRegistry(kCategoryCount,                                \
+                        &kCategories[0],                               \
+                        &g_category_state_storage[0]);                 \
+  }  // namespace internal
+
+// Defines the TrackEvent data source for the current track event namespace.
+// `virtual ~TrackEvent` is added to avoid `-Wweak-vtables` warning.
+// Learn more : aosp/2019906
+#define PERFETTO_INTERNAL_DECLARE_TRACK_EVENT_DATA_SOURCE(attrs)               \
+  struct attrs TrackEvent : public ::perfetto::internal::TrackEventDataSource< \
+                                TrackEvent, &internal::kCategoryRegistry> {    \
+    virtual ~TrackEvent();                                                     \
+  }
+
+#define PERFETTO_INTERNAL_DEFINE_TRACK_EVENT_DATA_SOURCE() \
+  TrackEvent::~TrackEvent() = default;
+
+// At compile time, turns a category name represented by a static string into an
+// index into the current category registry. A build error will be generated if
+// the category hasn't been registered or added to the list of allowed dynamic
+// categories. See PERFETTO_DEFINE_CATEGORIES.
+#define PERFETTO_GET_CATEGORY_INDEX(category)                                \
+  PERFETTO_TRACK_EVENT_NAMESPACE::internal::kConstExprCategoryRegistry.Find( \
+      category,                                                              \
+      ::PERFETTO_TRACK_EVENT_NAMESPACE::internal::IsDynamicCategory(category))
+
+// Generate a unique variable name with a given prefix.
+#define PERFETTO_INTERNAL_CONCAT2(a, b) a##b
+#define PERFETTO_INTERNAL_CONCAT(a, b) PERFETTO_INTERNAL_CONCAT2(a, b)
+#define PERFETTO_UID(prefix) PERFETTO_INTERNAL_CONCAT(prefix, __LINE__)
+
+// Efficiently determines whether tracing is enabled for the given category, and
+// if so, emits one trace event with the given arguments.
+#define PERFETTO_INTERNAL_TRACK_EVENT_WITH_METHOD(method, category, name, ...) \
+  do {                                                                         \
+    ::perfetto::internal::ValidateEventNameType<decltype(name)>();             \
+    namespace tns = PERFETTO_TRACK_EVENT_NAMESPACE;                            \
+    /* Compute the category index outside the lambda to work around a */       \
+    /* GCC 7 bug */                                                            \
+    constexpr auto PERFETTO_UID(                                               \
+        kCatIndex_ADD_TO_PERFETTO_DEFINE_CATEGORIES_IF_FAILS_) =               \
+        PERFETTO_GET_CATEGORY_INDEX(category);                                 \
+    if (::PERFETTO_TRACK_EVENT_NAMESPACE::internal::IsDynamicCategory(         \
+            category)) {                                                       \
+      tns::TrackEvent::CallIfEnabled(                                          \
+          [&](uint32_t instances) PERFETTO_NO_THREAD_SAFETY_ANALYSIS {         \
+            tns::TrackEvent::method(                                           \
+                instances, category,                                           \
+                ::perfetto::internal::DecayEventNameType(name),                \
+                ##__VA_ARGS__);                                                \
+          });                                                                  \
+    } else {                                                                   \
+      tns::TrackEvent::CallIfCategoryEnabled(                                  \
+          PERFETTO_UID(kCatIndex_ADD_TO_PERFETTO_DEFINE_CATEGORIES_IF_FAILS_), \
+          [&](uint32_t instances) PERFETTO_NO_THREAD_SAFETY_ANALYSIS {         \
+            tns::TrackEvent::method(                                           \
+                instances,                                                     \
+                PERFETTO_UID(                                                  \
+                    kCatIndex_ADD_TO_PERFETTO_DEFINE_CATEGORIES_IF_FAILS_),    \
+                ::perfetto::internal::DecayEventNameType(name),                \
+                ##__VA_ARGS__);                                                \
+          });                                                                  \
+    }                                                                          \
+  } while (false)
+
+// This internal macro is unused from the repo now, but some improper usage
+// remain outside of the repo.
+// TODO(b/294800182): Remove this.
+#define PERFETTO_INTERNAL_TRACK_EVENT(...) \
+  PERFETTO_INTERNAL_TRACK_EVENT_WITH_METHOD(TraceForCategory, ##__VA_ARGS__)
+
+// C++17 doesn't like a move constructor being defined for the EventFinalizer
+// class but C++11 and MSVC doesn't compile without it being defined so support
+// both.
+#if !PERFETTO_BUILDFLAG(PERFETTO_COMPILER_MSVC)
+#define PERFETTO_INTERNAL_EVENT_FINALIZER_KEYWORD delete
+#else
+#define PERFETTO_INTERNAL_EVENT_FINALIZER_KEYWORD default
+#endif
+
+#define PERFETTO_INTERNAL_SCOPED_EVENT_FINALIZER(category)                    \
+  struct PERFETTO_UID(ScopedEvent) {                                          \
+    struct EventFinalizer {                                                   \
+      /* The parameter is an implementation detail. It allows the          */ \
+      /* anonymous struct to use aggregate initialization to invoke the    */ \
+      /* lambda (which emits the BEGIN event and returns an integer)       */ \
+      /* with the proper reference capture for any                         */ \
+      /* TrackEventArgumentFunction in |__VA_ARGS__|. This is required so  */ \
+      /* that the scoped event is exactly ONE line and can't escape the    */ \
+      /* scope if used in a single line if statement.                      */ \
+      EventFinalizer(...) {}                                                  \
+      ~EventFinalizer() { TRACE_EVENT_END(category); }                        \
+                                                                              \
+      EventFinalizer(const EventFinalizer&) = delete;                         \
+      inline EventFinalizer& operator=(const EventFinalizer&) = delete;       \
+                                                                              \
+      EventFinalizer(EventFinalizer&&) =                                      \
+          PERFETTO_INTERNAL_EVENT_FINALIZER_KEYWORD;                          \
+      EventFinalizer& operator=(EventFinalizer&&) = delete;                   \
+    } finalizer;                                                              \
+  }
+
+#define PERFETTO_INTERNAL_SCOPED_TRACK_EVENT(category, name, ...) \
+  PERFETTO_INTERNAL_SCOPED_EVENT_FINALIZER(category)              \
+  PERFETTO_UID(scoped_event) {                                    \
+    [&]() {                                                       \
+      TRACE_EVENT_BEGIN(category, name, ##__VA_ARGS__);           \
+      return 0;                                                   \
+    }()                                                           \
+  }
+
+#if PERFETTO_ENABLE_LEGACY_TRACE_EVENTS
+// Required for TRACE_EVENT_WITH_FLOW legacy macros, which pass the bind_id as
+// id.
+#define PERFETTO_INTERNAL_SCOPED_LEGACY_TRACK_EVENT_WITH_ID(               \
+    category, name, track, flags, thread_id, id, ...)                      \
+  PERFETTO_INTERNAL_SCOPED_EVENT_FINALIZER(category)                       \
+  PERFETTO_UID(scoped_event) {                                             \
+    [&]() {                                                                \
+      PERFETTO_INTERNAL_TRACK_EVENT_WITH_METHOD(                           \
+          TraceForCategoryLegacyWithId, category, name,                    \
+          ::perfetto::protos::pbzero::TrackEvent::TYPE_SLICE_BEGIN, track, \
+          'B', flags, thread_id, id, ##__VA_ARGS__);                       \
+      return 0;                                                            \
+    }()                                                                    \
+  }
+#endif  // PERFETTO_ENABLE_LEGACY_TRACE_EVENTS
+
+#if PERFETTO_BUILDFLAG(PERFETTO_COMPILER_GCC) || \
+    PERFETTO_BUILDFLAG(PERFETTO_COMPILER_MSVC)
+// On GCC versions <9 there's a bug that prevents using captured constant
+// variables in constexpr evaluation inside a lambda:
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82643
+// TODO(khokhlov): Remove this fallback after Perfetto moves to a more recent
+// GCC version.
+#define PERFETTO_INTERNAL_CATEGORY_ENABLED(category)                           \
+  (::PERFETTO_TRACK_EVENT_NAMESPACE::internal::IsDynamicCategory(category)     \
+       ? PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent::IsDynamicCategoryEnabled( \
+             ::perfetto::DynamicCategory(category))                            \
+       : PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent::IsCategoryEnabled(        \
+             PERFETTO_GET_CATEGORY_INDEX(category)))
+#else  // !PERFETTO_BUILDFLAG(PERFETTO_COMPILER_GCC)
+#define PERFETTO_INTERNAL_CATEGORY_ENABLED(category)                     \
+  [&]() -> bool {                                                        \
+    using PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent;                    \
+    using ::PERFETTO_TRACK_EVENT_NAMESPACE::internal::IsDynamicCategory; \
+    constexpr auto PERFETTO_UID(index) =                                 \
+        PERFETTO_GET_CATEGORY_INDEX(category);                           \
+    constexpr auto PERFETTO_UID(dynamic) = IsDynamicCategory(category);  \
+    return PERFETTO_UID(dynamic)                                         \
+               ? TrackEvent::IsDynamicCategoryEnabled(                   \
+                     ::perfetto::DynamicCategory(category))              \
+               : TrackEvent::IsCategoryEnabled(PERFETTO_UID(index));     \
+  }()
+#endif  // !PERFETTO_BUILDFLAG(PERFETTO_COMPILER_GCC)
+
+// Emits an empty trace packet into the trace to ensure that the service can
+// safely read the last event from the trace buffer. This can be used to
+// periodically "flush" the last event on threads that don't support explicit
+// flushing of the shared memory buffer chunk when the tracing session stops
+// (e.g. thread pool workers in Chromium).
+//
+// This workaround is only required because the tracing service cannot safely
+// read the last trace packet from an incomplete SMB chunk (crbug.com/1021571
+// and b/162206162) when scraping the SMB. Adding an empty trace packet ensures
+// that all prior events can be scraped by the service.
+#define PERFETTO_INTERNAL_ADD_EMPTY_EVENT()                                \
+  do {                                                                     \
+    PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent::Trace(                     \
+        [](PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent::TraceContext ctx) { \
+          ctx.AddEmptyTracePacket();                                       \
+        });                                                                \
+  } while (false)
+
+#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_MACROS_H_
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_TRACK_EVENT_H_
+#define INCLUDE_PERFETTO_TRACING_TRACK_EVENT_H_
+
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_data_source.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_internal.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_macros.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/string_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track_event_category_registry.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_event.pbzero.h"
+
+#include <type_traits>
+
+// This file contains a set of macros designed for instrumenting applications
+// with track event trace points. While the underlying TrackEvent API can also
+// be used directly, doing so efficiently requires some care (e.g., to avoid
+// evaluating arguments while tracing is disabled). These types of optimizations
+// are abstracted away by the macros below.
+//
+// ================
+// Quickstart guide
+// ================
+//
+//   To add track events to your application, first define your categories in,
+//   e.g., my_tracing.h:
+//
+//       PERFETTO_DEFINE_CATEGORIES(
+//           perfetto::Category("base"),
+//           perfetto::Category("v8"),
+//           perfetto::Category("cc"));
+//
+//   Then in a single .cc file, e.g., my_tracing.cc:
+//
+//       #include "my_tracing.h"
+//       PERFETTO_TRACK_EVENT_STATIC_STORAGE();
+//
+//   Finally, register track events at startup, after which you can record
+//   events with the TRACE_EVENT macros:
+//
+//       #include "my_tracing.h"
+//
+//       int main() {
+//         perfetto::TrackEvent::Register();
+//
+//         // A basic track event with just a name.
+//         TRACE_EVENT("category", "MyEvent");
+//
+//         // A track event with (up to two) debug annotations.
+//         TRACE_EVENT("category", "MyEvent", "parameter", 42);
+//
+//         // A track event with a strongly typed parameter.
+//         TRACE_EVENT("category", "MyEvent", [](perfetto::EventContext ctx) {
+//           ctx.event()->set_foo(42);
+//           ctx.event()->set_bar(.5f);
+//         });
+//       }
+//
+//  Note that track events must be nested consistently, i.e., the following is
+//  not allowed:
+//
+//    TRACE_EVENT_BEGIN("a", "bar", ...);
+//    TRACE_EVENT_BEGIN("b", "foo", ...);
+//    TRACE_EVENT_END("a");  // "foo" must be closed before "bar".
+//    TRACE_EVENT_END("b");
+//
+// ====================
+// Implementation notes
+// ====================
+//
+// The track event library consists of the following layers and components. The
+// classes the internal namespace shouldn't be considered part of the public
+// API.
+//                    .--------------------------------.
+//               .----|  TRACE_EVENT                   |----.
+//      write   |     |   - App instrumentation point  |     |  write
+//      event   |     '--------------------------------'     |  arguments
+//              V                                            V
+//  .----------------------------------.    .-----------------------------.
+//  | TrackEvent                       |    | EventContext                |
+//  |  - Registry of event categories  |    |  - One track event instance |
+//  '----------------------------------'    '-----------------------------'
+//              |                                            |
+//              |                                            | look up
+//              | is                                         | interning ids
+//              V                                            V
+//  .----------------------------------.    .-----------------------------.
+//  | internal::TrackEventDataSource   |    | TrackEventInternedDataIndex |
+//  | - Perfetto data source           |    | - Corresponds to a field in |
+//  | - Has TrackEventIncrementalState |    |   in interned_data.proto    |
+//  '----------------------------------'    '-----------------------------'
+//              |                  |                         ^
+//              |                  |       owns (1:many)     |
+//              | write event      '-------------------------'
+//              V
+//  .----------------------------------.
+//  | internal::TrackEventInternal     |
+//  | - Outlined code to serialize     |
+//  |   one track event                |
+//  '----------------------------------'
+//
+
+// DEPRECATED: Please use PERFETTO_DEFINE_CATEGORIES_IN_NAMESPACE to implement
+// multiple track event category sets in one program.
+//
+// Each compilation unit can be in exactly one track event namespace,
+// allowing the overall program to use multiple track event data sources and
+// category lists if necessary. Use this macro to select the namespace for the
+// current compilation unit.
+//
+// If the program uses multiple track event namespaces, category & track event
+// registration (see quickstart above) needs to happen for both namespaces
+// separately.
+
+#ifndef PERFETTO_TRACK_EVENT_NAMESPACE
+#define PERFETTO_TRACK_EVENT_NAMESPACE perfetto_track_event
+#endif
+
+// Deprecated; see perfetto::Category().
+#define PERFETTO_CATEGORY(name) \
+  ::perfetto::Category { #name }
+
+// Internal helpers for determining if a given category is defined at build or
+// runtime.
+namespace PERFETTO_TRACK_EVENT_NAMESPACE {
+namespace internal {
+
+// By default no statically defined categories are dynamic, but this can be
+// overridden with PERFETTO_DEFINE_TEST_CATEGORY_PREFIXES.
+template <typename... T>
+constexpr bool IsDynamicCategory(const char*) {
+  return false;
+}
+
+// Explicitly dynamic categories are always dynamic.
+constexpr bool IsDynamicCategory(const ::perfetto::DynamicCategory&) {
+  return true;
+}
+
+}  // namespace internal
+}  // namespace PERFETTO_TRACK_EVENT_NAMESPACE
+
+// Normally all categories are defined statically at build-time (see
+// PERFETTO_DEFINE_CATEGORIES). However, some categories are only used for
+// testing, and we shouldn't publish them to the tracing service or include them
+// in a production binary. Use this macro to define a list of prefixes for these
+// types of categories. Note that trace points using these categories will be
+// slightly less efficient compared to regular trace points.
+#define PERFETTO_DEFINE_TEST_CATEGORY_PREFIXES(...)                       \
+  namespace PERFETTO_TRACK_EVENT_NAMESPACE {                              \
+  namespace internal {                                                    \
+  template <>                                                             \
+  constexpr bool IsDynamicCategory(const char* name) {                    \
+    return ::perfetto::internal::IsStringInPrefixList(name, __VA_ARGS__); \
+  }                                                                       \
+  } /* namespace internal */                                              \
+  } /* namespace PERFETTO_TRACK_EVENT_NAMESPACE */                        \
+  PERFETTO_INTERNAL_SWALLOW_SEMICOLON()
+
+// Register the set of available categories by passing a list of categories to
+// this macro: perfetto::Category("cat1"), perfetto::Category("cat2"), ...
+// `ns` is the name of the namespace in which the categories should be declared.
+// `attrs` are linkage attributes for the underlying data source. See
+// PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS_WITH_ATTRS.
+//
+// Implementation note: the extra namespace (PERFETTO_TRACK_EVENT_NAMESPACE) is
+// kept here only for backward compatibility.
+#define PERFETTO_DEFINE_CATEGORIES_IN_NAMESPACE_WITH_ATTRS(ns, attrs, ...) \
+  namespace ns {                                                           \
+  namespace PERFETTO_TRACK_EVENT_NAMESPACE {                               \
+  /* The list of category names */                                         \
+  PERFETTO_INTERNAL_DECLARE_CATEGORIES(attrs, __VA_ARGS__)                 \
+  /* The track event data source for this set of categories */             \
+  PERFETTO_INTERNAL_DECLARE_TRACK_EVENT_DATA_SOURCE(attrs);                \
+  } /* namespace PERFETTO_TRACK_EVENT_NAMESPACE  */                        \
+  using PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent;                        \
+  } /* namespace ns */                                                     \
+  PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS_WITH_ATTRS(                  \
+      attrs, ns::PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent,               \
+      ::perfetto::internal::TrackEventDataSourceTraits)
+
+// Register the set of available categories by passing a list of categories to
+// this macro: perfetto::Category("cat1"), perfetto::Category("cat2"), ...
+// `ns` is the name of the namespace in which the categories should be declared.
+#define PERFETTO_DEFINE_CATEGORIES_IN_NAMESPACE(ns, ...) \
+  PERFETTO_DEFINE_CATEGORIES_IN_NAMESPACE_WITH_ATTRS(    \
+      ns, PERFETTO_COMPONENT_EXPORT, __VA_ARGS__)
+
+// Make categories in a given namespace the default ones used by track events
+// for the current translation unit. Can only be used *once* in a given global
+// or namespace scope.
+#define PERFETTO_USE_CATEGORIES_FROM_NAMESPACE(ns)                         \
+  namespace PERFETTO_TRACK_EVENT_NAMESPACE {                               \
+  using ::ns::PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent;                  \
+  namespace internal {                                                     \
+  using ::ns::PERFETTO_TRACK_EVENT_NAMESPACE::internal::kCategoryRegistry; \
+  using ::ns::PERFETTO_TRACK_EVENT_NAMESPACE::internal::                   \
+      kConstExprCategoryRegistry;                                          \
+  } /* namespace internal */                                               \
+  } /* namespace PERFETTO_TRACK_EVENT_NAMESPACE */                         \
+  PERFETTO_INTERNAL_SWALLOW_SEMICOLON()
+
+// Make categories in a given namespace the default ones used by track events
+// for the current block scope. Can only be used in a function or block scope.
+#define PERFETTO_USE_CATEGORIES_FROM_NAMESPACE_SCOPED(ns) \
+  namespace PERFETTO_TRACK_EVENT_NAMESPACE = ns::PERFETTO_TRACK_EVENT_NAMESPACE
+
+// Register categories in the default (global) namespace. Warning: only one set
+// of global categories can be defined in a single program. Create namespaced
+// categories with PERFETTO_DEFINE_CATEGORIES_IN_NAMESPACE to work around this
+// limitation.
+#define PERFETTO_DEFINE_CATEGORIES(...)                           \
+  PERFETTO_DEFINE_CATEGORIES_IN_NAMESPACE(perfetto, __VA_ARGS__); \
+  PERFETTO_USE_CATEGORIES_FROM_NAMESPACE(perfetto)
+
+// Allocate storage for each category by using this macro once per track event
+// namespace. `ns` is the name of the namespace in which the categories should
+// be declared and `attrs` specify linkage attributes for the data source.
+#define PERFETTO_TRACK_EVENT_STATIC_STORAGE_IN_NAMESPACE_WITH_ATTRS(ns, attrs) \
+  namespace ns {                                                               \
+  namespace PERFETTO_TRACK_EVENT_NAMESPACE {                                   \
+  PERFETTO_INTERNAL_CATEGORY_STORAGE(attrs)                                    \
+  PERFETTO_INTERNAL_DEFINE_TRACK_EVENT_DATA_SOURCE()                           \
+  } /* namespace PERFETTO_TRACK_EVENT_NAMESPACE */                             \
+  } /* namespace ns */                                                         \
+  PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS_WITH_ATTRS(                       \
+      attrs, ns::PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent,                   \
+      ::perfetto::internal::TrackEventDataSourceTraits)
+
+// Allocate storage for each category by using this macro once per track event
+// namespace.
+#define PERFETTO_TRACK_EVENT_STATIC_STORAGE_IN_NAMESPACE(ns)   \
+  PERFETTO_TRACK_EVENT_STATIC_STORAGE_IN_NAMESPACE_WITH_ATTRS( \
+      ns, PERFETTO_COMPONENT_EXPORT)
+
+// Allocate storage for each category by using this macro once per track event
+// namespace.
+#define PERFETTO_TRACK_EVENT_STATIC_STORAGE() \
+  PERFETTO_TRACK_EVENT_STATIC_STORAGE_IN_NAMESPACE(perfetto)
+
+// Ignore GCC warning about a missing argument for a variadic macro parameter.
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC system_header
+#endif
+
+// Begin a slice under |category| with the title |name|. Both strings must be
+// static constants. The track event is only recorded if |category| is enabled
+// for a tracing session.
+//
+// The slice is thread-scoped (i.e., written to the default track of the current
+// thread) unless overridden with a custom track object (see Track).
+//
+// |name| must be a string with static lifetime (i.e., the same
+// address must not be used for a different event name in the future). If you
+// want to use a dynamically allocated name, do this:
+//
+//  TRACE_EVENT("category", nullptr, [&](perfetto::EventContext ctx) {
+//    ctx.event()->set_name(dynamic_name);
+//  });
+//
+// The following optional arguments can be passed to `TRACE_EVENT` to add extra
+// information to events:
+//
+// TRACE_EVENT("cat", "name"[, track][, timestamp]
+//                          [, "debug_name1", debug_value1]
+//                          [, "debug_name2", debug_value2]
+//                          ...
+//                          [, "debug_nameN", debug_valueN]
+//                          [, lambda]);
+//
+// Some examples of valid combinations:
+//
+// 1. A lambda for writing custom TrackEvent fields:
+//
+//   TRACE_EVENT("category", "Name", [&](perfetto::EventContext ctx) {
+//     ctx.event()->set_custom_value(...);
+//   });
+//
+// 2. A timestamp and a lambda:
+//
+//   TRACE_EVENT("category", "Name", time_in_nanoseconds,
+//       [&](perfetto::EventContext ctx) {
+//     ctx.event()->set_custom_value(...);
+//   });
+//
+//   |time_in_nanoseconds| should be an uint64_t by default. To support custom
+//   timestamp types,
+//   |perfetto::TraceTimestampTraits<T>::ConvertTimestampToTraceTimeNs|
+//   should be defined. See |ConvertTimestampToTraceTimeNs| for more details.
+//
+// 3. Arbitrary number of debug annotations:
+//
+//   TRACE_EVENT("category", "Name", "arg", value);
+//   TRACE_EVENT("category", "Name", "arg", value, "arg2", value2);
+//   TRACE_EVENT("category", "Name", "arg", value, "arg2", value2,
+//                                   "arg3", value3);
+//
+//   See |TracedValue| for recording custom types as debug annotations.
+//
+// 4. Arbitrary number of debug annotations and a lambda:
+//
+//   TRACE_EVENT("category", "Name", "arg", value,
+//       [&](perfetto::EventContext ctx) {
+//     ctx.event()->set_custom_value(...);
+//   });
+//
+// 5. An overridden track:
+//
+//   TRACE_EVENT("category", "Name", perfetto::Track(1234));
+//
+//   See |Track| for other types of tracks which may be used.
+//
+// 6. A track and a lambda:
+//
+//   TRACE_EVENT("category", "Name", perfetto::Track(1234),
+//       [&](perfetto::EventContext ctx) {
+//     ctx.event()->set_custom_value(...);
+//   });
+//
+// 7. A track and a timestamp:
+//
+//   TRACE_EVENT("category", "Name", perfetto::Track(1234),
+//       time_in_nanoseconds);
+//
+// 8. A track, a timestamp and a lambda:
+//
+//   TRACE_EVENT("category", "Name", perfetto::Track(1234),
+//       time_in_nanoseconds, [&](perfetto::EventContext ctx) {
+//     ctx.event()->set_custom_value(...);
+//   });
+//
+// 9. A track and an arbitrary number of debug annotions:
+//
+//   TRACE_EVENT("category", "Name", perfetto::Track(1234),
+//               "arg", value);
+//   TRACE_EVENT("category", "Name", perfetto::Track(1234),
+//               "arg", value, "arg2", value2);
+//
+#define TRACE_EVENT_BEGIN(category, name, ...) \
+  PERFETTO_INTERNAL_TRACK_EVENT_WITH_METHOD(   \
+      TraceForCategory, category, name,        \
+      ::perfetto::protos::pbzero::TrackEvent::TYPE_SLICE_BEGIN, ##__VA_ARGS__)
+
+// End a slice under |category|.
+#define TRACE_EVENT_END(category, ...)              \
+  PERFETTO_INTERNAL_TRACK_EVENT_WITH_METHOD(        \
+      TraceForCategory, category, /*name=*/nullptr, \
+      ::perfetto::protos::pbzero::TrackEvent::TYPE_SLICE_END, ##__VA_ARGS__)
+
+// Begin a slice which gets automatically closed when going out of scope.
+#define TRACE_EVENT(category, name, ...) \
+  PERFETTO_INTERNAL_SCOPED_TRACK_EVENT(category, name, ##__VA_ARGS__)
+
+// Emit a slice which has zero duration.
+#define TRACE_EVENT_INSTANT(category, name, ...) \
+  PERFETTO_INTERNAL_TRACK_EVENT_WITH_METHOD(     \
+      TraceForCategory, category, name,          \
+      ::perfetto::protos::pbzero::TrackEvent::TYPE_INSTANT, ##__VA_ARGS__)
+
+// Efficiently determine if the given static or dynamic trace category or
+// category group is enabled for tracing.
+#define TRACE_EVENT_CATEGORY_ENABLED(category) \
+  PERFETTO_INTERNAL_CATEGORY_ENABLED(category)
+
+// Time-varying numeric data can be recorded with the TRACE_COUNTER macro:
+//
+//   TRACE_COUNTER("cat", counter_track[, timestamp], value);
+//
+// For example, to record a single value for a counter called "MyCounter":
+//
+//   TRACE_COUNTER("category", "MyCounter", 1234.5);
+//
+// This data is displayed as a counter track in the Perfetto UI.
+//
+// Both integer and floating point counter values are supported. Counters can
+// also be annotated with additional information such as units, for example, for
+// tracking the rendering framerate in terms of frames per second or "fps":
+//
+//   TRACE_COUNTER("category", perfetto::CounterTrack("Framerate", "fps"), 120);
+//
+// As another example, a memory counter that records bytes but accepts samples
+// as kilobytes (to reduce trace binary size) can be defined like this:
+//
+//   perfetto::CounterTrack memory_track = perfetto::CounterTrack("Memory")
+//       .set_unit("bytes")
+//       .set_multiplier(1024);
+//   TRACE_COUNTER("category", memory_track, 4 /* = 4096 bytes */);
+//
+// See /protos/perfetto/trace/track_event/counter_descriptor.proto
+// for the full set of attributes for a counter track.
+//
+// To record a counter value at a specific point in time (instead of the current
+// time), you can pass in a custom timestamp:
+//
+//   // First record the current time and counter value.
+//   uint64_t timestamp = perfetto::TrackEvent::GetTraceTimeNs();
+//   int64_t value = 1234;
+//
+//   // Later, emit a sample at that point in time.
+//   TRACE_COUNTER("category", "MyCounter", timestamp, value);
+//
+#define TRACE_COUNTER(category, track, ...)                 \
+  PERFETTO_INTERNAL_TRACK_EVENT_WITH_METHOD(                \
+      TraceForCategory, category, /*name=*/nullptr,         \
+      ::perfetto::protos::pbzero::TrackEvent::TYPE_COUNTER, \
+      ::perfetto::CounterTrack(track), ##__VA_ARGS__)
+
+// TODO(skyostil): Add flow events.
+
+#endif  // INCLUDE_PERFETTO_TRACING_TRACK_EVENT_H_
+// gen_amalgamated begin header: include/perfetto/tracing/track_event_interned_data_index.h
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_TRACK_EVENT_INTERNED_DATA_INDEX_H_
+#define INCLUDE_PERFETTO_TRACING_TRACK_EVENT_INTERNED_DATA_INDEX_H_
+
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_internal.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/event_context.h"
+
+#include <map>
+#include <type_traits>
+#include <unordered_map>
+
+// This file has templates for defining your own interned data types to be used
+// with track event. Interned data can be useful for avoiding repeating the same
+// constant data (e.g., strings) throughout the trace.
+//
+// =============
+// Example usage
+// =============
+//
+// First define an interning index for your type. It should map to a specific
+// field of interned_data.proto and define how the interned data is written into
+// that message.
+//
+//   struct MyInternedData
+//       : public perfetto::TrackEventInternedDataIndex<
+//           MyInternedData,
+//           perfetto::protos::pbzero::InternedData::kMyInternedDataFieldNumber,
+//           const char*> {
+//     static void Add(perfetto::protos::pbzero::InternedData* interned_data,
+//                      size_t iid,
+//                      const char* value) {
+//       auto my_data = interned_data->add_my_interned_data();
+//       my_data->set_iid(iid);
+//       my_data->set_value(value);
+//     }
+//   };
+//
+// Next, use your interned data in a trace point as shown below. The interned
+// string will only be emitted the first time the trace point is hit.
+//
+//   TRACE_EVENT_BEGIN(
+//      "category", "Event", [&](perfetto::EventContext ctx) {
+//        auto my_message = ctx.event()->set_my_message();
+//        size_t iid = MyInternedData::Get(&ctx, "Some data");
+//        my_message->set_iid(iid);
+//      });
+//
+
+namespace perfetto {
+
+// By default, the interning index stores a full copy of the interned data. This
+// ensures the same data is always mapped to the same interning id, and there is
+// no danger of collisions. This comes at the cost of memory usage, however, so
+// consider using HashedInternedDataTraits if that may be an issue.
+//
+// This type of index also performs hashing on the stored data for lookups; for
+// types where this isn't necessary (e.g., raw const char*), use
+// SmallInternedDataTraits.
+struct BigInternedDataTraits {
+  template <typename ValueType>
+  class Index {
+   public:
+    bool LookUpOrInsert(size_t* iid, const ValueType& value) {
+      size_t next_id = data_.size() + 1;
+      auto it_and_inserted = data_.insert(std::make_pair(value, next_id));
+      if (!it_and_inserted.second) {
+        *iid = it_and_inserted.first->second;
+        return true;
+      }
+      *iid = next_id;
+      return false;
+    }
+
+   private:
+    std::unordered_map<ValueType, size_t> data_;
+  };
+};
+
+// This type of interning index keeps full copies of interned data without
+// hashing the values. This is a good fit for small types that can be directly
+// used as index keys.
+struct SmallInternedDataTraits {
+  template <typename ValueType>
+  class Index {
+   public:
+    bool LookUpOrInsert(size_t* iid, const ValueType& value) {
+      size_t next_id = data_.size() + 1;
+      auto it_and_inserted = data_.insert(std::make_pair(value, next_id));
+      if (!it_and_inserted.second) {
+        *iid = it_and_inserted.first->second;
+        return true;
+      }
+      *iid = next_id;
+      return false;
+    }
+
+   private:
+    std::map<ValueType, size_t> data_;
+  };
+};
+
+// This type of interning index only stores the hash of the interned values
+// instead of the values themselves. This is more efficient in terms of memory
+// usage, but assumes that there are no hash collisions. If a hash collision
+// occurs, two or more values will be mapped to the same interning id.
+//
+// Note that the given type must have a specialization for std::hash.
+struct HashedInternedDataTraits {
+  template <typename ValueType>
+  class Index {
+   public:
+    bool LookUpOrInsert(size_t* iid, const ValueType& value) {
+      auto key = std::hash<ValueType>()(value);
+      size_t next_id = data_.size() + 1;
+      auto it_and_inserted = data_.insert(std::make_pair(key, next_id));
+      if (!it_and_inserted.second) {
+        *iid = it_and_inserted.first->second;
+        return true;
+      }
+      *iid = next_id;
+      return false;
+    }
+
+   private:
+    std::map<size_t, size_t> data_;
+  };
+};
+
+// A templated base class for an interned data type which corresponds to a field
+// in interned_data.proto.
+//
+// |InternedDataType| must be the type of the subclass.
+// |FieldNumber| is the corresponding protobuf field in InternedData.
+// |ValueType| is the type which is stored in the index. It must be copyable.
+// |Traits| can be used to customize the storage and lookup mechanism.
+//
+// The subclass should define a static method with the following signature for
+// committing interned data together with the interning id |iid| into the trace:
+//
+//   static void Add(perfetto::protos::pbzero::InternedData*,
+//                   size_t iid,
+//                   const ValueType& value);
+//
+template <typename InternedDataType,
+          size_t FieldNumber,
+          typename ValueType,
+          // Avoid unnecessary hashing for pointers by default.
+          typename Traits =
+              typename std::conditional<(std::is_pointer<ValueType>::value),
+                                        SmallInternedDataTraits,
+                                        BigInternedDataTraits>::type>
+class TrackEventInternedDataIndex
+    : public internal::BaseTrackEventInternedDataIndex {
+ public:
+  // Return an interning id for |value|. The returned id can be immediately
+  // written to the trace. The optional |add_args| are passed to the Add()
+  // function.
+  template <typename... Args>
+  static size_t Get(EventContext* ctx,
+                    const ValueType& value,
+                    Args&&... add_args) {
+    return Get(ctx->incremental_state_, value, std::forward<Args>(add_args)...);
+  }
+
+  template <typename... Args>
+  static size_t Get(internal::TrackEventIncrementalState* incremental_state,
+                    const ValueType& value,
+                    Args&&... add_args) {
+    // First check if the value exists in the dictionary.
+    auto index_for_field = GetOrCreateIndexForField(incremental_state);
+    size_t iid;
+    if (PERFETTO_LIKELY(index_for_field->index_.LookUpOrInsert(&iid, value))) {
+      PERFETTO_DCHECK(iid);
+      return iid;
+    }
+
+    // If not, we need to serialize the definition of the interned value into
+    // the heap buffered message (which is committed to the trace when the
+    // packet ends).
+    PERFETTO_DCHECK(iid);
+    InternedDataType::Add(incremental_state->serialized_interned_data.get(),
+                          iid, std::move(value),
+                          std::forward<Args>(add_args)...);
+    return iid;
+  }
+
+ protected:
+  // Some use cases require a custom Get implemention, so they need access to
+  // GetOrCreateIndexForField + the returned index.
+  static InternedDataType* GetOrCreateIndexForField(
+      internal::TrackEventIncrementalState* incremental_state) {
+    // Fast path: look for matching field number.
+    for (const auto& entry : incremental_state->interned_data_indices) {
+      if (entry.first == FieldNumber) {
+#if PERFETTO_DCHECK_IS_ON()
+        if (strcmp(PERFETTO_DEBUG_FUNCTION_IDENTIFIER(),
+                   entry.second->type_id_)) {
+          PERFETTO_FATAL(
+              "Interned data accessed under different types! Previous type: "
+              "%s. New type: %s.",
+              entry.second->type_id_, PERFETTO_DEBUG_FUNCTION_IDENTIFIER());
+        }
+        // If an interned data index is defined in an anonymous namespace, we
+        // can end up with multiple copies of it in the same program. Because
+        // they will all share a memory address through TLS, this can lead to
+        // subtle data corruption if all the copies aren't exactly identical.
+        // Try to detect this by checking if the Add() function address remains
+        // constant.
+        if (reinterpret_cast<void*>(&InternedDataType::Add) !=
+            entry.second->add_function_ptr_) {
+          PERFETTO_FATAL(
+              "Inconsistent interned data index. Maybe the index was defined "
+              "in an anonymous namespace in a header or copied to multiple "
+              "files? Duplicate index definitions can lead to memory "
+              "corruption! Type id: %s",
+              entry.second->type_id_);
+        }
+#endif  // PERFETTO_DCHECK_IS_ON()
+        return reinterpret_cast<InternedDataType*>(entry.second.get());
+      }
+    }
+    // No match -- add a new entry for this field.
+    for (auto& entry : incremental_state->interned_data_indices) {
+      if (!entry.first) {
+        entry.first = FieldNumber;
+        entry.second.reset(new InternedDataType());
+#if PERFETTO_DCHECK_IS_ON()
+        entry.second->type_id_ = PERFETTO_DEBUG_FUNCTION_IDENTIFIER();
+        entry.second->add_function_ptr_ =
+            reinterpret_cast<void*>(&InternedDataType::Add);
+#endif  // PERFETTO_DCHECK_IS_ON()
+        return reinterpret_cast<InternedDataType*>(entry.second.get());
+      }
+    }
+    // Out of space in the interned data index table.
+    PERFETTO_CHECK(false);
+  }
+
+  // The actual interning dictionary for this type of interned data. The actual
+  // container type is defined by |Traits|, hence the extra layer of template
+  // indirection here.
+  typename Traits::template Index<ValueType> index_;
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_TRACK_EVENT_INTERNED_DATA_INDEX_H_
+// gen_amalgamated begin header: include/perfetto/tracing/track_event_legacy.h
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_TRACK_EVENT_LEGACY_H_
+#define INCLUDE_PERFETTO_TRACING_TRACK_EVENT_LEGACY_H_
+
+// This file defines a compatibility shim between legacy (Chrome, V8) trace
+// event macros and track events. To avoid accidentally introducing legacy
+// events in new code, the PERFETTO_ENABLE_LEGACY_TRACE_EVENTS macro must be set
+// to 1 activate the compatibility layer.
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track_event.h"
+
+#include <stdint.h>
+
+#ifndef PERFETTO_ENABLE_LEGACY_TRACE_EVENTS
+#define PERFETTO_ENABLE_LEGACY_TRACE_EVENTS 0
+#endif
+
+// Ignore GCC warning about a missing argument for a variadic macro parameter.
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC system_header
+#endif
+
+// ----------------------------------------------------------------------------
+// Internal legacy trace point implementation.
+// ----------------------------------------------------------------------------
+
+namespace perfetto {
+namespace legacy {
+
+// The following user-provided adaptors are used to serialize user-defined
+// thread id and time types into track events. For full compatibility, the user
+// should also define the following macros appropriately:
+//
+//   #define TRACE_TIME_TICKS_NOW() ...
+//   #define TRACE_TIME_NOW() ...
+
+// User-provided function to convert an abstract thread id into a thread track.
+template <typename T>
+ThreadTrack ConvertThreadId(const T&);
+
+// Built-in implementation for events referring to the current thread.
+template <>
+ThreadTrack PERFETTO_EXPORT_COMPONENT
+ConvertThreadId(const PerfettoLegacyCurrentThreadId&);
+
+}  // namespace legacy
+}  // namespace perfetto
+
+#if PERFETTO_ENABLE_LEGACY_TRACE_EVENTS
+
+// Implementations for the INTERNAL_* adapter macros used by the trace points
+// below.
+#define PERFETTO_INTERNAL_LEGACY_EVENT_ON_TRACK(phase, category, name, track, \
+                                                ...)                          \
+  PERFETTO_INTERNAL_TRACK_EVENT_WITH_METHOD(                                  \
+      TraceForCategory, category,                                             \
+      ::perfetto::internal::DecayEventNameType(name),                         \
+      ::perfetto::internal::TrackEventLegacy::PhaseToType(phase), track,      \
+      ##__VA_ARGS__);
+
+#define PERFETTO_INTERNAL_LEGACY_EVENT_WITH_FLAGS_ON_TRACK(              \
+    phase, category, name, track, flags, ...)                            \
+  PERFETTO_INTERNAL_TRACK_EVENT_WITH_METHOD(                             \
+      TraceForCategoryLegacy, category,                                  \
+      ::perfetto::internal::DecayEventNameType(name),                    \
+      ::perfetto::internal::TrackEventLegacy::PhaseToType(phase), track, \
+      phase, flags, ##__VA_ARGS__);
+
+#define PERFETTO_INTERNAL_LEGACY_EVENT_WITH_ID_ON_TRACK(                 \
+    phase, category, name, track, flags, thread_id, id, ...)             \
+  PERFETTO_INTERNAL_TRACK_EVENT_WITH_METHOD(                             \
+      TraceForCategoryLegacyWithId, category,                            \
+      ::perfetto::internal::DecayEventNameType(name),                    \
+      ::perfetto::internal::TrackEventLegacy::PhaseToType(phase), track, \
+      phase, flags, thread_id, id, ##__VA_ARGS__);
+
+// The main entrypoint for writing unscoped legacy events.  This macro
+// determines the right track to write the event on based on |flags| and
+// |thread_id|.
+#define PERFETTO_INTERNAL_LEGACY_EVENT(phase, category, name, flags,       \
+                                       thread_id, ...)                     \
+  [&]() {                                                                  \
+    using ::perfetto::internal::TrackEventInternal;                        \
+    PERFETTO_DCHECK(!(flags & TRACE_EVENT_FLAG_COPY));                     \
+    /* First check the scope for instant events. */                        \
+    if ((phase) == TRACE_EVENT_PHASE_INSTANT) {                            \
+      /* Note: Avoids the need to set LegacyEvent::instant_event_scope. */ \
+      auto scope = (flags)&TRACE_EVENT_FLAG_SCOPE_MASK;                    \
+      switch (scope) {                                                     \
+        case TRACE_EVENT_SCOPE_GLOBAL:                                     \
+          PERFETTO_INTERNAL_LEGACY_EVENT_WITH_FLAGS_ON_TRACK(              \
+              phase, category, name, ::perfetto::Track::Global(0), flags,  \
+              ##__VA_ARGS__);                                              \
+          return;                                                          \
+        case TRACE_EVENT_SCOPE_PROCESS:                                    \
+          PERFETTO_INTERNAL_LEGACY_EVENT_WITH_FLAGS_ON_TRACK(              \
+              phase, category, name, ::perfetto::ProcessTrack::Current(),  \
+              flags, ##__VA_ARGS__);                                       \
+          return;                                                          \
+        default:                                                           \
+        case TRACE_EVENT_SCOPE_THREAD:                                     \
+          /* Fallthrough. */                                               \
+          break;                                                           \
+      }                                                                    \
+    }                                                                      \
+    /* If an event targets the current thread or another process, write    \
+     * it on the current thread's track. The process override case is      \
+     * handled through |pid_override| in WriteLegacyEvent. */              \
+    if (std::is_same<                                                      \
+            decltype(thread_id),                                           \
+            ::perfetto::legacy::PerfettoLegacyCurrentThreadId>::value ||   \
+        ((flags)&TRACE_EVENT_FLAG_HAS_PROCESS_ID)) {                       \
+      PERFETTO_INTERNAL_LEGACY_EVENT_WITH_FLAGS_ON_TRACK(                  \
+          phase, category, name, TrackEventInternal::kDefaultTrack, flags, \
+          ##__VA_ARGS__);                                                  \
+    } else {                                                               \
+      PERFETTO_INTERNAL_LEGACY_EVENT_WITH_FLAGS_ON_TRACK(                  \
+          phase, category, name,                                           \
+          ::perfetto::legacy::ConvertThreadId(thread_id), flags,           \
+          ##__VA_ARGS__);                                                  \
+    }                                                                      \
+  }()
+
+#define PERFETTO_INTERNAL_LEGACY_EVENT_WITH_ID(phase, category, name, flags, \
+                                               thread_id, id, ...)           \
+  [&]() {                                                                    \
+    using ::perfetto::internal::TrackEventInternal;                          \
+    PERFETTO_DCHECK(!(flags & TRACE_EVENT_FLAG_COPY));                       \
+    /* First check the scope for instant events. */                          \
+    if ((phase) == TRACE_EVENT_PHASE_INSTANT) {                              \
+      /* Note: Avoids the need to set LegacyEvent::instant_event_scope. */   \
+      auto scope = (flags)&TRACE_EVENT_FLAG_SCOPE_MASK;                      \
+      switch (scope) {                                                       \
+        case TRACE_EVENT_SCOPE_GLOBAL:                                       \
+          PERFETTO_INTERNAL_LEGACY_EVENT_WITH_ID_ON_TRACK(                   \
+              phase, category, name, ::perfetto::Track::Global(0), flags,    \
+              thread_id, id, ##__VA_ARGS__);                                 \
+          return;                                                            \
+        case TRACE_EVENT_SCOPE_PROCESS:                                      \
+          PERFETTO_INTERNAL_LEGACY_EVENT_WITH_ID_ON_TRACK(                   \
+              phase, category, name, ::perfetto::ProcessTrack::Current(),    \
+              flags, thread_id, id, ##__VA_ARGS__);                          \
+          return;                                                            \
+        default:                                                             \
+        case TRACE_EVENT_SCOPE_THREAD:                                       \
+          /* Fallthrough. */                                                 \
+          break;                                                             \
+      }                                                                      \
+    }                                                                        \
+    /* If an event targets the current thread or another process, write      \
+     * it on the current thread's track. The process override case is        \
+     * handled through |pid_override| in WriteLegacyEvent. */                \
+    if (std::is_same<                                                        \
+            decltype(thread_id),                                             \
+            ::perfetto::legacy::PerfettoLegacyCurrentThreadId>::value ||     \
+        ((flags)&TRACE_EVENT_FLAG_HAS_PROCESS_ID)) {                         \
+      PERFETTO_INTERNAL_LEGACY_EVENT_WITH_ID_ON_TRACK(                       \
+          phase, category, name, TrackEventInternal::kDefaultTrack, flags,   \
+          thread_id, id, ##__VA_ARGS__);                                     \
+    } else {                                                                 \
+      PERFETTO_INTERNAL_LEGACY_EVENT_WITH_ID_ON_TRACK(                       \
+          phase, category, name,                                             \
+          ::perfetto::legacy::ConvertThreadId(thread_id), flags, thread_id,  \
+          id, ##__VA_ARGS__);                                                \
+    }                                                                        \
+  }()
+
+#define INTERNAL_TRACE_EVENT_ADD(phase, category, name, flags, ...)           \
+  PERFETTO_INTERNAL_LEGACY_EVENT(                                             \
+      phase, category, ::perfetto::internal::DecayEventNameType(name), flags, \
+      ::perfetto::legacy::kCurrentThreadId, ##__VA_ARGS__)
+
+#define INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name, ...) \
+  PERFETTO_INTERNAL_SCOPED_TRACK_EVENT(                      \
+      category, ::perfetto::internal::DecayEventNameType(name), ##__VA_ARGS__)
+
+#define INTERNAL_TRACE_EVENT_ADD_SCOPED_WITH_FLOW(category, name, bind_id, \
+                                                  flags, ...)              \
+  PERFETTO_INTERNAL_SCOPED_LEGACY_TRACK_EVENT_WITH_ID(                     \
+      category, ::perfetto::internal::DecayEventNameType(name),            \
+      ::perfetto::internal::TrackEventInternal::kDefaultTrack, flags,      \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, bind_id, ##__VA_ARGS__)
+
+#define INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(phase, category, name,        \
+                                                timestamp, flags, ...)        \
+  PERFETTO_INTERNAL_LEGACY_EVENT(                                             \
+      phase, category, ::perfetto::internal::DecayEventNameType(name), flags, \
+      ::perfetto::legacy::kCurrentThreadId, timestamp, ##__VA_ARGS__)
+
+#define INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                   \
+    phase, category, name, id, thread_id, timestamp, flags, ...)              \
+  PERFETTO_INTERNAL_LEGACY_EVENT_WITH_ID(                                     \
+      phase, category, ::perfetto::internal::DecayEventNameType(name), flags, \
+      thread_id, id, timestamp, ##__VA_ARGS__)
+
+#define INTERNAL_TRACE_EVENT_ADD_WITH_ID(phase, category, name, id, flags,    \
+                                         ...)                                 \
+  PERFETTO_INTERNAL_LEGACY_EVENT_WITH_ID(                                     \
+      phase, category, ::perfetto::internal::DecayEventNameType(name), flags, \
+      ::perfetto::legacy::kCurrentThreadId, id, ##__VA_ARGS__)
+
+#define INTERNAL_TRACE_EVENT_METADATA_ADD(category, name, ...)         \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_METADATA, category, name, \
+                           TRACE_EVENT_FLAG_NONE)
+
+// ----------------------------------------------------------------------------
+// Legacy tracing common API (adapted from trace_event_common.h).
+// ----------------------------------------------------------------------------
+
+#define TRACE_DISABLED_BY_DEFAULT(name) "disabled-by-default-" name
+
+// Scoped events.
+#define TRACE_EVENT0(category_group, name) \
+  INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name)
+#define TRACE_EVENT_WITH_FLOW0(category_group, name, bind_id, flow_flags)  \
+  INTERNAL_TRACE_EVENT_ADD_SCOPED_WITH_FLOW(category_group, name, bind_id, \
+                                            flow_flags)
+#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val) \
+  INTERNAL_TRACE_EVENT_ADD_SCOPED(                              \
+      category_group, name, arg1_name,                          \
+      ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_WITH_FLOW1(category_group, name, bind_id, flow_flags, \
+                               arg1_name, arg1_val)                       \
+  INTERNAL_TRACE_EVENT_ADD_SCOPED_WITH_FLOW(                              \
+      category_group, name, bind_id, flow_flags, arg1_name,               \
+      ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT2(category_group, name, arg1_name, arg1_val, arg2_name, \
+                     arg2_val)                                             \
+  INTERNAL_TRACE_EVENT_ADD_SCOPED(                                         \
+      category_group, name, arg1_name,                                     \
+      ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,             \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+#define TRACE_EVENT_WITH_FLOW2(category_group, name, bind_id, flow_flags, \
+                               arg1_name, arg1_val, arg2_name, arg2_val)  \
+  INTERNAL_TRACE_EVENT_ADD_SCOPED_WITH_FLOW(                              \
+      category_group, name, bind_id, flow_flags, arg1_name,               \
+      ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,            \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+
+// Instant events.
+#define TRACE_EVENT_INSTANT0(category_group, name, scope)                   \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name, \
+                           TRACE_EVENT_FLAG_NONE | scope)
+#define TRACE_EVENT_INSTANT1(category_group, name, scope, arg1_name, arg1_val) \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name,    \
+                           TRACE_EVENT_FLAG_NONE | scope, arg1_name,           \
+                           ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_INSTANT2(category_group, name, scope, arg1_name, arg1_val, \
+                             arg2_name, arg2_val)                              \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name,    \
+                           TRACE_EVENT_FLAG_NONE | scope, arg1_name,           \
+                           ::perfetto::internal::PossiblyNull(arg1_val),       \
+                           arg2_name,                                          \
+                           ::perfetto::internal::PossiblyNull(arg2_val))
+#define TRACE_EVENT_COPY_INSTANT0(category_group, name, scope)        \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, \
+                           ::perfetto::DynamicString{name}, scope)
+#define TRACE_EVENT_COPY_INSTANT1(category_group, name, scope, arg1_name, \
+                                  arg1_val)                               \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group,     \
+                           ::perfetto::DynamicString{name}, scope,        \
+                           ::perfetto::DynamicString{arg1_name},          \
+                           ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_COPY_INSTANT2(category_group, name, scope, arg1_name, \
+                                  arg1_val, arg2_name, arg2_val)          \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group,     \
+                           ::perfetto::DynamicString{name}, scope,        \
+                           ::perfetto::DynamicString{arg1_name},          \
+                           ::perfetto::internal::PossiblyNull(arg1_val),  \
+                           ::perfetto::DynamicString{arg2_name},          \
+                           ::perfetto::internal::PossiblyNull(arg2_val))
+#define TRACE_EVENT_INSTANT_WITH_FLAGS0(category_group, name, scope_and_flags) \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name,    \
+                           scope_and_flags)
+#define TRACE_EVENT_INSTANT_WITH_FLAGS1(category_group, name, scope_and_flags, \
+                                        arg1_name, arg1_val)                   \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name,    \
+                           scope_and_flags, arg1_name,                         \
+                           ::perfetto::internal::PossiblyNull(arg1_val))
+
+// Instant events with explicit timestamps.
+#define TRACE_EVENT_INSTANT_WITH_TIMESTAMP0(category_group, name, scope,   \
+                                            timestamp)                     \
+  INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(TRACE_EVENT_PHASE_INSTANT,       \
+                                          category_group, name, timestamp, \
+                                          TRACE_EVENT_FLAG_NONE | scope)
+
+#define TRACE_EVENT_INSTANT_WITH_TIMESTAMP1(category_group, name, scope,  \
+                                            timestamp, arg_name, arg_val) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(                                \
+      TRACE_EVENT_PHASE_INSTANT, category_group, name, timestamp,         \
+      TRACE_EVENT_FLAG_NONE | scope, arg_name,                            \
+      ::perfetto::internal::PossiblyNull(arg_val))
+
+// Begin events.
+#define TRACE_EVENT_BEGIN0(category_group, name)                          \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group, name, \
+                           TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_BEGIN1(category_group, name, arg1_name, arg1_val)     \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group, name, \
+                           TRACE_EVENT_FLAG_NONE, arg1_name,              \
+                           ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_BEGIN2(category_group, name, arg1_name, arg1_val,       \
+                           arg2_name, arg2_val)                             \
+  INTERNAL_TRACE_EVENT_ADD(                                                 \
+      TRACE_EVENT_PHASE_BEGIN, category_group, name, TRACE_EVENT_FLAG_NONE, \
+      arg1_name, ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,   \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+#define TRACE_EVENT_BEGIN_WITH_FLAGS0(category_group, name, flags) \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group, name, flags)
+#define TRACE_EVENT_BEGIN_WITH_FLAGS1(category_group, name, flags, arg1_name, \
+                                      arg1_val)                               \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group, name,     \
+                           flags, arg1_name,                                  \
+                           ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_COPY_BEGIN2(category_group, name, arg1_name, arg1_val, \
+                                arg2_name, arg2_val)                       \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group,        \
+                           ::perfetto::DynamicString{name},                \
+                           TRACE_EVENT_FLAG_NONE,                          \
+                           ::perfetto::DynamicString{arg1_name},           \
+                           ::perfetto::internal::PossiblyNull(arg1_val),   \
+                           ::perfetto::DynamicString{arg2_name},           \
+                           ::perfetto::internal::PossiblyNull(arg2_val))
+
+// Begin events with explicit timestamps.
+#define TRACE_EVENT_BEGIN_WITH_ID_TID_AND_TIMESTAMP0(category_group, name, id, \
+                                                     thread_id, timestamp)     \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                          \
+      TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, thread_id,      \
+      timestamp, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_COPY_BEGIN_WITH_ID_TID_AND_TIMESTAMP0(       \
+    category_group, name, id, thread_id, timestamp)              \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(            \
+      TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group,             \
+      ::perfetto::DynamicString{name}, id, thread_id, timestamp, \
+      TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_COPY_BEGIN_WITH_ID_TID_AND_TIMESTAMP1(               \
+    category_group, name, id, thread_id, timestamp, arg1_name, arg1_val) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                    \
+      TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group,                     \
+      ::perfetto::DynamicString{name}, id, thread_id, timestamp,         \
+      TRACE_EVENT_FLAG_NONE, ::perfetto::DynamicString{arg1_name},       \
+      ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_COPY_BEGIN_WITH_ID_TID_AND_TIMESTAMP2(               \
+    category_group, name, id, thread_id, timestamp, arg1_name, arg1_val, \
+    arg2_name, arg2_val)                                                 \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                    \
+      TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group,                     \
+      ::perfetto::DynamicString{name}, id, thread_id, timestamp,         \
+      TRACE_EVENT_FLAG_NONE, ::perfetto::DynamicString{arg1_name},       \
+      ::perfetto::internal::PossiblyNull(arg1_val),                      \
+      ::perfetto::DynamicString{arg2_name},                              \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+
+// End events.
+#define TRACE_EVENT_END0(category_group, name)                          \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category_group, name, \
+                           TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_END1(category_group, name, arg1_name, arg1_val)     \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category_group, name, \
+                           TRACE_EVENT_FLAG_NONE, arg1_name,            \
+                           ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_END2(category_group, name, arg1_name, arg1_val, arg2_name, \
+                         arg2_val)                                             \
+  INTERNAL_TRACE_EVENT_ADD(                                                    \
+      TRACE_EVENT_PHASE_END, category_group, name, TRACE_EVENT_FLAG_NONE,      \
+      arg1_name, ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,      \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+#define TRACE_EVENT_END_WITH_FLAGS0(category_group, name, flags) \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category_group, name, flags)
+#define TRACE_EVENT_END_WITH_FLAGS1(category_group, name, flags, arg1_name,    \
+                                    arg1_val)                                  \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category_group, name, flags, \
+                           arg1_name,                                          \
+                           ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_COPY_END2(category_group, name, arg1_name, arg1_val,      \
+                              arg2_name, arg2_val)                            \
+  INTERNAL_TRACE_EVENT_ADD(                                                   \
+      TRACE_EVENT_PHASE_END, category_group, ::perfetto::DynamicString{name}, \
+      TRACE_EVENT_FLAG_NONE, ::perfetto::DynamicString{arg1_name},            \
+      ::perfetto::internal::PossiblyNull(arg1_val),                           \
+      ::perfetto::DynamicString{arg2_name},                                   \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+
+// Mark events.
+#define TRACE_EVENT_MARK_WITH_TIMESTAMP0(category_group, name, timestamp)  \
+  INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(TRACE_EVENT_PHASE_MARK,          \
+                                          category_group, name, timestamp, \
+                                          TRACE_EVENT_FLAG_NONE)
+
+#define TRACE_EVENT_MARK_WITH_TIMESTAMP1(category_group, name, timestamp, \
+                                         arg1_name, arg1_val)             \
+  INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(                                \
+      TRACE_EVENT_PHASE_MARK, category_group, name, timestamp,            \
+      TRACE_EVENT_FLAG_NONE, arg1_name,                                   \
+      ::perfetto::internal::PossiblyNull(arg1_val))
+
+#define TRACE_EVENT_MARK_WITH_TIMESTAMP2(                                      \
+    category_group, name, timestamp, arg1_name, arg1_val, arg2_name, arg2_val) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(                                     \
+      TRACE_EVENT_PHASE_MARK, category_group, name, timestamp,                 \
+      TRACE_EVENT_FLAG_NONE, arg1_name,                                        \
+      ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,                 \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+
+#define TRACE_EVENT_COPY_MARK(category_group, name)                \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_MARK, category_group, \
+                           ::perfetto::DynamicString{name},        \
+                           TRACE_EVENT_FLAG_NONE)
+
+#define TRACE_EVENT_COPY_MARK1(category_group, name, arg1_name, arg1_val)      \
+  INTERNAL_TRACE_EVENT_ADD(                                                    \
+      TRACE_EVENT_PHASE_MARK, category_group, ::perfetto::DynamicString{name}, \
+      TRACE_EVENT_FLAG_NONE, ::perfetto::DynamicString{arg1_name},             \
+      ::perfetto::internal::PossiblyNull(arg1_val))
+
+#define TRACE_EVENT_COPY_MARK_WITH_TIMESTAMP(category_group, name, timestamp)  \
+  INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(                                     \
+      TRACE_EVENT_PHASE_MARK, category_group, ::perfetto::DynamicString{name}, \
+      timestamp, TRACE_EVENT_FLAG_NONE)
+
+// End events with explicit thread and timestamp.
+#define TRACE_EVENT_END_WITH_ID_TID_AND_TIMESTAMP0(category_group, name, id, \
+                                                   thread_id, timestamp)     \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                        \
+      TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id, thread_id,      \
+      timestamp, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_COPY_END_WITH_ID_TID_AND_TIMESTAMP0(         \
+    category_group, name, id, thread_id, timestamp)              \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(            \
+      TRACE_EVENT_PHASE_ASYNC_END, category_group,               \
+      ::perfetto::DynamicString{name}, id, thread_id, timestamp, \
+      TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_COPY_END_WITH_ID_TID_AND_TIMESTAMP1(                 \
+    category_group, name, id, thread_id, timestamp, arg1_name, arg1_val) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                    \
+      TRACE_EVENT_PHASE_ASYNC_END, category_group,                       \
+      ::perfetto::DynamicString{name}, id, thread_id, timestamp,         \
+      TRACE_EVENT_FLAG_NONE, ::perfetto::DynamicString{arg1_name},       \
+      ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_COPY_END_WITH_ID_TID_AND_TIMESTAMP2(                 \
+    category_group, name, id, thread_id, timestamp, arg1_name, arg1_val, \
+    arg2_name, arg2_val)                                                 \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                    \
+      TRACE_EVENT_PHASE_ASYNC_END, category_group,                       \
+      ::perfetto::DynamicString{name}, id, thread_id, timestamp,         \
+      TRACE_EVENT_FLAG_NONE, ::perfetto::DynamicString{arg1_name},       \
+      ::perfetto::internal::PossiblyNull(arg1_val),                      \
+      ::perfetto::DynamicString{arg2_name},                              \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+
+// Counters.
+#define TRACE_COUNTER1(category_group, name, value)                         \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, category_group, name, \
+                           TRACE_EVENT_FLAG_NONE, "value",                  \
+                           static_cast<int>(value))
+#define TRACE_COUNTER_WITH_FLAG1(category_group, name, flag, value)         \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, category_group, name, \
+                           flag, "value", static_cast<int>(value))
+#define TRACE_COPY_COUNTER1(category_group, name, value)              \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, category_group, \
+                           ::perfetto::DynamicString{name},           \
+                           TRACE_EVENT_FLAG_NONE, "value",            \
+                           static_cast<int>(value))
+#define TRACE_COUNTER2(category_group, name, value1_name, value1_val,       \
+                       value2_name, value2_val)                             \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, category_group, name, \
+                           TRACE_EVENT_FLAG_NONE, value1_name,              \
+                           static_cast<int>(value1_val), value2_name,       \
+                           static_cast<int>(value2_val))
+#define TRACE_COPY_COUNTER2(category_group, name, value1_name, value1_val, \
+                            value2_name, value2_val)                       \
+  INTERNAL_TRACE_EVENT_ADD(                                                \
+      TRACE_EVENT_PHASE_COUNTER, category_group,                           \
+      ::perfetto::DynamicString{name}, TRACE_EVENT_FLAG_NONE, value1_name, \
+      static_cast<int>(value1_val), value2_name, static_cast<int>(value2_val))
+
+// Counters with explicit timestamps.
+#define TRACE_COUNTER_WITH_TIMESTAMP1(category_group, name, timestamp, value) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(                                    \
+      TRACE_EVENT_PHASE_COUNTER, category_group, name, timestamp,             \
+      TRACE_EVENT_FLAG_NONE, "value", static_cast<int>(value))
+
+#define TRACE_COUNTER_WITH_TIMESTAMP2(category_group, name, timestamp,      \
+                                      value1_name, value1_val, value2_name, \
+                                      value2_val)                           \
+  INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(                                  \
+      TRACE_EVENT_PHASE_COUNTER, category_group, name, timestamp,           \
+      TRACE_EVENT_FLAG_NONE, value1_name, static_cast<int>(value1_val),     \
+      value2_name, static_cast<int>(value2_val))
+
+// Counters with ids.
+#define TRACE_COUNTER_ID1(category_group, name, id, value)                    \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, category_group, \
+                                   name, id, TRACE_EVENT_FLAG_NONE, "value",  \
+                                   static_cast<int>(value))
+#define TRACE_COPY_COUNTER_ID1(category_group, name, id, value)               \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, category_group, \
+                                   ::perfetto::DynamicString{name}, id,       \
+                                   TRACE_EVENT_FLAG_NONE, "value",            \
+                                   static_cast<int>(value))
+#define TRACE_COUNTER_ID2(category_group, name, id, value1_name, value1_val,  \
+                          value2_name, value2_val)                            \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, category_group, \
+                                   name, id, TRACE_EVENT_FLAG_NONE,           \
+                                   value1_name, static_cast<int>(value1_val), \
+                                   value2_name, static_cast<int>(value2_val))
+#define TRACE_COPY_COUNTER_ID2(category_group, name, id, value1_name,          \
+                               value1_val, value2_name, value2_val)            \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                            \
+      TRACE_EVENT_PHASE_COUNTER, category_group,                               \
+      ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_NONE, value1_name, \
+      static_cast<int>(value1_val), value2_name, static_cast<int>(value2_val))
+
+// Sampling profiler events.
+#define TRACE_EVENT_SAMPLE_WITH_ID1(category_group, name, id, arg1_name,       \
+                                    arg1_val)                                  \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_SAMPLE, category_group,   \
+                                   name, id, TRACE_EVENT_FLAG_NONE, arg1_name, \
+                                   arg1_val)
+
+// Legacy async events.
+#define TRACE_EVENT_ASYNC_BEGIN0(category_group, name, id)        \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
+                                   category_group, name, id,      \
+                                   TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_ASYNC_BEGIN1(category_group, name, id, arg1_name, \
+                                 arg1_val)                            \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                   \
+      TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id,        \
+      TRACE_EVENT_FLAG_NONE, arg1_name,                               \
+      ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_ASYNC_BEGIN2(category_group, name, id, arg1_name, \
+                                 arg1_val, arg2_name, arg2_val)       \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                   \
+      TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id,        \
+      TRACE_EVENT_FLAG_NONE, arg1_name,                               \
+      ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,        \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+#define TRACE_EVENT_COPY_ASYNC_BEGIN0(category_group, name, id) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                             \
+      TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group,            \
+      ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_COPY_ASYNC_BEGIN1(category_group, name, id, arg1_name, \
+                                      arg1_val)                            \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                        \
+      TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group,                       \
+      ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_NONE,          \
+      ::perfetto::DynamicString{arg1_name},                                \
+      ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_COPY_ASYNC_BEGIN2(category_group, name, id, arg1_name, \
+                                      arg1_val, arg2_name, arg2_val)       \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                        \
+      TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group,                       \
+      ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_NONE,          \
+      ::perfetto::DynamicString{arg1_name},                                \
+      ::perfetto::internal::PossiblyNull(arg1_val),                        \
+      ::perfetto::DynamicString{arg2_name},                                \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+#define TRACE_EVENT_ASYNC_BEGIN_WITH_FLAGS0(category_group, name, id, flags) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN,            \
+                                   category_group, name, id, flags)
+
+// Legacy async events with explicit timestamps.
+#define TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP0(category_group, name, id, \
+                                                timestamp)                \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                     \
+      TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id,            \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP1(                           \
+    category_group, name, id, timestamp, arg1_name, arg1_val)              \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                      \
+      TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id,             \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE, \
+      arg1_name, ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP_AND_FLAGS0(     \
+    category_group, name, id, timestamp, flags)                         \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                   \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group, name, id, \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, flags)
+#define TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP0(category_group, name, \
+                                                       id, timestamp)        \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                        \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id,        \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP2(category_group, name, id,      \
+                                                timestamp, arg1_name,          \
+                                                arg1_val, arg2_name, arg2_val) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                          \
+      TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id,                 \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE,     \
+      arg1_name, ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,      \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+#define TRACE_EVENT_COPY_ASYNC_BEGIN_WITH_TIMESTAMP0(category_group, name, id, \
+                                                     timestamp)                \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                          \
+      TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group,                           \
+      ::perfetto::DynamicString{name}, id, TRACE_EVENT_API_CURRENT_THREAD_ID,  \
+      timestamp, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP_AND_FLAGS0(     \
+    category_group, name, id, timestamp, flags)                \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(          \
+      TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, flags)
+
+// Legacy async step into events.
+#define TRACE_EVENT_ASYNC_STEP_INTO0(category_group, name, id, step)  \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP_INTO, \
+                                   category_group, name, id,          \
+                                   TRACE_EVENT_FLAG_NONE, "step", step)
+#define TRACE_EVENT_ASYNC_STEP_INTO1(category_group, name, id, step, \
+                                     arg1_name, arg1_val)            \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                  \
+      TRACE_EVENT_PHASE_ASYNC_STEP_INTO, category_group, name, id,   \
+      TRACE_EVENT_FLAG_NONE, "step", step, arg1_name,                \
+      ::perfetto::internal::PossiblyNull(arg1_val))
+
+// Legacy async step into events with timestamps.
+#define TRACE_EVENT_ASYNC_STEP_INTO_WITH_TIMESTAMP0(category_group, name, id, \
+                                                    step, timestamp)          \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                         \
+      TRACE_EVENT_PHASE_ASYNC_STEP_INTO, category_group, name, id,            \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE,    \
+      "step", step)
+
+// Legacy async step past events.
+#define TRACE_EVENT_ASYNC_STEP_PAST0(category_group, name, id, step)  \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP_PAST, \
+                                   category_group, name, id,          \
+                                   TRACE_EVENT_FLAG_NONE, "step", step)
+#define TRACE_EVENT_ASYNC_STEP_PAST1(category_group, name, id, step, \
+                                     arg1_name, arg1_val)            \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                  \
+      TRACE_EVENT_PHASE_ASYNC_STEP_PAST, category_group, name, id,   \
+      TRACE_EVENT_FLAG_NONE, "step", step, arg1_name,                \
+      ::perfetto::internal::PossiblyNull(arg1_val))
+
+// Legacy async end events.
+#define TRACE_EVENT_ASYNC_END0(category_group, name, id)        \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
+                                   category_group, name, id,    \
+                                   TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_ASYNC_END1(category_group, name, id, arg1_name, arg1_val) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                           \
+      TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id,                  \
+      TRACE_EVENT_FLAG_NONE, arg1_name,                                       \
+      ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_ASYNC_END2(category_group, name, id, arg1_name, arg1_val, \
+                               arg2_name, arg2_val)                           \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                           \
+      TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id,                  \
+      TRACE_EVENT_FLAG_NONE, arg1_name,                                       \
+      ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,                \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+#define TRACE_EVENT_COPY_ASYNC_END0(category_group, name, id) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                           \
+      TRACE_EVENT_PHASE_ASYNC_END, category_group,            \
+      ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_COPY_ASYNC_END1(category_group, name, id, arg1_name, \
+                                    arg1_val)                            \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                      \
+      TRACE_EVENT_PHASE_ASYNC_END, category_group,                       \
+      ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_NONE,        \
+      ::perfetto::DynamicString{arg1_name},                              \
+      ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_COPY_ASYNC_END2(category_group, name, id, arg1_name, \
+                                    arg1_val, arg2_name, arg2_val)       \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                      \
+      TRACE_EVENT_PHASE_ASYNC_END, category_group,                       \
+      ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_NONE,        \
+      ::perfetto::DynamicString{arg1_name},                              \
+      ::perfetto::internal::PossiblyNull(arg1_val),                      \
+      ::perfetto::DynamicString{arg2_name},                              \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+#define TRACE_EVENT_ASYNC_END_WITH_FLAGS0(category_group, name, id, flags) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END,            \
+                                   category_group, name, id, flags)
+
+// Legacy async end events with explicit timestamps.
+#define TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP0(category_group, name, id, \
+                                              timestamp)                \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                   \
+      TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id,            \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP1(category_group, name, id,       \
+                                              timestamp, arg1_name, arg1_val) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                         \
+      TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id,                  \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE,    \
+      arg1_name, ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP2(category_group, name, id,       \
+                                              timestamp, arg1_name, arg1_val, \
+                                              arg2_name, arg2_val)            \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                         \
+      TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id,                  \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE,    \
+      arg1_name, ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,     \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+#define TRACE_EVENT_COPY_ASYNC_END_WITH_TIMESTAMP0(category_group, name, id,  \
+                                                   timestamp)                 \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                         \
+      TRACE_EVENT_PHASE_ASYNC_END, category_group,                            \
+      ::perfetto::DynamicString{name}, id, TRACE_EVENT_API_CURRENT_THREAD_ID, \
+      timestamp, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP_AND_FLAGS0(category_group, name, \
+                                                        id, timestamp, flags) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                         \
+      TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id,                  \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, flags)
+
+// Async events.
+#define TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(category_group, name, id)        \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, \
+                                   category_group, name, id,               \
+                                   TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_NESTABLE_ASYNC_BEGIN1(category_group, name, id, arg1_name, \
+                                          arg1_val)                            \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                            \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group, name, id,        \
+      TRACE_EVENT_FLAG_NONE, arg1_name,                                        \
+      ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_NESTABLE_ASYNC_BEGIN2(category_group, name, id, arg1_name, \
+                                          arg1_val, arg2_name, arg2_val)       \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                            \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group, name, id,        \
+      TRACE_EVENT_FLAG_NONE, arg1_name,                                        \
+      ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,                 \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+#define TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_FLAGS0(category_group, name, id, \
+                                                     flags)                    \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN,     \
+                                   category_group, name, id, flags)
+#define TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP1(                  \
+    category_group, name, id, timestamp, arg1_name, arg1_val)              \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                      \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group, name, id,    \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE, \
+      arg1_name, ::perfetto::internal::PossiblyNull(arg1_val))
+
+// Async end events.
+#define TRACE_EVENT_NESTABLE_ASYNC_END0(category_group, name, id)        \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, \
+                                   category_group, name, id,             \
+                                   TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_NESTABLE_ASYNC_END1(category_group, name, id, arg1_name, \
+                                        arg1_val)                            \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                          \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id,        \
+      TRACE_EVENT_FLAG_NONE, arg1_name,                                      \
+      ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_NESTABLE_ASYNC_END2(category_group, name, id, arg1_name, \
+                                        arg1_val, arg2_name, arg2_val)       \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                          \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id,        \
+      TRACE_EVENT_FLAG_NONE, arg1_name,                                      \
+      ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,               \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+#define TRACE_EVENT_NESTABLE_ASYNC_END_WITH_FLAGS0(category_group, name, id, \
+                                                   flags)                    \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_END,     \
+                                   category_group, name, id, flags)
+
+// Async instant events.
+#define TRACE_EVENT_NESTABLE_ASYNC_INSTANT0(category_group, name, id)        \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT, \
+                                   category_group, name, id,                 \
+                                   TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_NESTABLE_ASYNC_INSTANT1(category_group, name, id,     \
+                                            arg1_name, arg1_val)          \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                       \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT, category_group, name, id, \
+      TRACE_EVENT_FLAG_NONE, arg1_name,                                   \
+      ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_NESTABLE_ASYNC_INSTANT2(                              \
+    category_group, name, id, arg1_name, arg1_val, arg2_name, arg2_val)   \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                       \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT, category_group, name, id, \
+      TRACE_EVENT_FLAG_NONE, arg1_name,                                   \
+      ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,            \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+#define TRACE_EVENT_COPY_NESTABLE_ASYNC_BEGIN_WITH_TTS2(                \
+    category_group, name, id, arg1_name, arg1_val, arg2_name, arg2_val) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                     \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group,           \
+      ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_ASYNC_TTS,  \
+      ::perfetto::DynamicString{arg1_name},                             \
+      ::perfetto::internal::PossiblyNull(arg1_val),                     \
+      ::perfetto::DynamicString{arg2_name},                             \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+#define TRACE_EVENT_COPY_NESTABLE_ASYNC_END_WITH_TTS2(                  \
+    category_group, name, id, arg1_name, arg1_val, arg2_name, arg2_val) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                     \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group,             \
+      ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_ASYNC_TTS,  \
+      ::perfetto::DynamicString{arg1_name},                             \
+      ::perfetto::internal::PossiblyNull(arg1_val),                     \
+      ::perfetto::DynamicString{arg2_name},                             \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+
+// Async events with explicit timestamps.
+#define TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP0(category_group, name, \
+                                                         id, timestamp)        \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                          \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group, name, id,        \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP0(category_group, name, \
+                                                       id, timestamp)        \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                        \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id,        \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP1(                    \
+    category_group, name, id, timestamp, arg1_name, arg1_val)              \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                      \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id,      \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE, \
+      arg1_name, ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP2(                    \
+    category_group, name, id, timestamp, arg1_name, arg1_val, arg2_name,   \
+    arg2_val)                                                              \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                      \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id,      \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE, \
+      arg1_name, ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,  \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+#define TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP_AND_FLAGS0(     \
+    category_group, name, id, timestamp, flags)                       \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                 \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id, \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, flags)
+#define TRACE_EVENT_NESTABLE_ASYNC_INSTANT_WITH_TIMESTAMP0(               \
+    category_group, name, id, timestamp)                                  \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                     \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT, category_group, name, id, \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_COPY_NESTABLE_ASYNC_BEGIN0(category_group, name, id) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                      \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group,            \
+      ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_COPY_NESTABLE_ASYNC_BEGIN1(category_group, name, id, \
+                                               arg1_name, arg1_val)      \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                      \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group,            \
+      ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_NONE,        \
+      ::perfetto::DynamicString{arg1_name},                              \
+      ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_COPY_NESTABLE_ASYNC_BEGIN2(                         \
+    category_group, name, id, arg1_name, arg1_val, arg2_name, arg2_val) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                     \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group,           \
+      ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_NONE,       \
+      ::perfetto::DynamicString{arg1_name},                             \
+      ::perfetto::internal::PossiblyNull(arg1_val),                     \
+      ::perfetto::DynamicString{arg2_name},                             \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+#define TRACE_EVENT_COPY_NESTABLE_ASYNC_END0(category_group, name, id) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                    \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group,            \
+      ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_COPY_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP0(                \
+    category_group, name, id, timestamp)                                      \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                         \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group,                 \
+      ::perfetto::DynamicString{name}, id, TRACE_EVENT_API_CURRENT_THREAD_ID, \
+      timestamp, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_COPY_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP1(                \
+    category_group, name, id, timestamp, arg1_name, arg1_val)                 \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                         \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group,                 \
+      ::perfetto::DynamicString{name}, id, TRACE_EVENT_API_CURRENT_THREAD_ID, \
+      timestamp, TRACE_EVENT_FLAG_NONE, ::perfetto::DynamicString{arg1_name}, \
+      ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_COPY_NESTABLE_ASYNC_END_WITH_TIMESTAMP0(                  \
+    category_group, name, id, timestamp)                                      \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                         \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group,                   \
+      ::perfetto::DynamicString{name}, id, TRACE_EVENT_API_CURRENT_THREAD_ID, \
+      timestamp, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_COPY_NESTABLE_ASYNC_END_WITH_TIMESTAMP2(               \
+    category_group, name, id, timestamp, arg1_name, arg1_val, arg2_name,   \
+    arg2_val)                                                              \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                      \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id,      \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE, \
+      ::perfetto::DynamicString{arg1_name},                                \
+      ::perfetto::internal::PossiblyNull(arg1_val),                        \
+      ::perfetto::DynamicString{arg2_name},                                \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+
+// Metadata events.
+#define TRACE_EVENT_METADATA1(category_group, name, arg1_name, arg1_val) \
+  INTERNAL_TRACE_EVENT_METADATA_ADD(                                     \
+      category_group, name, arg1_name,                                   \
+      ::perfetto::internal::PossiblyNull(arg1_val))
+
+// Clock sync events.
+#define TRACE_EVENT_CLOCK_SYNC_RECEIVER(sync_id)                           \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_CLOCK_SYNC, "__metadata",     \
+                           "clock_sync", TRACE_EVENT_FLAG_NONE, "sync_id", \
+                           sync_id)
+#define TRACE_EVENT_CLOCK_SYNC_ISSUER(sync_id, issue_ts, issue_end_ts)        \
+  INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(                                    \
+      TRACE_EVENT_PHASE_CLOCK_SYNC, "__metadata", "clock_sync", issue_end_ts, \
+      TRACE_EVENT_FLAG_NONE, "sync_id", sync_id, "issue_ts", issue_ts)
+
+// Object events.
+#define TRACE_EVENT_OBJECT_CREATED_WITH_ID(category_group, name, id) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_CREATE_OBJECT,  \
+                                   category_group, name, id,         \
+                                   TRACE_EVENT_FLAG_NONE)
+
+#define TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(category_group, name, id, \
+                                            snapshot)                 \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                   \
+      TRACE_EVENT_PHASE_SNAPSHOT_OBJECT, category_group, name, id,    \
+      TRACE_EVENT_FLAG_NONE, "snapshot", snapshot)
+
+#define TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID_AND_TIMESTAMP(                 \
+    category_group, name, id, timestamp, snapshot)                         \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                      \
+      TRACE_EVENT_PHASE_SNAPSHOT_OBJECT, category_group, name, id,         \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE, \
+      "snapshot", snapshot)
+
+#define TRACE_EVENT_OBJECT_DELETED_WITH_ID(category_group, name, id) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_DELETE_OBJECT,  \
+                                   category_group, name, id,         \
+                                   TRACE_EVENT_FLAG_NONE)
+
+// TODO(skyostil): Implement binary-efficient trace events.
+#define TRACE_EVENT_BINARY_EFFICIENT0 TRACE_EVENT0
+#define TRACE_EVENT_BINARY_EFFICIENT1 TRACE_EVENT1
+#define TRACE_EVENT_BINARY_EFFICIENT2 TRACE_EVENT2
+
+// Macro to efficiently determine if a given category group is enabled.
+#define TRACE_EVENT_CATEGORY_GROUP_ENABLED(category, ret) \
+  do {                                                    \
+    *ret = TRACE_EVENT_CATEGORY_ENABLED(category);        \
+  } while (0)
+
+// Macro to efficiently determine, through polling, if a new trace has begun.
+#define TRACE_EVENT_IS_NEW_TRACE(ret)                                \
+  do {                                                               \
+    static int PERFETTO_UID(prev) = -1;                              \
+    int PERFETTO_UID(curr) =                                         \
+        ::perfetto::internal::TrackEventInternal::GetSessionCount(); \
+    if (PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent::IsEnabled() &&   \
+        (PERFETTO_UID(prev) != PERFETTO_UID(curr))) {                \
+      *(ret) = true;                                                 \
+      PERFETTO_UID(prev) = PERFETTO_UID(curr);                       \
+    } else {                                                         \
+      *(ret) = false;                                                \
+    }                                                                \
+  } while (0)
+
+// ----------------------------------------------------------------------------
+// Legacy tracing API (adapted from trace_event.h).
+// ----------------------------------------------------------------------------
+
+// We can implement the following subset of the legacy tracing API without
+// involvement from the embedder. APIs such as TRACE_EVENT_API_ADD_TRACE_EVENT
+// are still up to the embedder to define.
+
+#define TRACE_STR_COPY(str) \
+  ::perfetto::DynamicString { ::perfetto::internal::PossiblyNull(str) }
+
+#define TRACE_ID_WITH_SCOPE(scope, ...) \
+  ::perfetto::internal::LegacyTraceId::WithScope(scope, ##__VA_ARGS__)
+
+// Use this for ids that are unique across processes. This allows different
+// processes to use the same id to refer to the same event.
+#define TRACE_ID_GLOBAL(id) ::perfetto::internal::LegacyTraceId::GlobalId(id)
+
+// Use this for ids that are unique within a single process. This allows
+// different processes to use the same id to refer to different events.
+#define TRACE_ID_LOCAL(id) ::perfetto::internal::LegacyTraceId::LocalId(id)
+
+// Returns a pointer to a uint8_t which indicates whether tracing is enabled for
+// the given category or not. A zero value means tracing is disabled and
+// non-zero indicates at least one tracing session for this category is active.
+// Note that callers should not make any assumptions at what each bit represents
+// in the status byte. Does not support dynamic categories.
+#define TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category)              \
+  reinterpret_cast<const uint8_t*>(                                       \
+      [&] {                                                               \
+        static_assert(                                                    \
+            !std::is_same<::perfetto::DynamicCategory,                    \
+                          decltype(category)>::value,                     \
+            "Enabled flag pointers are not supported for dynamic trace "  \
+            "categories.");                                               \
+      },                                                                  \
+      PERFETTO_TRACK_EVENT_NAMESPACE::internal::kCategoryRegistry         \
+          .GetCategoryState(                                              \
+              PERFETTO_TRACK_EVENT_NAMESPACE::internal::kCategoryRegistry \
+                  .Find(category, /*is_dynamic=*/false)))
+
+// Given a pointer returned by TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED,
+// yields a pointer to the name of the corresponding category group.
+#define TRACE_EVENT_API_GET_CATEGORY_GROUP_NAME(category_enabled_ptr)     \
+  PERFETTO_TRACK_EVENT_NAMESPACE::internal::kCategoryRegistry             \
+      .GetCategory(                                                       \
+          category_enabled_ptr -                                          \
+          reinterpret_cast<const uint8_t*>(                               \
+              PERFETTO_TRACK_EVENT_NAMESPACE::internal::kCategoryRegistry \
+                  .GetCategoryState(0u)))                                 \
+      ->name
+
+#endif  // PERFETTO_ENABLE_LEGACY_TRACE_EVENTS
+
+#endif  // INCLUDE_PERFETTO_TRACING_TRACK_EVENT_LEGACY_H_
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_H_
+#define INCLUDE_PERFETTO_TRACING_H_
+
+// This headers wraps all the headers necessary to use the public Perfetto
+// Tracing API. Embedders should preferably use this one header to avoid having
+// to figure out the various set of header required for each class.
+// The only exception to this should be large projects where build time is a
+// concern (e.g. chromium), which migh prefer sticking to strict IWYU.
+
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/buffer_exhausted_policy.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/console_interceptor.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_config.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/trace_config.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/data_source.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/interceptor.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/platform.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/tracing.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/tracing_backend.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track_event.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track_event_interned_data_index.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track_event_legacy.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track_event_state_tracker.h"
+
+#endif  // INCLUDE_PERFETTO_TRACING_H_
+// gen_amalgamated begin header: gen/protos/perfetto/common/android_energy_consumer_descriptor.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_ENERGY_CONSUMER_DESCRIPTOR_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_ENERGY_CONSUMER_DESCRIPTOR_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class AndroidEnergyConsumerDescriptor;
+class AndroidEnergyConsumer;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT AndroidEnergyConsumerDescriptor : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kEnergyConsumersFieldNumber = 1,
+  };
+
+  AndroidEnergyConsumerDescriptor();
+  ~AndroidEnergyConsumerDescriptor() override;
+  AndroidEnergyConsumerDescriptor(AndroidEnergyConsumerDescriptor&&) noexcept;
+  AndroidEnergyConsumerDescriptor& operator=(AndroidEnergyConsumerDescriptor&&);
+  AndroidEnergyConsumerDescriptor(const AndroidEnergyConsumerDescriptor&);
+  AndroidEnergyConsumerDescriptor& operator=(const AndroidEnergyConsumerDescriptor&);
+  bool operator==(const AndroidEnergyConsumerDescriptor&) const;
+  bool operator!=(const AndroidEnergyConsumerDescriptor& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<AndroidEnergyConsumer>& energy_consumers() const { return energy_consumers_; }
+  std::vector<AndroidEnergyConsumer>* mutable_energy_consumers() { return &energy_consumers_; }
+  int energy_consumers_size() const;
+  void clear_energy_consumers();
+  AndroidEnergyConsumer* add_energy_consumers();
+
+ private:
+  std::vector<AndroidEnergyConsumer> energy_consumers_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT AndroidEnergyConsumer : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kEnergyConsumerIdFieldNumber = 1,
+    kOrdinalFieldNumber = 2,
+    kTypeFieldNumber = 3,
+    kNameFieldNumber = 4,
+  };
+
+  AndroidEnergyConsumer();
+  ~AndroidEnergyConsumer() override;
+  AndroidEnergyConsumer(AndroidEnergyConsumer&&) noexcept;
+  AndroidEnergyConsumer& operator=(AndroidEnergyConsumer&&);
+  AndroidEnergyConsumer(const AndroidEnergyConsumer&);
+  AndroidEnergyConsumer& operator=(const AndroidEnergyConsumer&);
+  bool operator==(const AndroidEnergyConsumer&) const;
+  bool operator!=(const AndroidEnergyConsumer& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_energy_consumer_id() const { return _has_field_[1]; }
+  int32_t energy_consumer_id() const { return energy_consumer_id_; }
+  void set_energy_consumer_id(int32_t value) { energy_consumer_id_ = value; _has_field_.set(1); }
+
+  bool has_ordinal() const { return _has_field_[2]; }
+  int32_t ordinal() const { return ordinal_; }
+  void set_ordinal(int32_t value) { ordinal_ = value; _has_field_.set(2); }
+
+  bool has_type() const { return _has_field_[3]; }
+  const std::string& type() const { return type_; }
+  void set_type(const std::string& value) { type_ = value; _has_field_.set(3); }
+
+  bool has_name() const { return _has_field_[4]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(4); }
+
+ private:
+  int32_t energy_consumer_id_{};
+  int32_t ordinal_{};
+  std::string type_{};
+  std::string name_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<5> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_ENERGY_CONSUMER_DESCRIPTOR_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/common/android_log_constants.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_LOG_CONSTANTS_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_LOG_CONSTANTS_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum AndroidLogId : int;
+enum AndroidLogPriority : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum AndroidLogId : int {
+  LID_DEFAULT = 0,
+  LID_RADIO = 1,
+  LID_EVENTS = 2,
+  LID_SYSTEM = 3,
+  LID_CRASH = 4,
+  LID_STATS = 5,
+  LID_SECURITY = 6,
+  LID_KERNEL = 7,
+};
+enum AndroidLogPriority : int {
+  PRIO_UNSPECIFIED = 0,
+  PRIO_UNUSED = 1,
+  PRIO_VERBOSE = 2,
+  PRIO_DEBUG = 3,
+  PRIO_INFO = 4,
+  PRIO_WARN = 5,
+  PRIO_ERROR = 6,
+  PRIO_FATAL = 7,
+};
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_LOG_CONSTANTS_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/common/builtin_clock.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_BUILTIN_CLOCK_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_BUILTIN_CLOCK_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum BuiltinClock : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum BuiltinClock : int {
+  BUILTIN_CLOCK_UNKNOWN = 0,
+  BUILTIN_CLOCK_REALTIME = 1,
+  BUILTIN_CLOCK_REALTIME_COARSE = 2,
+  BUILTIN_CLOCK_MONOTONIC = 3,
+  BUILTIN_CLOCK_MONOTONIC_COARSE = 4,
+  BUILTIN_CLOCK_MONOTONIC_RAW = 5,
+  BUILTIN_CLOCK_BOOTTIME = 6,
+  BUILTIN_CLOCK_TSC = 9,
+  BUILTIN_CLOCK_MAX_ID = 63,
+};
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_BUILTIN_CLOCK_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/common/commit_data_request.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_COMMIT_DATA_REQUEST_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_COMMIT_DATA_REQUEST_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class CommitDataRequest;
+class CommitDataRequest_ChunkToPatch;
+class CommitDataRequest_ChunkToPatch_Patch;
+class CommitDataRequest_ChunksToMove;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT CommitDataRequest : public ::protozero::CppMessageObj {
+ public:
+  using ChunksToMove = CommitDataRequest_ChunksToMove;
+  using ChunkToPatch = CommitDataRequest_ChunkToPatch;
+  enum FieldNumbers {
+    kChunksToMoveFieldNumber = 1,
+    kChunksToPatchFieldNumber = 2,
+    kFlushRequestIdFieldNumber = 3,
+  };
+
+  CommitDataRequest();
+  ~CommitDataRequest() override;
+  CommitDataRequest(CommitDataRequest&&) noexcept;
+  CommitDataRequest& operator=(CommitDataRequest&&);
+  CommitDataRequest(const CommitDataRequest&);
+  CommitDataRequest& operator=(const CommitDataRequest&);
+  bool operator==(const CommitDataRequest&) const;
+  bool operator!=(const CommitDataRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<CommitDataRequest_ChunksToMove>& chunks_to_move() const { return chunks_to_move_; }
+  std::vector<CommitDataRequest_ChunksToMove>* mutable_chunks_to_move() { return &chunks_to_move_; }
+  int chunks_to_move_size() const;
+  void clear_chunks_to_move();
+  CommitDataRequest_ChunksToMove* add_chunks_to_move();
+
+  const std::vector<CommitDataRequest_ChunkToPatch>& chunks_to_patch() const { return chunks_to_patch_; }
+  std::vector<CommitDataRequest_ChunkToPatch>* mutable_chunks_to_patch() { return &chunks_to_patch_; }
+  int chunks_to_patch_size() const;
+  void clear_chunks_to_patch();
+  CommitDataRequest_ChunkToPatch* add_chunks_to_patch();
+
+  bool has_flush_request_id() const { return _has_field_[3]; }
+  uint64_t flush_request_id() const { return flush_request_id_; }
+  void set_flush_request_id(uint64_t value) { flush_request_id_ = value; _has_field_.set(3); }
+
+ private:
+  std::vector<CommitDataRequest_ChunksToMove> chunks_to_move_;
+  std::vector<CommitDataRequest_ChunkToPatch> chunks_to_patch_;
+  uint64_t flush_request_id_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT CommitDataRequest_ChunkToPatch : public ::protozero::CppMessageObj {
+ public:
+  using Patch = CommitDataRequest_ChunkToPatch_Patch;
+  enum FieldNumbers {
+    kTargetBufferFieldNumber = 1,
+    kWriterIdFieldNumber = 2,
+    kChunkIdFieldNumber = 3,
+    kPatchesFieldNumber = 4,
+    kHasMorePatchesFieldNumber = 5,
+  };
+
+  CommitDataRequest_ChunkToPatch();
+  ~CommitDataRequest_ChunkToPatch() override;
+  CommitDataRequest_ChunkToPatch(CommitDataRequest_ChunkToPatch&&) noexcept;
+  CommitDataRequest_ChunkToPatch& operator=(CommitDataRequest_ChunkToPatch&&);
+  CommitDataRequest_ChunkToPatch(const CommitDataRequest_ChunkToPatch&);
+  CommitDataRequest_ChunkToPatch& operator=(const CommitDataRequest_ChunkToPatch&);
+  bool operator==(const CommitDataRequest_ChunkToPatch&) const;
+  bool operator!=(const CommitDataRequest_ChunkToPatch& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_target_buffer() const { return _has_field_[1]; }
+  uint32_t target_buffer() const { return target_buffer_; }
+  void set_target_buffer(uint32_t value) { target_buffer_ = value; _has_field_.set(1); }
+
+  bool has_writer_id() const { return _has_field_[2]; }
+  uint32_t writer_id() const { return writer_id_; }
+  void set_writer_id(uint32_t value) { writer_id_ = value; _has_field_.set(2); }
+
+  bool has_chunk_id() const { return _has_field_[3]; }
+  uint32_t chunk_id() const { return chunk_id_; }
+  void set_chunk_id(uint32_t value) { chunk_id_ = value; _has_field_.set(3); }
+
+  const std::vector<CommitDataRequest_ChunkToPatch_Patch>& patches() const { return patches_; }
+  std::vector<CommitDataRequest_ChunkToPatch_Patch>* mutable_patches() { return &patches_; }
+  int patches_size() const;
+  void clear_patches();
+  CommitDataRequest_ChunkToPatch_Patch* add_patches();
+
+  bool has_has_more_patches() const { return _has_field_[5]; }
+  bool has_more_patches() const { return has_more_patches_; }
+  void set_has_more_patches(bool value) { has_more_patches_ = value; _has_field_.set(5); }
+
+ private:
+  uint32_t target_buffer_{};
+  uint32_t writer_id_{};
+  uint32_t chunk_id_{};
+  std::vector<CommitDataRequest_ChunkToPatch_Patch> patches_;
+  bool has_more_patches_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<6> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT CommitDataRequest_ChunkToPatch_Patch : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kOffsetFieldNumber = 1,
+    kDataFieldNumber = 2,
+  };
+
+  CommitDataRequest_ChunkToPatch_Patch();
+  ~CommitDataRequest_ChunkToPatch_Patch() override;
+  CommitDataRequest_ChunkToPatch_Patch(CommitDataRequest_ChunkToPatch_Patch&&) noexcept;
+  CommitDataRequest_ChunkToPatch_Patch& operator=(CommitDataRequest_ChunkToPatch_Patch&&);
+  CommitDataRequest_ChunkToPatch_Patch(const CommitDataRequest_ChunkToPatch_Patch&);
+  CommitDataRequest_ChunkToPatch_Patch& operator=(const CommitDataRequest_ChunkToPatch_Patch&);
+  bool operator==(const CommitDataRequest_ChunkToPatch_Patch&) const;
+  bool operator!=(const CommitDataRequest_ChunkToPatch_Patch& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_offset() const { return _has_field_[1]; }
+  uint32_t offset() const { return offset_; }
+  void set_offset(uint32_t value) { offset_ = value; _has_field_.set(1); }
+
+  bool has_data() const { return _has_field_[2]; }
+  const std::string& data() const { return data_; }
+  void set_data(const std::string& value) { data_ = value; _has_field_.set(2); }
+  void set_data(const void* p, size_t s) { data_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(2); }
+
+ private:
+  uint32_t offset_{};
+  std::string data_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT CommitDataRequest_ChunksToMove : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kPageFieldNumber = 1,
+    kChunkFieldNumber = 2,
+    kTargetBufferFieldNumber = 3,
+    kDataFieldNumber = 4,
+  };
+
+  CommitDataRequest_ChunksToMove();
+  ~CommitDataRequest_ChunksToMove() override;
+  CommitDataRequest_ChunksToMove(CommitDataRequest_ChunksToMove&&) noexcept;
+  CommitDataRequest_ChunksToMove& operator=(CommitDataRequest_ChunksToMove&&);
+  CommitDataRequest_ChunksToMove(const CommitDataRequest_ChunksToMove&);
+  CommitDataRequest_ChunksToMove& operator=(const CommitDataRequest_ChunksToMove&);
+  bool operator==(const CommitDataRequest_ChunksToMove&) const;
+  bool operator!=(const CommitDataRequest_ChunksToMove& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_page() const { return _has_field_[1]; }
+  uint32_t page() const { return page_; }
+  void set_page(uint32_t value) { page_ = value; _has_field_.set(1); }
+
+  bool has_chunk() const { return _has_field_[2]; }
+  uint32_t chunk() const { return chunk_; }
+  void set_chunk(uint32_t value) { chunk_ = value; _has_field_.set(2); }
+
+  bool has_target_buffer() const { return _has_field_[3]; }
+  uint32_t target_buffer() const { return target_buffer_; }
+  void set_target_buffer(uint32_t value) { target_buffer_ = value; _has_field_.set(3); }
+
+  bool has_data() const { return _has_field_[4]; }
+  const std::string& data() const { return data_; }
+  void set_data(const std::string& value) { data_ = value; _has_field_.set(4); }
+  void set_data(const void* p, size_t s) { data_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(4); }
+
+ private:
+  uint32_t page_{};
+  uint32_t chunk_{};
+  uint32_t target_buffer_{};
+  std::string data_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<5> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_COMMIT_DATA_REQUEST_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/common/descriptor.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DESCRIPTOR_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DESCRIPTOR_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class OneofOptions;
+class EnumValueDescriptorProto;
+class EnumDescriptorProto;
+class OneofDescriptorProto;
+class FieldDescriptorProto;
+class FieldOptions;
+class UninterpretedOption;
+class UninterpretedOption_NamePart;
+class DescriptorProto;
+class DescriptorProto_ReservedRange;
+class FileDescriptorProto;
+class FileDescriptorSet;
+enum FieldDescriptorProto_Type : int;
+enum FieldDescriptorProto_Label : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum FieldDescriptorProto_Type : int {
+  FieldDescriptorProto_Type_TYPE_DOUBLE = 1,
+  FieldDescriptorProto_Type_TYPE_FLOAT = 2,
+  FieldDescriptorProto_Type_TYPE_INT64 = 3,
+  FieldDescriptorProto_Type_TYPE_UINT64 = 4,
+  FieldDescriptorProto_Type_TYPE_INT32 = 5,
+  FieldDescriptorProto_Type_TYPE_FIXED64 = 6,
+  FieldDescriptorProto_Type_TYPE_FIXED32 = 7,
+  FieldDescriptorProto_Type_TYPE_BOOL = 8,
+  FieldDescriptorProto_Type_TYPE_STRING = 9,
+  FieldDescriptorProto_Type_TYPE_GROUP = 10,
+  FieldDescriptorProto_Type_TYPE_MESSAGE = 11,
+  FieldDescriptorProto_Type_TYPE_BYTES = 12,
+  FieldDescriptorProto_Type_TYPE_UINT32 = 13,
+  FieldDescriptorProto_Type_TYPE_ENUM = 14,
+  FieldDescriptorProto_Type_TYPE_SFIXED32 = 15,
+  FieldDescriptorProto_Type_TYPE_SFIXED64 = 16,
+  FieldDescriptorProto_Type_TYPE_SINT32 = 17,
+  FieldDescriptorProto_Type_TYPE_SINT64 = 18,
+};
+enum FieldDescriptorProto_Label : int {
+  FieldDescriptorProto_Label_LABEL_OPTIONAL = 1,
+  FieldDescriptorProto_Label_LABEL_REQUIRED = 2,
+  FieldDescriptorProto_Label_LABEL_REPEATED = 3,
+};
+
+class PERFETTO_EXPORT_COMPONENT OneofOptions : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  OneofOptions();
+  ~OneofOptions() override;
+  OneofOptions(OneofOptions&&) noexcept;
+  OneofOptions& operator=(OneofOptions&&);
+  OneofOptions(const OneofOptions&);
+  OneofOptions& operator=(const OneofOptions&);
+  bool operator==(const OneofOptions&) const;
+  bool operator!=(const OneofOptions& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT EnumValueDescriptorProto : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kNameFieldNumber = 1,
+    kNumberFieldNumber = 2,
+  };
+
+  EnumValueDescriptorProto();
+  ~EnumValueDescriptorProto() override;
+  EnumValueDescriptorProto(EnumValueDescriptorProto&&) noexcept;
+  EnumValueDescriptorProto& operator=(EnumValueDescriptorProto&&);
+  EnumValueDescriptorProto(const EnumValueDescriptorProto&);
+  EnumValueDescriptorProto& operator=(const EnumValueDescriptorProto&);
+  bool operator==(const EnumValueDescriptorProto&) const;
+  bool operator!=(const EnumValueDescriptorProto& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name() const { return _has_field_[1]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
+
+  bool has_number() const { return _has_field_[2]; }
+  int32_t number() const { return number_; }
+  void set_number(int32_t value) { number_ = value; _has_field_.set(2); }
+
+ private:
+  std::string name_{};
+  int32_t number_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT EnumDescriptorProto : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kNameFieldNumber = 1,
+    kValueFieldNumber = 2,
+    kReservedNameFieldNumber = 5,
+  };
+
+  EnumDescriptorProto();
+  ~EnumDescriptorProto() override;
+  EnumDescriptorProto(EnumDescriptorProto&&) noexcept;
+  EnumDescriptorProto& operator=(EnumDescriptorProto&&);
+  EnumDescriptorProto(const EnumDescriptorProto&);
+  EnumDescriptorProto& operator=(const EnumDescriptorProto&);
+  bool operator==(const EnumDescriptorProto&) const;
+  bool operator!=(const EnumDescriptorProto& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name() const { return _has_field_[1]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
+
+  const std::vector<EnumValueDescriptorProto>& value() const { return value_; }
+  std::vector<EnumValueDescriptorProto>* mutable_value() { return &value_; }
+  int value_size() const;
+  void clear_value();
+  EnumValueDescriptorProto* add_value();
+
+  const std::vector<std::string>& reserved_name() const { return reserved_name_; }
+  std::vector<std::string>* mutable_reserved_name() { return &reserved_name_; }
+  int reserved_name_size() const { return static_cast<int>(reserved_name_.size()); }
+  void clear_reserved_name() { reserved_name_.clear(); }
+  void add_reserved_name(std::string value) { reserved_name_.emplace_back(value); }
+  std::string* add_reserved_name() { reserved_name_.emplace_back(); return &reserved_name_.back(); }
+
+ private:
+  std::string name_{};
+  std::vector<EnumValueDescriptorProto> value_;
+  std::vector<std::string> reserved_name_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<6> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT OneofDescriptorProto : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kNameFieldNumber = 1,
+    kOptionsFieldNumber = 2,
+  };
+
+  OneofDescriptorProto();
+  ~OneofDescriptorProto() override;
+  OneofDescriptorProto(OneofDescriptorProto&&) noexcept;
+  OneofDescriptorProto& operator=(OneofDescriptorProto&&);
+  OneofDescriptorProto(const OneofDescriptorProto&);
+  OneofDescriptorProto& operator=(const OneofDescriptorProto&);
+  bool operator==(const OneofDescriptorProto&) const;
+  bool operator!=(const OneofDescriptorProto& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name() const { return _has_field_[1]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
+
+  bool has_options() const { return _has_field_[2]; }
+  const OneofOptions& options() const { return *options_; }
+  OneofOptions* mutable_options() { _has_field_.set(2); return options_.get(); }
+
+ private:
+  std::string name_{};
+  ::protozero::CopyablePtr<OneofOptions> options_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT FieldDescriptorProto : public ::protozero::CppMessageObj {
+ public:
+  using Type = FieldDescriptorProto_Type;
+  static constexpr auto TYPE_DOUBLE = FieldDescriptorProto_Type_TYPE_DOUBLE;
+  static constexpr auto TYPE_FLOAT = FieldDescriptorProto_Type_TYPE_FLOAT;
+  static constexpr auto TYPE_INT64 = FieldDescriptorProto_Type_TYPE_INT64;
+  static constexpr auto TYPE_UINT64 = FieldDescriptorProto_Type_TYPE_UINT64;
+  static constexpr auto TYPE_INT32 = FieldDescriptorProto_Type_TYPE_INT32;
+  static constexpr auto TYPE_FIXED64 = FieldDescriptorProto_Type_TYPE_FIXED64;
+  static constexpr auto TYPE_FIXED32 = FieldDescriptorProto_Type_TYPE_FIXED32;
+  static constexpr auto TYPE_BOOL = FieldDescriptorProto_Type_TYPE_BOOL;
+  static constexpr auto TYPE_STRING = FieldDescriptorProto_Type_TYPE_STRING;
+  static constexpr auto TYPE_GROUP = FieldDescriptorProto_Type_TYPE_GROUP;
+  static constexpr auto TYPE_MESSAGE = FieldDescriptorProto_Type_TYPE_MESSAGE;
+  static constexpr auto TYPE_BYTES = FieldDescriptorProto_Type_TYPE_BYTES;
+  static constexpr auto TYPE_UINT32 = FieldDescriptorProto_Type_TYPE_UINT32;
+  static constexpr auto TYPE_ENUM = FieldDescriptorProto_Type_TYPE_ENUM;
+  static constexpr auto TYPE_SFIXED32 = FieldDescriptorProto_Type_TYPE_SFIXED32;
+  static constexpr auto TYPE_SFIXED64 = FieldDescriptorProto_Type_TYPE_SFIXED64;
+  static constexpr auto TYPE_SINT32 = FieldDescriptorProto_Type_TYPE_SINT32;
+  static constexpr auto TYPE_SINT64 = FieldDescriptorProto_Type_TYPE_SINT64;
+  static constexpr auto Type_MIN = FieldDescriptorProto_Type_TYPE_DOUBLE;
+  static constexpr auto Type_MAX = FieldDescriptorProto_Type_TYPE_SINT64;
+  using Label = FieldDescriptorProto_Label;
+  static constexpr auto LABEL_OPTIONAL = FieldDescriptorProto_Label_LABEL_OPTIONAL;
+  static constexpr auto LABEL_REQUIRED = FieldDescriptorProto_Label_LABEL_REQUIRED;
+  static constexpr auto LABEL_REPEATED = FieldDescriptorProto_Label_LABEL_REPEATED;
+  static constexpr auto Label_MIN = FieldDescriptorProto_Label_LABEL_OPTIONAL;
+  static constexpr auto Label_MAX = FieldDescriptorProto_Label_LABEL_REPEATED;
+  enum FieldNumbers {
+    kNameFieldNumber = 1,
+    kNumberFieldNumber = 3,
+    kLabelFieldNumber = 4,
+    kTypeFieldNumber = 5,
+    kTypeNameFieldNumber = 6,
+    kExtendeeFieldNumber = 2,
+    kDefaultValueFieldNumber = 7,
+    kOptionsFieldNumber = 8,
+    kOneofIndexFieldNumber = 9,
+  };
+
+  FieldDescriptorProto();
+  ~FieldDescriptorProto() override;
+  FieldDescriptorProto(FieldDescriptorProto&&) noexcept;
+  FieldDescriptorProto& operator=(FieldDescriptorProto&&);
+  FieldDescriptorProto(const FieldDescriptorProto&);
+  FieldDescriptorProto& operator=(const FieldDescriptorProto&);
+  bool operator==(const FieldDescriptorProto&) const;
+  bool operator!=(const FieldDescriptorProto& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name() const { return _has_field_[1]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
+
+  bool has_number() const { return _has_field_[3]; }
+  int32_t number() const { return number_; }
+  void set_number(int32_t value) { number_ = value; _has_field_.set(3); }
+
+  bool has_label() const { return _has_field_[4]; }
+  FieldDescriptorProto_Label label() const { return label_; }
+  void set_label(FieldDescriptorProto_Label value) { label_ = value; _has_field_.set(4); }
+
+  bool has_type() const { return _has_field_[5]; }
+  FieldDescriptorProto_Type type() const { return type_; }
+  void set_type(FieldDescriptorProto_Type value) { type_ = value; _has_field_.set(5); }
+
+  bool has_type_name() const { return _has_field_[6]; }
+  const std::string& type_name() const { return type_name_; }
+  void set_type_name(const std::string& value) { type_name_ = value; _has_field_.set(6); }
+
+  bool has_extendee() const { return _has_field_[2]; }
+  const std::string& extendee() const { return extendee_; }
+  void set_extendee(const std::string& value) { extendee_ = value; _has_field_.set(2); }
+
+  bool has_default_value() const { return _has_field_[7]; }
+  const std::string& default_value() const { return default_value_; }
+  void set_default_value(const std::string& value) { default_value_ = value; _has_field_.set(7); }
+
+  bool has_options() const { return _has_field_[8]; }
+  const FieldOptions& options() const { return *options_; }
+  FieldOptions* mutable_options() { _has_field_.set(8); return options_.get(); }
+
+  bool has_oneof_index() const { return _has_field_[9]; }
+  int32_t oneof_index() const { return oneof_index_; }
+  void set_oneof_index(int32_t value) { oneof_index_ = value; _has_field_.set(9); }
+
+ private:
+  std::string name_{};
+  int32_t number_{};
+  FieldDescriptorProto_Label label_{};
+  FieldDescriptorProto_Type type_{};
+  std::string type_name_{};
+  std::string extendee_{};
+  std::string default_value_{};
+  ::protozero::CopyablePtr<FieldOptions> options_;
+  int32_t oneof_index_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<10> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT FieldOptions : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kPackedFieldNumber = 2,
+    kUninterpretedOptionFieldNumber = 999,
+  };
+
+  FieldOptions();
+  ~FieldOptions() override;
+  FieldOptions(FieldOptions&&) noexcept;
+  FieldOptions& operator=(FieldOptions&&);
+  FieldOptions(const FieldOptions&);
+  FieldOptions& operator=(const FieldOptions&);
+  bool operator==(const FieldOptions&) const;
+  bool operator!=(const FieldOptions& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_packed() const { return _has_field_[2]; }
+  bool packed() const { return packed_; }
+  void set_packed(bool value) { packed_ = value; _has_field_.set(2); }
+
+  const std::vector<UninterpretedOption>& uninterpreted_option() const { return uninterpreted_option_; }
+  std::vector<UninterpretedOption>* mutable_uninterpreted_option() { return &uninterpreted_option_; }
+  int uninterpreted_option_size() const;
+  void clear_uninterpreted_option();
+  UninterpretedOption* add_uninterpreted_option();
+
+ private:
+  bool packed_{};
+  std::vector<UninterpretedOption> uninterpreted_option_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<1000> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT UninterpretedOption : public ::protozero::CppMessageObj {
+ public:
+  using NamePart = UninterpretedOption_NamePart;
+  enum FieldNumbers {
+    kNameFieldNumber = 2,
+    kIdentifierValueFieldNumber = 3,
+    kPositiveIntValueFieldNumber = 4,
+    kNegativeIntValueFieldNumber = 5,
+    kDoubleValueFieldNumber = 6,
+    kStringValueFieldNumber = 7,
+    kAggregateValueFieldNumber = 8,
+  };
+
+  UninterpretedOption();
+  ~UninterpretedOption() override;
+  UninterpretedOption(UninterpretedOption&&) noexcept;
+  UninterpretedOption& operator=(UninterpretedOption&&);
+  UninterpretedOption(const UninterpretedOption&);
+  UninterpretedOption& operator=(const UninterpretedOption&);
+  bool operator==(const UninterpretedOption&) const;
+  bool operator!=(const UninterpretedOption& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<UninterpretedOption_NamePart>& name() const { return name_; }
+  std::vector<UninterpretedOption_NamePart>* mutable_name() { return &name_; }
+  int name_size() const;
+  void clear_name();
+  UninterpretedOption_NamePart* add_name();
+
+  bool has_identifier_value() const { return _has_field_[3]; }
+  const std::string& identifier_value() const { return identifier_value_; }
+  void set_identifier_value(const std::string& value) { identifier_value_ = value; _has_field_.set(3); }
+
+  bool has_positive_int_value() const { return _has_field_[4]; }
+  uint64_t positive_int_value() const { return positive_int_value_; }
+  void set_positive_int_value(uint64_t value) { positive_int_value_ = value; _has_field_.set(4); }
+
+  bool has_negative_int_value() const { return _has_field_[5]; }
+  int64_t negative_int_value() const { return negative_int_value_; }
+  void set_negative_int_value(int64_t value) { negative_int_value_ = value; _has_field_.set(5); }
+
+  bool has_double_value() const { return _has_field_[6]; }
+  double double_value() const { return double_value_; }
+  void set_double_value(double value) { double_value_ = value; _has_field_.set(6); }
+
+  bool has_string_value() const { return _has_field_[7]; }
+  const std::string& string_value() const { return string_value_; }
+  void set_string_value(const std::string& value) { string_value_ = value; _has_field_.set(7); }
+  void set_string_value(const void* p, size_t s) { string_value_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(7); }
+
+  bool has_aggregate_value() const { return _has_field_[8]; }
+  const std::string& aggregate_value() const { return aggregate_value_; }
+  void set_aggregate_value(const std::string& value) { aggregate_value_ = value; _has_field_.set(8); }
+
+ private:
+  std::vector<UninterpretedOption_NamePart> name_;
+  std::string identifier_value_{};
+  uint64_t positive_int_value_{};
+  int64_t negative_int_value_{};
+  double double_value_{};
+  std::string string_value_{};
+  std::string aggregate_value_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<9> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT UninterpretedOption_NamePart : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kNamePartFieldNumber = 1,
+    kIsExtensionFieldNumber = 2,
+  };
+
+  UninterpretedOption_NamePart();
+  ~UninterpretedOption_NamePart() override;
+  UninterpretedOption_NamePart(UninterpretedOption_NamePart&&) noexcept;
+  UninterpretedOption_NamePart& operator=(UninterpretedOption_NamePart&&);
+  UninterpretedOption_NamePart(const UninterpretedOption_NamePart&);
+  UninterpretedOption_NamePart& operator=(const UninterpretedOption_NamePart&);
+  bool operator==(const UninterpretedOption_NamePart&) const;
+  bool operator!=(const UninterpretedOption_NamePart& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name_part() const { return _has_field_[1]; }
+  const std::string& name_part() const { return name_part_; }
+  void set_name_part(const std::string& value) { name_part_ = value; _has_field_.set(1); }
+
+  bool has_is_extension() const { return _has_field_[2]; }
+  bool is_extension() const { return is_extension_; }
+  void set_is_extension(bool value) { is_extension_ = value; _has_field_.set(2); }
+
+ private:
+  std::string name_part_{};
+  bool is_extension_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT DescriptorProto : public ::protozero::CppMessageObj {
+ public:
+  using ReservedRange = DescriptorProto_ReservedRange;
+  enum FieldNumbers {
+    kNameFieldNumber = 1,
+    kFieldFieldNumber = 2,
+    kExtensionFieldNumber = 6,
+    kNestedTypeFieldNumber = 3,
+    kEnumTypeFieldNumber = 4,
+    kOneofDeclFieldNumber = 8,
+    kReservedRangeFieldNumber = 9,
+    kReservedNameFieldNumber = 10,
+  };
+
+  DescriptorProto();
+  ~DescriptorProto() override;
+  DescriptorProto(DescriptorProto&&) noexcept;
+  DescriptorProto& operator=(DescriptorProto&&);
+  DescriptorProto(const DescriptorProto&);
+  DescriptorProto& operator=(const DescriptorProto&);
+  bool operator==(const DescriptorProto&) const;
+  bool operator!=(const DescriptorProto& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name() const { return _has_field_[1]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
+
+  const std::vector<FieldDescriptorProto>& field() const { return field_; }
+  std::vector<FieldDescriptorProto>* mutable_field() { return &field_; }
+  int field_size() const;
+  void clear_field();
+  FieldDescriptorProto* add_field();
+
+  const std::vector<FieldDescriptorProto>& extension() const { return extension_; }
+  std::vector<FieldDescriptorProto>* mutable_extension() { return &extension_; }
+  int extension_size() const;
+  void clear_extension();
+  FieldDescriptorProto* add_extension();
+
+  const std::vector<DescriptorProto>& nested_type() const { return nested_type_; }
+  std::vector<DescriptorProto>* mutable_nested_type() { return &nested_type_; }
+  int nested_type_size() const;
+  void clear_nested_type();
+  DescriptorProto* add_nested_type();
+
+  const std::vector<EnumDescriptorProto>& enum_type() const { return enum_type_; }
+  std::vector<EnumDescriptorProto>* mutable_enum_type() { return &enum_type_; }
+  int enum_type_size() const;
+  void clear_enum_type();
+  EnumDescriptorProto* add_enum_type();
+
+  const std::vector<OneofDescriptorProto>& oneof_decl() const { return oneof_decl_; }
+  std::vector<OneofDescriptorProto>* mutable_oneof_decl() { return &oneof_decl_; }
+  int oneof_decl_size() const;
+  void clear_oneof_decl();
+  OneofDescriptorProto* add_oneof_decl();
+
+  const std::vector<DescriptorProto_ReservedRange>& reserved_range() const { return reserved_range_; }
+  std::vector<DescriptorProto_ReservedRange>* mutable_reserved_range() { return &reserved_range_; }
+  int reserved_range_size() const;
+  void clear_reserved_range();
+  DescriptorProto_ReservedRange* add_reserved_range();
+
+  const std::vector<std::string>& reserved_name() const { return reserved_name_; }
+  std::vector<std::string>* mutable_reserved_name() { return &reserved_name_; }
+  int reserved_name_size() const { return static_cast<int>(reserved_name_.size()); }
+  void clear_reserved_name() { reserved_name_.clear(); }
+  void add_reserved_name(std::string value) { reserved_name_.emplace_back(value); }
+  std::string* add_reserved_name() { reserved_name_.emplace_back(); return &reserved_name_.back(); }
+
+ private:
+  std::string name_{};
+  std::vector<FieldDescriptorProto> field_;
+  std::vector<FieldDescriptorProto> extension_;
+  std::vector<DescriptorProto> nested_type_;
+  std::vector<EnumDescriptorProto> enum_type_;
+  std::vector<OneofDescriptorProto> oneof_decl_;
+  std::vector<DescriptorProto_ReservedRange> reserved_range_;
+  std::vector<std::string> reserved_name_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<11> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT DescriptorProto_ReservedRange : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kStartFieldNumber = 1,
+    kEndFieldNumber = 2,
+  };
+
+  DescriptorProto_ReservedRange();
+  ~DescriptorProto_ReservedRange() override;
+  DescriptorProto_ReservedRange(DescriptorProto_ReservedRange&&) noexcept;
+  DescriptorProto_ReservedRange& operator=(DescriptorProto_ReservedRange&&);
+  DescriptorProto_ReservedRange(const DescriptorProto_ReservedRange&);
+  DescriptorProto_ReservedRange& operator=(const DescriptorProto_ReservedRange&);
+  bool operator==(const DescriptorProto_ReservedRange&) const;
+  bool operator!=(const DescriptorProto_ReservedRange& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_start() const { return _has_field_[1]; }
+  int32_t start() const { return start_; }
+  void set_start(int32_t value) { start_ = value; _has_field_.set(1); }
+
+  bool has_end() const { return _has_field_[2]; }
+  int32_t end() const { return end_; }
+  void set_end(int32_t value) { end_ = value; _has_field_.set(2); }
+
+ private:
+  int32_t start_{};
+  int32_t end_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT FileDescriptorProto : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kNameFieldNumber = 1,
+    kPackageFieldNumber = 2,
+    kDependencyFieldNumber = 3,
+    kPublicDependencyFieldNumber = 10,
+    kWeakDependencyFieldNumber = 11,
+    kMessageTypeFieldNumber = 4,
+    kEnumTypeFieldNumber = 5,
+    kExtensionFieldNumber = 7,
+  };
+
+  FileDescriptorProto();
+  ~FileDescriptorProto() override;
+  FileDescriptorProto(FileDescriptorProto&&) noexcept;
+  FileDescriptorProto& operator=(FileDescriptorProto&&);
+  FileDescriptorProto(const FileDescriptorProto&);
+  FileDescriptorProto& operator=(const FileDescriptorProto&);
+  bool operator==(const FileDescriptorProto&) const;
+  bool operator!=(const FileDescriptorProto& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name() const { return _has_field_[1]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
+
+  bool has_package() const { return _has_field_[2]; }
+  const std::string& package() const { return package_; }
+  void set_package(const std::string& value) { package_ = value; _has_field_.set(2); }
+
+  const std::vector<std::string>& dependency() const { return dependency_; }
+  std::vector<std::string>* mutable_dependency() { return &dependency_; }
+  int dependency_size() const { return static_cast<int>(dependency_.size()); }
+  void clear_dependency() { dependency_.clear(); }
+  void add_dependency(std::string value) { dependency_.emplace_back(value); }
+  std::string* add_dependency() { dependency_.emplace_back(); return &dependency_.back(); }
+
+  const std::vector<int32_t>& public_dependency() const { return public_dependency_; }
+  std::vector<int32_t>* mutable_public_dependency() { return &public_dependency_; }
+  int public_dependency_size() const { return static_cast<int>(public_dependency_.size()); }
+  void clear_public_dependency() { public_dependency_.clear(); }
+  void add_public_dependency(int32_t value) { public_dependency_.emplace_back(value); }
+  int32_t* add_public_dependency() { public_dependency_.emplace_back(); return &public_dependency_.back(); }
+
+  const std::vector<int32_t>& weak_dependency() const { return weak_dependency_; }
+  std::vector<int32_t>* mutable_weak_dependency() { return &weak_dependency_; }
+  int weak_dependency_size() const { return static_cast<int>(weak_dependency_.size()); }
+  void clear_weak_dependency() { weak_dependency_.clear(); }
+  void add_weak_dependency(int32_t value) { weak_dependency_.emplace_back(value); }
+  int32_t* add_weak_dependency() { weak_dependency_.emplace_back(); return &weak_dependency_.back(); }
+
+  const std::vector<DescriptorProto>& message_type() const { return message_type_; }
+  std::vector<DescriptorProto>* mutable_message_type() { return &message_type_; }
+  int message_type_size() const;
+  void clear_message_type();
+  DescriptorProto* add_message_type();
+
+  const std::vector<EnumDescriptorProto>& enum_type() const { return enum_type_; }
+  std::vector<EnumDescriptorProto>* mutable_enum_type() { return &enum_type_; }
+  int enum_type_size() const;
+  void clear_enum_type();
+  EnumDescriptorProto* add_enum_type();
+
+  const std::vector<FieldDescriptorProto>& extension() const { return extension_; }
+  std::vector<FieldDescriptorProto>* mutable_extension() { return &extension_; }
+  int extension_size() const;
+  void clear_extension();
+  FieldDescriptorProto* add_extension();
+
+ private:
+  std::string name_{};
+  std::string package_{};
+  std::vector<std::string> dependency_;
+  std::vector<int32_t> public_dependency_;
+  std::vector<int32_t> weak_dependency_;
+  std::vector<DescriptorProto> message_type_;
+  std::vector<EnumDescriptorProto> enum_type_;
+  std::vector<FieldDescriptorProto> extension_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<12> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT FileDescriptorSet : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kFileFieldNumber = 1,
+  };
+
+  FileDescriptorSet();
+  ~FileDescriptorSet() override;
+  FileDescriptorSet(FileDescriptorSet&&) noexcept;
+  FileDescriptorSet& operator=(FileDescriptorSet&&);
+  FileDescriptorSet(const FileDescriptorSet&);
+  FileDescriptorSet& operator=(const FileDescriptorSet&);
+  bool operator==(const FileDescriptorSet&) const;
+  bool operator!=(const FileDescriptorSet& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<FileDescriptorProto>& file() const { return file_; }
+  std::vector<FileDescriptorProto>* mutable_file() { return &file_; }
+  int file_size() const;
+  void clear_file();
+  FileDescriptorProto* add_file();
+
+ private:
+  std::vector<FileDescriptorProto> file_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DESCRIPTOR_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/common/ftrace_descriptor.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_FTRACE_DESCRIPTOR_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_FTRACE_DESCRIPTOR_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class FtraceDescriptor;
+class FtraceDescriptor_AtraceCategory;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT FtraceDescriptor : public ::protozero::CppMessageObj {
+ public:
+  using AtraceCategory = FtraceDescriptor_AtraceCategory;
+  enum FieldNumbers {
+    kAtraceCategoriesFieldNumber = 1,
+  };
+
+  FtraceDescriptor();
+  ~FtraceDescriptor() override;
+  FtraceDescriptor(FtraceDescriptor&&) noexcept;
+  FtraceDescriptor& operator=(FtraceDescriptor&&);
+  FtraceDescriptor(const FtraceDescriptor&);
+  FtraceDescriptor& operator=(const FtraceDescriptor&);
+  bool operator==(const FtraceDescriptor&) const;
+  bool operator!=(const FtraceDescriptor& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<FtraceDescriptor_AtraceCategory>& atrace_categories() const { return atrace_categories_; }
+  std::vector<FtraceDescriptor_AtraceCategory>* mutable_atrace_categories() { return &atrace_categories_; }
+  int atrace_categories_size() const;
+  void clear_atrace_categories();
+  FtraceDescriptor_AtraceCategory* add_atrace_categories();
+
+ private:
+  std::vector<FtraceDescriptor_AtraceCategory> atrace_categories_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT FtraceDescriptor_AtraceCategory : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kNameFieldNumber = 1,
+    kDescriptionFieldNumber = 2,
+  };
+
+  FtraceDescriptor_AtraceCategory();
+  ~FtraceDescriptor_AtraceCategory() override;
+  FtraceDescriptor_AtraceCategory(FtraceDescriptor_AtraceCategory&&) noexcept;
+  FtraceDescriptor_AtraceCategory& operator=(FtraceDescriptor_AtraceCategory&&);
+  FtraceDescriptor_AtraceCategory(const FtraceDescriptor_AtraceCategory&);
+  FtraceDescriptor_AtraceCategory& operator=(const FtraceDescriptor_AtraceCategory&);
+  bool operator==(const FtraceDescriptor_AtraceCategory&) const;
+  bool operator!=(const FtraceDescriptor_AtraceCategory& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name() const { return _has_field_[1]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
+
+  bool has_description() const { return _has_field_[2]; }
+  const std::string& description() const { return description_; }
+  void set_description(const std::string& value) { description_ = value; _has_field_.set(2); }
+
+ private:
+  std::string name_{};
+  std::string description_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_FTRACE_DESCRIPTOR_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/common/gpu_counter_descriptor.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_GPU_COUNTER_DESCRIPTOR_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_GPU_COUNTER_DESCRIPTOR_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class GpuCounterDescriptor;
+class GpuCounterDescriptor_GpuCounterBlock;
+class GpuCounterDescriptor_GpuCounterSpec;
+enum GpuCounterDescriptor_GpuCounterGroup : int;
+enum GpuCounterDescriptor_MeasureUnit : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum GpuCounterDescriptor_GpuCounterGroup : int {
+  GpuCounterDescriptor_GpuCounterGroup_UNCLASSIFIED = 0,
+  GpuCounterDescriptor_GpuCounterGroup_SYSTEM = 1,
+  GpuCounterDescriptor_GpuCounterGroup_VERTICES = 2,
+  GpuCounterDescriptor_GpuCounterGroup_FRAGMENTS = 3,
+  GpuCounterDescriptor_GpuCounterGroup_PRIMITIVES = 4,
+  GpuCounterDescriptor_GpuCounterGroup_MEMORY = 5,
+  GpuCounterDescriptor_GpuCounterGroup_COMPUTE = 6,
+};
+enum GpuCounterDescriptor_MeasureUnit : int {
+  GpuCounterDescriptor_MeasureUnit_NONE = 0,
+  GpuCounterDescriptor_MeasureUnit_BIT = 1,
+  GpuCounterDescriptor_MeasureUnit_KILOBIT = 2,
+  GpuCounterDescriptor_MeasureUnit_MEGABIT = 3,
+  GpuCounterDescriptor_MeasureUnit_GIGABIT = 4,
+  GpuCounterDescriptor_MeasureUnit_TERABIT = 5,
+  GpuCounterDescriptor_MeasureUnit_PETABIT = 6,
+  GpuCounterDescriptor_MeasureUnit_BYTE = 7,
+  GpuCounterDescriptor_MeasureUnit_KILOBYTE = 8,
+  GpuCounterDescriptor_MeasureUnit_MEGABYTE = 9,
+  GpuCounterDescriptor_MeasureUnit_GIGABYTE = 10,
+  GpuCounterDescriptor_MeasureUnit_TERABYTE = 11,
+  GpuCounterDescriptor_MeasureUnit_PETABYTE = 12,
+  GpuCounterDescriptor_MeasureUnit_HERTZ = 13,
+  GpuCounterDescriptor_MeasureUnit_KILOHERTZ = 14,
+  GpuCounterDescriptor_MeasureUnit_MEGAHERTZ = 15,
+  GpuCounterDescriptor_MeasureUnit_GIGAHERTZ = 16,
+  GpuCounterDescriptor_MeasureUnit_TERAHERTZ = 17,
+  GpuCounterDescriptor_MeasureUnit_PETAHERTZ = 18,
+  GpuCounterDescriptor_MeasureUnit_NANOSECOND = 19,
+  GpuCounterDescriptor_MeasureUnit_MICROSECOND = 20,
+  GpuCounterDescriptor_MeasureUnit_MILLISECOND = 21,
+  GpuCounterDescriptor_MeasureUnit_SECOND = 22,
+  GpuCounterDescriptor_MeasureUnit_MINUTE = 23,
+  GpuCounterDescriptor_MeasureUnit_HOUR = 24,
+  GpuCounterDescriptor_MeasureUnit_VERTEX = 25,
+  GpuCounterDescriptor_MeasureUnit_PIXEL = 26,
+  GpuCounterDescriptor_MeasureUnit_TRIANGLE = 27,
+  GpuCounterDescriptor_MeasureUnit_PRIMITIVE = 38,
+  GpuCounterDescriptor_MeasureUnit_FRAGMENT = 39,
+  GpuCounterDescriptor_MeasureUnit_MILLIWATT = 28,
+  GpuCounterDescriptor_MeasureUnit_WATT = 29,
+  GpuCounterDescriptor_MeasureUnit_KILOWATT = 30,
+  GpuCounterDescriptor_MeasureUnit_JOULE = 31,
+  GpuCounterDescriptor_MeasureUnit_VOLT = 32,
+  GpuCounterDescriptor_MeasureUnit_AMPERE = 33,
+  GpuCounterDescriptor_MeasureUnit_CELSIUS = 34,
+  GpuCounterDescriptor_MeasureUnit_FAHRENHEIT = 35,
+  GpuCounterDescriptor_MeasureUnit_KELVIN = 36,
+  GpuCounterDescriptor_MeasureUnit_PERCENT = 37,
+  GpuCounterDescriptor_MeasureUnit_INSTRUCTION = 40,
+};
+
+class PERFETTO_EXPORT_COMPONENT GpuCounterDescriptor : public ::protozero::CppMessageObj {
+ public:
+  using GpuCounterSpec = GpuCounterDescriptor_GpuCounterSpec;
+  using GpuCounterBlock = GpuCounterDescriptor_GpuCounterBlock;
+  using GpuCounterGroup = GpuCounterDescriptor_GpuCounterGroup;
+  static constexpr auto UNCLASSIFIED = GpuCounterDescriptor_GpuCounterGroup_UNCLASSIFIED;
+  static constexpr auto SYSTEM = GpuCounterDescriptor_GpuCounterGroup_SYSTEM;
+  static constexpr auto VERTICES = GpuCounterDescriptor_GpuCounterGroup_VERTICES;
+  static constexpr auto FRAGMENTS = GpuCounterDescriptor_GpuCounterGroup_FRAGMENTS;
+  static constexpr auto PRIMITIVES = GpuCounterDescriptor_GpuCounterGroup_PRIMITIVES;
+  static constexpr auto MEMORY = GpuCounterDescriptor_GpuCounterGroup_MEMORY;
+  static constexpr auto COMPUTE = GpuCounterDescriptor_GpuCounterGroup_COMPUTE;
+  static constexpr auto GpuCounterGroup_MIN = GpuCounterDescriptor_GpuCounterGroup_UNCLASSIFIED;
+  static constexpr auto GpuCounterGroup_MAX = GpuCounterDescriptor_GpuCounterGroup_COMPUTE;
+  using MeasureUnit = GpuCounterDescriptor_MeasureUnit;
+  static constexpr auto NONE = GpuCounterDescriptor_MeasureUnit_NONE;
+  static constexpr auto BIT = GpuCounterDescriptor_MeasureUnit_BIT;
+  static constexpr auto KILOBIT = GpuCounterDescriptor_MeasureUnit_KILOBIT;
+  static constexpr auto MEGABIT = GpuCounterDescriptor_MeasureUnit_MEGABIT;
+  static constexpr auto GIGABIT = GpuCounterDescriptor_MeasureUnit_GIGABIT;
+  static constexpr auto TERABIT = GpuCounterDescriptor_MeasureUnit_TERABIT;
+  static constexpr auto PETABIT = GpuCounterDescriptor_MeasureUnit_PETABIT;
+  static constexpr auto BYTE = GpuCounterDescriptor_MeasureUnit_BYTE;
+  static constexpr auto KILOBYTE = GpuCounterDescriptor_MeasureUnit_KILOBYTE;
+  static constexpr auto MEGABYTE = GpuCounterDescriptor_MeasureUnit_MEGABYTE;
+  static constexpr auto GIGABYTE = GpuCounterDescriptor_MeasureUnit_GIGABYTE;
+  static constexpr auto TERABYTE = GpuCounterDescriptor_MeasureUnit_TERABYTE;
+  static constexpr auto PETABYTE = GpuCounterDescriptor_MeasureUnit_PETABYTE;
+  static constexpr auto HERTZ = GpuCounterDescriptor_MeasureUnit_HERTZ;
+  static constexpr auto KILOHERTZ = GpuCounterDescriptor_MeasureUnit_KILOHERTZ;
+  static constexpr auto MEGAHERTZ = GpuCounterDescriptor_MeasureUnit_MEGAHERTZ;
+  static constexpr auto GIGAHERTZ = GpuCounterDescriptor_MeasureUnit_GIGAHERTZ;
+  static constexpr auto TERAHERTZ = GpuCounterDescriptor_MeasureUnit_TERAHERTZ;
+  static constexpr auto PETAHERTZ = GpuCounterDescriptor_MeasureUnit_PETAHERTZ;
+  static constexpr auto NANOSECOND = GpuCounterDescriptor_MeasureUnit_NANOSECOND;
+  static constexpr auto MICROSECOND = GpuCounterDescriptor_MeasureUnit_MICROSECOND;
+  static constexpr auto MILLISECOND = GpuCounterDescriptor_MeasureUnit_MILLISECOND;
+  static constexpr auto SECOND = GpuCounterDescriptor_MeasureUnit_SECOND;
+  static constexpr auto MINUTE = GpuCounterDescriptor_MeasureUnit_MINUTE;
+  static constexpr auto HOUR = GpuCounterDescriptor_MeasureUnit_HOUR;
+  static constexpr auto VERTEX = GpuCounterDescriptor_MeasureUnit_VERTEX;
+  static constexpr auto PIXEL = GpuCounterDescriptor_MeasureUnit_PIXEL;
+  static constexpr auto TRIANGLE = GpuCounterDescriptor_MeasureUnit_TRIANGLE;
+  static constexpr auto PRIMITIVE = GpuCounterDescriptor_MeasureUnit_PRIMITIVE;
+  static constexpr auto FRAGMENT = GpuCounterDescriptor_MeasureUnit_FRAGMENT;
+  static constexpr auto MILLIWATT = GpuCounterDescriptor_MeasureUnit_MILLIWATT;
+  static constexpr auto WATT = GpuCounterDescriptor_MeasureUnit_WATT;
+  static constexpr auto KILOWATT = GpuCounterDescriptor_MeasureUnit_KILOWATT;
+  static constexpr auto JOULE = GpuCounterDescriptor_MeasureUnit_JOULE;
+  static constexpr auto VOLT = GpuCounterDescriptor_MeasureUnit_VOLT;
+  static constexpr auto AMPERE = GpuCounterDescriptor_MeasureUnit_AMPERE;
+  static constexpr auto CELSIUS = GpuCounterDescriptor_MeasureUnit_CELSIUS;
+  static constexpr auto FAHRENHEIT = GpuCounterDescriptor_MeasureUnit_FAHRENHEIT;
+  static constexpr auto KELVIN = GpuCounterDescriptor_MeasureUnit_KELVIN;
+  static constexpr auto PERCENT = GpuCounterDescriptor_MeasureUnit_PERCENT;
+  static constexpr auto INSTRUCTION = GpuCounterDescriptor_MeasureUnit_INSTRUCTION;
+  static constexpr auto MeasureUnit_MIN = GpuCounterDescriptor_MeasureUnit_NONE;
+  static constexpr auto MeasureUnit_MAX = GpuCounterDescriptor_MeasureUnit_INSTRUCTION;
+  enum FieldNumbers {
+    kSpecsFieldNumber = 1,
+    kBlocksFieldNumber = 2,
+    kMinSamplingPeriodNsFieldNumber = 3,
+    kMaxSamplingPeriodNsFieldNumber = 4,
+    kSupportsInstrumentedSamplingFieldNumber = 5,
+  };
+
+  GpuCounterDescriptor();
+  ~GpuCounterDescriptor() override;
+  GpuCounterDescriptor(GpuCounterDescriptor&&) noexcept;
+  GpuCounterDescriptor& operator=(GpuCounterDescriptor&&);
+  GpuCounterDescriptor(const GpuCounterDescriptor&);
+  GpuCounterDescriptor& operator=(const GpuCounterDescriptor&);
+  bool operator==(const GpuCounterDescriptor&) const;
+  bool operator!=(const GpuCounterDescriptor& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<GpuCounterDescriptor_GpuCounterSpec>& specs() const { return specs_; }
+  std::vector<GpuCounterDescriptor_GpuCounterSpec>* mutable_specs() { return &specs_; }
+  int specs_size() const;
+  void clear_specs();
+  GpuCounterDescriptor_GpuCounterSpec* add_specs();
+
+  const std::vector<GpuCounterDescriptor_GpuCounterBlock>& blocks() const { return blocks_; }
+  std::vector<GpuCounterDescriptor_GpuCounterBlock>* mutable_blocks() { return &blocks_; }
+  int blocks_size() const;
+  void clear_blocks();
+  GpuCounterDescriptor_GpuCounterBlock* add_blocks();
+
+  bool has_min_sampling_period_ns() const { return _has_field_[3]; }
+  uint64_t min_sampling_period_ns() const { return min_sampling_period_ns_; }
+  void set_min_sampling_period_ns(uint64_t value) { min_sampling_period_ns_ = value; _has_field_.set(3); }
+
+  bool has_max_sampling_period_ns() const { return _has_field_[4]; }
+  uint64_t max_sampling_period_ns() const { return max_sampling_period_ns_; }
+  void set_max_sampling_period_ns(uint64_t value) { max_sampling_period_ns_ = value; _has_field_.set(4); }
+
+  bool has_supports_instrumented_sampling() const { return _has_field_[5]; }
+  bool supports_instrumented_sampling() const { return supports_instrumented_sampling_; }
+  void set_supports_instrumented_sampling(bool value) { supports_instrumented_sampling_ = value; _has_field_.set(5); }
+
+ private:
+  std::vector<GpuCounterDescriptor_GpuCounterSpec> specs_;
+  std::vector<GpuCounterDescriptor_GpuCounterBlock> blocks_;
+  uint64_t min_sampling_period_ns_{};
+  uint64_t max_sampling_period_ns_{};
+  bool supports_instrumented_sampling_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<6> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT GpuCounterDescriptor_GpuCounterBlock : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kBlockIdFieldNumber = 1,
+    kBlockCapacityFieldNumber = 2,
+    kNameFieldNumber = 3,
+    kDescriptionFieldNumber = 4,
+    kCounterIdsFieldNumber = 5,
+  };
+
+  GpuCounterDescriptor_GpuCounterBlock();
+  ~GpuCounterDescriptor_GpuCounterBlock() override;
+  GpuCounterDescriptor_GpuCounterBlock(GpuCounterDescriptor_GpuCounterBlock&&) noexcept;
+  GpuCounterDescriptor_GpuCounterBlock& operator=(GpuCounterDescriptor_GpuCounterBlock&&);
+  GpuCounterDescriptor_GpuCounterBlock(const GpuCounterDescriptor_GpuCounterBlock&);
+  GpuCounterDescriptor_GpuCounterBlock& operator=(const GpuCounterDescriptor_GpuCounterBlock&);
+  bool operator==(const GpuCounterDescriptor_GpuCounterBlock&) const;
+  bool operator!=(const GpuCounterDescriptor_GpuCounterBlock& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_block_id() const { return _has_field_[1]; }
+  uint32_t block_id() const { return block_id_; }
+  void set_block_id(uint32_t value) { block_id_ = value; _has_field_.set(1); }
+
+  bool has_block_capacity() const { return _has_field_[2]; }
+  uint32_t block_capacity() const { return block_capacity_; }
+  void set_block_capacity(uint32_t value) { block_capacity_ = value; _has_field_.set(2); }
+
+  bool has_name() const { return _has_field_[3]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(3); }
+
+  bool has_description() const { return _has_field_[4]; }
+  const std::string& description() const { return description_; }
+  void set_description(const std::string& value) { description_ = value; _has_field_.set(4); }
+
+  const std::vector<uint32_t>& counter_ids() const { return counter_ids_; }
+  std::vector<uint32_t>* mutable_counter_ids() { return &counter_ids_; }
+  int counter_ids_size() const { return static_cast<int>(counter_ids_.size()); }
+  void clear_counter_ids() { counter_ids_.clear(); }
+  void add_counter_ids(uint32_t value) { counter_ids_.emplace_back(value); }
+  uint32_t* add_counter_ids() { counter_ids_.emplace_back(); return &counter_ids_.back(); }
+
+ private:
+  uint32_t block_id_{};
+  uint32_t block_capacity_{};
+  std::string name_{};
+  std::string description_{};
+  std::vector<uint32_t> counter_ids_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<6> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT GpuCounterDescriptor_GpuCounterSpec : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kCounterIdFieldNumber = 1,
+    kNameFieldNumber = 2,
+    kDescriptionFieldNumber = 3,
+    kIntPeakValueFieldNumber = 5,
+    kDoublePeakValueFieldNumber = 6,
+    kNumeratorUnitsFieldNumber = 7,
+    kDenominatorUnitsFieldNumber = 8,
+    kSelectByDefaultFieldNumber = 9,
+    kGroupsFieldNumber = 10,
+  };
+
+  GpuCounterDescriptor_GpuCounterSpec();
+  ~GpuCounterDescriptor_GpuCounterSpec() override;
+  GpuCounterDescriptor_GpuCounterSpec(GpuCounterDescriptor_GpuCounterSpec&&) noexcept;
+  GpuCounterDescriptor_GpuCounterSpec& operator=(GpuCounterDescriptor_GpuCounterSpec&&);
+  GpuCounterDescriptor_GpuCounterSpec(const GpuCounterDescriptor_GpuCounterSpec&);
+  GpuCounterDescriptor_GpuCounterSpec& operator=(const GpuCounterDescriptor_GpuCounterSpec&);
+  bool operator==(const GpuCounterDescriptor_GpuCounterSpec&) const;
+  bool operator!=(const GpuCounterDescriptor_GpuCounterSpec& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_counter_id() const { return _has_field_[1]; }
+  uint32_t counter_id() const { return counter_id_; }
+  void set_counter_id(uint32_t value) { counter_id_ = value; _has_field_.set(1); }
+
+  bool has_name() const { return _has_field_[2]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
+
+  bool has_description() const { return _has_field_[3]; }
+  const std::string& description() const { return description_; }
+  void set_description(const std::string& value) { description_ = value; _has_field_.set(3); }
+
+  bool has_int_peak_value() const { return _has_field_[5]; }
+  int64_t int_peak_value() const { return int_peak_value_; }
+  void set_int_peak_value(int64_t value) { int_peak_value_ = value; _has_field_.set(5); }
+
+  bool has_double_peak_value() const { return _has_field_[6]; }
+  double double_peak_value() const { return double_peak_value_; }
+  void set_double_peak_value(double value) { double_peak_value_ = value; _has_field_.set(6); }
+
+  const std::vector<GpuCounterDescriptor_MeasureUnit>& numerator_units() const { return numerator_units_; }
+  std::vector<GpuCounterDescriptor_MeasureUnit>* mutable_numerator_units() { return &numerator_units_; }
+  int numerator_units_size() const { return static_cast<int>(numerator_units_.size()); }
+  void clear_numerator_units() { numerator_units_.clear(); }
+  void add_numerator_units(GpuCounterDescriptor_MeasureUnit value) { numerator_units_.emplace_back(value); }
+  GpuCounterDescriptor_MeasureUnit* add_numerator_units() { numerator_units_.emplace_back(); return &numerator_units_.back(); }
+
+  const std::vector<GpuCounterDescriptor_MeasureUnit>& denominator_units() const { return denominator_units_; }
+  std::vector<GpuCounterDescriptor_MeasureUnit>* mutable_denominator_units() { return &denominator_units_; }
+  int denominator_units_size() const { return static_cast<int>(denominator_units_.size()); }
+  void clear_denominator_units() { denominator_units_.clear(); }
+  void add_denominator_units(GpuCounterDescriptor_MeasureUnit value) { denominator_units_.emplace_back(value); }
+  GpuCounterDescriptor_MeasureUnit* add_denominator_units() { denominator_units_.emplace_back(); return &denominator_units_.back(); }
+
+  bool has_select_by_default() const { return _has_field_[9]; }
+  bool select_by_default() const { return select_by_default_; }
+  void set_select_by_default(bool value) { select_by_default_ = value; _has_field_.set(9); }
+
+  const std::vector<GpuCounterDescriptor_GpuCounterGroup>& groups() const { return groups_; }
+  std::vector<GpuCounterDescriptor_GpuCounterGroup>* mutable_groups() { return &groups_; }
+  int groups_size() const { return static_cast<int>(groups_.size()); }
+  void clear_groups() { groups_.clear(); }
+  void add_groups(GpuCounterDescriptor_GpuCounterGroup value) { groups_.emplace_back(value); }
+  GpuCounterDescriptor_GpuCounterGroup* add_groups() { groups_.emplace_back(); return &groups_.back(); }
+
+ private:
+  uint32_t counter_id_{};
+  std::string name_{};
+  std::string description_{};
+  int64_t int_peak_value_{};
+  double double_peak_value_{};
+  std::vector<GpuCounterDescriptor_MeasureUnit> numerator_units_;
+  std::vector<GpuCounterDescriptor_MeasureUnit> denominator_units_;
+  bool select_by_default_{};
+  std::vector<GpuCounterDescriptor_GpuCounterGroup> groups_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<11> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_GPU_COUNTER_DESCRIPTOR_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/common/interceptor_descriptor.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_INTERCEPTOR_DESCRIPTOR_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_INTERCEPTOR_DESCRIPTOR_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class InterceptorDescriptor;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT InterceptorDescriptor : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kNameFieldNumber = 1,
+  };
+
+  InterceptorDescriptor();
+  ~InterceptorDescriptor() override;
+  InterceptorDescriptor(InterceptorDescriptor&&) noexcept;
+  InterceptorDescriptor& operator=(InterceptorDescriptor&&);
+  InterceptorDescriptor(const InterceptorDescriptor&);
+  InterceptorDescriptor& operator=(const InterceptorDescriptor&);
+  bool operator==(const InterceptorDescriptor&) const;
+  bool operator!=(const InterceptorDescriptor& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name() const { return _has_field_[1]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
+
+ private:
+  std::string name_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_INTERCEPTOR_DESCRIPTOR_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/common/observable_events.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_OBSERVABLE_EVENTS_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_OBSERVABLE_EVENTS_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ObservableEvents;
+class ObservableEvents_CloneTriggerHit;
+class ObservableEvents_DataSourceInstanceStateChange;
+enum ObservableEvents_Type : int;
+enum ObservableEvents_DataSourceInstanceState : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum ObservableEvents_Type : int {
+  ObservableEvents_Type_TYPE_UNSPECIFIED = 0,
+  ObservableEvents_Type_TYPE_DATA_SOURCES_INSTANCES = 1,
+  ObservableEvents_Type_TYPE_ALL_DATA_SOURCES_STARTED = 2,
+  ObservableEvents_Type_TYPE_CLONE_TRIGGER_HIT = 4,
+};
+enum ObservableEvents_DataSourceInstanceState : int {
+  ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STOPPED = 1,
+  ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STARTED = 2,
+};
+
+class PERFETTO_EXPORT_COMPONENT ObservableEvents : public ::protozero::CppMessageObj {
+ public:
+  using DataSourceInstanceStateChange = ObservableEvents_DataSourceInstanceStateChange;
+  using CloneTriggerHit = ObservableEvents_CloneTriggerHit;
+  using Type = ObservableEvents_Type;
+  static constexpr auto TYPE_UNSPECIFIED = ObservableEvents_Type_TYPE_UNSPECIFIED;
+  static constexpr auto TYPE_DATA_SOURCES_INSTANCES = ObservableEvents_Type_TYPE_DATA_SOURCES_INSTANCES;
+  static constexpr auto TYPE_ALL_DATA_SOURCES_STARTED = ObservableEvents_Type_TYPE_ALL_DATA_SOURCES_STARTED;
+  static constexpr auto TYPE_CLONE_TRIGGER_HIT = ObservableEvents_Type_TYPE_CLONE_TRIGGER_HIT;
+  static constexpr auto Type_MIN = ObservableEvents_Type_TYPE_UNSPECIFIED;
+  static constexpr auto Type_MAX = ObservableEvents_Type_TYPE_CLONE_TRIGGER_HIT;
+  using DataSourceInstanceState = ObservableEvents_DataSourceInstanceState;
+  static constexpr auto DATA_SOURCE_INSTANCE_STATE_STOPPED = ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STOPPED;
+  static constexpr auto DATA_SOURCE_INSTANCE_STATE_STARTED = ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STARTED;
+  static constexpr auto DataSourceInstanceState_MIN = ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STOPPED;
+  static constexpr auto DataSourceInstanceState_MAX = ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STARTED;
+  enum FieldNumbers {
+    kInstanceStateChangesFieldNumber = 1,
+    kAllDataSourcesStartedFieldNumber = 2,
+    kCloneTriggerHitFieldNumber = 3,
+  };
+
+  ObservableEvents();
+  ~ObservableEvents() override;
+  ObservableEvents(ObservableEvents&&) noexcept;
+  ObservableEvents& operator=(ObservableEvents&&);
+  ObservableEvents(const ObservableEvents&);
+  ObservableEvents& operator=(const ObservableEvents&);
+  bool operator==(const ObservableEvents&) const;
+  bool operator!=(const ObservableEvents& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<ObservableEvents_DataSourceInstanceStateChange>& instance_state_changes() const { return instance_state_changes_; }
+  std::vector<ObservableEvents_DataSourceInstanceStateChange>* mutable_instance_state_changes() { return &instance_state_changes_; }
+  int instance_state_changes_size() const;
+  void clear_instance_state_changes();
+  ObservableEvents_DataSourceInstanceStateChange* add_instance_state_changes();
+
+  bool has_all_data_sources_started() const { return _has_field_[2]; }
+  bool all_data_sources_started() const { return all_data_sources_started_; }
+  void set_all_data_sources_started(bool value) { all_data_sources_started_ = value; _has_field_.set(2); }
+
+  bool has_clone_trigger_hit() const { return _has_field_[3]; }
+  const ObservableEvents_CloneTriggerHit& clone_trigger_hit() const { return *clone_trigger_hit_; }
+  ObservableEvents_CloneTriggerHit* mutable_clone_trigger_hit() { _has_field_.set(3); return clone_trigger_hit_.get(); }
+
+ private:
+  std::vector<ObservableEvents_DataSourceInstanceStateChange> instance_state_changes_;
+  bool all_data_sources_started_{};
+  ::protozero::CopyablePtr<ObservableEvents_CloneTriggerHit> clone_trigger_hit_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT ObservableEvents_CloneTriggerHit : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kTracingSessionIdFieldNumber = 1,
+  };
+
+  ObservableEvents_CloneTriggerHit();
+  ~ObservableEvents_CloneTriggerHit() override;
+  ObservableEvents_CloneTriggerHit(ObservableEvents_CloneTriggerHit&&) noexcept;
+  ObservableEvents_CloneTriggerHit& operator=(ObservableEvents_CloneTriggerHit&&);
+  ObservableEvents_CloneTriggerHit(const ObservableEvents_CloneTriggerHit&);
+  ObservableEvents_CloneTriggerHit& operator=(const ObservableEvents_CloneTriggerHit&);
+  bool operator==(const ObservableEvents_CloneTriggerHit&) const;
+  bool operator!=(const ObservableEvents_CloneTriggerHit& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_tracing_session_id() const { return _has_field_[1]; }
+  int64_t tracing_session_id() const { return tracing_session_id_; }
+  void set_tracing_session_id(int64_t value) { tracing_session_id_ = value; _has_field_.set(1); }
+
+ private:
+  int64_t tracing_session_id_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT ObservableEvents_DataSourceInstanceStateChange : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kProducerNameFieldNumber = 1,
+    kDataSourceNameFieldNumber = 2,
+    kStateFieldNumber = 3,
+  };
+
+  ObservableEvents_DataSourceInstanceStateChange();
+  ~ObservableEvents_DataSourceInstanceStateChange() override;
+  ObservableEvents_DataSourceInstanceStateChange(ObservableEvents_DataSourceInstanceStateChange&&) noexcept;
+  ObservableEvents_DataSourceInstanceStateChange& operator=(ObservableEvents_DataSourceInstanceStateChange&&);
+  ObservableEvents_DataSourceInstanceStateChange(const ObservableEvents_DataSourceInstanceStateChange&);
+  ObservableEvents_DataSourceInstanceStateChange& operator=(const ObservableEvents_DataSourceInstanceStateChange&);
+  bool operator==(const ObservableEvents_DataSourceInstanceStateChange&) const;
+  bool operator!=(const ObservableEvents_DataSourceInstanceStateChange& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_producer_name() const { return _has_field_[1]; }
+  const std::string& producer_name() const { return producer_name_; }
+  void set_producer_name(const std::string& value) { producer_name_ = value; _has_field_.set(1); }
+
+  bool has_data_source_name() const { return _has_field_[2]; }
+  const std::string& data_source_name() const { return data_source_name_; }
+  void set_data_source_name(const std::string& value) { data_source_name_ = value; _has_field_.set(2); }
+
+  bool has_state() const { return _has_field_[3]; }
+  ObservableEvents_DataSourceInstanceState state() const { return state_; }
+  void set_state(ObservableEvents_DataSourceInstanceState value) { state_ = value; _has_field_.set(3); }
+
+ private:
+  std::string producer_name_{};
+  std::string data_source_name_{};
+  ObservableEvents_DataSourceInstanceState state_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_OBSERVABLE_EVENTS_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/common/perf_events.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_PERF_EVENTS_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_PERF_EVENTS_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class PerfEvents;
+class PerfEvents_RawEvent;
+class PerfEvents_Tracepoint;
+class PerfEvents_Timebase;
+enum PerfEvents_Counter : int;
+enum PerfEvents_PerfClock : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum PerfEvents_Counter : int {
+  PerfEvents_Counter_UNKNOWN_COUNTER = 0,
+  PerfEvents_Counter_SW_CPU_CLOCK = 1,
+  PerfEvents_Counter_SW_PAGE_FAULTS = 2,
+  PerfEvents_Counter_SW_TASK_CLOCK = 3,
+  PerfEvents_Counter_SW_CONTEXT_SWITCHES = 4,
+  PerfEvents_Counter_SW_CPU_MIGRATIONS = 5,
+  PerfEvents_Counter_SW_PAGE_FAULTS_MIN = 6,
+  PerfEvents_Counter_SW_PAGE_FAULTS_MAJ = 7,
+  PerfEvents_Counter_SW_ALIGNMENT_FAULTS = 8,
+  PerfEvents_Counter_SW_EMULATION_FAULTS = 9,
+  PerfEvents_Counter_SW_DUMMY = 20,
+  PerfEvents_Counter_HW_CPU_CYCLES = 10,
+  PerfEvents_Counter_HW_INSTRUCTIONS = 11,
+  PerfEvents_Counter_HW_CACHE_REFERENCES = 12,
+  PerfEvents_Counter_HW_CACHE_MISSES = 13,
+  PerfEvents_Counter_HW_BRANCH_INSTRUCTIONS = 14,
+  PerfEvents_Counter_HW_BRANCH_MISSES = 15,
+  PerfEvents_Counter_HW_BUS_CYCLES = 16,
+  PerfEvents_Counter_HW_STALLED_CYCLES_FRONTEND = 17,
+  PerfEvents_Counter_HW_STALLED_CYCLES_BACKEND = 18,
+  PerfEvents_Counter_HW_REF_CPU_CYCLES = 19,
+};
+enum PerfEvents_PerfClock : int {
+  PerfEvents_PerfClock_UNKNOWN_PERF_CLOCK = 0,
+  PerfEvents_PerfClock_PERF_CLOCK_REALTIME = 1,
+  PerfEvents_PerfClock_PERF_CLOCK_MONOTONIC = 2,
+  PerfEvents_PerfClock_PERF_CLOCK_MONOTONIC_RAW = 3,
+  PerfEvents_PerfClock_PERF_CLOCK_BOOTTIME = 4,
+};
+
+class PERFETTO_EXPORT_COMPONENT PerfEvents : public ::protozero::CppMessageObj {
+ public:
+  using Timebase = PerfEvents_Timebase;
+  using Tracepoint = PerfEvents_Tracepoint;
+  using RawEvent = PerfEvents_RawEvent;
+  using Counter = PerfEvents_Counter;
+  static constexpr auto UNKNOWN_COUNTER = PerfEvents_Counter_UNKNOWN_COUNTER;
+  static constexpr auto SW_CPU_CLOCK = PerfEvents_Counter_SW_CPU_CLOCK;
+  static constexpr auto SW_PAGE_FAULTS = PerfEvents_Counter_SW_PAGE_FAULTS;
+  static constexpr auto SW_TASK_CLOCK = PerfEvents_Counter_SW_TASK_CLOCK;
+  static constexpr auto SW_CONTEXT_SWITCHES = PerfEvents_Counter_SW_CONTEXT_SWITCHES;
+  static constexpr auto SW_CPU_MIGRATIONS = PerfEvents_Counter_SW_CPU_MIGRATIONS;
+  static constexpr auto SW_PAGE_FAULTS_MIN = PerfEvents_Counter_SW_PAGE_FAULTS_MIN;
+  static constexpr auto SW_PAGE_FAULTS_MAJ = PerfEvents_Counter_SW_PAGE_FAULTS_MAJ;
+  static constexpr auto SW_ALIGNMENT_FAULTS = PerfEvents_Counter_SW_ALIGNMENT_FAULTS;
+  static constexpr auto SW_EMULATION_FAULTS = PerfEvents_Counter_SW_EMULATION_FAULTS;
+  static constexpr auto SW_DUMMY = PerfEvents_Counter_SW_DUMMY;
+  static constexpr auto HW_CPU_CYCLES = PerfEvents_Counter_HW_CPU_CYCLES;
+  static constexpr auto HW_INSTRUCTIONS = PerfEvents_Counter_HW_INSTRUCTIONS;
+  static constexpr auto HW_CACHE_REFERENCES = PerfEvents_Counter_HW_CACHE_REFERENCES;
+  static constexpr auto HW_CACHE_MISSES = PerfEvents_Counter_HW_CACHE_MISSES;
+  static constexpr auto HW_BRANCH_INSTRUCTIONS = PerfEvents_Counter_HW_BRANCH_INSTRUCTIONS;
+  static constexpr auto HW_BRANCH_MISSES = PerfEvents_Counter_HW_BRANCH_MISSES;
+  static constexpr auto HW_BUS_CYCLES = PerfEvents_Counter_HW_BUS_CYCLES;
+  static constexpr auto HW_STALLED_CYCLES_FRONTEND = PerfEvents_Counter_HW_STALLED_CYCLES_FRONTEND;
+  static constexpr auto HW_STALLED_CYCLES_BACKEND = PerfEvents_Counter_HW_STALLED_CYCLES_BACKEND;
+  static constexpr auto HW_REF_CPU_CYCLES = PerfEvents_Counter_HW_REF_CPU_CYCLES;
+  static constexpr auto Counter_MIN = PerfEvents_Counter_UNKNOWN_COUNTER;
+  static constexpr auto Counter_MAX = PerfEvents_Counter_SW_DUMMY;
+  using PerfClock = PerfEvents_PerfClock;
+  static constexpr auto UNKNOWN_PERF_CLOCK = PerfEvents_PerfClock_UNKNOWN_PERF_CLOCK;
+  static constexpr auto PERF_CLOCK_REALTIME = PerfEvents_PerfClock_PERF_CLOCK_REALTIME;
+  static constexpr auto PERF_CLOCK_MONOTONIC = PerfEvents_PerfClock_PERF_CLOCK_MONOTONIC;
+  static constexpr auto PERF_CLOCK_MONOTONIC_RAW = PerfEvents_PerfClock_PERF_CLOCK_MONOTONIC_RAW;
+  static constexpr auto PERF_CLOCK_BOOTTIME = PerfEvents_PerfClock_PERF_CLOCK_BOOTTIME;
+  static constexpr auto PerfClock_MIN = PerfEvents_PerfClock_UNKNOWN_PERF_CLOCK;
+  static constexpr auto PerfClock_MAX = PerfEvents_PerfClock_PERF_CLOCK_BOOTTIME;
+  enum FieldNumbers {
+  };
+
+  PerfEvents();
+  ~PerfEvents() override;
+  PerfEvents(PerfEvents&&) noexcept;
+  PerfEvents& operator=(PerfEvents&&);
+  PerfEvents(const PerfEvents&);
+  PerfEvents& operator=(const PerfEvents&);
+  bool operator==(const PerfEvents&) const;
+  bool operator!=(const PerfEvents& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT PerfEvents_RawEvent : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kTypeFieldNumber = 1,
+    kConfigFieldNumber = 2,
+    kConfig1FieldNumber = 3,
+    kConfig2FieldNumber = 4,
+  };
+
+  PerfEvents_RawEvent();
+  ~PerfEvents_RawEvent() override;
+  PerfEvents_RawEvent(PerfEvents_RawEvent&&) noexcept;
+  PerfEvents_RawEvent& operator=(PerfEvents_RawEvent&&);
+  PerfEvents_RawEvent(const PerfEvents_RawEvent&);
+  PerfEvents_RawEvent& operator=(const PerfEvents_RawEvent&);
+  bool operator==(const PerfEvents_RawEvent&) const;
+  bool operator!=(const PerfEvents_RawEvent& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_type() const { return _has_field_[1]; }
+  uint32_t type() const { return type_; }
+  void set_type(uint32_t value) { type_ = value; _has_field_.set(1); }
+
+  bool has_config() const { return _has_field_[2]; }
+  uint64_t config() const { return config_; }
+  void set_config(uint64_t value) { config_ = value; _has_field_.set(2); }
+
+  bool has_config1() const { return _has_field_[3]; }
+  uint64_t config1() const { return config1_; }
+  void set_config1(uint64_t value) { config1_ = value; _has_field_.set(3); }
+
+  bool has_config2() const { return _has_field_[4]; }
+  uint64_t config2() const { return config2_; }
+  void set_config2(uint64_t value) { config2_ = value; _has_field_.set(4); }
+
+ private:
+  uint32_t type_{};
+  uint64_t config_{};
+  uint64_t config1_{};
+  uint64_t config2_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<5> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT PerfEvents_Tracepoint : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kNameFieldNumber = 1,
+    kFilterFieldNumber = 2,
+  };
+
+  PerfEvents_Tracepoint();
+  ~PerfEvents_Tracepoint() override;
+  PerfEvents_Tracepoint(PerfEvents_Tracepoint&&) noexcept;
+  PerfEvents_Tracepoint& operator=(PerfEvents_Tracepoint&&);
+  PerfEvents_Tracepoint(const PerfEvents_Tracepoint&);
+  PerfEvents_Tracepoint& operator=(const PerfEvents_Tracepoint&);
+  bool operator==(const PerfEvents_Tracepoint&) const;
+  bool operator!=(const PerfEvents_Tracepoint& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name() const { return _has_field_[1]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
+
+  bool has_filter() const { return _has_field_[2]; }
+  const std::string& filter() const { return filter_; }
+  void set_filter(const std::string& value) { filter_ = value; _has_field_.set(2); }
+
+ private:
+  std::string name_{};
+  std::string filter_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT PerfEvents_Timebase : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kFrequencyFieldNumber = 2,
+    kPeriodFieldNumber = 1,
+    kCounterFieldNumber = 4,
+    kTracepointFieldNumber = 3,
+    kRawEventFieldNumber = 5,
+    kTimestampClockFieldNumber = 11,
+    kNameFieldNumber = 10,
+  };
+
+  PerfEvents_Timebase();
+  ~PerfEvents_Timebase() override;
+  PerfEvents_Timebase(PerfEvents_Timebase&&) noexcept;
+  PerfEvents_Timebase& operator=(PerfEvents_Timebase&&);
+  PerfEvents_Timebase(const PerfEvents_Timebase&);
+  PerfEvents_Timebase& operator=(const PerfEvents_Timebase&);
+  bool operator==(const PerfEvents_Timebase&) const;
+  bool operator!=(const PerfEvents_Timebase& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_frequency() const { return _has_field_[2]; }
+  uint64_t frequency() const { return frequency_; }
+  void set_frequency(uint64_t value) { frequency_ = value; _has_field_.set(2); }
+
+  bool has_period() const { return _has_field_[1]; }
+  uint64_t period() const { return period_; }
+  void set_period(uint64_t value) { period_ = value; _has_field_.set(1); }
+
+  bool has_counter() const { return _has_field_[4]; }
+  PerfEvents_Counter counter() const { return counter_; }
+  void set_counter(PerfEvents_Counter value) { counter_ = value; _has_field_.set(4); }
+
+  bool has_tracepoint() const { return _has_field_[3]; }
+  const PerfEvents_Tracepoint& tracepoint() const { return *tracepoint_; }
+  PerfEvents_Tracepoint* mutable_tracepoint() { _has_field_.set(3); return tracepoint_.get(); }
+
+  bool has_raw_event() const { return _has_field_[5]; }
+  const PerfEvents_RawEvent& raw_event() const { return *raw_event_; }
+  PerfEvents_RawEvent* mutable_raw_event() { _has_field_.set(5); return raw_event_.get(); }
+
+  bool has_timestamp_clock() const { return _has_field_[11]; }
+  PerfEvents_PerfClock timestamp_clock() const { return timestamp_clock_; }
+  void set_timestamp_clock(PerfEvents_PerfClock value) { timestamp_clock_ = value; _has_field_.set(11); }
+
+  bool has_name() const { return _has_field_[10]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(10); }
+
+ private:
+  uint64_t frequency_{};
+  uint64_t period_{};
+  PerfEvents_Counter counter_{};
+  ::protozero::CopyablePtr<PerfEvents_Tracepoint> tracepoint_;
+  ::protozero::CopyablePtr<PerfEvents_RawEvent> raw_event_;
+  PerfEvents_PerfClock timestamp_clock_{};
+  std::string name_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<12> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_PERF_EVENTS_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/common/protolog_common.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_PROTOLOG_COMMON_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_PROTOLOG_COMMON_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum ProtoLogLevel : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum ProtoLogLevel : int {
+  PROTOLOG_LEVEL_UNDEFINED = 0,
+  PROTOLOG_LEVEL_DEBUG = 1,
+  PROTOLOG_LEVEL_VERBOSE = 2,
+  PROTOLOG_LEVEL_INFO = 3,
+  PROTOLOG_LEVEL_WARN = 4,
+  PROTOLOG_LEVEL_ERROR = 5,
+  PROTOLOG_LEVEL_WTF = 6,
+};
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_PROTOLOG_COMMON_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/common/sys_stats_counters.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_SYS_STATS_COUNTERS_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_SYS_STATS_COUNTERS_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum MeminfoCounters : int;
+enum VmstatCounters : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum MeminfoCounters : int {
+  MEMINFO_UNSPECIFIED = 0,
+  MEMINFO_MEM_TOTAL = 1,
+  MEMINFO_MEM_FREE = 2,
+  MEMINFO_MEM_AVAILABLE = 3,
+  MEMINFO_BUFFERS = 4,
+  MEMINFO_CACHED = 5,
+  MEMINFO_SWAP_CACHED = 6,
+  MEMINFO_ACTIVE = 7,
+  MEMINFO_INACTIVE = 8,
+  MEMINFO_ACTIVE_ANON = 9,
+  MEMINFO_INACTIVE_ANON = 10,
+  MEMINFO_ACTIVE_FILE = 11,
+  MEMINFO_INACTIVE_FILE = 12,
+  MEMINFO_UNEVICTABLE = 13,
+  MEMINFO_MLOCKED = 14,
+  MEMINFO_SWAP_TOTAL = 15,
+  MEMINFO_SWAP_FREE = 16,
+  MEMINFO_DIRTY = 17,
+  MEMINFO_WRITEBACK = 18,
+  MEMINFO_ANON_PAGES = 19,
+  MEMINFO_MAPPED = 20,
+  MEMINFO_SHMEM = 21,
+  MEMINFO_SLAB = 22,
+  MEMINFO_SLAB_RECLAIMABLE = 23,
+  MEMINFO_SLAB_UNRECLAIMABLE = 24,
+  MEMINFO_KERNEL_STACK = 25,
+  MEMINFO_PAGE_TABLES = 26,
+  MEMINFO_COMMIT_LIMIT = 27,
+  MEMINFO_COMMITED_AS = 28,
+  MEMINFO_VMALLOC_TOTAL = 29,
+  MEMINFO_VMALLOC_USED = 30,
+  MEMINFO_VMALLOC_CHUNK = 31,
+  MEMINFO_CMA_TOTAL = 32,
+  MEMINFO_CMA_FREE = 33,
+};
+enum VmstatCounters : int {
+  VMSTAT_UNSPECIFIED = 0,
+  VMSTAT_NR_FREE_PAGES = 1,
+  VMSTAT_NR_ALLOC_BATCH = 2,
+  VMSTAT_NR_INACTIVE_ANON = 3,
+  VMSTAT_NR_ACTIVE_ANON = 4,
+  VMSTAT_NR_INACTIVE_FILE = 5,
+  VMSTAT_NR_ACTIVE_FILE = 6,
+  VMSTAT_NR_UNEVICTABLE = 7,
+  VMSTAT_NR_MLOCK = 8,
+  VMSTAT_NR_ANON_PAGES = 9,
+  VMSTAT_NR_MAPPED = 10,
+  VMSTAT_NR_FILE_PAGES = 11,
+  VMSTAT_NR_DIRTY = 12,
+  VMSTAT_NR_WRITEBACK = 13,
+  VMSTAT_NR_SLAB_RECLAIMABLE = 14,
+  VMSTAT_NR_SLAB_UNRECLAIMABLE = 15,
+  VMSTAT_NR_PAGE_TABLE_PAGES = 16,
+  VMSTAT_NR_KERNEL_STACK = 17,
+  VMSTAT_NR_OVERHEAD = 18,
+  VMSTAT_NR_UNSTABLE = 19,
+  VMSTAT_NR_BOUNCE = 20,
+  VMSTAT_NR_VMSCAN_WRITE = 21,
+  VMSTAT_NR_VMSCAN_IMMEDIATE_RECLAIM = 22,
+  VMSTAT_NR_WRITEBACK_TEMP = 23,
+  VMSTAT_NR_ISOLATED_ANON = 24,
+  VMSTAT_NR_ISOLATED_FILE = 25,
+  VMSTAT_NR_SHMEM = 26,
+  VMSTAT_NR_DIRTIED = 27,
+  VMSTAT_NR_WRITTEN = 28,
+  VMSTAT_NR_PAGES_SCANNED = 29,
+  VMSTAT_WORKINGSET_REFAULT = 30,
+  VMSTAT_WORKINGSET_ACTIVATE = 31,
+  VMSTAT_WORKINGSET_NODERECLAIM = 32,
+  VMSTAT_NR_ANON_TRANSPARENT_HUGEPAGES = 33,
+  VMSTAT_NR_FREE_CMA = 34,
+  VMSTAT_NR_SWAPCACHE = 35,
+  VMSTAT_NR_DIRTY_THRESHOLD = 36,
+  VMSTAT_NR_DIRTY_BACKGROUND_THRESHOLD = 37,
+  VMSTAT_PGPGIN = 38,
+  VMSTAT_PGPGOUT = 39,
+  VMSTAT_PGPGOUTCLEAN = 40,
+  VMSTAT_PSWPIN = 41,
+  VMSTAT_PSWPOUT = 42,
+  VMSTAT_PGALLOC_DMA = 43,
+  VMSTAT_PGALLOC_NORMAL = 44,
+  VMSTAT_PGALLOC_MOVABLE = 45,
+  VMSTAT_PGFREE = 46,
+  VMSTAT_PGACTIVATE = 47,
+  VMSTAT_PGDEACTIVATE = 48,
+  VMSTAT_PGFAULT = 49,
+  VMSTAT_PGMAJFAULT = 50,
+  VMSTAT_PGREFILL_DMA = 51,
+  VMSTAT_PGREFILL_NORMAL = 52,
+  VMSTAT_PGREFILL_MOVABLE = 53,
+  VMSTAT_PGSTEAL_KSWAPD_DMA = 54,
+  VMSTAT_PGSTEAL_KSWAPD_NORMAL = 55,
+  VMSTAT_PGSTEAL_KSWAPD_MOVABLE = 56,
+  VMSTAT_PGSTEAL_DIRECT_DMA = 57,
+  VMSTAT_PGSTEAL_DIRECT_NORMAL = 58,
+  VMSTAT_PGSTEAL_DIRECT_MOVABLE = 59,
+  VMSTAT_PGSCAN_KSWAPD_DMA = 60,
+  VMSTAT_PGSCAN_KSWAPD_NORMAL = 61,
+  VMSTAT_PGSCAN_KSWAPD_MOVABLE = 62,
+  VMSTAT_PGSCAN_DIRECT_DMA = 63,
+  VMSTAT_PGSCAN_DIRECT_NORMAL = 64,
+  VMSTAT_PGSCAN_DIRECT_MOVABLE = 65,
+  VMSTAT_PGSCAN_DIRECT_THROTTLE = 66,
+  VMSTAT_PGINODESTEAL = 67,
+  VMSTAT_SLABS_SCANNED = 68,
+  VMSTAT_KSWAPD_INODESTEAL = 69,
+  VMSTAT_KSWAPD_LOW_WMARK_HIT_QUICKLY = 70,
+  VMSTAT_KSWAPD_HIGH_WMARK_HIT_QUICKLY = 71,
+  VMSTAT_PAGEOUTRUN = 72,
+  VMSTAT_ALLOCSTALL = 73,
+  VMSTAT_PGROTATED = 74,
+  VMSTAT_DROP_PAGECACHE = 75,
+  VMSTAT_DROP_SLAB = 76,
+  VMSTAT_PGMIGRATE_SUCCESS = 77,
+  VMSTAT_PGMIGRATE_FAIL = 78,
+  VMSTAT_COMPACT_MIGRATE_SCANNED = 79,
+  VMSTAT_COMPACT_FREE_SCANNED = 80,
+  VMSTAT_COMPACT_ISOLATED = 81,
+  VMSTAT_COMPACT_STALL = 82,
+  VMSTAT_COMPACT_FAIL = 83,
+  VMSTAT_COMPACT_SUCCESS = 84,
+  VMSTAT_COMPACT_DAEMON_WAKE = 85,
+  VMSTAT_UNEVICTABLE_PGS_CULLED = 86,
+  VMSTAT_UNEVICTABLE_PGS_SCANNED = 87,
+  VMSTAT_UNEVICTABLE_PGS_RESCUED = 88,
+  VMSTAT_UNEVICTABLE_PGS_MLOCKED = 89,
+  VMSTAT_UNEVICTABLE_PGS_MUNLOCKED = 90,
+  VMSTAT_UNEVICTABLE_PGS_CLEARED = 91,
+  VMSTAT_UNEVICTABLE_PGS_STRANDED = 92,
+  VMSTAT_NR_ZSPAGES = 93,
+  VMSTAT_NR_ION_HEAP = 94,
+  VMSTAT_NR_GPU_HEAP = 95,
+  VMSTAT_ALLOCSTALL_DMA = 96,
+  VMSTAT_ALLOCSTALL_MOVABLE = 97,
+  VMSTAT_ALLOCSTALL_NORMAL = 98,
+  VMSTAT_COMPACT_DAEMON_FREE_SCANNED = 99,
+  VMSTAT_COMPACT_DAEMON_MIGRATE_SCANNED = 100,
+  VMSTAT_NR_FASTRPC = 101,
+  VMSTAT_NR_INDIRECTLY_RECLAIMABLE = 102,
+  VMSTAT_NR_ION_HEAP_POOL = 103,
+  VMSTAT_NR_KERNEL_MISC_RECLAIMABLE = 104,
+  VMSTAT_NR_SHADOW_CALL_STACK_BYTES = 105,
+  VMSTAT_NR_SHMEM_HUGEPAGES = 106,
+  VMSTAT_NR_SHMEM_PMDMAPPED = 107,
+  VMSTAT_NR_UNRECLAIMABLE_PAGES = 108,
+  VMSTAT_NR_ZONE_ACTIVE_ANON = 109,
+  VMSTAT_NR_ZONE_ACTIVE_FILE = 110,
+  VMSTAT_NR_ZONE_INACTIVE_ANON = 111,
+  VMSTAT_NR_ZONE_INACTIVE_FILE = 112,
+  VMSTAT_NR_ZONE_UNEVICTABLE = 113,
+  VMSTAT_NR_ZONE_WRITE_PENDING = 114,
+  VMSTAT_OOM_KILL = 115,
+  VMSTAT_PGLAZYFREE = 116,
+  VMSTAT_PGLAZYFREED = 117,
+  VMSTAT_PGREFILL = 118,
+  VMSTAT_PGSCAN_DIRECT = 119,
+  VMSTAT_PGSCAN_KSWAPD = 120,
+  VMSTAT_PGSKIP_DMA = 121,
+  VMSTAT_PGSKIP_MOVABLE = 122,
+  VMSTAT_PGSKIP_NORMAL = 123,
+  VMSTAT_PGSTEAL_DIRECT = 124,
+  VMSTAT_PGSTEAL_KSWAPD = 125,
+  VMSTAT_SWAP_RA = 126,
+  VMSTAT_SWAP_RA_HIT = 127,
+  VMSTAT_WORKINGSET_RESTORE = 128,
+  VMSTAT_ALLOCSTALL_DEVICE = 129,
+  VMSTAT_ALLOCSTALL_DMA32 = 130,
+  VMSTAT_BALLOON_DEFLATE = 131,
+  VMSTAT_BALLOON_INFLATE = 132,
+  VMSTAT_BALLOON_MIGRATE = 133,
+  VMSTAT_CMA_ALLOC_FAIL = 134,
+  VMSTAT_CMA_ALLOC_SUCCESS = 135,
+  VMSTAT_NR_FILE_HUGEPAGES = 136,
+  VMSTAT_NR_FILE_PMDMAPPED = 137,
+  VMSTAT_NR_FOLL_PIN_ACQUIRED = 138,
+  VMSTAT_NR_FOLL_PIN_RELEASED = 139,
+  VMSTAT_NR_SEC_PAGE_TABLE_PAGES = 140,
+  VMSTAT_NR_SHADOW_CALL_STACK = 141,
+  VMSTAT_NR_SWAPCACHED = 142,
+  VMSTAT_NR_THROTTLED_WRITTEN = 143,
+  VMSTAT_PGALLOC_DEVICE = 144,
+  VMSTAT_PGALLOC_DMA32 = 145,
+  VMSTAT_PGDEMOTE_DIRECT = 146,
+  VMSTAT_PGDEMOTE_KSWAPD = 147,
+  VMSTAT_PGREUSE = 148,
+  VMSTAT_PGSCAN_ANON = 149,
+  VMSTAT_PGSCAN_FILE = 150,
+  VMSTAT_PGSKIP_DEVICE = 151,
+  VMSTAT_PGSKIP_DMA32 = 152,
+  VMSTAT_PGSTEAL_ANON = 153,
+  VMSTAT_PGSTEAL_FILE = 154,
+  VMSTAT_THP_COLLAPSE_ALLOC = 155,
+  VMSTAT_THP_COLLAPSE_ALLOC_FAILED = 156,
+  VMSTAT_THP_DEFERRED_SPLIT_PAGE = 157,
+  VMSTAT_THP_FAULT_ALLOC = 158,
+  VMSTAT_THP_FAULT_FALLBACK = 159,
+  VMSTAT_THP_FAULT_FALLBACK_CHARGE = 160,
+  VMSTAT_THP_FILE_ALLOC = 161,
+  VMSTAT_THP_FILE_FALLBACK = 162,
+  VMSTAT_THP_FILE_FALLBACK_CHARGE = 163,
+  VMSTAT_THP_FILE_MAPPED = 164,
+  VMSTAT_THP_MIGRATION_FAIL = 165,
+  VMSTAT_THP_MIGRATION_SPLIT = 166,
+  VMSTAT_THP_MIGRATION_SUCCESS = 167,
+  VMSTAT_THP_SCAN_EXCEED_NONE_PTE = 168,
+  VMSTAT_THP_SCAN_EXCEED_SHARE_PTE = 169,
+  VMSTAT_THP_SCAN_EXCEED_SWAP_PTE = 170,
+  VMSTAT_THP_SPLIT_PAGE = 171,
+  VMSTAT_THP_SPLIT_PAGE_FAILED = 172,
+  VMSTAT_THP_SPLIT_PMD = 173,
+  VMSTAT_THP_SWPOUT = 174,
+  VMSTAT_THP_SWPOUT_FALLBACK = 175,
+  VMSTAT_THP_ZERO_PAGE_ALLOC = 176,
+  VMSTAT_THP_ZERO_PAGE_ALLOC_FAILED = 177,
+  VMSTAT_VMA_LOCK_ABORT = 178,
+  VMSTAT_VMA_LOCK_MISS = 179,
+  VMSTAT_VMA_LOCK_RETRY = 180,
+  VMSTAT_VMA_LOCK_SUCCESS = 181,
+  VMSTAT_WORKINGSET_ACTIVATE_ANON = 182,
+  VMSTAT_WORKINGSET_ACTIVATE_FILE = 183,
+  VMSTAT_WORKINGSET_NODES = 184,
+  VMSTAT_WORKINGSET_REFAULT_ANON = 185,
+  VMSTAT_WORKINGSET_REFAULT_FILE = 186,
+  VMSTAT_WORKINGSET_RESTORE_ANON = 187,
+  VMSTAT_WORKINGSET_RESTORE_FILE = 188,
+};
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_SYS_STATS_COUNTERS_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/common/trace_stats.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACE_STATS_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACE_STATS_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class TraceStats;
+class TraceStats_FilterStats;
+class TraceStats_WriterStats;
+class TraceStats_BufferStats;
+enum TraceStats_FinalFlushOutcome : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum TraceStats_FinalFlushOutcome : int {
+  TraceStats_FinalFlushOutcome_FINAL_FLUSH_UNSPECIFIED = 0,
+  TraceStats_FinalFlushOutcome_FINAL_FLUSH_SUCCEEDED = 1,
+  TraceStats_FinalFlushOutcome_FINAL_FLUSH_FAILED = 2,
+};
+
+class PERFETTO_EXPORT_COMPONENT TraceStats : public ::protozero::CppMessageObj {
+ public:
+  using BufferStats = TraceStats_BufferStats;
+  using WriterStats = TraceStats_WriterStats;
+  using FilterStats = TraceStats_FilterStats;
+  using FinalFlushOutcome = TraceStats_FinalFlushOutcome;
+  static constexpr auto FINAL_FLUSH_UNSPECIFIED = TraceStats_FinalFlushOutcome_FINAL_FLUSH_UNSPECIFIED;
+  static constexpr auto FINAL_FLUSH_SUCCEEDED = TraceStats_FinalFlushOutcome_FINAL_FLUSH_SUCCEEDED;
+  static constexpr auto FINAL_FLUSH_FAILED = TraceStats_FinalFlushOutcome_FINAL_FLUSH_FAILED;
+  static constexpr auto FinalFlushOutcome_MIN = TraceStats_FinalFlushOutcome_FINAL_FLUSH_UNSPECIFIED;
+  static constexpr auto FinalFlushOutcome_MAX = TraceStats_FinalFlushOutcome_FINAL_FLUSH_FAILED;
+  enum FieldNumbers {
+    kBufferStatsFieldNumber = 1,
+    kChunkPayloadHistogramDefFieldNumber = 17,
+    kWriterStatsFieldNumber = 18,
+    kProducersConnectedFieldNumber = 2,
+    kProducersSeenFieldNumber = 3,
+    kDataSourcesRegisteredFieldNumber = 4,
+    kDataSourcesSeenFieldNumber = 5,
+    kTracingSessionsFieldNumber = 6,
+    kTotalBuffersFieldNumber = 7,
+    kChunksDiscardedFieldNumber = 8,
+    kPatchesDiscardedFieldNumber = 9,
+    kInvalidPacketsFieldNumber = 10,
+    kFilterStatsFieldNumber = 11,
+    kFlushesRequestedFieldNumber = 12,
+    kFlushesSucceededFieldNumber = 13,
+    kFlushesFailedFieldNumber = 14,
+    kFinalFlushOutcomeFieldNumber = 15,
+  };
+
+  TraceStats();
+  ~TraceStats() override;
+  TraceStats(TraceStats&&) noexcept;
+  TraceStats& operator=(TraceStats&&);
+  TraceStats(const TraceStats&);
+  TraceStats& operator=(const TraceStats&);
+  bool operator==(const TraceStats&) const;
+  bool operator!=(const TraceStats& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<TraceStats_BufferStats>& buffer_stats() const { return buffer_stats_; }
+  std::vector<TraceStats_BufferStats>* mutable_buffer_stats() { return &buffer_stats_; }
+  int buffer_stats_size() const;
+  void clear_buffer_stats();
+  TraceStats_BufferStats* add_buffer_stats();
+
+  const std::vector<int64_t>& chunk_payload_histogram_def() const { return chunk_payload_histogram_def_; }
+  std::vector<int64_t>* mutable_chunk_payload_histogram_def() { return &chunk_payload_histogram_def_; }
+  int chunk_payload_histogram_def_size() const { return static_cast<int>(chunk_payload_histogram_def_.size()); }
+  void clear_chunk_payload_histogram_def() { chunk_payload_histogram_def_.clear(); }
+  void add_chunk_payload_histogram_def(int64_t value) { chunk_payload_histogram_def_.emplace_back(value); }
+  int64_t* add_chunk_payload_histogram_def() { chunk_payload_histogram_def_.emplace_back(); return &chunk_payload_histogram_def_.back(); }
+
+  const std::vector<TraceStats_WriterStats>& writer_stats() const { return writer_stats_; }
+  std::vector<TraceStats_WriterStats>* mutable_writer_stats() { return &writer_stats_; }
+  int writer_stats_size() const;
+  void clear_writer_stats();
+  TraceStats_WriterStats* add_writer_stats();
+
+  bool has_producers_connected() const { return _has_field_[2]; }
+  uint32_t producers_connected() const { return producers_connected_; }
+  void set_producers_connected(uint32_t value) { producers_connected_ = value; _has_field_.set(2); }
+
+  bool has_producers_seen() const { return _has_field_[3]; }
+  uint64_t producers_seen() const { return producers_seen_; }
+  void set_producers_seen(uint64_t value) { producers_seen_ = value; _has_field_.set(3); }
+
+  bool has_data_sources_registered() const { return _has_field_[4]; }
+  uint32_t data_sources_registered() const { return data_sources_registered_; }
+  void set_data_sources_registered(uint32_t value) { data_sources_registered_ = value; _has_field_.set(4); }
+
+  bool has_data_sources_seen() const { return _has_field_[5]; }
+  uint64_t data_sources_seen() const { return data_sources_seen_; }
+  void set_data_sources_seen(uint64_t value) { data_sources_seen_ = value; _has_field_.set(5); }
+
+  bool has_tracing_sessions() const { return _has_field_[6]; }
+  uint32_t tracing_sessions() const { return tracing_sessions_; }
+  void set_tracing_sessions(uint32_t value) { tracing_sessions_ = value; _has_field_.set(6); }
+
+  bool has_total_buffers() const { return _has_field_[7]; }
+  uint32_t total_buffers() const { return total_buffers_; }
+  void set_total_buffers(uint32_t value) { total_buffers_ = value; _has_field_.set(7); }
+
+  bool has_chunks_discarded() const { return _has_field_[8]; }
+  uint64_t chunks_discarded() const { return chunks_discarded_; }
+  void set_chunks_discarded(uint64_t value) { chunks_discarded_ = value; _has_field_.set(8); }
+
+  bool has_patches_discarded() const { return _has_field_[9]; }
+  uint64_t patches_discarded() const { return patches_discarded_; }
+  void set_patches_discarded(uint64_t value) { patches_discarded_ = value; _has_field_.set(9); }
+
+  bool has_invalid_packets() const { return _has_field_[10]; }
+  uint64_t invalid_packets() const { return invalid_packets_; }
+  void set_invalid_packets(uint64_t value) { invalid_packets_ = value; _has_field_.set(10); }
+
+  bool has_filter_stats() const { return _has_field_[11]; }
+  const TraceStats_FilterStats& filter_stats() const { return *filter_stats_; }
+  TraceStats_FilterStats* mutable_filter_stats() { _has_field_.set(11); return filter_stats_.get(); }
+
+  bool has_flushes_requested() const { return _has_field_[12]; }
+  uint64_t flushes_requested() const { return flushes_requested_; }
+  void set_flushes_requested(uint64_t value) { flushes_requested_ = value; _has_field_.set(12); }
+
+  bool has_flushes_succeeded() const { return _has_field_[13]; }
+  uint64_t flushes_succeeded() const { return flushes_succeeded_; }
+  void set_flushes_succeeded(uint64_t value) { flushes_succeeded_ = value; _has_field_.set(13); }
+
+  bool has_flushes_failed() const { return _has_field_[14]; }
+  uint64_t flushes_failed() const { return flushes_failed_; }
+  void set_flushes_failed(uint64_t value) { flushes_failed_ = value; _has_field_.set(14); }
+
+  bool has_final_flush_outcome() const { return _has_field_[15]; }
+  TraceStats_FinalFlushOutcome final_flush_outcome() const { return final_flush_outcome_; }
+  void set_final_flush_outcome(TraceStats_FinalFlushOutcome value) { final_flush_outcome_ = value; _has_field_.set(15); }
+
+ private:
+  std::vector<TraceStats_BufferStats> buffer_stats_;
+  std::vector<int64_t> chunk_payload_histogram_def_;
+  std::vector<TraceStats_WriterStats> writer_stats_;
+  uint32_t producers_connected_{};
+  uint64_t producers_seen_{};
+  uint32_t data_sources_registered_{};
+  uint64_t data_sources_seen_{};
+  uint32_t tracing_sessions_{};
+  uint32_t total_buffers_{};
+  uint64_t chunks_discarded_{};
+  uint64_t patches_discarded_{};
+  uint64_t invalid_packets_{};
+  ::protozero::CopyablePtr<TraceStats_FilterStats> filter_stats_;
+  uint64_t flushes_requested_{};
+  uint64_t flushes_succeeded_{};
+  uint64_t flushes_failed_{};
+  TraceStats_FinalFlushOutcome final_flush_outcome_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<19> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TraceStats_FilterStats : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kInputPacketsFieldNumber = 1,
+    kInputBytesFieldNumber = 2,
+    kOutputBytesFieldNumber = 3,
+    kErrorsFieldNumber = 4,
+    kTimeTakenNsFieldNumber = 5,
+    kBytesDiscardedPerBufferFieldNumber = 20,
+  };
+
+  TraceStats_FilterStats();
+  ~TraceStats_FilterStats() override;
+  TraceStats_FilterStats(TraceStats_FilterStats&&) noexcept;
+  TraceStats_FilterStats& operator=(TraceStats_FilterStats&&);
+  TraceStats_FilterStats(const TraceStats_FilterStats&);
+  TraceStats_FilterStats& operator=(const TraceStats_FilterStats&);
+  bool operator==(const TraceStats_FilterStats&) const;
+  bool operator!=(const TraceStats_FilterStats& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_input_packets() const { return _has_field_[1]; }
+  uint64_t input_packets() const { return input_packets_; }
+  void set_input_packets(uint64_t value) { input_packets_ = value; _has_field_.set(1); }
+
+  bool has_input_bytes() const { return _has_field_[2]; }
+  uint64_t input_bytes() const { return input_bytes_; }
+  void set_input_bytes(uint64_t value) { input_bytes_ = value; _has_field_.set(2); }
+
+  bool has_output_bytes() const { return _has_field_[3]; }
+  uint64_t output_bytes() const { return output_bytes_; }
+  void set_output_bytes(uint64_t value) { output_bytes_ = value; _has_field_.set(3); }
+
+  bool has_errors() const { return _has_field_[4]; }
+  uint64_t errors() const { return errors_; }
+  void set_errors(uint64_t value) { errors_ = value; _has_field_.set(4); }
+
+  bool has_time_taken_ns() const { return _has_field_[5]; }
+  uint64_t time_taken_ns() const { return time_taken_ns_; }
+  void set_time_taken_ns(uint64_t value) { time_taken_ns_ = value; _has_field_.set(5); }
+
+  const std::vector<uint64_t>& bytes_discarded_per_buffer() const { return bytes_discarded_per_buffer_; }
+  std::vector<uint64_t>* mutable_bytes_discarded_per_buffer() { return &bytes_discarded_per_buffer_; }
+  int bytes_discarded_per_buffer_size() const { return static_cast<int>(bytes_discarded_per_buffer_.size()); }
+  void clear_bytes_discarded_per_buffer() { bytes_discarded_per_buffer_.clear(); }
+  void add_bytes_discarded_per_buffer(uint64_t value) { bytes_discarded_per_buffer_.emplace_back(value); }
+  uint64_t* add_bytes_discarded_per_buffer() { bytes_discarded_per_buffer_.emplace_back(); return &bytes_discarded_per_buffer_.back(); }
+
+ private:
+  uint64_t input_packets_{};
+  uint64_t input_bytes_{};
+  uint64_t output_bytes_{};
+  uint64_t errors_{};
+  uint64_t time_taken_ns_{};
+  std::vector<uint64_t> bytes_discarded_per_buffer_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<21> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TraceStats_WriterStats : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kSequenceIdFieldNumber = 1,
+    kBufferFieldNumber = 4,
+    kChunkPayloadHistogramCountsFieldNumber = 2,
+    kChunkPayloadHistogramSumFieldNumber = 3,
+  };
+
+  TraceStats_WriterStats();
+  ~TraceStats_WriterStats() override;
+  TraceStats_WriterStats(TraceStats_WriterStats&&) noexcept;
+  TraceStats_WriterStats& operator=(TraceStats_WriterStats&&);
+  TraceStats_WriterStats(const TraceStats_WriterStats&);
+  TraceStats_WriterStats& operator=(const TraceStats_WriterStats&);
+  bool operator==(const TraceStats_WriterStats&) const;
+  bool operator!=(const TraceStats_WriterStats& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_sequence_id() const { return _has_field_[1]; }
+  uint64_t sequence_id() const { return sequence_id_; }
+  void set_sequence_id(uint64_t value) { sequence_id_ = value; _has_field_.set(1); }
+
+  bool has_buffer() const { return _has_field_[4]; }
+  uint32_t buffer() const { return buffer_; }
+  void set_buffer(uint32_t value) { buffer_ = value; _has_field_.set(4); }
+
+  const std::vector<uint64_t>& chunk_payload_histogram_counts() const { return chunk_payload_histogram_counts_; }
+  std::vector<uint64_t>* mutable_chunk_payload_histogram_counts() { return &chunk_payload_histogram_counts_; }
+  int chunk_payload_histogram_counts_size() const { return static_cast<int>(chunk_payload_histogram_counts_.size()); }
+  void clear_chunk_payload_histogram_counts() { chunk_payload_histogram_counts_.clear(); }
+  void add_chunk_payload_histogram_counts(uint64_t value) { chunk_payload_histogram_counts_.emplace_back(value); }
+  uint64_t* add_chunk_payload_histogram_counts() { chunk_payload_histogram_counts_.emplace_back(); return &chunk_payload_histogram_counts_.back(); }
+
+  const std::vector<int64_t>& chunk_payload_histogram_sum() const { return chunk_payload_histogram_sum_; }
+  std::vector<int64_t>* mutable_chunk_payload_histogram_sum() { return &chunk_payload_histogram_sum_; }
+  int chunk_payload_histogram_sum_size() const { return static_cast<int>(chunk_payload_histogram_sum_.size()); }
+  void clear_chunk_payload_histogram_sum() { chunk_payload_histogram_sum_.clear(); }
+  void add_chunk_payload_histogram_sum(int64_t value) { chunk_payload_histogram_sum_.emplace_back(value); }
+  int64_t* add_chunk_payload_histogram_sum() { chunk_payload_histogram_sum_.emplace_back(); return &chunk_payload_histogram_sum_.back(); }
+
+ private:
+  uint64_t sequence_id_{};
+  uint32_t buffer_{};
+  std::vector<uint64_t> chunk_payload_histogram_counts_;
+  std::vector<int64_t> chunk_payload_histogram_sum_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<5> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TraceStats_BufferStats : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kBufferSizeFieldNumber = 12,
+    kBytesWrittenFieldNumber = 1,
+    kBytesOverwrittenFieldNumber = 13,
+    kBytesReadFieldNumber = 14,
+    kPaddingBytesWrittenFieldNumber = 15,
+    kPaddingBytesClearedFieldNumber = 16,
+    kChunksWrittenFieldNumber = 2,
+    kChunksRewrittenFieldNumber = 10,
+    kChunksOverwrittenFieldNumber = 3,
+    kChunksDiscardedFieldNumber = 18,
+    kChunksReadFieldNumber = 17,
+    kChunksCommittedOutOfOrderFieldNumber = 11,
+    kWriteWrapCountFieldNumber = 4,
+    kPatchesSucceededFieldNumber = 5,
+    kPatchesFailedFieldNumber = 6,
+    kReadaheadsSucceededFieldNumber = 7,
+    kReadaheadsFailedFieldNumber = 8,
+    kAbiViolationsFieldNumber = 9,
+    kTraceWriterPacketLossFieldNumber = 19,
+  };
+
+  TraceStats_BufferStats();
+  ~TraceStats_BufferStats() override;
+  TraceStats_BufferStats(TraceStats_BufferStats&&) noexcept;
+  TraceStats_BufferStats& operator=(TraceStats_BufferStats&&);
+  TraceStats_BufferStats(const TraceStats_BufferStats&);
+  TraceStats_BufferStats& operator=(const TraceStats_BufferStats&);
+  bool operator==(const TraceStats_BufferStats&) const;
+  bool operator!=(const TraceStats_BufferStats& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_buffer_size() const { return _has_field_[12]; }
+  uint64_t buffer_size() const { return buffer_size_; }
+  void set_buffer_size(uint64_t value) { buffer_size_ = value; _has_field_.set(12); }
+
+  bool has_bytes_written() const { return _has_field_[1]; }
+  uint64_t bytes_written() const { return bytes_written_; }
+  void set_bytes_written(uint64_t value) { bytes_written_ = value; _has_field_.set(1); }
+
+  bool has_bytes_overwritten() const { return _has_field_[13]; }
+  uint64_t bytes_overwritten() const { return bytes_overwritten_; }
+  void set_bytes_overwritten(uint64_t value) { bytes_overwritten_ = value; _has_field_.set(13); }
+
+  bool has_bytes_read() const { return _has_field_[14]; }
+  uint64_t bytes_read() const { return bytes_read_; }
+  void set_bytes_read(uint64_t value) { bytes_read_ = value; _has_field_.set(14); }
+
+  bool has_padding_bytes_written() const { return _has_field_[15]; }
+  uint64_t padding_bytes_written() const { return padding_bytes_written_; }
+  void set_padding_bytes_written(uint64_t value) { padding_bytes_written_ = value; _has_field_.set(15); }
+
+  bool has_padding_bytes_cleared() const { return _has_field_[16]; }
+  uint64_t padding_bytes_cleared() const { return padding_bytes_cleared_; }
+  void set_padding_bytes_cleared(uint64_t value) { padding_bytes_cleared_ = value; _has_field_.set(16); }
+
+  bool has_chunks_written() const { return _has_field_[2]; }
+  uint64_t chunks_written() const { return chunks_written_; }
+  void set_chunks_written(uint64_t value) { chunks_written_ = value; _has_field_.set(2); }
+
+  bool has_chunks_rewritten() const { return _has_field_[10]; }
+  uint64_t chunks_rewritten() const { return chunks_rewritten_; }
+  void set_chunks_rewritten(uint64_t value) { chunks_rewritten_ = value; _has_field_.set(10); }
+
+  bool has_chunks_overwritten() const { return _has_field_[3]; }
+  uint64_t chunks_overwritten() const { return chunks_overwritten_; }
+  void set_chunks_overwritten(uint64_t value) { chunks_overwritten_ = value; _has_field_.set(3); }
+
+  bool has_chunks_discarded() const { return _has_field_[18]; }
+  uint64_t chunks_discarded() const { return chunks_discarded_; }
+  void set_chunks_discarded(uint64_t value) { chunks_discarded_ = value; _has_field_.set(18); }
+
+  bool has_chunks_read() const { return _has_field_[17]; }
+  uint64_t chunks_read() const { return chunks_read_; }
+  void set_chunks_read(uint64_t value) { chunks_read_ = value; _has_field_.set(17); }
+
+  bool has_chunks_committed_out_of_order() const { return _has_field_[11]; }
+  uint64_t chunks_committed_out_of_order() const { return chunks_committed_out_of_order_; }
+  void set_chunks_committed_out_of_order(uint64_t value) { chunks_committed_out_of_order_ = value; _has_field_.set(11); }
+
+  bool has_write_wrap_count() const { return _has_field_[4]; }
+  uint64_t write_wrap_count() const { return write_wrap_count_; }
+  void set_write_wrap_count(uint64_t value) { write_wrap_count_ = value; _has_field_.set(4); }
+
+  bool has_patches_succeeded() const { return _has_field_[5]; }
+  uint64_t patches_succeeded() const { return patches_succeeded_; }
+  void set_patches_succeeded(uint64_t value) { patches_succeeded_ = value; _has_field_.set(5); }
+
+  bool has_patches_failed() const { return _has_field_[6]; }
+  uint64_t patches_failed() const { return patches_failed_; }
+  void set_patches_failed(uint64_t value) { patches_failed_ = value; _has_field_.set(6); }
+
+  bool has_readaheads_succeeded() const { return _has_field_[7]; }
+  uint64_t readaheads_succeeded() const { return readaheads_succeeded_; }
+  void set_readaheads_succeeded(uint64_t value) { readaheads_succeeded_ = value; _has_field_.set(7); }
+
+  bool has_readaheads_failed() const { return _has_field_[8]; }
+  uint64_t readaheads_failed() const { return readaheads_failed_; }
+  void set_readaheads_failed(uint64_t value) { readaheads_failed_ = value; _has_field_.set(8); }
+
+  bool has_abi_violations() const { return _has_field_[9]; }
+  uint64_t abi_violations() const { return abi_violations_; }
+  void set_abi_violations(uint64_t value) { abi_violations_ = value; _has_field_.set(9); }
+
+  bool has_trace_writer_packet_loss() const { return _has_field_[19]; }
+  uint64_t trace_writer_packet_loss() const { return trace_writer_packet_loss_; }
+  void set_trace_writer_packet_loss(uint64_t value) { trace_writer_packet_loss_ = value; _has_field_.set(19); }
+
+ private:
+  uint64_t buffer_size_{};
+  uint64_t bytes_written_{};
+  uint64_t bytes_overwritten_{};
+  uint64_t bytes_read_{};
+  uint64_t padding_bytes_written_{};
+  uint64_t padding_bytes_cleared_{};
+  uint64_t chunks_written_{};
+  uint64_t chunks_rewritten_{};
+  uint64_t chunks_overwritten_{};
+  uint64_t chunks_discarded_{};
+  uint64_t chunks_read_{};
+  uint64_t chunks_committed_out_of_order_{};
+  uint64_t write_wrap_count_{};
+  uint64_t patches_succeeded_{};
+  uint64_t patches_failed_{};
+  uint64_t readaheads_succeeded_{};
+  uint64_t readaheads_failed_{};
+  uint64_t abi_violations_{};
+  uint64_t trace_writer_packet_loss_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<20> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACE_STATS_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/common/tracing_service_capabilities.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_CAPABILITIES_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_CAPABILITIES_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class TracingServiceCapabilities;
+enum ObservableEvents_Type : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT TracingServiceCapabilities : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kHasQueryCapabilitiesFieldNumber = 1,
+    kObservableEventsFieldNumber = 2,
+    kHasTraceConfigOutputPathFieldNumber = 3,
+    kHasCloneSessionFieldNumber = 4,
+  };
+
+  TracingServiceCapabilities();
+  ~TracingServiceCapabilities() override;
+  TracingServiceCapabilities(TracingServiceCapabilities&&) noexcept;
+  TracingServiceCapabilities& operator=(TracingServiceCapabilities&&);
+  TracingServiceCapabilities(const TracingServiceCapabilities&);
+  TracingServiceCapabilities& operator=(const TracingServiceCapabilities&);
+  bool operator==(const TracingServiceCapabilities&) const;
+  bool operator!=(const TracingServiceCapabilities& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_has_query_capabilities() const { return _has_field_[1]; }
+  bool has_query_capabilities() const { return has_query_capabilities_; }
+  void set_has_query_capabilities(bool value) { has_query_capabilities_ = value; _has_field_.set(1); }
+
+  const std::vector<ObservableEvents_Type>& observable_events() const { return observable_events_; }
+  std::vector<ObservableEvents_Type>* mutable_observable_events() { return &observable_events_; }
+  int observable_events_size() const { return static_cast<int>(observable_events_.size()); }
+  void clear_observable_events() { observable_events_.clear(); }
+  void add_observable_events(ObservableEvents_Type value) { observable_events_.emplace_back(value); }
+  ObservableEvents_Type* add_observable_events() { observable_events_.emplace_back(); return &observable_events_.back(); }
+
+  bool has_has_trace_config_output_path() const { return _has_field_[3]; }
+  bool has_trace_config_output_path() const { return has_trace_config_output_path_; }
+  void set_has_trace_config_output_path(bool value) { has_trace_config_output_path_ = value; _has_field_.set(3); }
+
+  bool has_has_clone_session() const { return _has_field_[4]; }
+  bool has_clone_session() const { return has_clone_session_; }
+  void set_has_clone_session(bool value) { has_clone_session_ = value; _has_field_.set(4); }
+
+ private:
+  bool has_query_capabilities_{};
+  std::vector<ObservableEvents_Type> observable_events_;
+  bool has_trace_config_output_path_{};
+  bool has_clone_session_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<5> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_CAPABILITIES_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/common/tracing_service_state.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_STATE_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_STATE_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class TracingServiceState;
+class TracingServiceState_TracingSession;
+class TracingServiceState_DataSource;
+class DataSourceDescriptor;
+class TracingServiceState_Producer;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT TracingServiceState : public ::protozero::CppMessageObj {
+ public:
+  using Producer = TracingServiceState_Producer;
+  using DataSource = TracingServiceState_DataSource;
+  using TracingSession = TracingServiceState_TracingSession;
+  enum FieldNumbers {
+    kProducersFieldNumber = 1,
+    kDataSourcesFieldNumber = 2,
+    kTracingSessionsFieldNumber = 6,
+    kSupportsTracingSessionsFieldNumber = 7,
+    kNumSessionsFieldNumber = 3,
+    kNumSessionsStartedFieldNumber = 4,
+    kTracingServiceVersionFieldNumber = 5,
+  };
+
+  TracingServiceState();
+  ~TracingServiceState() override;
+  TracingServiceState(TracingServiceState&&) noexcept;
+  TracingServiceState& operator=(TracingServiceState&&);
+  TracingServiceState(const TracingServiceState&);
+  TracingServiceState& operator=(const TracingServiceState&);
+  bool operator==(const TracingServiceState&) const;
+  bool operator!=(const TracingServiceState& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<TracingServiceState_Producer>& producers() const { return producers_; }
+  std::vector<TracingServiceState_Producer>* mutable_producers() { return &producers_; }
+  int producers_size() const;
+  void clear_producers();
+  TracingServiceState_Producer* add_producers();
+
+  const std::vector<TracingServiceState_DataSource>& data_sources() const { return data_sources_; }
+  std::vector<TracingServiceState_DataSource>* mutable_data_sources() { return &data_sources_; }
+  int data_sources_size() const;
+  void clear_data_sources();
+  TracingServiceState_DataSource* add_data_sources();
+
+  const std::vector<TracingServiceState_TracingSession>& tracing_sessions() const { return tracing_sessions_; }
+  std::vector<TracingServiceState_TracingSession>* mutable_tracing_sessions() { return &tracing_sessions_; }
+  int tracing_sessions_size() const;
+  void clear_tracing_sessions();
+  TracingServiceState_TracingSession* add_tracing_sessions();
+
+  bool has_supports_tracing_sessions() const { return _has_field_[7]; }
+  bool supports_tracing_sessions() const { return supports_tracing_sessions_; }
+  void set_supports_tracing_sessions(bool value) { supports_tracing_sessions_ = value; _has_field_.set(7); }
+
+  bool has_num_sessions() const { return _has_field_[3]; }
+  int32_t num_sessions() const { return num_sessions_; }
+  void set_num_sessions(int32_t value) { num_sessions_ = value; _has_field_.set(3); }
+
+  bool has_num_sessions_started() const { return _has_field_[4]; }
+  int32_t num_sessions_started() const { return num_sessions_started_; }
+  void set_num_sessions_started(int32_t value) { num_sessions_started_ = value; _has_field_.set(4); }
+
+  bool has_tracing_service_version() const { return _has_field_[5]; }
+  const std::string& tracing_service_version() const { return tracing_service_version_; }
+  void set_tracing_service_version(const std::string& value) { tracing_service_version_ = value; _has_field_.set(5); }
+
+ private:
+  std::vector<TracingServiceState_Producer> producers_;
+  std::vector<TracingServiceState_DataSource> data_sources_;
+  std::vector<TracingServiceState_TracingSession> tracing_sessions_;
+  bool supports_tracing_sessions_{};
+  int32_t num_sessions_{};
+  int32_t num_sessions_started_{};
+  std::string tracing_service_version_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<8> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TracingServiceState_TracingSession : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kIdFieldNumber = 1,
+    kConsumerUidFieldNumber = 2,
+    kStateFieldNumber = 3,
+    kUniqueSessionNameFieldNumber = 4,
+    kBufferSizeKbFieldNumber = 5,
+    kDurationMsFieldNumber = 6,
+    kNumDataSourcesFieldNumber = 7,
+    kStartRealtimeNsFieldNumber = 8,
+    kBugreportScoreFieldNumber = 9,
+    kBugreportFilenameFieldNumber = 10,
+    kIsStartedFieldNumber = 11,
+  };
+
+  TracingServiceState_TracingSession();
+  ~TracingServiceState_TracingSession() override;
+  TracingServiceState_TracingSession(TracingServiceState_TracingSession&&) noexcept;
+  TracingServiceState_TracingSession& operator=(TracingServiceState_TracingSession&&);
+  TracingServiceState_TracingSession(const TracingServiceState_TracingSession&);
+  TracingServiceState_TracingSession& operator=(const TracingServiceState_TracingSession&);
+  bool operator==(const TracingServiceState_TracingSession&) const;
+  bool operator!=(const TracingServiceState_TracingSession& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_id() const { return _has_field_[1]; }
+  uint64_t id() const { return id_; }
+  void set_id(uint64_t value) { id_ = value; _has_field_.set(1); }
+
+  bool has_consumer_uid() const { return _has_field_[2]; }
+  int32_t consumer_uid() const { return consumer_uid_; }
+  void set_consumer_uid(int32_t value) { consumer_uid_ = value; _has_field_.set(2); }
+
+  bool has_state() const { return _has_field_[3]; }
+  const std::string& state() const { return state_; }
+  void set_state(const std::string& value) { state_ = value; _has_field_.set(3); }
+
+  bool has_unique_session_name() const { return _has_field_[4]; }
+  const std::string& unique_session_name() const { return unique_session_name_; }
+  void set_unique_session_name(const std::string& value) { unique_session_name_ = value; _has_field_.set(4); }
+
+  const std::vector<uint32_t>& buffer_size_kb() const { return buffer_size_kb_; }
+  std::vector<uint32_t>* mutable_buffer_size_kb() { return &buffer_size_kb_; }
+  int buffer_size_kb_size() const { return static_cast<int>(buffer_size_kb_.size()); }
+  void clear_buffer_size_kb() { buffer_size_kb_.clear(); }
+  void add_buffer_size_kb(uint32_t value) { buffer_size_kb_.emplace_back(value); }
+  uint32_t* add_buffer_size_kb() { buffer_size_kb_.emplace_back(); return &buffer_size_kb_.back(); }
+
+  bool has_duration_ms() const { return _has_field_[6]; }
+  uint32_t duration_ms() const { return duration_ms_; }
+  void set_duration_ms(uint32_t value) { duration_ms_ = value; _has_field_.set(6); }
+
+  bool has_num_data_sources() const { return _has_field_[7]; }
+  uint32_t num_data_sources() const { return num_data_sources_; }
+  void set_num_data_sources(uint32_t value) { num_data_sources_ = value; _has_field_.set(7); }
+
+  bool has_start_realtime_ns() const { return _has_field_[8]; }
+  int64_t start_realtime_ns() const { return start_realtime_ns_; }
+  void set_start_realtime_ns(int64_t value) { start_realtime_ns_ = value; _has_field_.set(8); }
+
+  bool has_bugreport_score() const { return _has_field_[9]; }
+  int32_t bugreport_score() const { return bugreport_score_; }
+  void set_bugreport_score(int32_t value) { bugreport_score_ = value; _has_field_.set(9); }
+
+  bool has_bugreport_filename() const { return _has_field_[10]; }
+  const std::string& bugreport_filename() const { return bugreport_filename_; }
+  void set_bugreport_filename(const std::string& value) { bugreport_filename_ = value; _has_field_.set(10); }
+
+  bool has_is_started() const { return _has_field_[11]; }
+  bool is_started() const { return is_started_; }
+  void set_is_started(bool value) { is_started_ = value; _has_field_.set(11); }
+
+ private:
+  uint64_t id_{};
+  int32_t consumer_uid_{};
+  std::string state_{};
+  std::string unique_session_name_{};
+  std::vector<uint32_t> buffer_size_kb_;
+  uint32_t duration_ms_{};
+  uint32_t num_data_sources_{};
+  int64_t start_realtime_ns_{};
+  int32_t bugreport_score_{};
+  std::string bugreport_filename_{};
+  bool is_started_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<12> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TracingServiceState_DataSource : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDsDescriptorFieldNumber = 1,
+    kProducerIdFieldNumber = 2,
+  };
+
+  TracingServiceState_DataSource();
+  ~TracingServiceState_DataSource() override;
+  TracingServiceState_DataSource(TracingServiceState_DataSource&&) noexcept;
+  TracingServiceState_DataSource& operator=(TracingServiceState_DataSource&&);
+  TracingServiceState_DataSource(const TracingServiceState_DataSource&);
+  TracingServiceState_DataSource& operator=(const TracingServiceState_DataSource&);
+  bool operator==(const TracingServiceState_DataSource&) const;
+  bool operator!=(const TracingServiceState_DataSource& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_ds_descriptor() const { return _has_field_[1]; }
+  const DataSourceDescriptor& ds_descriptor() const { return *ds_descriptor_; }
+  DataSourceDescriptor* mutable_ds_descriptor() { _has_field_.set(1); return ds_descriptor_.get(); }
+
+  bool has_producer_id() const { return _has_field_[2]; }
+  int32_t producer_id() const { return producer_id_; }
+  void set_producer_id(int32_t value) { producer_id_ = value; _has_field_.set(2); }
+
+ private:
+  ::protozero::CopyablePtr<DataSourceDescriptor> ds_descriptor_;
+  int32_t producer_id_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TracingServiceState_Producer : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kIdFieldNumber = 1,
+    kNameFieldNumber = 2,
+    kPidFieldNumber = 5,
+    kUidFieldNumber = 3,
+    kSdkVersionFieldNumber = 4,
+  };
+
+  TracingServiceState_Producer();
+  ~TracingServiceState_Producer() override;
+  TracingServiceState_Producer(TracingServiceState_Producer&&) noexcept;
+  TracingServiceState_Producer& operator=(TracingServiceState_Producer&&);
+  TracingServiceState_Producer(const TracingServiceState_Producer&);
+  TracingServiceState_Producer& operator=(const TracingServiceState_Producer&);
+  bool operator==(const TracingServiceState_Producer&) const;
+  bool operator!=(const TracingServiceState_Producer& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_id() const { return _has_field_[1]; }
+  int32_t id() const { return id_; }
+  void set_id(int32_t value) { id_ = value; _has_field_.set(1); }
+
+  bool has_name() const { return _has_field_[2]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
+
+  bool has_pid() const { return _has_field_[5]; }
+  int32_t pid() const { return pid_; }
+  void set_pid(int32_t value) { pid_ = value; _has_field_.set(5); }
+
+  bool has_uid() const { return _has_field_[3]; }
+  int32_t uid() const { return uid_; }
+  void set_uid(int32_t value) { uid_ = value; _has_field_.set(3); }
+
+  bool has_sdk_version() const { return _has_field_[4]; }
+  const std::string& sdk_version() const { return sdk_version_; }
+  void set_sdk_version(const std::string& value) { sdk_version_ = value; _has_field_.set(4); }
+
+ private:
+  int32_t id_{};
+  std::string name_{};
+  int32_t pid_{};
+  int32_t uid_{};
+  std::string sdk_version_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<6> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_STATE_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/common/track_event_descriptor.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACK_EVENT_DESCRIPTOR_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACK_EVENT_DESCRIPTOR_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class TrackEventDescriptor;
+class TrackEventCategory;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT TrackEventDescriptor : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kAvailableCategoriesFieldNumber = 1,
+  };
+
+  TrackEventDescriptor();
+  ~TrackEventDescriptor() override;
+  TrackEventDescriptor(TrackEventDescriptor&&) noexcept;
+  TrackEventDescriptor& operator=(TrackEventDescriptor&&);
+  TrackEventDescriptor(const TrackEventDescriptor&);
+  TrackEventDescriptor& operator=(const TrackEventDescriptor&);
+  bool operator==(const TrackEventDescriptor&) const;
+  bool operator!=(const TrackEventDescriptor& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<TrackEventCategory>& available_categories() const { return available_categories_; }
+  std::vector<TrackEventCategory>* mutable_available_categories() { return &available_categories_; }
+  int available_categories_size() const;
+  void clear_available_categories();
+  TrackEventCategory* add_available_categories();
+
+ private:
+  std::vector<TrackEventCategory> available_categories_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TrackEventCategory : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kNameFieldNumber = 1,
+    kDescriptionFieldNumber = 2,
+    kTagsFieldNumber = 3,
+  };
+
+  TrackEventCategory();
+  ~TrackEventCategory() override;
+  TrackEventCategory(TrackEventCategory&&) noexcept;
+  TrackEventCategory& operator=(TrackEventCategory&&);
+  TrackEventCategory(const TrackEventCategory&);
+  TrackEventCategory& operator=(const TrackEventCategory&);
+  bool operator==(const TrackEventCategory&) const;
+  bool operator!=(const TrackEventCategory& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name() const { return _has_field_[1]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
+
+  bool has_description() const { return _has_field_[2]; }
+  const std::string& description() const { return description_; }
+  void set_description(const std::string& value) { description_ = value; _has_field_.set(2); }
+
+  const std::vector<std::string>& tags() const { return tags_; }
+  std::vector<std::string>* mutable_tags() { return &tags_; }
+  int tags_size() const { return static_cast<int>(tags_.size()); }
+  void clear_tags() { tags_.clear(); }
+  void add_tags(std::string value) { tags_.emplace_back(value); }
+  std::string* add_tags() { tags_.emplace_back(); return &tags_.back(); }
+
+ private:
+  std::string name_{};
+  std::string description_{};
+  std::vector<std::string> tags_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACK_EVENT_DESCRIPTOR_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/common/android_energy_consumer_descriptor.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_ENERGY_CONSUMER_DESCRIPTOR_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_ENERGY_CONSUMER_DESCRIPTOR_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class AndroidEnergyConsumer;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class AndroidEnergyConsumerDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AndroidEnergyConsumerDescriptor_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidEnergyConsumerDescriptor_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidEnergyConsumerDescriptor_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_energy_consumers() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> energy_consumers() const { return GetRepeated<::protozero::ConstBytes>(1); }
+};
+
+class AndroidEnergyConsumerDescriptor : public ::protozero::Message {
+ public:
+  using Decoder = AndroidEnergyConsumerDescriptor_Decoder;
+  enum : int32_t {
+    kEnergyConsumersFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidEnergyConsumerDescriptor"; }
+
+
+  using FieldMetadata_EnergyConsumers =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidEnergyConsumer,
+      AndroidEnergyConsumerDescriptor>;
+
+  static constexpr FieldMetadata_EnergyConsumers kEnergyConsumers{};
+  template <typename T = AndroidEnergyConsumer> T* add_energy_consumers() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+class AndroidEnergyConsumer_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AndroidEnergyConsumer_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidEnergyConsumer_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidEnergyConsumer_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_energy_consumer_id() const { return at<1>().valid(); }
+  int32_t energy_consumer_id() const { return at<1>().as_int32(); }
+  bool has_ordinal() const { return at<2>().valid(); }
+  int32_t ordinal() const { return at<2>().as_int32(); }
+  bool has_type() const { return at<3>().valid(); }
+  ::protozero::ConstChars type() const { return at<3>().as_string(); }
+  bool has_name() const { return at<4>().valid(); }
+  ::protozero::ConstChars name() const { return at<4>().as_string(); }
+};
+
+class AndroidEnergyConsumer : public ::protozero::Message {
+ public:
+  using Decoder = AndroidEnergyConsumer_Decoder;
+  enum : int32_t {
+    kEnergyConsumerIdFieldNumber = 1,
+    kOrdinalFieldNumber = 2,
+    kTypeFieldNumber = 3,
+    kNameFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidEnergyConsumer"; }
+
+
+  using FieldMetadata_EnergyConsumerId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidEnergyConsumer>;
+
+  static constexpr FieldMetadata_EnergyConsumerId kEnergyConsumerId{};
+  void set_energy_consumer_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EnergyConsumerId::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_Ordinal =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidEnergyConsumer>;
+
+  static constexpr FieldMetadata_Ordinal kOrdinal{};
+  void set_ordinal(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ordinal::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_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidEnergyConsumer>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Type::kFieldId, data, size);
+  }
+  void set_type(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Type::kFieldId, chars.data, chars.size);
+  }
+  void set_type(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidEnergyConsumer>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/common/android_log_constants.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_LOG_CONSTANTS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_LOG_CONSTANTS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+enum AndroidLogId : int32_t {
+  LID_DEFAULT = 0,
+  LID_RADIO = 1,
+  LID_EVENTS = 2,
+  LID_SYSTEM = 3,
+  LID_CRASH = 4,
+  LID_STATS = 5,
+  LID_SECURITY = 6,
+  LID_KERNEL = 7,
+};
+
+constexpr AndroidLogId AndroidLogId_MIN = AndroidLogId::LID_DEFAULT;
+constexpr AndroidLogId AndroidLogId_MAX = AndroidLogId::LID_KERNEL;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* AndroidLogId_Name(::perfetto::protos::pbzero::AndroidLogId value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::AndroidLogId::LID_DEFAULT:
+    return "LID_DEFAULT";
+
+  case ::perfetto::protos::pbzero::AndroidLogId::LID_RADIO:
+    return "LID_RADIO";
+
+  case ::perfetto::protos::pbzero::AndroidLogId::LID_EVENTS:
+    return "LID_EVENTS";
+
+  case ::perfetto::protos::pbzero::AndroidLogId::LID_SYSTEM:
+    return "LID_SYSTEM";
+
+  case ::perfetto::protos::pbzero::AndroidLogId::LID_CRASH:
+    return "LID_CRASH";
+
+  case ::perfetto::protos::pbzero::AndroidLogId::LID_STATS:
+    return "LID_STATS";
+
+  case ::perfetto::protos::pbzero::AndroidLogId::LID_SECURITY:
+    return "LID_SECURITY";
+
+  case ::perfetto::protos::pbzero::AndroidLogId::LID_KERNEL:
+    return "LID_KERNEL";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+enum AndroidLogPriority : int32_t {
+  PRIO_UNSPECIFIED = 0,
+  PRIO_UNUSED = 1,
+  PRIO_VERBOSE = 2,
+  PRIO_DEBUG = 3,
+  PRIO_INFO = 4,
+  PRIO_WARN = 5,
+  PRIO_ERROR = 6,
+  PRIO_FATAL = 7,
+};
+
+constexpr AndroidLogPriority AndroidLogPriority_MIN = AndroidLogPriority::PRIO_UNSPECIFIED;
+constexpr AndroidLogPriority AndroidLogPriority_MAX = AndroidLogPriority::PRIO_FATAL;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* AndroidLogPriority_Name(::perfetto::protos::pbzero::AndroidLogPriority value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::AndroidLogPriority::PRIO_UNSPECIFIED:
+    return "PRIO_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::AndroidLogPriority::PRIO_UNUSED:
+    return "PRIO_UNUSED";
+
+  case ::perfetto::protos::pbzero::AndroidLogPriority::PRIO_VERBOSE:
+    return "PRIO_VERBOSE";
+
+  case ::perfetto::protos::pbzero::AndroidLogPriority::PRIO_DEBUG:
+    return "PRIO_DEBUG";
+
+  case ::perfetto::protos::pbzero::AndroidLogPriority::PRIO_INFO:
+    return "PRIO_INFO";
+
+  case ::perfetto::protos::pbzero::AndroidLogPriority::PRIO_WARN:
+    return "PRIO_WARN";
+
+  case ::perfetto::protos::pbzero::AndroidLogPriority::PRIO_ERROR:
+    return "PRIO_ERROR";
+
+  case ::perfetto::protos::pbzero::AndroidLogPriority::PRIO_FATAL:
+    return "PRIO_FATAL";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/common/commit_data_request.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_COMMIT_DATA_REQUEST_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_COMMIT_DATA_REQUEST_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class CommitDataRequest_ChunkToPatch;
+class CommitDataRequest_ChunkToPatch_Patch;
+class CommitDataRequest_ChunksToMove;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class CommitDataRequest_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  CommitDataRequest_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CommitDataRequest_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CommitDataRequest_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_chunks_to_move() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> chunks_to_move() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_chunks_to_patch() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> chunks_to_patch() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_flush_request_id() const { return at<3>().valid(); }
+  uint64_t flush_request_id() const { return at<3>().as_uint64(); }
+};
+
+class CommitDataRequest : public ::protozero::Message {
+ public:
+  using Decoder = CommitDataRequest_Decoder;
+  enum : int32_t {
+    kChunksToMoveFieldNumber = 1,
+    kChunksToPatchFieldNumber = 2,
+    kFlushRequestIdFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CommitDataRequest"; }
+
+  using ChunksToMove = ::perfetto::protos::pbzero::CommitDataRequest_ChunksToMove;
+  using ChunkToPatch = ::perfetto::protos::pbzero::CommitDataRequest_ChunkToPatch;
+
+  using FieldMetadata_ChunksToMove =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CommitDataRequest_ChunksToMove,
+      CommitDataRequest>;
+
+  static constexpr FieldMetadata_ChunksToMove kChunksToMove{};
+  template <typename T = CommitDataRequest_ChunksToMove> T* add_chunks_to_move() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_ChunksToPatch =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CommitDataRequest_ChunkToPatch,
+      CommitDataRequest>;
+
+  static constexpr FieldMetadata_ChunksToPatch kChunksToPatch{};
+  template <typename T = CommitDataRequest_ChunkToPatch> T* add_chunks_to_patch() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_FlushRequestId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      CommitDataRequest>;
+
+  static constexpr FieldMetadata_FlushRequestId kFlushRequestId{};
+  void set_flush_request_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FlushRequestId::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 CommitDataRequest_ChunkToPatch_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  CommitDataRequest_ChunkToPatch_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CommitDataRequest_ChunkToPatch_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CommitDataRequest_ChunkToPatch_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_target_buffer() const { return at<1>().valid(); }
+  uint32_t target_buffer() const { return at<1>().as_uint32(); }
+  bool has_writer_id() const { return at<2>().valid(); }
+  uint32_t writer_id() const { return at<2>().as_uint32(); }
+  bool has_chunk_id() const { return at<3>().valid(); }
+  uint32_t chunk_id() const { return at<3>().as_uint32(); }
+  bool has_patches() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> patches() const { return GetRepeated<::protozero::ConstBytes>(4); }
+  bool has_has_more_patches() const { return at<5>().valid(); }
+  bool has_more_patches() const { return at<5>().as_bool(); }
+};
+
+class CommitDataRequest_ChunkToPatch : public ::protozero::Message {
+ public:
+  using Decoder = CommitDataRequest_ChunkToPatch_Decoder;
+  enum : int32_t {
+    kTargetBufferFieldNumber = 1,
+    kWriterIdFieldNumber = 2,
+    kChunkIdFieldNumber = 3,
+    kPatchesFieldNumber = 4,
+    kHasMorePatchesFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CommitDataRequest.ChunkToPatch"; }
+
+  using Patch = ::perfetto::protos::pbzero::CommitDataRequest_ChunkToPatch_Patch;
+
+  using FieldMetadata_TargetBuffer =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CommitDataRequest_ChunkToPatch>;
+
+  static constexpr FieldMetadata_TargetBuffer kTargetBuffer{};
+  void set_target_buffer(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TargetBuffer::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_WriterId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CommitDataRequest_ChunkToPatch>;
+
+  static constexpr FieldMetadata_WriterId kWriterId{};
+  void set_writer_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_WriterId::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_ChunkId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CommitDataRequest_ChunkToPatch>;
+
+  static constexpr FieldMetadata_ChunkId kChunkId{};
+  void set_chunk_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChunkId::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_Patches =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CommitDataRequest_ChunkToPatch_Patch,
+      CommitDataRequest_ChunkToPatch>;
+
+  static constexpr FieldMetadata_Patches kPatches{};
+  template <typename T = CommitDataRequest_ChunkToPatch_Patch> T* add_patches() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_HasMorePatches =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      CommitDataRequest_ChunkToPatch>;
+
+  static constexpr FieldMetadata_HasMorePatches kHasMorePatches{};
+  void set_has_more_patches(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_HasMorePatches::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 CommitDataRequest_ChunkToPatch_Patch_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CommitDataRequest_ChunkToPatch_Patch_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CommitDataRequest_ChunkToPatch_Patch_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CommitDataRequest_ChunkToPatch_Patch_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_offset() const { return at<1>().valid(); }
+  uint32_t offset() const { return at<1>().as_uint32(); }
+  bool has_data() const { return at<2>().valid(); }
+  ::protozero::ConstBytes data() const { return at<2>().as_bytes(); }
+};
+
+class CommitDataRequest_ChunkToPatch_Patch : public ::protozero::Message {
+ public:
+  using Decoder = CommitDataRequest_ChunkToPatch_Patch_Decoder;
+  enum : int32_t {
+    kOffsetFieldNumber = 1,
+    kDataFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CommitDataRequest.ChunkToPatch.Patch"; }
+
+
+  using FieldMetadata_Offset =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CommitDataRequest_ChunkToPatch_Patch>;
+
+  static constexpr FieldMetadata_Offset kOffset{};
+  void set_offset(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Offset::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_Data =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      CommitDataRequest_ChunkToPatch_Patch>;
+
+  static constexpr FieldMetadata_Data kData{};
+  void set_data(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_Data::kFieldId, data, size);
+  }
+  void set_data(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_Data::kFieldId, bytes.data, bytes.size);
+  }
+  void set_data(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Data::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 CommitDataRequest_ChunksToMove_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CommitDataRequest_ChunksToMove_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CommitDataRequest_ChunksToMove_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CommitDataRequest_ChunksToMove_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_page() const { return at<1>().valid(); }
+  uint32_t page() const { return at<1>().as_uint32(); }
+  bool has_chunk() const { return at<2>().valid(); }
+  uint32_t chunk() const { return at<2>().as_uint32(); }
+  bool has_target_buffer() const { return at<3>().valid(); }
+  uint32_t target_buffer() const { return at<3>().as_uint32(); }
+  bool has_data() const { return at<4>().valid(); }
+  ::protozero::ConstBytes data() const { return at<4>().as_bytes(); }
+};
+
+class CommitDataRequest_ChunksToMove : public ::protozero::Message {
+ public:
+  using Decoder = CommitDataRequest_ChunksToMove_Decoder;
+  enum : int32_t {
+    kPageFieldNumber = 1,
+    kChunkFieldNumber = 2,
+    kTargetBufferFieldNumber = 3,
+    kDataFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CommitDataRequest.ChunksToMove"; }
+
+
+  using FieldMetadata_Page =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CommitDataRequest_ChunksToMove>;
+
+  static constexpr FieldMetadata_Page kPage{};
+  void set_page(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Page::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_Chunk =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CommitDataRequest_ChunksToMove>;
+
+  static constexpr FieldMetadata_Chunk kChunk{};
+  void set_chunk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Chunk::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_TargetBuffer =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CommitDataRequest_ChunksToMove>;
+
+  static constexpr FieldMetadata_TargetBuffer kTargetBuffer{};
+  void set_target_buffer(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TargetBuffer::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_Data =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      CommitDataRequest_ChunksToMove>;
+
+  static constexpr FieldMetadata_Data kData{};
+  void set_data(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_Data::kFieldId, data, size);
+  }
+  void set_data(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_Data::kFieldId, bytes.data, bytes.size);
+  }
+  void set_data(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Data::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/common/data_source_descriptor.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DATA_SOURCE_DESCRIPTOR_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DATA_SOURCE_DESCRIPTOR_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class FtraceDescriptor;
+class GpuCounterDescriptor;
+class TrackEventDescriptor;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class DataSourceDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DataSourceDescriptor_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DataSourceDescriptor_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DataSourceDescriptor_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_id() const { return at<7>().valid(); }
+  uint64_t id() const { return at<7>().as_uint64(); }
+  bool has_will_notify_on_stop() const { return at<2>().valid(); }
+  bool will_notify_on_stop() const { return at<2>().as_bool(); }
+  bool has_will_notify_on_start() const { return at<3>().valid(); }
+  bool will_notify_on_start() const { return at<3>().as_bool(); }
+  bool has_handles_incremental_state_clear() const { return at<4>().valid(); }
+  bool handles_incremental_state_clear() const { return at<4>().as_bool(); }
+  bool has_no_flush() const { return at<9>().valid(); }
+  bool no_flush() const { return at<9>().as_bool(); }
+  bool has_gpu_counter_descriptor() const { return at<5>().valid(); }
+  ::protozero::ConstBytes gpu_counter_descriptor() const { return at<5>().as_bytes(); }
+  bool has_track_event_descriptor() const { return at<6>().valid(); }
+  ::protozero::ConstBytes track_event_descriptor() const { return at<6>().as_bytes(); }
+  bool has_ftrace_descriptor() const { return at<8>().valid(); }
+  ::protozero::ConstBytes ftrace_descriptor() const { return at<8>().as_bytes(); }
+};
+
+class DataSourceDescriptor : public ::protozero::Message {
+ public:
+  using Decoder = DataSourceDescriptor_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kIdFieldNumber = 7,
+    kWillNotifyOnStopFieldNumber = 2,
+    kWillNotifyOnStartFieldNumber = 3,
+    kHandlesIncrementalStateClearFieldNumber = 4,
+    kNoFlushFieldNumber = 9,
+    kGpuCounterDescriptorFieldNumber = 5,
+    kTrackEventDescriptorFieldNumber = 6,
+    kFtraceDescriptorFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DataSourceDescriptor"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DataSourceDescriptor>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DataSourceDescriptor>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::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_WillNotifyOnStop =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      DataSourceDescriptor>;
+
+  static constexpr FieldMetadata_WillNotifyOnStop kWillNotifyOnStop{};
+  void set_will_notify_on_stop(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_WillNotifyOnStop::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_WillNotifyOnStart =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      DataSourceDescriptor>;
+
+  static constexpr FieldMetadata_WillNotifyOnStart kWillNotifyOnStart{};
+  void set_will_notify_on_start(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_WillNotifyOnStart::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_HandlesIncrementalStateClear =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      DataSourceDescriptor>;
+
+  static constexpr FieldMetadata_HandlesIncrementalStateClear kHandlesIncrementalStateClear{};
+  void set_handles_incremental_state_clear(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_HandlesIncrementalStateClear::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_NoFlush =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      DataSourceDescriptor>;
+
+  static constexpr FieldMetadata_NoFlush kNoFlush{};
+  void set_no_flush(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_NoFlush::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_GpuCounterDescriptor =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuCounterDescriptor,
+      DataSourceDescriptor>;
+
+  static constexpr FieldMetadata_GpuCounterDescriptor kGpuCounterDescriptor{};
+  template <typename T = GpuCounterDescriptor> T* set_gpu_counter_descriptor() {
+    return BeginNestedMessage<T>(5);
+  }
+
+  void set_gpu_counter_descriptor_raw(const std::string& raw) {
+    return AppendBytes(5, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_TrackEventDescriptor =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrackEventDescriptor,
+      DataSourceDescriptor>;
+
+  static constexpr FieldMetadata_TrackEventDescriptor kTrackEventDescriptor{};
+  template <typename T = TrackEventDescriptor> T* set_track_event_descriptor() {
+    return BeginNestedMessage<T>(6);
+  }
+
+  void set_track_event_descriptor_raw(const std::string& raw) {
+    return AppendBytes(6, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_FtraceDescriptor =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FtraceDescriptor,
+      DataSourceDescriptor>;
+
+  static constexpr FieldMetadata_FtraceDescriptor kFtraceDescriptor{};
+  template <typename T = FtraceDescriptor> T* set_ftrace_descriptor() {
+    return BeginNestedMessage<T>(8);
+  }
+
+  void set_ftrace_descriptor_raw(const std::string& raw) {
+    return AppendBytes(8, raw.data(), raw.size());
+  }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/common/descriptor.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DESCRIPTOR_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DESCRIPTOR_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class DescriptorProto;
+class DescriptorProto_ReservedRange;
+class EnumDescriptorProto;
+class EnumValueDescriptorProto;
+class FieldDescriptorProto;
+class FieldOptions;
+class FileDescriptorProto;
+class OneofDescriptorProto;
+class OneofOptions;
+class UninterpretedOption;
+class UninterpretedOption_NamePart;
+namespace perfetto_pbzero_enum_FieldDescriptorProto {
+enum Label : int32_t;
+}  // namespace perfetto_pbzero_enum_FieldDescriptorProto
+using FieldDescriptorProto_Label = perfetto_pbzero_enum_FieldDescriptorProto::Label;
+namespace perfetto_pbzero_enum_FieldDescriptorProto {
+enum Type : int32_t;
+}  // namespace perfetto_pbzero_enum_FieldDescriptorProto
+using FieldDescriptorProto_Type = perfetto_pbzero_enum_FieldDescriptorProto::Type;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_FieldDescriptorProto {
+enum Type : int32_t {
+  TYPE_DOUBLE = 1,
+  TYPE_FLOAT = 2,
+  TYPE_INT64 = 3,
+  TYPE_UINT64 = 4,
+  TYPE_INT32 = 5,
+  TYPE_FIXED64 = 6,
+  TYPE_FIXED32 = 7,
+  TYPE_BOOL = 8,
+  TYPE_STRING = 9,
+  TYPE_GROUP = 10,
+  TYPE_MESSAGE = 11,
+  TYPE_BYTES = 12,
+  TYPE_UINT32 = 13,
+  TYPE_ENUM = 14,
+  TYPE_SFIXED32 = 15,
+  TYPE_SFIXED64 = 16,
+  TYPE_SINT32 = 17,
+  TYPE_SINT64 = 18,
+};
+} // namespace perfetto_pbzero_enum_FieldDescriptorProto
+using FieldDescriptorProto_Type = perfetto_pbzero_enum_FieldDescriptorProto::Type;
+
+
+constexpr FieldDescriptorProto_Type FieldDescriptorProto_Type_MIN = FieldDescriptorProto_Type::TYPE_DOUBLE;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto_Type_MAX = FieldDescriptorProto_Type::TYPE_SINT64;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* FieldDescriptorProto_Type_Name(::perfetto::protos::pbzero::FieldDescriptorProto_Type value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Type::TYPE_DOUBLE:
+    return "TYPE_DOUBLE";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Type::TYPE_FLOAT:
+    return "TYPE_FLOAT";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Type::TYPE_INT64:
+    return "TYPE_INT64";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Type::TYPE_UINT64:
+    return "TYPE_UINT64";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Type::TYPE_INT32:
+    return "TYPE_INT32";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Type::TYPE_FIXED64:
+    return "TYPE_FIXED64";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Type::TYPE_FIXED32:
+    return "TYPE_FIXED32";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Type::TYPE_BOOL:
+    return "TYPE_BOOL";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Type::TYPE_STRING:
+    return "TYPE_STRING";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Type::TYPE_GROUP:
+    return "TYPE_GROUP";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Type::TYPE_MESSAGE:
+    return "TYPE_MESSAGE";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Type::TYPE_BYTES:
+    return "TYPE_BYTES";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Type::TYPE_UINT32:
+    return "TYPE_UINT32";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Type::TYPE_ENUM:
+    return "TYPE_ENUM";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Type::TYPE_SFIXED32:
+    return "TYPE_SFIXED32";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Type::TYPE_SFIXED64:
+    return "TYPE_SFIXED64";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Type::TYPE_SINT32:
+    return "TYPE_SINT32";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Type::TYPE_SINT64:
+    return "TYPE_SINT64";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_FieldDescriptorProto {
+enum Label : int32_t {
+  LABEL_OPTIONAL = 1,
+  LABEL_REQUIRED = 2,
+  LABEL_REPEATED = 3,
+};
+} // namespace perfetto_pbzero_enum_FieldDescriptorProto
+using FieldDescriptorProto_Label = perfetto_pbzero_enum_FieldDescriptorProto::Label;
+
+
+constexpr FieldDescriptorProto_Label FieldDescriptorProto_Label_MIN = FieldDescriptorProto_Label::LABEL_OPTIONAL;
+constexpr FieldDescriptorProto_Label FieldDescriptorProto_Label_MAX = FieldDescriptorProto_Label::LABEL_REPEATED;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* FieldDescriptorProto_Label_Name(::perfetto::protos::pbzero::FieldDescriptorProto_Label value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Label::LABEL_OPTIONAL:
+    return "LABEL_OPTIONAL";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Label::LABEL_REQUIRED:
+    return "LABEL_REQUIRED";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Label::LABEL_REPEATED:
+    return "LABEL_REPEATED";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class OneofOptions_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/0, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  OneofOptions_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit OneofOptions_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit OneofOptions_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+};
+
+class OneofOptions : public ::protozero::Message {
+ public:
+  using Decoder = OneofOptions_Decoder;
+  static constexpr const char* GetName() { return ".perfetto.protos.OneofOptions"; }
+
+};
+
+class EnumValueDescriptorProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  EnumValueDescriptorProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit EnumValueDescriptorProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit EnumValueDescriptorProto_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_number() const { return at<2>().valid(); }
+  int32_t number() const { return at<2>().as_int32(); }
+};
+
+class EnumValueDescriptorProto : public ::protozero::Message {
+ public:
+  using Decoder = EnumValueDescriptorProto_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kNumberFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.EnumValueDescriptorProto"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      EnumValueDescriptorProto>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Number =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      EnumValueDescriptorProto>;
+
+  static constexpr FieldMetadata_Number kNumber{};
+  void set_number(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Number::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);
+  }
+};
+
+class EnumDescriptorProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  EnumDescriptorProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit EnumDescriptorProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit EnumDescriptorProto_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_value() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> value() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_reserved_name() const { return at<5>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> reserved_name() const { return GetRepeated<::protozero::ConstChars>(5); }
+};
+
+class EnumDescriptorProto : public ::protozero::Message {
+ public:
+  using Decoder = EnumDescriptorProto_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kValueFieldNumber = 2,
+    kReservedNameFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.EnumDescriptorProto"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      EnumDescriptorProto>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      EnumValueDescriptorProto,
+      EnumDescriptorProto>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  template <typename T = EnumValueDescriptorProto> T* add_value() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_ReservedName =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      EnumDescriptorProto>;
+
+  static constexpr FieldMetadata_ReservedName kReservedName{};
+  void add_reserved_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ReservedName::kFieldId, data, size);
+  }
+  void add_reserved_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ReservedName::kFieldId, chars.data, chars.size);
+  }
+  void add_reserved_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReservedName::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 OneofDescriptorProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  OneofDescriptorProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit OneofDescriptorProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit OneofDescriptorProto_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_options() const { return at<2>().valid(); }
+  ::protozero::ConstBytes options() const { return at<2>().as_bytes(); }
+};
+
+class OneofDescriptorProto : public ::protozero::Message {
+ public:
+  using Decoder = OneofDescriptorProto_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kOptionsFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.OneofDescriptorProto"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      OneofDescriptorProto>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Options =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      OneofOptions,
+      OneofDescriptorProto>;
+
+  static constexpr FieldMetadata_Options kOptions{};
+  template <typename T = OneofOptions> T* set_options() {
+    return BeginNestedMessage<T>(2);
+  }
+
+};
+
+class FieldDescriptorProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FieldDescriptorProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FieldDescriptorProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FieldDescriptorProto_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_number() const { return at<3>().valid(); }
+  int32_t number() const { return at<3>().as_int32(); }
+  bool has_label() const { return at<4>().valid(); }
+  int32_t label() const { return at<4>().as_int32(); }
+  bool has_type() const { return at<5>().valid(); }
+  int32_t type() const { return at<5>().as_int32(); }
+  bool has_type_name() const { return at<6>().valid(); }
+  ::protozero::ConstChars type_name() const { return at<6>().as_string(); }
+  bool has_extendee() const { return at<2>().valid(); }
+  ::protozero::ConstChars extendee() const { return at<2>().as_string(); }
+  bool has_default_value() const { return at<7>().valid(); }
+  ::protozero::ConstChars default_value() const { return at<7>().as_string(); }
+  bool has_options() const { return at<8>().valid(); }
+  ::protozero::ConstBytes options() const { return at<8>().as_bytes(); }
+  bool has_oneof_index() const { return at<9>().valid(); }
+  int32_t oneof_index() const { return at<9>().as_int32(); }
+};
+
+class FieldDescriptorProto : public ::protozero::Message {
+ public:
+  using Decoder = FieldDescriptorProto_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kNumberFieldNumber = 3,
+    kLabelFieldNumber = 4,
+    kTypeFieldNumber = 5,
+    kTypeNameFieldNumber = 6,
+    kExtendeeFieldNumber = 2,
+    kDefaultValueFieldNumber = 7,
+    kOptionsFieldNumber = 8,
+    kOneofIndexFieldNumber = 9,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FieldDescriptorProto"; }
+
+
+  using Type = ::perfetto::protos::pbzero::FieldDescriptorProto_Type;
+  static inline const char* Type_Name(Type value) {
+    return ::perfetto::protos::pbzero::FieldDescriptorProto_Type_Name(value);
+  }
+
+  using Label = ::perfetto::protos::pbzero::FieldDescriptorProto_Label;
+  static inline const char* Label_Name(Label value) {
+    return ::perfetto::protos::pbzero::FieldDescriptorProto_Label_Name(value);
+  }
+  static inline const Type TYPE_DOUBLE = Type::TYPE_DOUBLE;
+  static inline const Type TYPE_FLOAT = Type::TYPE_FLOAT;
+  static inline const Type TYPE_INT64 = Type::TYPE_INT64;
+  static inline const Type TYPE_UINT64 = Type::TYPE_UINT64;
+  static inline const Type TYPE_INT32 = Type::TYPE_INT32;
+  static inline const Type TYPE_FIXED64 = Type::TYPE_FIXED64;
+  static inline const Type TYPE_FIXED32 = Type::TYPE_FIXED32;
+  static inline const Type TYPE_BOOL = Type::TYPE_BOOL;
+  static inline const Type TYPE_STRING = Type::TYPE_STRING;
+  static inline const Type TYPE_GROUP = Type::TYPE_GROUP;
+  static inline const Type TYPE_MESSAGE = Type::TYPE_MESSAGE;
+  static inline const Type TYPE_BYTES = Type::TYPE_BYTES;
+  static inline const Type TYPE_UINT32 = Type::TYPE_UINT32;
+  static inline const Type TYPE_ENUM = Type::TYPE_ENUM;
+  static inline const Type TYPE_SFIXED32 = Type::TYPE_SFIXED32;
+  static inline const Type TYPE_SFIXED64 = Type::TYPE_SFIXED64;
+  static inline const Type TYPE_SINT32 = Type::TYPE_SINT32;
+  static inline const Type TYPE_SINT64 = Type::TYPE_SINT64;
+  static inline const Label LABEL_OPTIONAL = Label::LABEL_OPTIONAL;
+  static inline const Label LABEL_REQUIRED = Label::LABEL_REQUIRED;
+  static inline const Label LABEL_REPEATED = Label::LABEL_REPEATED;
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FieldDescriptorProto>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Number =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FieldDescriptorProto>;
+
+  static constexpr FieldMetadata_Number kNumber{};
+  void set_number(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Number::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_Label =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      FieldDescriptorProto_Label,
+      FieldDescriptorProto>;
+
+  static constexpr FieldMetadata_Label kLabel{};
+  void set_label(FieldDescriptorProto_Label value) {
+    static constexpr uint32_t field_id = FieldMetadata_Label::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_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      FieldDescriptorProto_Type,
+      FieldDescriptorProto>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(FieldDescriptorProto_Type value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::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_TypeName =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FieldDescriptorProto>;
+
+  static constexpr FieldMetadata_TypeName kTypeName{};
+  void set_type_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TypeName::kFieldId, data, size);
+  }
+  void set_type_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_TypeName::kFieldId, chars.data, chars.size);
+  }
+  void set_type_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_TypeName::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_Extendee =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FieldDescriptorProto>;
+
+  static constexpr FieldMetadata_Extendee kExtendee{};
+  void set_extendee(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Extendee::kFieldId, data, size);
+  }
+  void set_extendee(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Extendee::kFieldId, chars.data, chars.size);
+  }
+  void set_extendee(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Extendee::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_DefaultValue =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FieldDescriptorProto>;
+
+  static constexpr FieldMetadata_DefaultValue kDefaultValue{};
+  void set_default_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DefaultValue::kFieldId, data, size);
+  }
+  void set_default_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_DefaultValue::kFieldId, chars.data, chars.size);
+  }
+  void set_default_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_DefaultValue::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_Options =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FieldOptions,
+      FieldDescriptorProto>;
+
+  static constexpr FieldMetadata_Options kOptions{};
+  template <typename T = FieldOptions> T* set_options() {
+    return BeginNestedMessage<T>(8);
+  }
+
+
+  using FieldMetadata_OneofIndex =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FieldDescriptorProto>;
+
+  static constexpr FieldMetadata_OneofIndex kOneofIndex{};
+  void set_oneof_index(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OneofIndex::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);
+  }
+};
+
+class FieldOptions_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/999, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  FieldOptions_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FieldOptions_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FieldOptions_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_packed() const { return at<2>().valid(); }
+  bool packed() const { return at<2>().as_bool(); }
+  bool has_uninterpreted_option() const { return at<999>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> uninterpreted_option() const { return GetRepeated<::protozero::ConstBytes>(999); }
+};
+
+class FieldOptions : public ::protozero::Message {
+ public:
+  using Decoder = FieldOptions_Decoder;
+  enum : int32_t {
+    kPackedFieldNumber = 2,
+    kUninterpretedOptionFieldNumber = 999,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FieldOptions"; }
+
+
+  using FieldMetadata_Packed =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FieldOptions>;
+
+  static constexpr FieldMetadata_Packed kPacked{};
+  void set_packed(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_Packed::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_UninterpretedOption =
+    ::protozero::proto_utils::FieldMetadata<
+      999,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      UninterpretedOption,
+      FieldOptions>;
+
+  static constexpr FieldMetadata_UninterpretedOption kUninterpretedOption{};
+  template <typename T = UninterpretedOption> T* add_uninterpreted_option() {
+    return BeginNestedMessage<T>(999);
+  }
+
+};
+
+class UninterpretedOption_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  UninterpretedOption_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit UninterpretedOption_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit UninterpretedOption_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> name() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_identifier_value() const { return at<3>().valid(); }
+  ::protozero::ConstChars identifier_value() const { return at<3>().as_string(); }
+  bool has_positive_int_value() const { return at<4>().valid(); }
+  uint64_t positive_int_value() const { return at<4>().as_uint64(); }
+  bool has_negative_int_value() const { return at<5>().valid(); }
+  int64_t negative_int_value() const { return at<5>().as_int64(); }
+  bool has_double_value() const { return at<6>().valid(); }
+  double double_value() const { return at<6>().as_double(); }
+  bool has_string_value() const { return at<7>().valid(); }
+  ::protozero::ConstBytes string_value() const { return at<7>().as_bytes(); }
+  bool has_aggregate_value() const { return at<8>().valid(); }
+  ::protozero::ConstChars aggregate_value() const { return at<8>().as_string(); }
+};
+
+class UninterpretedOption : public ::protozero::Message {
+ public:
+  using Decoder = UninterpretedOption_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 2,
+    kIdentifierValueFieldNumber = 3,
+    kPositiveIntValueFieldNumber = 4,
+    kNegativeIntValueFieldNumber = 5,
+    kDoubleValueFieldNumber = 6,
+    kStringValueFieldNumber = 7,
+    kAggregateValueFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.UninterpretedOption"; }
+
+  using NamePart = ::perfetto::protos::pbzero::UninterpretedOption_NamePart;
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      UninterpretedOption_NamePart,
+      UninterpretedOption>;
+
+  static constexpr FieldMetadata_Name kName{};
+  template <typename T = UninterpretedOption_NamePart> T* add_name() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_IdentifierValue =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      UninterpretedOption>;
+
+  static constexpr FieldMetadata_IdentifierValue kIdentifierValue{};
+  void set_identifier_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_IdentifierValue::kFieldId, data, size);
+  }
+  void set_identifier_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_IdentifierValue::kFieldId, chars.data, chars.size);
+  }
+  void set_identifier_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_IdentifierValue::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_PositiveIntValue =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      UninterpretedOption>;
+
+  static constexpr FieldMetadata_PositiveIntValue kPositiveIntValue{};
+  void set_positive_int_value(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PositiveIntValue::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_NegativeIntValue =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      UninterpretedOption>;
+
+  static constexpr FieldMetadata_NegativeIntValue kNegativeIntValue{};
+  void set_negative_int_value(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NegativeIntValue::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_DoubleValue =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      UninterpretedOption>;
+
+  static constexpr FieldMetadata_DoubleValue kDoubleValue{};
+  void set_double_value(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_DoubleValue::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);
+  }
+
+  using FieldMetadata_StringValue =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      UninterpretedOption>;
+
+  static constexpr FieldMetadata_StringValue kStringValue{};
+  void set_string_value(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_StringValue::kFieldId, data, size);
+  }
+  void set_string_value(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_StringValue::kFieldId, bytes.data, bytes.size);
+  }
+  void set_string_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_StringValue::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);
+  }
+
+  using FieldMetadata_AggregateValue =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      UninterpretedOption>;
+
+  static constexpr FieldMetadata_AggregateValue kAggregateValue{};
+  void set_aggregate_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_AggregateValue::kFieldId, data, size);
+  }
+  void set_aggregate_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_AggregateValue::kFieldId, chars.data, chars.size);
+  }
+  void set_aggregate_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_AggregateValue::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 UninterpretedOption_NamePart_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  UninterpretedOption_NamePart_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit UninterpretedOption_NamePart_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit UninterpretedOption_NamePart_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name_part() const { return at<1>().valid(); }
+  ::protozero::ConstChars name_part() const { return at<1>().as_string(); }
+  bool has_is_extension() const { return at<2>().valid(); }
+  bool is_extension() const { return at<2>().as_bool(); }
+};
+
+class UninterpretedOption_NamePart : public ::protozero::Message {
+ public:
+  using Decoder = UninterpretedOption_NamePart_Decoder;
+  enum : int32_t {
+    kNamePartFieldNumber = 1,
+    kIsExtensionFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.UninterpretedOption.NamePart"; }
+
+
+  using FieldMetadata_NamePart =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      UninterpretedOption_NamePart>;
+
+  static constexpr FieldMetadata_NamePart kNamePart{};
+  void set_name_part(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_NamePart::kFieldId, data, size);
+  }
+  void set_name_part(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_NamePart::kFieldId, chars.data, chars.size);
+  }
+  void set_name_part(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_NamePart::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_IsExtension =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      UninterpretedOption_NamePart>;
+
+  static constexpr FieldMetadata_IsExtension kIsExtension{};
+  void set_is_extension(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsExtension::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 DescriptorProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/10, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  DescriptorProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DescriptorProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DescriptorProto_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_field() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> field() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_extension() const { return at<6>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> extension() const { return GetRepeated<::protozero::ConstBytes>(6); }
+  bool has_nested_type() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> nested_type() const { return GetRepeated<::protozero::ConstBytes>(3); }
+  bool has_enum_type() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> enum_type() const { return GetRepeated<::protozero::ConstBytes>(4); }
+  bool has_oneof_decl() const { return at<8>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> oneof_decl() const { return GetRepeated<::protozero::ConstBytes>(8); }
+  bool has_reserved_range() const { return at<9>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> reserved_range() const { return GetRepeated<::protozero::ConstBytes>(9); }
+  bool has_reserved_name() const { return at<10>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> reserved_name() const { return GetRepeated<::protozero::ConstChars>(10); }
+};
+
+class DescriptorProto : public ::protozero::Message {
+ public:
+  using Decoder = DescriptorProto_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kFieldFieldNumber = 2,
+    kExtensionFieldNumber = 6,
+    kNestedTypeFieldNumber = 3,
+    kEnumTypeFieldNumber = 4,
+    kOneofDeclFieldNumber = 8,
+    kReservedRangeFieldNumber = 9,
+    kReservedNameFieldNumber = 10,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DescriptorProto"; }
+
+  using ReservedRange = ::perfetto::protos::pbzero::DescriptorProto_ReservedRange;
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DescriptorProto>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Field =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FieldDescriptorProto,
+      DescriptorProto>;
+
+  static constexpr FieldMetadata_Field kField{};
+  template <typename T = FieldDescriptorProto> T* add_field() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_Extension =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FieldDescriptorProto,
+      DescriptorProto>;
+
+  static constexpr FieldMetadata_Extension kExtension{};
+  template <typename T = FieldDescriptorProto> T* add_extension() {
+    return BeginNestedMessage<T>(6);
+  }
+
+
+  using FieldMetadata_NestedType =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DescriptorProto,
+      DescriptorProto>;
+
+  static constexpr FieldMetadata_NestedType kNestedType{};
+  template <typename T = DescriptorProto> T* add_nested_type() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_EnumType =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      EnumDescriptorProto,
+      DescriptorProto>;
+
+  static constexpr FieldMetadata_EnumType kEnumType{};
+  template <typename T = EnumDescriptorProto> T* add_enum_type() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_OneofDecl =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      OneofDescriptorProto,
+      DescriptorProto>;
+
+  static constexpr FieldMetadata_OneofDecl kOneofDecl{};
+  template <typename T = OneofDescriptorProto> T* add_oneof_decl() {
+    return BeginNestedMessage<T>(8);
+  }
+
+
+  using FieldMetadata_ReservedRange =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DescriptorProto_ReservedRange,
+      DescriptorProto>;
+
+  static constexpr FieldMetadata_ReservedRange kReservedRange{};
+  template <typename T = DescriptorProto_ReservedRange> T* add_reserved_range() {
+    return BeginNestedMessage<T>(9);
+  }
+
+
+  using FieldMetadata_ReservedName =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DescriptorProto>;
+
+  static constexpr FieldMetadata_ReservedName kReservedName{};
+  void add_reserved_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ReservedName::kFieldId, data, size);
+  }
+  void add_reserved_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ReservedName::kFieldId, chars.data, chars.size);
+  }
+  void add_reserved_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReservedName::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 DescriptorProto_ReservedRange_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DescriptorProto_ReservedRange_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DescriptorProto_ReservedRange_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DescriptorProto_ReservedRange_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_start() const { return at<1>().valid(); }
+  int32_t start() const { return at<1>().as_int32(); }
+  bool has_end() const { return at<2>().valid(); }
+  int32_t end() const { return at<2>().as_int32(); }
+};
+
+class DescriptorProto_ReservedRange : public ::protozero::Message {
+ public:
+  using Decoder = DescriptorProto_ReservedRange_Decoder;
+  enum : int32_t {
+    kStartFieldNumber = 1,
+    kEndFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DescriptorProto.ReservedRange"; }
+
+
+  using FieldMetadata_Start =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      DescriptorProto_ReservedRange>;
+
+  static constexpr FieldMetadata_Start kStart{};
+  void set_start(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Start::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_End =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      DescriptorProto_ReservedRange>;
+
+  static constexpr FieldMetadata_End kEnd{};
+  void set_end(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_End::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);
+  }
+};
+
+class FileDescriptorProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/11, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  FileDescriptorProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FileDescriptorProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FileDescriptorProto_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_package() const { return at<2>().valid(); }
+  ::protozero::ConstChars package() const { return at<2>().as_string(); }
+  bool has_dependency() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> dependency() const { return GetRepeated<::protozero::ConstChars>(3); }
+  bool has_public_dependency() const { return at<10>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> public_dependency() const { return GetRepeated<int32_t>(10); }
+  bool has_weak_dependency() const { return at<11>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> weak_dependency() const { return GetRepeated<int32_t>(11); }
+  bool has_message_type() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> message_type() const { return GetRepeated<::protozero::ConstBytes>(4); }
+  bool has_enum_type() const { return at<5>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> enum_type() const { return GetRepeated<::protozero::ConstBytes>(5); }
+  bool has_extension() const { return at<7>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> extension() const { return GetRepeated<::protozero::ConstBytes>(7); }
+};
+
+class FileDescriptorProto : public ::protozero::Message {
+ public:
+  using Decoder = FileDescriptorProto_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kPackageFieldNumber = 2,
+    kDependencyFieldNumber = 3,
+    kPublicDependencyFieldNumber = 10,
+    kWeakDependencyFieldNumber = 11,
+    kMessageTypeFieldNumber = 4,
+    kEnumTypeFieldNumber = 5,
+    kExtensionFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FileDescriptorProto"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FileDescriptorProto>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Package =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FileDescriptorProto>;
+
+  static constexpr FieldMetadata_Package kPackage{};
+  void set_package(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Package::kFieldId, data, size);
+  }
+  void set_package(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Package::kFieldId, chars.data, chars.size);
+  }
+  void set_package(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Package::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_Dependency =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FileDescriptorProto>;
+
+  static constexpr FieldMetadata_Dependency kDependency{};
+  void add_dependency(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Dependency::kFieldId, data, size);
+  }
+  void add_dependency(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Dependency::kFieldId, chars.data, chars.size);
+  }
+  void add_dependency(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dependency::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_PublicDependency =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FileDescriptorProto>;
+
+  static constexpr FieldMetadata_PublicDependency kPublicDependency{};
+  void add_public_dependency(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PublicDependency::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_WeakDependency =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FileDescriptorProto>;
+
+  static constexpr FieldMetadata_WeakDependency kWeakDependency{};
+  void add_weak_dependency(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_WeakDependency::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_MessageType =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DescriptorProto,
+      FileDescriptorProto>;
+
+  static constexpr FieldMetadata_MessageType kMessageType{};
+  template <typename T = DescriptorProto> T* add_message_type() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_EnumType =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      EnumDescriptorProto,
+      FileDescriptorProto>;
+
+  static constexpr FieldMetadata_EnumType kEnumType{};
+  template <typename T = EnumDescriptorProto> T* add_enum_type() {
+    return BeginNestedMessage<T>(5);
+  }
+
+
+  using FieldMetadata_Extension =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FieldDescriptorProto,
+      FileDescriptorProto>;
+
+  static constexpr FieldMetadata_Extension kExtension{};
+  template <typename T = FieldDescriptorProto> T* add_extension() {
+    return BeginNestedMessage<T>(7);
+  }
+
+};
+
+class FileDescriptorSet_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  FileDescriptorSet_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FileDescriptorSet_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FileDescriptorSet_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_file() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> file() const { return GetRepeated<::protozero::ConstBytes>(1); }
+};
+
+class FileDescriptorSet : public ::protozero::Message {
+ public:
+  using Decoder = FileDescriptorSet_Decoder;
+  enum : int32_t {
+    kFileFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FileDescriptorSet"; }
+
+
+  using FieldMetadata_File =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FileDescriptorProto,
+      FileDescriptorSet>;
+
+  static constexpr FieldMetadata_File kFile{};
+  template <typename T = FileDescriptorProto> T* add_file() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/common/ftrace_descriptor.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_FTRACE_DESCRIPTOR_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_FTRACE_DESCRIPTOR_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class FtraceDescriptor_AtraceCategory;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class FtraceDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  FtraceDescriptor_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FtraceDescriptor_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FtraceDescriptor_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_atrace_categories() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> atrace_categories() const { return GetRepeated<::protozero::ConstBytes>(1); }
+};
+
+class FtraceDescriptor : public ::protozero::Message {
+ public:
+  using Decoder = FtraceDescriptor_Decoder;
+  enum : int32_t {
+    kAtraceCategoriesFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FtraceDescriptor"; }
+
+  using AtraceCategory = ::perfetto::protos::pbzero::FtraceDescriptor_AtraceCategory;
+
+  using FieldMetadata_AtraceCategories =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FtraceDescriptor_AtraceCategory,
+      FtraceDescriptor>;
+
+  static constexpr FieldMetadata_AtraceCategories kAtraceCategories{};
+  template <typename T = FtraceDescriptor_AtraceCategory> T* add_atrace_categories() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+class FtraceDescriptor_AtraceCategory_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FtraceDescriptor_AtraceCategory_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FtraceDescriptor_AtraceCategory_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FtraceDescriptor_AtraceCategory_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_description() const { return at<2>().valid(); }
+  ::protozero::ConstChars description() const { return at<2>().as_string(); }
+};
+
+class FtraceDescriptor_AtraceCategory : public ::protozero::Message {
+ public:
+  using Decoder = FtraceDescriptor_AtraceCategory_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kDescriptionFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FtraceDescriptor.AtraceCategory"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FtraceDescriptor_AtraceCategory>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Description =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FtraceDescriptor_AtraceCategory>;
+
+  static constexpr FieldMetadata_Description kDescription{};
+  void set_description(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Description::kFieldId, data, size);
+  }
+  void set_description(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Description::kFieldId, chars.data, chars.size);
+  }
+  void set_description(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Description::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/common/gpu_counter_descriptor.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_GPU_COUNTER_DESCRIPTOR_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_GPU_COUNTER_DESCRIPTOR_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class GpuCounterDescriptor_GpuCounterBlock;
+class GpuCounterDescriptor_GpuCounterSpec;
+namespace perfetto_pbzero_enum_GpuCounterDescriptor {
+enum GpuCounterGroup : int32_t;
+}  // namespace perfetto_pbzero_enum_GpuCounterDescriptor
+using GpuCounterDescriptor_GpuCounterGroup = perfetto_pbzero_enum_GpuCounterDescriptor::GpuCounterGroup;
+namespace perfetto_pbzero_enum_GpuCounterDescriptor {
+enum MeasureUnit : int32_t;
+}  // namespace perfetto_pbzero_enum_GpuCounterDescriptor
+using GpuCounterDescriptor_MeasureUnit = perfetto_pbzero_enum_GpuCounterDescriptor::MeasureUnit;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_GpuCounterDescriptor {
+enum GpuCounterGroup : int32_t {
+  UNCLASSIFIED = 0,
+  SYSTEM = 1,
+  VERTICES = 2,
+  FRAGMENTS = 3,
+  PRIMITIVES = 4,
+  MEMORY = 5,
+  COMPUTE = 6,
+};
+} // namespace perfetto_pbzero_enum_GpuCounterDescriptor
+using GpuCounterDescriptor_GpuCounterGroup = perfetto_pbzero_enum_GpuCounterDescriptor::GpuCounterGroup;
+
+
+constexpr GpuCounterDescriptor_GpuCounterGroup GpuCounterDescriptor_GpuCounterGroup_MIN = GpuCounterDescriptor_GpuCounterGroup::UNCLASSIFIED;
+constexpr GpuCounterDescriptor_GpuCounterGroup GpuCounterDescriptor_GpuCounterGroup_MAX = GpuCounterDescriptor_GpuCounterGroup::COMPUTE;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* GpuCounterDescriptor_GpuCounterGroup_Name(::perfetto::protos::pbzero::GpuCounterDescriptor_GpuCounterGroup value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_GpuCounterGroup::UNCLASSIFIED:
+    return "UNCLASSIFIED";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_GpuCounterGroup::SYSTEM:
+    return "SYSTEM";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_GpuCounterGroup::VERTICES:
+    return "VERTICES";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_GpuCounterGroup::FRAGMENTS:
+    return "FRAGMENTS";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_GpuCounterGroup::PRIMITIVES:
+    return "PRIMITIVES";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_GpuCounterGroup::MEMORY:
+    return "MEMORY";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_GpuCounterGroup::COMPUTE:
+    return "COMPUTE";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_GpuCounterDescriptor {
+enum MeasureUnit : int32_t {
+  NONE = 0,
+  BIT = 1,
+  KILOBIT = 2,
+  MEGABIT = 3,
+  GIGABIT = 4,
+  TERABIT = 5,
+  PETABIT = 6,
+  BYTE = 7,
+  KILOBYTE = 8,
+  MEGABYTE = 9,
+  GIGABYTE = 10,
+  TERABYTE = 11,
+  PETABYTE = 12,
+  HERTZ = 13,
+  KILOHERTZ = 14,
+  MEGAHERTZ = 15,
+  GIGAHERTZ = 16,
+  TERAHERTZ = 17,
+  PETAHERTZ = 18,
+  NANOSECOND = 19,
+  MICROSECOND = 20,
+  MILLISECOND = 21,
+  SECOND = 22,
+  MINUTE = 23,
+  HOUR = 24,
+  VERTEX = 25,
+  PIXEL = 26,
+  TRIANGLE = 27,
+  PRIMITIVE = 38,
+  FRAGMENT = 39,
+  MILLIWATT = 28,
+  WATT = 29,
+  KILOWATT = 30,
+  JOULE = 31,
+  VOLT = 32,
+  AMPERE = 33,
+  CELSIUS = 34,
+  FAHRENHEIT = 35,
+  KELVIN = 36,
+  PERCENT = 37,
+  INSTRUCTION = 40,
+};
+} // namespace perfetto_pbzero_enum_GpuCounterDescriptor
+using GpuCounterDescriptor_MeasureUnit = perfetto_pbzero_enum_GpuCounterDescriptor::MeasureUnit;
+
+
+constexpr GpuCounterDescriptor_MeasureUnit GpuCounterDescriptor_MeasureUnit_MIN = GpuCounterDescriptor_MeasureUnit::NONE;
+constexpr GpuCounterDescriptor_MeasureUnit GpuCounterDescriptor_MeasureUnit_MAX = GpuCounterDescriptor_MeasureUnit::INSTRUCTION;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* GpuCounterDescriptor_MeasureUnit_Name(::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::NONE:
+    return "NONE";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::BIT:
+    return "BIT";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::KILOBIT:
+    return "KILOBIT";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::MEGABIT:
+    return "MEGABIT";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::GIGABIT:
+    return "GIGABIT";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::TERABIT:
+    return "TERABIT";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::PETABIT:
+    return "PETABIT";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::BYTE:
+    return "BYTE";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::KILOBYTE:
+    return "KILOBYTE";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::MEGABYTE:
+    return "MEGABYTE";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::GIGABYTE:
+    return "GIGABYTE";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::TERABYTE:
+    return "TERABYTE";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::PETABYTE:
+    return "PETABYTE";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::HERTZ:
+    return "HERTZ";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::KILOHERTZ:
+    return "KILOHERTZ";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::MEGAHERTZ:
+    return "MEGAHERTZ";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::GIGAHERTZ:
+    return "GIGAHERTZ";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::TERAHERTZ:
+    return "TERAHERTZ";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::PETAHERTZ:
+    return "PETAHERTZ";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::NANOSECOND:
+    return "NANOSECOND";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::MICROSECOND:
+    return "MICROSECOND";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::MILLISECOND:
+    return "MILLISECOND";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::SECOND:
+    return "SECOND";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::MINUTE:
+    return "MINUTE";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::HOUR:
+    return "HOUR";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::VERTEX:
+    return "VERTEX";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::PIXEL:
+    return "PIXEL";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::TRIANGLE:
+    return "TRIANGLE";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::PRIMITIVE:
+    return "PRIMITIVE";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::FRAGMENT:
+    return "FRAGMENT";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::MILLIWATT:
+    return "MILLIWATT";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::WATT:
+    return "WATT";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::KILOWATT:
+    return "KILOWATT";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::JOULE:
+    return "JOULE";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::VOLT:
+    return "VOLT";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::AMPERE:
+    return "AMPERE";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::CELSIUS:
+    return "CELSIUS";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::FAHRENHEIT:
+    return "FAHRENHEIT";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::KELVIN:
+    return "KELVIN";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::PERCENT:
+    return "PERCENT";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::INSTRUCTION:
+    return "INSTRUCTION";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class GpuCounterDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  GpuCounterDescriptor_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GpuCounterDescriptor_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GpuCounterDescriptor_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_specs() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> specs() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_blocks() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> blocks() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_min_sampling_period_ns() const { return at<3>().valid(); }
+  uint64_t min_sampling_period_ns() const { return at<3>().as_uint64(); }
+  bool has_max_sampling_period_ns() const { return at<4>().valid(); }
+  uint64_t max_sampling_period_ns() const { return at<4>().as_uint64(); }
+  bool has_supports_instrumented_sampling() const { return at<5>().valid(); }
+  bool supports_instrumented_sampling() const { return at<5>().as_bool(); }
+};
+
+class GpuCounterDescriptor : public ::protozero::Message {
+ public:
+  using Decoder = GpuCounterDescriptor_Decoder;
+  enum : int32_t {
+    kSpecsFieldNumber = 1,
+    kBlocksFieldNumber = 2,
+    kMinSamplingPeriodNsFieldNumber = 3,
+    kMaxSamplingPeriodNsFieldNumber = 4,
+    kSupportsInstrumentedSamplingFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GpuCounterDescriptor"; }
+
+  using GpuCounterSpec = ::perfetto::protos::pbzero::GpuCounterDescriptor_GpuCounterSpec;
+  using GpuCounterBlock = ::perfetto::protos::pbzero::GpuCounterDescriptor_GpuCounterBlock;
+
+  using GpuCounterGroup = ::perfetto::protos::pbzero::GpuCounterDescriptor_GpuCounterGroup;
+  static inline const char* GpuCounterGroup_Name(GpuCounterGroup value) {
+    return ::perfetto::protos::pbzero::GpuCounterDescriptor_GpuCounterGroup_Name(value);
+  }
+
+  using MeasureUnit = ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit;
+  static inline const char* MeasureUnit_Name(MeasureUnit value) {
+    return ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit_Name(value);
+  }
+  static inline const GpuCounterGroup UNCLASSIFIED = GpuCounterGroup::UNCLASSIFIED;
+  static inline const GpuCounterGroup SYSTEM = GpuCounterGroup::SYSTEM;
+  static inline const GpuCounterGroup VERTICES = GpuCounterGroup::VERTICES;
+  static inline const GpuCounterGroup FRAGMENTS = GpuCounterGroup::FRAGMENTS;
+  static inline const GpuCounterGroup PRIMITIVES = GpuCounterGroup::PRIMITIVES;
+  static inline const GpuCounterGroup MEMORY = GpuCounterGroup::MEMORY;
+  static inline const GpuCounterGroup COMPUTE = GpuCounterGroup::COMPUTE;
+  static inline const MeasureUnit NONE = MeasureUnit::NONE;
+  static inline const MeasureUnit BIT = MeasureUnit::BIT;
+  static inline const MeasureUnit KILOBIT = MeasureUnit::KILOBIT;
+  static inline const MeasureUnit MEGABIT = MeasureUnit::MEGABIT;
+  static inline const MeasureUnit GIGABIT = MeasureUnit::GIGABIT;
+  static inline const MeasureUnit TERABIT = MeasureUnit::TERABIT;
+  static inline const MeasureUnit PETABIT = MeasureUnit::PETABIT;
+  static inline const MeasureUnit BYTE = MeasureUnit::BYTE;
+  static inline const MeasureUnit KILOBYTE = MeasureUnit::KILOBYTE;
+  static inline const MeasureUnit MEGABYTE = MeasureUnit::MEGABYTE;
+  static inline const MeasureUnit GIGABYTE = MeasureUnit::GIGABYTE;
+  static inline const MeasureUnit TERABYTE = MeasureUnit::TERABYTE;
+  static inline const MeasureUnit PETABYTE = MeasureUnit::PETABYTE;
+  static inline const MeasureUnit HERTZ = MeasureUnit::HERTZ;
+  static inline const MeasureUnit KILOHERTZ = MeasureUnit::KILOHERTZ;
+  static inline const MeasureUnit MEGAHERTZ = MeasureUnit::MEGAHERTZ;
+  static inline const MeasureUnit GIGAHERTZ = MeasureUnit::GIGAHERTZ;
+  static inline const MeasureUnit TERAHERTZ = MeasureUnit::TERAHERTZ;
+  static inline const MeasureUnit PETAHERTZ = MeasureUnit::PETAHERTZ;
+  static inline const MeasureUnit NANOSECOND = MeasureUnit::NANOSECOND;
+  static inline const MeasureUnit MICROSECOND = MeasureUnit::MICROSECOND;
+  static inline const MeasureUnit MILLISECOND = MeasureUnit::MILLISECOND;
+  static inline const MeasureUnit SECOND = MeasureUnit::SECOND;
+  static inline const MeasureUnit MINUTE = MeasureUnit::MINUTE;
+  static inline const MeasureUnit HOUR = MeasureUnit::HOUR;
+  static inline const MeasureUnit VERTEX = MeasureUnit::VERTEX;
+  static inline const MeasureUnit PIXEL = MeasureUnit::PIXEL;
+  static inline const MeasureUnit TRIANGLE = MeasureUnit::TRIANGLE;
+  static inline const MeasureUnit PRIMITIVE = MeasureUnit::PRIMITIVE;
+  static inline const MeasureUnit FRAGMENT = MeasureUnit::FRAGMENT;
+  static inline const MeasureUnit MILLIWATT = MeasureUnit::MILLIWATT;
+  static inline const MeasureUnit WATT = MeasureUnit::WATT;
+  static inline const MeasureUnit KILOWATT = MeasureUnit::KILOWATT;
+  static inline const MeasureUnit JOULE = MeasureUnit::JOULE;
+  static inline const MeasureUnit VOLT = MeasureUnit::VOLT;
+  static inline const MeasureUnit AMPERE = MeasureUnit::AMPERE;
+  static inline const MeasureUnit CELSIUS = MeasureUnit::CELSIUS;
+  static inline const MeasureUnit FAHRENHEIT = MeasureUnit::FAHRENHEIT;
+  static inline const MeasureUnit KELVIN = MeasureUnit::KELVIN;
+  static inline const MeasureUnit PERCENT = MeasureUnit::PERCENT;
+  static inline const MeasureUnit INSTRUCTION = MeasureUnit::INSTRUCTION;
+
+  using FieldMetadata_Specs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuCounterDescriptor_GpuCounterSpec,
+      GpuCounterDescriptor>;
+
+  static constexpr FieldMetadata_Specs kSpecs{};
+  template <typename T = GpuCounterDescriptor_GpuCounterSpec> T* add_specs() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_Blocks =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuCounterDescriptor_GpuCounterBlock,
+      GpuCounterDescriptor>;
+
+  static constexpr FieldMetadata_Blocks kBlocks{};
+  template <typename T = GpuCounterDescriptor_GpuCounterBlock> T* add_blocks() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_MinSamplingPeriodNs =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuCounterDescriptor>;
+
+  static constexpr FieldMetadata_MinSamplingPeriodNs kMinSamplingPeriodNs{};
+  void set_min_sampling_period_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MinSamplingPeriodNs::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_MaxSamplingPeriodNs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuCounterDescriptor>;
+
+  static constexpr FieldMetadata_MaxSamplingPeriodNs kMaxSamplingPeriodNs{};
+  void set_max_sampling_period_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MaxSamplingPeriodNs::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_SupportsInstrumentedSampling =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      GpuCounterDescriptor>;
+
+  static constexpr FieldMetadata_SupportsInstrumentedSampling kSupportsInstrumentedSampling{};
+  void set_supports_instrumented_sampling(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_SupportsInstrumentedSampling::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 GpuCounterDescriptor_GpuCounterBlock_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  GpuCounterDescriptor_GpuCounterBlock_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GpuCounterDescriptor_GpuCounterBlock_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GpuCounterDescriptor_GpuCounterBlock_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_block_id() const { return at<1>().valid(); }
+  uint32_t block_id() const { return at<1>().as_uint32(); }
+  bool has_block_capacity() const { return at<2>().valid(); }
+  uint32_t block_capacity() const { return at<2>().as_uint32(); }
+  bool has_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars name() const { return at<3>().as_string(); }
+  bool has_description() const { return at<4>().valid(); }
+  ::protozero::ConstChars description() const { return at<4>().as_string(); }
+  bool has_counter_ids() const { return at<5>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint32_t> counter_ids() const { return GetRepeated<uint32_t>(5); }
+};
+
+class GpuCounterDescriptor_GpuCounterBlock : public ::protozero::Message {
+ public:
+  using Decoder = GpuCounterDescriptor_GpuCounterBlock_Decoder;
+  enum : int32_t {
+    kBlockIdFieldNumber = 1,
+    kBlockCapacityFieldNumber = 2,
+    kNameFieldNumber = 3,
+    kDescriptionFieldNumber = 4,
+    kCounterIdsFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GpuCounterDescriptor.GpuCounterBlock"; }
+
+
+  using FieldMetadata_BlockId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GpuCounterDescriptor_GpuCounterBlock>;
+
+  static constexpr FieldMetadata_BlockId kBlockId{};
+  void set_block_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BlockId::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_BlockCapacity =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GpuCounterDescriptor_GpuCounterBlock>;
+
+  static constexpr FieldMetadata_BlockCapacity kBlockCapacity{};
+  void set_block_capacity(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BlockCapacity::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      GpuCounterDescriptor_GpuCounterBlock>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Description =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      GpuCounterDescriptor_GpuCounterBlock>;
+
+  static constexpr FieldMetadata_Description kDescription{};
+  void set_description(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Description::kFieldId, data, size);
+  }
+  void set_description(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Description::kFieldId, chars.data, chars.size);
+  }
+  void set_description(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Description::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_CounterIds =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GpuCounterDescriptor_GpuCounterBlock>;
+
+  static constexpr FieldMetadata_CounterIds kCounterIds{};
+  void add_counter_ids(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CounterIds::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 GpuCounterDescriptor_GpuCounterSpec_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/10, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  GpuCounterDescriptor_GpuCounterSpec_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GpuCounterDescriptor_GpuCounterSpec_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GpuCounterDescriptor_GpuCounterSpec_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_counter_id() const { return at<1>().valid(); }
+  uint32_t counter_id() const { return at<1>().as_uint32(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+  bool has_description() const { return at<3>().valid(); }
+  ::protozero::ConstChars description() const { return at<3>().as_string(); }
+  bool has_int_peak_value() const { return at<5>().valid(); }
+  int64_t int_peak_value() const { return at<5>().as_int64(); }
+  bool has_double_peak_value() const { return at<6>().valid(); }
+  double double_peak_value() const { return at<6>().as_double(); }
+  bool has_numerator_units() const { return at<7>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> numerator_units() const { return GetRepeated<int32_t>(7); }
+  bool has_denominator_units() const { return at<8>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> denominator_units() const { return GetRepeated<int32_t>(8); }
+  bool has_select_by_default() const { return at<9>().valid(); }
+  bool select_by_default() const { return at<9>().as_bool(); }
+  bool has_groups() const { return at<10>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> groups() const { return GetRepeated<int32_t>(10); }
+};
+
+class GpuCounterDescriptor_GpuCounterSpec : public ::protozero::Message {
+ public:
+  using Decoder = GpuCounterDescriptor_GpuCounterSpec_Decoder;
+  enum : int32_t {
+    kCounterIdFieldNumber = 1,
+    kNameFieldNumber = 2,
+    kDescriptionFieldNumber = 3,
+    kIntPeakValueFieldNumber = 5,
+    kDoublePeakValueFieldNumber = 6,
+    kNumeratorUnitsFieldNumber = 7,
+    kDenominatorUnitsFieldNumber = 8,
+    kSelectByDefaultFieldNumber = 9,
+    kGroupsFieldNumber = 10,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GpuCounterDescriptor.GpuCounterSpec"; }
+
+
+  using FieldMetadata_CounterId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GpuCounterDescriptor_GpuCounterSpec>;
+
+  static constexpr FieldMetadata_CounterId kCounterId{};
+  void set_counter_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CounterId::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      GpuCounterDescriptor_GpuCounterSpec>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Description =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      GpuCounterDescriptor_GpuCounterSpec>;
+
+  static constexpr FieldMetadata_Description kDescription{};
+  void set_description(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Description::kFieldId, data, size);
+  }
+  void set_description(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Description::kFieldId, chars.data, chars.size);
+  }
+  void set_description(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Description::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_IntPeakValue =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      GpuCounterDescriptor_GpuCounterSpec>;
+
+  static constexpr FieldMetadata_IntPeakValue kIntPeakValue{};
+  void set_int_peak_value(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IntPeakValue::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_DoublePeakValue =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      GpuCounterDescriptor_GpuCounterSpec>;
+
+  static constexpr FieldMetadata_DoublePeakValue kDoublePeakValue{};
+  void set_double_peak_value(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_DoublePeakValue::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);
+  }
+
+  using FieldMetadata_NumeratorUnits =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      GpuCounterDescriptor_MeasureUnit,
+      GpuCounterDescriptor_GpuCounterSpec>;
+
+  static constexpr FieldMetadata_NumeratorUnits kNumeratorUnits{};
+  void add_numerator_units(GpuCounterDescriptor_MeasureUnit value) {
+    static constexpr uint32_t field_id = FieldMetadata_NumeratorUnits::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_DenominatorUnits =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      GpuCounterDescriptor_MeasureUnit,
+      GpuCounterDescriptor_GpuCounterSpec>;
+
+  static constexpr FieldMetadata_DenominatorUnits kDenominatorUnits{};
+  void add_denominator_units(GpuCounterDescriptor_MeasureUnit value) {
+    static constexpr uint32_t field_id = FieldMetadata_DenominatorUnits::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_SelectByDefault =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      GpuCounterDescriptor_GpuCounterSpec>;
+
+  static constexpr FieldMetadata_SelectByDefault kSelectByDefault{};
+  void set_select_by_default(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_SelectByDefault::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_Groups =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      GpuCounterDescriptor_GpuCounterGroup,
+      GpuCounterDescriptor_GpuCounterSpec>;
+
+  static constexpr FieldMetadata_Groups kGroups{};
+  void add_groups(GpuCounterDescriptor_GpuCounterGroup value) {
+    static constexpr uint32_t field_id = FieldMetadata_Groups::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.
+// gen_amalgamated begin header: gen/protos/perfetto/common/interceptor_descriptor.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_INTERCEPTOR_DESCRIPTOR_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_INTERCEPTOR_DESCRIPTOR_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class InterceptorDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  InterceptorDescriptor_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit InterceptorDescriptor_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit InterceptorDescriptor_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(); }
+};
+
+class InterceptorDescriptor : public ::protozero::Message {
+ public:
+  using Decoder = InterceptorDescriptor_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.InterceptorDescriptor"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      InterceptorDescriptor>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/common/observable_events.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_OBSERVABLE_EVENTS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_OBSERVABLE_EVENTS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class ObservableEvents_CloneTriggerHit;
+class ObservableEvents_DataSourceInstanceStateChange;
+namespace perfetto_pbzero_enum_ObservableEvents {
+enum DataSourceInstanceState : int32_t;
+}  // namespace perfetto_pbzero_enum_ObservableEvents
+using ObservableEvents_DataSourceInstanceState = perfetto_pbzero_enum_ObservableEvents::DataSourceInstanceState;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_ObservableEvents {
+enum Type : int32_t {
+  TYPE_UNSPECIFIED = 0,
+  TYPE_DATA_SOURCES_INSTANCES = 1,
+  TYPE_ALL_DATA_SOURCES_STARTED = 2,
+  TYPE_CLONE_TRIGGER_HIT = 4,
+};
+} // namespace perfetto_pbzero_enum_ObservableEvents
+using ObservableEvents_Type = perfetto_pbzero_enum_ObservableEvents::Type;
+
+
+constexpr ObservableEvents_Type ObservableEvents_Type_MIN = ObservableEvents_Type::TYPE_UNSPECIFIED;
+constexpr ObservableEvents_Type ObservableEvents_Type_MAX = ObservableEvents_Type::TYPE_CLONE_TRIGGER_HIT;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ObservableEvents_Type_Name(::perfetto::protos::pbzero::ObservableEvents_Type value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ObservableEvents_Type::TYPE_UNSPECIFIED:
+    return "TYPE_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ObservableEvents_Type::TYPE_DATA_SOURCES_INSTANCES:
+    return "TYPE_DATA_SOURCES_INSTANCES";
+
+  case ::perfetto::protos::pbzero::ObservableEvents_Type::TYPE_ALL_DATA_SOURCES_STARTED:
+    return "TYPE_ALL_DATA_SOURCES_STARTED";
+
+  case ::perfetto::protos::pbzero::ObservableEvents_Type::TYPE_CLONE_TRIGGER_HIT:
+    return "TYPE_CLONE_TRIGGER_HIT";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_ObservableEvents {
+enum DataSourceInstanceState : int32_t {
+  DATA_SOURCE_INSTANCE_STATE_STOPPED = 1,
+  DATA_SOURCE_INSTANCE_STATE_STARTED = 2,
+};
+} // namespace perfetto_pbzero_enum_ObservableEvents
+using ObservableEvents_DataSourceInstanceState = perfetto_pbzero_enum_ObservableEvents::DataSourceInstanceState;
+
+
+constexpr ObservableEvents_DataSourceInstanceState ObservableEvents_DataSourceInstanceState_MIN = ObservableEvents_DataSourceInstanceState::DATA_SOURCE_INSTANCE_STATE_STOPPED;
+constexpr ObservableEvents_DataSourceInstanceState ObservableEvents_DataSourceInstanceState_MAX = ObservableEvents_DataSourceInstanceState::DATA_SOURCE_INSTANCE_STATE_STARTED;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ObservableEvents_DataSourceInstanceState_Name(::perfetto::protos::pbzero::ObservableEvents_DataSourceInstanceState value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ObservableEvents_DataSourceInstanceState::DATA_SOURCE_INSTANCE_STATE_STOPPED:
+    return "DATA_SOURCE_INSTANCE_STATE_STOPPED";
+
+  case ::perfetto::protos::pbzero::ObservableEvents_DataSourceInstanceState::DATA_SOURCE_INSTANCE_STATE_STARTED:
+    return "DATA_SOURCE_INSTANCE_STATE_STARTED";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class ObservableEvents_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ObservableEvents_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ObservableEvents_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ObservableEvents_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_instance_state_changes() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> instance_state_changes() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_all_data_sources_started() const { return at<2>().valid(); }
+  bool all_data_sources_started() const { return at<2>().as_bool(); }
+  bool has_clone_trigger_hit() const { return at<3>().valid(); }
+  ::protozero::ConstBytes clone_trigger_hit() const { return at<3>().as_bytes(); }
+};
+
+class ObservableEvents : public ::protozero::Message {
+ public:
+  using Decoder = ObservableEvents_Decoder;
+  enum : int32_t {
+    kInstanceStateChangesFieldNumber = 1,
+    kAllDataSourcesStartedFieldNumber = 2,
+    kCloneTriggerHitFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ObservableEvents"; }
+
+  using DataSourceInstanceStateChange = ::perfetto::protos::pbzero::ObservableEvents_DataSourceInstanceStateChange;
+  using CloneTriggerHit = ::perfetto::protos::pbzero::ObservableEvents_CloneTriggerHit;
+
+  using Type = ::perfetto::protos::pbzero::ObservableEvents_Type;
+  static inline const char* Type_Name(Type value) {
+    return ::perfetto::protos::pbzero::ObservableEvents_Type_Name(value);
+  }
+
+  using DataSourceInstanceState = ::perfetto::protos::pbzero::ObservableEvents_DataSourceInstanceState;
+  static inline const char* DataSourceInstanceState_Name(DataSourceInstanceState value) {
+    return ::perfetto::protos::pbzero::ObservableEvents_DataSourceInstanceState_Name(value);
+  }
+  static inline const Type TYPE_UNSPECIFIED = Type::TYPE_UNSPECIFIED;
+  static inline const Type TYPE_DATA_SOURCES_INSTANCES = Type::TYPE_DATA_SOURCES_INSTANCES;
+  static inline const Type TYPE_ALL_DATA_SOURCES_STARTED = Type::TYPE_ALL_DATA_SOURCES_STARTED;
+  static inline const Type TYPE_CLONE_TRIGGER_HIT = Type::TYPE_CLONE_TRIGGER_HIT;
+  static inline const DataSourceInstanceState DATA_SOURCE_INSTANCE_STATE_STOPPED = DataSourceInstanceState::DATA_SOURCE_INSTANCE_STATE_STOPPED;
+  static inline const DataSourceInstanceState DATA_SOURCE_INSTANCE_STATE_STARTED = DataSourceInstanceState::DATA_SOURCE_INSTANCE_STATE_STARTED;
+
+  using FieldMetadata_InstanceStateChanges =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ObservableEvents_DataSourceInstanceStateChange,
+      ObservableEvents>;
+
+  static constexpr FieldMetadata_InstanceStateChanges kInstanceStateChanges{};
+  template <typename T = ObservableEvents_DataSourceInstanceStateChange> T* add_instance_state_changes() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_AllDataSourcesStarted =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ObservableEvents>;
+
+  static constexpr FieldMetadata_AllDataSourcesStarted kAllDataSourcesStarted{};
+  void set_all_data_sources_started(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_AllDataSourcesStarted::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_CloneTriggerHit =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ObservableEvents_CloneTriggerHit,
+      ObservableEvents>;
+
+  static constexpr FieldMetadata_CloneTriggerHit kCloneTriggerHit{};
+  template <typename T = ObservableEvents_CloneTriggerHit> T* set_clone_trigger_hit() {
+    return BeginNestedMessage<T>(3);
+  }
+
+};
+
+class ObservableEvents_CloneTriggerHit_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ObservableEvents_CloneTriggerHit_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ObservableEvents_CloneTriggerHit_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ObservableEvents_CloneTriggerHit_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_tracing_session_id() const { return at<1>().valid(); }
+  int64_t tracing_session_id() const { return at<1>().as_int64(); }
+};
+
+class ObservableEvents_CloneTriggerHit : public ::protozero::Message {
+ public:
+  using Decoder = ObservableEvents_CloneTriggerHit_Decoder;
+  enum : int32_t {
+    kTracingSessionIdFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ObservableEvents.CloneTriggerHit"; }
+
+
+  using FieldMetadata_TracingSessionId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ObservableEvents_CloneTriggerHit>;
+
+  static constexpr FieldMetadata_TracingSessionId kTracingSessionId{};
+  void set_tracing_session_id(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TracingSessionId::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 ObservableEvents_DataSourceInstanceStateChange_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ObservableEvents_DataSourceInstanceStateChange_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ObservableEvents_DataSourceInstanceStateChange_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ObservableEvents_DataSourceInstanceStateChange_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_data_source_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars data_source_name() const { return at<2>().as_string(); }
+  bool has_state() const { return at<3>().valid(); }
+  int32_t state() const { return at<3>().as_int32(); }
+};
+
+class ObservableEvents_DataSourceInstanceStateChange : public ::protozero::Message {
+ public:
+  using Decoder = ObservableEvents_DataSourceInstanceStateChange_Decoder;
+  enum : int32_t {
+    kProducerNameFieldNumber = 1,
+    kDataSourceNameFieldNumber = 2,
+    kStateFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ObservableEvents.DataSourceInstanceStateChange"; }
+
+
+  using FieldMetadata_ProducerName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ObservableEvents_DataSourceInstanceStateChange>;
+
+  static constexpr FieldMetadata_ProducerName kProducerName{};
+  void set_producer_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ProducerName::kFieldId, data, size);
+  }
+  void set_producer_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ProducerName::kFieldId, chars.data, chars.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_DataSourceName =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ObservableEvents_DataSourceInstanceStateChange>;
+
+  static constexpr FieldMetadata_DataSourceName kDataSourceName{};
+  void set_data_source_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DataSourceName::kFieldId, data, size);
+  }
+  void set_data_source_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_DataSourceName::kFieldId, chars.data, chars.size);
+  }
+  void set_data_source_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_DataSourceName::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_State =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ObservableEvents_DataSourceInstanceState,
+      ObservableEvents_DataSourceInstanceStateChange>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(ObservableEvents_DataSourceInstanceState value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::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.
+// gen_amalgamated begin header: gen/protos/perfetto/common/perf_events.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_PERF_EVENTS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_PERF_EVENTS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class PerfEvents_RawEvent;
+class PerfEvents_Timebase;
+class PerfEvents_Tracepoint;
+namespace perfetto_pbzero_enum_PerfEvents {
+enum Counter : int32_t;
+}  // namespace perfetto_pbzero_enum_PerfEvents
+using PerfEvents_Counter = perfetto_pbzero_enum_PerfEvents::Counter;
+namespace perfetto_pbzero_enum_PerfEvents {
+enum PerfClock : int32_t;
+}  // namespace perfetto_pbzero_enum_PerfEvents
+using PerfEvents_PerfClock = perfetto_pbzero_enum_PerfEvents::PerfClock;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_PerfEvents {
+enum Counter : int32_t {
+  UNKNOWN_COUNTER = 0,
+  SW_CPU_CLOCK = 1,
+  SW_PAGE_FAULTS = 2,
+  SW_TASK_CLOCK = 3,
+  SW_CONTEXT_SWITCHES = 4,
+  SW_CPU_MIGRATIONS = 5,
+  SW_PAGE_FAULTS_MIN = 6,
+  SW_PAGE_FAULTS_MAJ = 7,
+  SW_ALIGNMENT_FAULTS = 8,
+  SW_EMULATION_FAULTS = 9,
+  SW_DUMMY = 20,
+  HW_CPU_CYCLES = 10,
+  HW_INSTRUCTIONS = 11,
+  HW_CACHE_REFERENCES = 12,
+  HW_CACHE_MISSES = 13,
+  HW_BRANCH_INSTRUCTIONS = 14,
+  HW_BRANCH_MISSES = 15,
+  HW_BUS_CYCLES = 16,
+  HW_STALLED_CYCLES_FRONTEND = 17,
+  HW_STALLED_CYCLES_BACKEND = 18,
+  HW_REF_CPU_CYCLES = 19,
+};
+} // namespace perfetto_pbzero_enum_PerfEvents
+using PerfEvents_Counter = perfetto_pbzero_enum_PerfEvents::Counter;
+
+
+constexpr PerfEvents_Counter PerfEvents_Counter_MIN = PerfEvents_Counter::UNKNOWN_COUNTER;
+constexpr PerfEvents_Counter PerfEvents_Counter_MAX = PerfEvents_Counter::SW_DUMMY;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* PerfEvents_Counter_Name(::perfetto::protos::pbzero::PerfEvents_Counter value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::UNKNOWN_COUNTER:
+    return "UNKNOWN_COUNTER";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::SW_CPU_CLOCK:
+    return "SW_CPU_CLOCK";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::SW_PAGE_FAULTS:
+    return "SW_PAGE_FAULTS";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::SW_TASK_CLOCK:
+    return "SW_TASK_CLOCK";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::SW_CONTEXT_SWITCHES:
+    return "SW_CONTEXT_SWITCHES";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::SW_CPU_MIGRATIONS:
+    return "SW_CPU_MIGRATIONS";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::SW_PAGE_FAULTS_MIN:
+    return "SW_PAGE_FAULTS_MIN";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::SW_PAGE_FAULTS_MAJ:
+    return "SW_PAGE_FAULTS_MAJ";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::SW_ALIGNMENT_FAULTS:
+    return "SW_ALIGNMENT_FAULTS";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::SW_EMULATION_FAULTS:
+    return "SW_EMULATION_FAULTS";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::SW_DUMMY:
+    return "SW_DUMMY";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::HW_CPU_CYCLES:
+    return "HW_CPU_CYCLES";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::HW_INSTRUCTIONS:
+    return "HW_INSTRUCTIONS";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::HW_CACHE_REFERENCES:
+    return "HW_CACHE_REFERENCES";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::HW_CACHE_MISSES:
+    return "HW_CACHE_MISSES";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::HW_BRANCH_INSTRUCTIONS:
+    return "HW_BRANCH_INSTRUCTIONS";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::HW_BRANCH_MISSES:
+    return "HW_BRANCH_MISSES";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::HW_BUS_CYCLES:
+    return "HW_BUS_CYCLES";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::HW_STALLED_CYCLES_FRONTEND:
+    return "HW_STALLED_CYCLES_FRONTEND";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::HW_STALLED_CYCLES_BACKEND:
+    return "HW_STALLED_CYCLES_BACKEND";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::HW_REF_CPU_CYCLES:
+    return "HW_REF_CPU_CYCLES";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_PerfEvents {
+enum PerfClock : int32_t {
+  UNKNOWN_PERF_CLOCK = 0,
+  PERF_CLOCK_REALTIME = 1,
+  PERF_CLOCK_MONOTONIC = 2,
+  PERF_CLOCK_MONOTONIC_RAW = 3,
+  PERF_CLOCK_BOOTTIME = 4,
+};
+} // namespace perfetto_pbzero_enum_PerfEvents
+using PerfEvents_PerfClock = perfetto_pbzero_enum_PerfEvents::PerfClock;
+
+
+constexpr PerfEvents_PerfClock PerfEvents_PerfClock_MIN = PerfEvents_PerfClock::UNKNOWN_PERF_CLOCK;
+constexpr PerfEvents_PerfClock PerfEvents_PerfClock_MAX = PerfEvents_PerfClock::PERF_CLOCK_BOOTTIME;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* PerfEvents_PerfClock_Name(::perfetto::protos::pbzero::PerfEvents_PerfClock value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::PerfEvents_PerfClock::UNKNOWN_PERF_CLOCK:
+    return "UNKNOWN_PERF_CLOCK";
+
+  case ::perfetto::protos::pbzero::PerfEvents_PerfClock::PERF_CLOCK_REALTIME:
+    return "PERF_CLOCK_REALTIME";
+
+  case ::perfetto::protos::pbzero::PerfEvents_PerfClock::PERF_CLOCK_MONOTONIC:
+    return "PERF_CLOCK_MONOTONIC";
+
+  case ::perfetto::protos::pbzero::PerfEvents_PerfClock::PERF_CLOCK_MONOTONIC_RAW:
+    return "PERF_CLOCK_MONOTONIC_RAW";
+
+  case ::perfetto::protos::pbzero::PerfEvents_PerfClock::PERF_CLOCK_BOOTTIME:
+    return "PERF_CLOCK_BOOTTIME";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class PerfEvents_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/0, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  PerfEvents_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PerfEvents_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PerfEvents_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+};
+
+class PerfEvents : public ::protozero::Message {
+ public:
+  using Decoder = PerfEvents_Decoder;
+  static constexpr const char* GetName() { return ".perfetto.protos.PerfEvents"; }
+
+  using Timebase = ::perfetto::protos::pbzero::PerfEvents_Timebase;
+  using Tracepoint = ::perfetto::protos::pbzero::PerfEvents_Tracepoint;
+  using RawEvent = ::perfetto::protos::pbzero::PerfEvents_RawEvent;
+
+  using Counter = ::perfetto::protos::pbzero::PerfEvents_Counter;
+  static inline const char* Counter_Name(Counter value) {
+    return ::perfetto::protos::pbzero::PerfEvents_Counter_Name(value);
+  }
+
+  using PerfClock = ::perfetto::protos::pbzero::PerfEvents_PerfClock;
+  static inline const char* PerfClock_Name(PerfClock value) {
+    return ::perfetto::protos::pbzero::PerfEvents_PerfClock_Name(value);
+  }
+  static inline const Counter UNKNOWN_COUNTER = Counter::UNKNOWN_COUNTER;
+  static inline const Counter SW_CPU_CLOCK = Counter::SW_CPU_CLOCK;
+  static inline const Counter SW_PAGE_FAULTS = Counter::SW_PAGE_FAULTS;
+  static inline const Counter SW_TASK_CLOCK = Counter::SW_TASK_CLOCK;
+  static inline const Counter SW_CONTEXT_SWITCHES = Counter::SW_CONTEXT_SWITCHES;
+  static inline const Counter SW_CPU_MIGRATIONS = Counter::SW_CPU_MIGRATIONS;
+  static inline const Counter SW_PAGE_FAULTS_MIN = Counter::SW_PAGE_FAULTS_MIN;
+  static inline const Counter SW_PAGE_FAULTS_MAJ = Counter::SW_PAGE_FAULTS_MAJ;
+  static inline const Counter SW_ALIGNMENT_FAULTS = Counter::SW_ALIGNMENT_FAULTS;
+  static inline const Counter SW_EMULATION_FAULTS = Counter::SW_EMULATION_FAULTS;
+  static inline const Counter SW_DUMMY = Counter::SW_DUMMY;
+  static inline const Counter HW_CPU_CYCLES = Counter::HW_CPU_CYCLES;
+  static inline const Counter HW_INSTRUCTIONS = Counter::HW_INSTRUCTIONS;
+  static inline const Counter HW_CACHE_REFERENCES = Counter::HW_CACHE_REFERENCES;
+  static inline const Counter HW_CACHE_MISSES = Counter::HW_CACHE_MISSES;
+  static inline const Counter HW_BRANCH_INSTRUCTIONS = Counter::HW_BRANCH_INSTRUCTIONS;
+  static inline const Counter HW_BRANCH_MISSES = Counter::HW_BRANCH_MISSES;
+  static inline const Counter HW_BUS_CYCLES = Counter::HW_BUS_CYCLES;
+  static inline const Counter HW_STALLED_CYCLES_FRONTEND = Counter::HW_STALLED_CYCLES_FRONTEND;
+  static inline const Counter HW_STALLED_CYCLES_BACKEND = Counter::HW_STALLED_CYCLES_BACKEND;
+  static inline const Counter HW_REF_CPU_CYCLES = Counter::HW_REF_CPU_CYCLES;
+  static inline const PerfClock UNKNOWN_PERF_CLOCK = PerfClock::UNKNOWN_PERF_CLOCK;
+  static inline const PerfClock PERF_CLOCK_REALTIME = PerfClock::PERF_CLOCK_REALTIME;
+  static inline const PerfClock PERF_CLOCK_MONOTONIC = PerfClock::PERF_CLOCK_MONOTONIC;
+  static inline const PerfClock PERF_CLOCK_MONOTONIC_RAW = PerfClock::PERF_CLOCK_MONOTONIC_RAW;
+  static inline const PerfClock PERF_CLOCK_BOOTTIME = PerfClock::PERF_CLOCK_BOOTTIME;
+};
+
+class PerfEvents_RawEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  PerfEvents_RawEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PerfEvents_RawEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PerfEvents_RawEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_type() const { return at<1>().valid(); }
+  uint32_t type() const { return at<1>().as_uint32(); }
+  bool has_config() const { return at<2>().valid(); }
+  uint64_t config() const { return at<2>().as_uint64(); }
+  bool has_config1() const { return at<3>().valid(); }
+  uint64_t config1() const { return at<3>().as_uint64(); }
+  bool has_config2() const { return at<4>().valid(); }
+  uint64_t config2() const { return at<4>().as_uint64(); }
+};
+
+class PerfEvents_RawEvent : public ::protozero::Message {
+ public:
+  using Decoder = PerfEvents_RawEvent_Decoder;
+  enum : int32_t {
+    kTypeFieldNumber = 1,
+    kConfigFieldNumber = 2,
+    kConfig1FieldNumber = 3,
+    kConfig2FieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PerfEvents.RawEvent"; }
+
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfEvents_RawEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::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_Config =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PerfEvents_RawEvent>;
+
+  static constexpr FieldMetadata_Config kConfig{};
+  void set_config(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Config::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_Config1 =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PerfEvents_RawEvent>;
+
+  static constexpr FieldMetadata_Config1 kConfig1{};
+  void set_config1(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Config1::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_Config2 =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PerfEvents_RawEvent>;
+
+  static constexpr FieldMetadata_Config2 kConfig2{};
+  void set_config2(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Config2::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 PerfEvents_Tracepoint_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  PerfEvents_Tracepoint_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PerfEvents_Tracepoint_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PerfEvents_Tracepoint_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_filter() const { return at<2>().valid(); }
+  ::protozero::ConstChars filter() const { return at<2>().as_string(); }
+};
+
+class PerfEvents_Tracepoint : public ::protozero::Message {
+ public:
+  using Decoder = PerfEvents_Tracepoint_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kFilterFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PerfEvents.Tracepoint"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PerfEvents_Tracepoint>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Filter =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PerfEvents_Tracepoint>;
+
+  static constexpr FieldMetadata_Filter kFilter{};
+  void set_filter(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Filter::kFieldId, data, size);
+  }
+  void set_filter(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Filter::kFieldId, chars.data, chars.size);
+  }
+  void set_filter(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Filter::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 PerfEvents_Timebase_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/11, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  PerfEvents_Timebase_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PerfEvents_Timebase_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PerfEvents_Timebase_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_frequency() const { return at<2>().valid(); }
+  uint64_t frequency() const { return at<2>().as_uint64(); }
+  bool has_period() const { return at<1>().valid(); }
+  uint64_t period() const { return at<1>().as_uint64(); }
+  bool has_counter() const { return at<4>().valid(); }
+  int32_t counter() const { return at<4>().as_int32(); }
+  bool has_tracepoint() const { return at<3>().valid(); }
+  ::protozero::ConstBytes tracepoint() const { return at<3>().as_bytes(); }
+  bool has_raw_event() const { return at<5>().valid(); }
+  ::protozero::ConstBytes raw_event() const { return at<5>().as_bytes(); }
+  bool has_timestamp_clock() const { return at<11>().valid(); }
+  int32_t timestamp_clock() const { return at<11>().as_int32(); }
+  bool has_name() const { return at<10>().valid(); }
+  ::protozero::ConstChars name() const { return at<10>().as_string(); }
+};
+
+class PerfEvents_Timebase : public ::protozero::Message {
+ public:
+  using Decoder = PerfEvents_Timebase_Decoder;
+  enum : int32_t {
+    kFrequencyFieldNumber = 2,
+    kPeriodFieldNumber = 1,
+    kCounterFieldNumber = 4,
+    kTracepointFieldNumber = 3,
+    kRawEventFieldNumber = 5,
+    kTimestampClockFieldNumber = 11,
+    kNameFieldNumber = 10,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PerfEvents.Timebase"; }
+
+
+  using FieldMetadata_Frequency =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PerfEvents_Timebase>;
+
+  static constexpr FieldMetadata_Frequency kFrequency{};
+  void set_frequency(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Frequency::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_Period =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PerfEvents_Timebase>;
+
+  static constexpr FieldMetadata_Period kPeriod{};
+  void set_period(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Period::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_Counter =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      PerfEvents_Counter,
+      PerfEvents_Timebase>;
+
+  static constexpr FieldMetadata_Counter kCounter{};
+  void set_counter(PerfEvents_Counter value) {
+    static constexpr uint32_t field_id = FieldMetadata_Counter::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_Tracepoint =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PerfEvents_Tracepoint,
+      PerfEvents_Timebase>;
+
+  static constexpr FieldMetadata_Tracepoint kTracepoint{};
+  template <typename T = PerfEvents_Tracepoint> T* set_tracepoint() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_RawEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PerfEvents_RawEvent,
+      PerfEvents_Timebase>;
+
+  static constexpr FieldMetadata_RawEvent kRawEvent{};
+  template <typename T = PerfEvents_RawEvent> T* set_raw_event() {
+    return BeginNestedMessage<T>(5);
+  }
+
+
+  using FieldMetadata_TimestampClock =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      PerfEvents_PerfClock,
+      PerfEvents_Timebase>;
+
+  static constexpr FieldMetadata_TimestampClock kTimestampClock{};
+  void set_timestamp_clock(PerfEvents_PerfClock value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimestampClock::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PerfEvents_Timebase>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/common/protolog_common.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_PROTOLOG_COMMON_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_PROTOLOG_COMMON_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+enum ProtoLogLevel : int32_t {
+  PROTOLOG_LEVEL_UNDEFINED = 0,
+  PROTOLOG_LEVEL_DEBUG = 1,
+  PROTOLOG_LEVEL_VERBOSE = 2,
+  PROTOLOG_LEVEL_INFO = 3,
+  PROTOLOG_LEVEL_WARN = 4,
+  PROTOLOG_LEVEL_ERROR = 5,
+  PROTOLOG_LEVEL_WTF = 6,
+};
+
+constexpr ProtoLogLevel ProtoLogLevel_MIN = ProtoLogLevel::PROTOLOG_LEVEL_UNDEFINED;
+constexpr ProtoLogLevel ProtoLogLevel_MAX = ProtoLogLevel::PROTOLOG_LEVEL_WTF;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ProtoLogLevel_Name(::perfetto::protos::pbzero::ProtoLogLevel value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ProtoLogLevel::PROTOLOG_LEVEL_UNDEFINED:
+    return "PROTOLOG_LEVEL_UNDEFINED";
+
+  case ::perfetto::protos::pbzero::ProtoLogLevel::PROTOLOG_LEVEL_DEBUG:
+    return "PROTOLOG_LEVEL_DEBUG";
+
+  case ::perfetto::protos::pbzero::ProtoLogLevel::PROTOLOG_LEVEL_VERBOSE:
+    return "PROTOLOG_LEVEL_VERBOSE";
+
+  case ::perfetto::protos::pbzero::ProtoLogLevel::PROTOLOG_LEVEL_INFO:
+    return "PROTOLOG_LEVEL_INFO";
+
+  case ::perfetto::protos::pbzero::ProtoLogLevel::PROTOLOG_LEVEL_WARN:
+    return "PROTOLOG_LEVEL_WARN";
+
+  case ::perfetto::protos::pbzero::ProtoLogLevel::PROTOLOG_LEVEL_ERROR:
+    return "PROTOLOG_LEVEL_ERROR";
+
+  case ::perfetto::protos::pbzero::ProtoLogLevel::PROTOLOG_LEVEL_WTF:
+    return "PROTOLOG_LEVEL_WTF";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/common/sys_stats_counters.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_SYS_STATS_COUNTERS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_SYS_STATS_COUNTERS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+enum MeminfoCounters : int32_t {
+  MEMINFO_UNSPECIFIED = 0,
+  MEMINFO_MEM_TOTAL = 1,
+  MEMINFO_MEM_FREE = 2,
+  MEMINFO_MEM_AVAILABLE = 3,
+  MEMINFO_BUFFERS = 4,
+  MEMINFO_CACHED = 5,
+  MEMINFO_SWAP_CACHED = 6,
+  MEMINFO_ACTIVE = 7,
+  MEMINFO_INACTIVE = 8,
+  MEMINFO_ACTIVE_ANON = 9,
+  MEMINFO_INACTIVE_ANON = 10,
+  MEMINFO_ACTIVE_FILE = 11,
+  MEMINFO_INACTIVE_FILE = 12,
+  MEMINFO_UNEVICTABLE = 13,
+  MEMINFO_MLOCKED = 14,
+  MEMINFO_SWAP_TOTAL = 15,
+  MEMINFO_SWAP_FREE = 16,
+  MEMINFO_DIRTY = 17,
+  MEMINFO_WRITEBACK = 18,
+  MEMINFO_ANON_PAGES = 19,
+  MEMINFO_MAPPED = 20,
+  MEMINFO_SHMEM = 21,
+  MEMINFO_SLAB = 22,
+  MEMINFO_SLAB_RECLAIMABLE = 23,
+  MEMINFO_SLAB_UNRECLAIMABLE = 24,
+  MEMINFO_KERNEL_STACK = 25,
+  MEMINFO_PAGE_TABLES = 26,
+  MEMINFO_COMMIT_LIMIT = 27,
+  MEMINFO_COMMITED_AS = 28,
+  MEMINFO_VMALLOC_TOTAL = 29,
+  MEMINFO_VMALLOC_USED = 30,
+  MEMINFO_VMALLOC_CHUNK = 31,
+  MEMINFO_CMA_TOTAL = 32,
+  MEMINFO_CMA_FREE = 33,
+};
+
+constexpr MeminfoCounters MeminfoCounters_MIN = MeminfoCounters::MEMINFO_UNSPECIFIED;
+constexpr MeminfoCounters MeminfoCounters_MAX = MeminfoCounters::MEMINFO_CMA_FREE;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* MeminfoCounters_Name(::perfetto::protos::pbzero::MeminfoCounters value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_UNSPECIFIED:
+    return "MEMINFO_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_MEM_TOTAL:
+    return "MEMINFO_MEM_TOTAL";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_MEM_FREE:
+    return "MEMINFO_MEM_FREE";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_MEM_AVAILABLE:
+    return "MEMINFO_MEM_AVAILABLE";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_BUFFERS:
+    return "MEMINFO_BUFFERS";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_CACHED:
+    return "MEMINFO_CACHED";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_SWAP_CACHED:
+    return "MEMINFO_SWAP_CACHED";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_ACTIVE:
+    return "MEMINFO_ACTIVE";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_INACTIVE:
+    return "MEMINFO_INACTIVE";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_ACTIVE_ANON:
+    return "MEMINFO_ACTIVE_ANON";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_INACTIVE_ANON:
+    return "MEMINFO_INACTIVE_ANON";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_ACTIVE_FILE:
+    return "MEMINFO_ACTIVE_FILE";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_INACTIVE_FILE:
+    return "MEMINFO_INACTIVE_FILE";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_UNEVICTABLE:
+    return "MEMINFO_UNEVICTABLE";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_MLOCKED:
+    return "MEMINFO_MLOCKED";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_SWAP_TOTAL:
+    return "MEMINFO_SWAP_TOTAL";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_SWAP_FREE:
+    return "MEMINFO_SWAP_FREE";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_DIRTY:
+    return "MEMINFO_DIRTY";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_WRITEBACK:
+    return "MEMINFO_WRITEBACK";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_ANON_PAGES:
+    return "MEMINFO_ANON_PAGES";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_MAPPED:
+    return "MEMINFO_MAPPED";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_SHMEM:
+    return "MEMINFO_SHMEM";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_SLAB:
+    return "MEMINFO_SLAB";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_SLAB_RECLAIMABLE:
+    return "MEMINFO_SLAB_RECLAIMABLE";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_SLAB_UNRECLAIMABLE:
+    return "MEMINFO_SLAB_UNRECLAIMABLE";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_KERNEL_STACK:
+    return "MEMINFO_KERNEL_STACK";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_PAGE_TABLES:
+    return "MEMINFO_PAGE_TABLES";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_COMMIT_LIMIT:
+    return "MEMINFO_COMMIT_LIMIT";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_COMMITED_AS:
+    return "MEMINFO_COMMITED_AS";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_VMALLOC_TOTAL:
+    return "MEMINFO_VMALLOC_TOTAL";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_VMALLOC_USED:
+    return "MEMINFO_VMALLOC_USED";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_VMALLOC_CHUNK:
+    return "MEMINFO_VMALLOC_CHUNK";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_CMA_TOTAL:
+    return "MEMINFO_CMA_TOTAL";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_CMA_FREE:
+    return "MEMINFO_CMA_FREE";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+enum VmstatCounters : int32_t {
+  VMSTAT_UNSPECIFIED = 0,
+  VMSTAT_NR_FREE_PAGES = 1,
+  VMSTAT_NR_ALLOC_BATCH = 2,
+  VMSTAT_NR_INACTIVE_ANON = 3,
+  VMSTAT_NR_ACTIVE_ANON = 4,
+  VMSTAT_NR_INACTIVE_FILE = 5,
+  VMSTAT_NR_ACTIVE_FILE = 6,
+  VMSTAT_NR_UNEVICTABLE = 7,
+  VMSTAT_NR_MLOCK = 8,
+  VMSTAT_NR_ANON_PAGES = 9,
+  VMSTAT_NR_MAPPED = 10,
+  VMSTAT_NR_FILE_PAGES = 11,
+  VMSTAT_NR_DIRTY = 12,
+  VMSTAT_NR_WRITEBACK = 13,
+  VMSTAT_NR_SLAB_RECLAIMABLE = 14,
+  VMSTAT_NR_SLAB_UNRECLAIMABLE = 15,
+  VMSTAT_NR_PAGE_TABLE_PAGES = 16,
+  VMSTAT_NR_KERNEL_STACK = 17,
+  VMSTAT_NR_OVERHEAD = 18,
+  VMSTAT_NR_UNSTABLE = 19,
+  VMSTAT_NR_BOUNCE = 20,
+  VMSTAT_NR_VMSCAN_WRITE = 21,
+  VMSTAT_NR_VMSCAN_IMMEDIATE_RECLAIM = 22,
+  VMSTAT_NR_WRITEBACK_TEMP = 23,
+  VMSTAT_NR_ISOLATED_ANON = 24,
+  VMSTAT_NR_ISOLATED_FILE = 25,
+  VMSTAT_NR_SHMEM = 26,
+  VMSTAT_NR_DIRTIED = 27,
+  VMSTAT_NR_WRITTEN = 28,
+  VMSTAT_NR_PAGES_SCANNED = 29,
+  VMSTAT_WORKINGSET_REFAULT = 30,
+  VMSTAT_WORKINGSET_ACTIVATE = 31,
+  VMSTAT_WORKINGSET_NODERECLAIM = 32,
+  VMSTAT_NR_ANON_TRANSPARENT_HUGEPAGES = 33,
+  VMSTAT_NR_FREE_CMA = 34,
+  VMSTAT_NR_SWAPCACHE = 35,
+  VMSTAT_NR_DIRTY_THRESHOLD = 36,
+  VMSTAT_NR_DIRTY_BACKGROUND_THRESHOLD = 37,
+  VMSTAT_PGPGIN = 38,
+  VMSTAT_PGPGOUT = 39,
+  VMSTAT_PGPGOUTCLEAN = 40,
+  VMSTAT_PSWPIN = 41,
+  VMSTAT_PSWPOUT = 42,
+  VMSTAT_PGALLOC_DMA = 43,
+  VMSTAT_PGALLOC_NORMAL = 44,
+  VMSTAT_PGALLOC_MOVABLE = 45,
+  VMSTAT_PGFREE = 46,
+  VMSTAT_PGACTIVATE = 47,
+  VMSTAT_PGDEACTIVATE = 48,
+  VMSTAT_PGFAULT = 49,
+  VMSTAT_PGMAJFAULT = 50,
+  VMSTAT_PGREFILL_DMA = 51,
+  VMSTAT_PGREFILL_NORMAL = 52,
+  VMSTAT_PGREFILL_MOVABLE = 53,
+  VMSTAT_PGSTEAL_KSWAPD_DMA = 54,
+  VMSTAT_PGSTEAL_KSWAPD_NORMAL = 55,
+  VMSTAT_PGSTEAL_KSWAPD_MOVABLE = 56,
+  VMSTAT_PGSTEAL_DIRECT_DMA = 57,
+  VMSTAT_PGSTEAL_DIRECT_NORMAL = 58,
+  VMSTAT_PGSTEAL_DIRECT_MOVABLE = 59,
+  VMSTAT_PGSCAN_KSWAPD_DMA = 60,
+  VMSTAT_PGSCAN_KSWAPD_NORMAL = 61,
+  VMSTAT_PGSCAN_KSWAPD_MOVABLE = 62,
+  VMSTAT_PGSCAN_DIRECT_DMA = 63,
+  VMSTAT_PGSCAN_DIRECT_NORMAL = 64,
+  VMSTAT_PGSCAN_DIRECT_MOVABLE = 65,
+  VMSTAT_PGSCAN_DIRECT_THROTTLE = 66,
+  VMSTAT_PGINODESTEAL = 67,
+  VMSTAT_SLABS_SCANNED = 68,
+  VMSTAT_KSWAPD_INODESTEAL = 69,
+  VMSTAT_KSWAPD_LOW_WMARK_HIT_QUICKLY = 70,
+  VMSTAT_KSWAPD_HIGH_WMARK_HIT_QUICKLY = 71,
+  VMSTAT_PAGEOUTRUN = 72,
+  VMSTAT_ALLOCSTALL = 73,
+  VMSTAT_PGROTATED = 74,
+  VMSTAT_DROP_PAGECACHE = 75,
+  VMSTAT_DROP_SLAB = 76,
+  VMSTAT_PGMIGRATE_SUCCESS = 77,
+  VMSTAT_PGMIGRATE_FAIL = 78,
+  VMSTAT_COMPACT_MIGRATE_SCANNED = 79,
+  VMSTAT_COMPACT_FREE_SCANNED = 80,
+  VMSTAT_COMPACT_ISOLATED = 81,
+  VMSTAT_COMPACT_STALL = 82,
+  VMSTAT_COMPACT_FAIL = 83,
+  VMSTAT_COMPACT_SUCCESS = 84,
+  VMSTAT_COMPACT_DAEMON_WAKE = 85,
+  VMSTAT_UNEVICTABLE_PGS_CULLED = 86,
+  VMSTAT_UNEVICTABLE_PGS_SCANNED = 87,
+  VMSTAT_UNEVICTABLE_PGS_RESCUED = 88,
+  VMSTAT_UNEVICTABLE_PGS_MLOCKED = 89,
+  VMSTAT_UNEVICTABLE_PGS_MUNLOCKED = 90,
+  VMSTAT_UNEVICTABLE_PGS_CLEARED = 91,
+  VMSTAT_UNEVICTABLE_PGS_STRANDED = 92,
+  VMSTAT_NR_ZSPAGES = 93,
+  VMSTAT_NR_ION_HEAP = 94,
+  VMSTAT_NR_GPU_HEAP = 95,
+  VMSTAT_ALLOCSTALL_DMA = 96,
+  VMSTAT_ALLOCSTALL_MOVABLE = 97,
+  VMSTAT_ALLOCSTALL_NORMAL = 98,
+  VMSTAT_COMPACT_DAEMON_FREE_SCANNED = 99,
+  VMSTAT_COMPACT_DAEMON_MIGRATE_SCANNED = 100,
+  VMSTAT_NR_FASTRPC = 101,
+  VMSTAT_NR_INDIRECTLY_RECLAIMABLE = 102,
+  VMSTAT_NR_ION_HEAP_POOL = 103,
+  VMSTAT_NR_KERNEL_MISC_RECLAIMABLE = 104,
+  VMSTAT_NR_SHADOW_CALL_STACK_BYTES = 105,
+  VMSTAT_NR_SHMEM_HUGEPAGES = 106,
+  VMSTAT_NR_SHMEM_PMDMAPPED = 107,
+  VMSTAT_NR_UNRECLAIMABLE_PAGES = 108,
+  VMSTAT_NR_ZONE_ACTIVE_ANON = 109,
+  VMSTAT_NR_ZONE_ACTIVE_FILE = 110,
+  VMSTAT_NR_ZONE_INACTIVE_ANON = 111,
+  VMSTAT_NR_ZONE_INACTIVE_FILE = 112,
+  VMSTAT_NR_ZONE_UNEVICTABLE = 113,
+  VMSTAT_NR_ZONE_WRITE_PENDING = 114,
+  VMSTAT_OOM_KILL = 115,
+  VMSTAT_PGLAZYFREE = 116,
+  VMSTAT_PGLAZYFREED = 117,
+  VMSTAT_PGREFILL = 118,
+  VMSTAT_PGSCAN_DIRECT = 119,
+  VMSTAT_PGSCAN_KSWAPD = 120,
+  VMSTAT_PGSKIP_DMA = 121,
+  VMSTAT_PGSKIP_MOVABLE = 122,
+  VMSTAT_PGSKIP_NORMAL = 123,
+  VMSTAT_PGSTEAL_DIRECT = 124,
+  VMSTAT_PGSTEAL_KSWAPD = 125,
+  VMSTAT_SWAP_RA = 126,
+  VMSTAT_SWAP_RA_HIT = 127,
+  VMSTAT_WORKINGSET_RESTORE = 128,
+  VMSTAT_ALLOCSTALL_DEVICE = 129,
+  VMSTAT_ALLOCSTALL_DMA32 = 130,
+  VMSTAT_BALLOON_DEFLATE = 131,
+  VMSTAT_BALLOON_INFLATE = 132,
+  VMSTAT_BALLOON_MIGRATE = 133,
+  VMSTAT_CMA_ALLOC_FAIL = 134,
+  VMSTAT_CMA_ALLOC_SUCCESS = 135,
+  VMSTAT_NR_FILE_HUGEPAGES = 136,
+  VMSTAT_NR_FILE_PMDMAPPED = 137,
+  VMSTAT_NR_FOLL_PIN_ACQUIRED = 138,
+  VMSTAT_NR_FOLL_PIN_RELEASED = 139,
+  VMSTAT_NR_SEC_PAGE_TABLE_PAGES = 140,
+  VMSTAT_NR_SHADOW_CALL_STACK = 141,
+  VMSTAT_NR_SWAPCACHED = 142,
+  VMSTAT_NR_THROTTLED_WRITTEN = 143,
+  VMSTAT_PGALLOC_DEVICE = 144,
+  VMSTAT_PGALLOC_DMA32 = 145,
+  VMSTAT_PGDEMOTE_DIRECT = 146,
+  VMSTAT_PGDEMOTE_KSWAPD = 147,
+  VMSTAT_PGREUSE = 148,
+  VMSTAT_PGSCAN_ANON = 149,
+  VMSTAT_PGSCAN_FILE = 150,
+  VMSTAT_PGSKIP_DEVICE = 151,
+  VMSTAT_PGSKIP_DMA32 = 152,
+  VMSTAT_PGSTEAL_ANON = 153,
+  VMSTAT_PGSTEAL_FILE = 154,
+  VMSTAT_THP_COLLAPSE_ALLOC = 155,
+  VMSTAT_THP_COLLAPSE_ALLOC_FAILED = 156,
+  VMSTAT_THP_DEFERRED_SPLIT_PAGE = 157,
+  VMSTAT_THP_FAULT_ALLOC = 158,
+  VMSTAT_THP_FAULT_FALLBACK = 159,
+  VMSTAT_THP_FAULT_FALLBACK_CHARGE = 160,
+  VMSTAT_THP_FILE_ALLOC = 161,
+  VMSTAT_THP_FILE_FALLBACK = 162,
+  VMSTAT_THP_FILE_FALLBACK_CHARGE = 163,
+  VMSTAT_THP_FILE_MAPPED = 164,
+  VMSTAT_THP_MIGRATION_FAIL = 165,
+  VMSTAT_THP_MIGRATION_SPLIT = 166,
+  VMSTAT_THP_MIGRATION_SUCCESS = 167,
+  VMSTAT_THP_SCAN_EXCEED_NONE_PTE = 168,
+  VMSTAT_THP_SCAN_EXCEED_SHARE_PTE = 169,
+  VMSTAT_THP_SCAN_EXCEED_SWAP_PTE = 170,
+  VMSTAT_THP_SPLIT_PAGE = 171,
+  VMSTAT_THP_SPLIT_PAGE_FAILED = 172,
+  VMSTAT_THP_SPLIT_PMD = 173,
+  VMSTAT_THP_SWPOUT = 174,
+  VMSTAT_THP_SWPOUT_FALLBACK = 175,
+  VMSTAT_THP_ZERO_PAGE_ALLOC = 176,
+  VMSTAT_THP_ZERO_PAGE_ALLOC_FAILED = 177,
+  VMSTAT_VMA_LOCK_ABORT = 178,
+  VMSTAT_VMA_LOCK_MISS = 179,
+  VMSTAT_VMA_LOCK_RETRY = 180,
+  VMSTAT_VMA_LOCK_SUCCESS = 181,
+  VMSTAT_WORKINGSET_ACTIVATE_ANON = 182,
+  VMSTAT_WORKINGSET_ACTIVATE_FILE = 183,
+  VMSTAT_WORKINGSET_NODES = 184,
+  VMSTAT_WORKINGSET_REFAULT_ANON = 185,
+  VMSTAT_WORKINGSET_REFAULT_FILE = 186,
+  VMSTAT_WORKINGSET_RESTORE_ANON = 187,
+  VMSTAT_WORKINGSET_RESTORE_FILE = 188,
+};
+
+constexpr VmstatCounters VmstatCounters_MIN = VmstatCounters::VMSTAT_UNSPECIFIED;
+constexpr VmstatCounters VmstatCounters_MAX = VmstatCounters::VMSTAT_WORKINGSET_RESTORE_FILE;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* VmstatCounters_Name(::perfetto::protos::pbzero::VmstatCounters value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_UNSPECIFIED:
+    return "VMSTAT_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_FREE_PAGES:
+    return "VMSTAT_NR_FREE_PAGES";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_ALLOC_BATCH:
+    return "VMSTAT_NR_ALLOC_BATCH";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_INACTIVE_ANON:
+    return "VMSTAT_NR_INACTIVE_ANON";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_ACTIVE_ANON:
+    return "VMSTAT_NR_ACTIVE_ANON";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_INACTIVE_FILE:
+    return "VMSTAT_NR_INACTIVE_FILE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_ACTIVE_FILE:
+    return "VMSTAT_NR_ACTIVE_FILE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_UNEVICTABLE:
+    return "VMSTAT_NR_UNEVICTABLE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_MLOCK:
+    return "VMSTAT_NR_MLOCK";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_ANON_PAGES:
+    return "VMSTAT_NR_ANON_PAGES";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_MAPPED:
+    return "VMSTAT_NR_MAPPED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_FILE_PAGES:
+    return "VMSTAT_NR_FILE_PAGES";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_DIRTY:
+    return "VMSTAT_NR_DIRTY";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_WRITEBACK:
+    return "VMSTAT_NR_WRITEBACK";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_SLAB_RECLAIMABLE:
+    return "VMSTAT_NR_SLAB_RECLAIMABLE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_SLAB_UNRECLAIMABLE:
+    return "VMSTAT_NR_SLAB_UNRECLAIMABLE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_PAGE_TABLE_PAGES:
+    return "VMSTAT_NR_PAGE_TABLE_PAGES";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_KERNEL_STACK:
+    return "VMSTAT_NR_KERNEL_STACK";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_OVERHEAD:
+    return "VMSTAT_NR_OVERHEAD";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_UNSTABLE:
+    return "VMSTAT_NR_UNSTABLE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_BOUNCE:
+    return "VMSTAT_NR_BOUNCE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_VMSCAN_WRITE:
+    return "VMSTAT_NR_VMSCAN_WRITE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_VMSCAN_IMMEDIATE_RECLAIM:
+    return "VMSTAT_NR_VMSCAN_IMMEDIATE_RECLAIM";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_WRITEBACK_TEMP:
+    return "VMSTAT_NR_WRITEBACK_TEMP";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_ISOLATED_ANON:
+    return "VMSTAT_NR_ISOLATED_ANON";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_ISOLATED_FILE:
+    return "VMSTAT_NR_ISOLATED_FILE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_SHMEM:
+    return "VMSTAT_NR_SHMEM";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_DIRTIED:
+    return "VMSTAT_NR_DIRTIED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_WRITTEN:
+    return "VMSTAT_NR_WRITTEN";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_PAGES_SCANNED:
+    return "VMSTAT_NR_PAGES_SCANNED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_WORKINGSET_REFAULT:
+    return "VMSTAT_WORKINGSET_REFAULT";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_WORKINGSET_ACTIVATE:
+    return "VMSTAT_WORKINGSET_ACTIVATE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_WORKINGSET_NODERECLAIM:
+    return "VMSTAT_WORKINGSET_NODERECLAIM";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_ANON_TRANSPARENT_HUGEPAGES:
+    return "VMSTAT_NR_ANON_TRANSPARENT_HUGEPAGES";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_FREE_CMA:
+    return "VMSTAT_NR_FREE_CMA";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_SWAPCACHE:
+    return "VMSTAT_NR_SWAPCACHE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_DIRTY_THRESHOLD:
+    return "VMSTAT_NR_DIRTY_THRESHOLD";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_DIRTY_BACKGROUND_THRESHOLD:
+    return "VMSTAT_NR_DIRTY_BACKGROUND_THRESHOLD";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGPGIN:
+    return "VMSTAT_PGPGIN";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGPGOUT:
+    return "VMSTAT_PGPGOUT";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGPGOUTCLEAN:
+    return "VMSTAT_PGPGOUTCLEAN";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PSWPIN:
+    return "VMSTAT_PSWPIN";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PSWPOUT:
+    return "VMSTAT_PSWPOUT";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGALLOC_DMA:
+    return "VMSTAT_PGALLOC_DMA";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGALLOC_NORMAL:
+    return "VMSTAT_PGALLOC_NORMAL";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGALLOC_MOVABLE:
+    return "VMSTAT_PGALLOC_MOVABLE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGFREE:
+    return "VMSTAT_PGFREE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGACTIVATE:
+    return "VMSTAT_PGACTIVATE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGDEACTIVATE:
+    return "VMSTAT_PGDEACTIVATE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGFAULT:
+    return "VMSTAT_PGFAULT";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGMAJFAULT:
+    return "VMSTAT_PGMAJFAULT";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGREFILL_DMA:
+    return "VMSTAT_PGREFILL_DMA";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGREFILL_NORMAL:
+    return "VMSTAT_PGREFILL_NORMAL";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGREFILL_MOVABLE:
+    return "VMSTAT_PGREFILL_MOVABLE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSTEAL_KSWAPD_DMA:
+    return "VMSTAT_PGSTEAL_KSWAPD_DMA";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSTEAL_KSWAPD_NORMAL:
+    return "VMSTAT_PGSTEAL_KSWAPD_NORMAL";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSTEAL_KSWAPD_MOVABLE:
+    return "VMSTAT_PGSTEAL_KSWAPD_MOVABLE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSTEAL_DIRECT_DMA:
+    return "VMSTAT_PGSTEAL_DIRECT_DMA";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSTEAL_DIRECT_NORMAL:
+    return "VMSTAT_PGSTEAL_DIRECT_NORMAL";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSTEAL_DIRECT_MOVABLE:
+    return "VMSTAT_PGSTEAL_DIRECT_MOVABLE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSCAN_KSWAPD_DMA:
+    return "VMSTAT_PGSCAN_KSWAPD_DMA";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSCAN_KSWAPD_NORMAL:
+    return "VMSTAT_PGSCAN_KSWAPD_NORMAL";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSCAN_KSWAPD_MOVABLE:
+    return "VMSTAT_PGSCAN_KSWAPD_MOVABLE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSCAN_DIRECT_DMA:
+    return "VMSTAT_PGSCAN_DIRECT_DMA";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSCAN_DIRECT_NORMAL:
+    return "VMSTAT_PGSCAN_DIRECT_NORMAL";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSCAN_DIRECT_MOVABLE:
+    return "VMSTAT_PGSCAN_DIRECT_MOVABLE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSCAN_DIRECT_THROTTLE:
+    return "VMSTAT_PGSCAN_DIRECT_THROTTLE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGINODESTEAL:
+    return "VMSTAT_PGINODESTEAL";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_SLABS_SCANNED:
+    return "VMSTAT_SLABS_SCANNED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_KSWAPD_INODESTEAL:
+    return "VMSTAT_KSWAPD_INODESTEAL";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_KSWAPD_LOW_WMARK_HIT_QUICKLY:
+    return "VMSTAT_KSWAPD_LOW_WMARK_HIT_QUICKLY";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_KSWAPD_HIGH_WMARK_HIT_QUICKLY:
+    return "VMSTAT_KSWAPD_HIGH_WMARK_HIT_QUICKLY";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PAGEOUTRUN:
+    return "VMSTAT_PAGEOUTRUN";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_ALLOCSTALL:
+    return "VMSTAT_ALLOCSTALL";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGROTATED:
+    return "VMSTAT_PGROTATED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_DROP_PAGECACHE:
+    return "VMSTAT_DROP_PAGECACHE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_DROP_SLAB:
+    return "VMSTAT_DROP_SLAB";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGMIGRATE_SUCCESS:
+    return "VMSTAT_PGMIGRATE_SUCCESS";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGMIGRATE_FAIL:
+    return "VMSTAT_PGMIGRATE_FAIL";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_COMPACT_MIGRATE_SCANNED:
+    return "VMSTAT_COMPACT_MIGRATE_SCANNED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_COMPACT_FREE_SCANNED:
+    return "VMSTAT_COMPACT_FREE_SCANNED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_COMPACT_ISOLATED:
+    return "VMSTAT_COMPACT_ISOLATED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_COMPACT_STALL:
+    return "VMSTAT_COMPACT_STALL";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_COMPACT_FAIL:
+    return "VMSTAT_COMPACT_FAIL";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_COMPACT_SUCCESS:
+    return "VMSTAT_COMPACT_SUCCESS";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_COMPACT_DAEMON_WAKE:
+    return "VMSTAT_COMPACT_DAEMON_WAKE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_UNEVICTABLE_PGS_CULLED:
+    return "VMSTAT_UNEVICTABLE_PGS_CULLED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_UNEVICTABLE_PGS_SCANNED:
+    return "VMSTAT_UNEVICTABLE_PGS_SCANNED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_UNEVICTABLE_PGS_RESCUED:
+    return "VMSTAT_UNEVICTABLE_PGS_RESCUED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_UNEVICTABLE_PGS_MLOCKED:
+    return "VMSTAT_UNEVICTABLE_PGS_MLOCKED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_UNEVICTABLE_PGS_MUNLOCKED:
+    return "VMSTAT_UNEVICTABLE_PGS_MUNLOCKED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_UNEVICTABLE_PGS_CLEARED:
+    return "VMSTAT_UNEVICTABLE_PGS_CLEARED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_UNEVICTABLE_PGS_STRANDED:
+    return "VMSTAT_UNEVICTABLE_PGS_STRANDED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_ZSPAGES:
+    return "VMSTAT_NR_ZSPAGES";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_ION_HEAP:
+    return "VMSTAT_NR_ION_HEAP";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_GPU_HEAP:
+    return "VMSTAT_NR_GPU_HEAP";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_ALLOCSTALL_DMA:
+    return "VMSTAT_ALLOCSTALL_DMA";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_ALLOCSTALL_MOVABLE:
+    return "VMSTAT_ALLOCSTALL_MOVABLE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_ALLOCSTALL_NORMAL:
+    return "VMSTAT_ALLOCSTALL_NORMAL";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_COMPACT_DAEMON_FREE_SCANNED:
+    return "VMSTAT_COMPACT_DAEMON_FREE_SCANNED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_COMPACT_DAEMON_MIGRATE_SCANNED:
+    return "VMSTAT_COMPACT_DAEMON_MIGRATE_SCANNED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_FASTRPC:
+    return "VMSTAT_NR_FASTRPC";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_INDIRECTLY_RECLAIMABLE:
+    return "VMSTAT_NR_INDIRECTLY_RECLAIMABLE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_ION_HEAP_POOL:
+    return "VMSTAT_NR_ION_HEAP_POOL";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_KERNEL_MISC_RECLAIMABLE:
+    return "VMSTAT_NR_KERNEL_MISC_RECLAIMABLE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_SHADOW_CALL_STACK_BYTES:
+    return "VMSTAT_NR_SHADOW_CALL_STACK_BYTES";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_SHMEM_HUGEPAGES:
+    return "VMSTAT_NR_SHMEM_HUGEPAGES";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_SHMEM_PMDMAPPED:
+    return "VMSTAT_NR_SHMEM_PMDMAPPED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_UNRECLAIMABLE_PAGES:
+    return "VMSTAT_NR_UNRECLAIMABLE_PAGES";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_ZONE_ACTIVE_ANON:
+    return "VMSTAT_NR_ZONE_ACTIVE_ANON";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_ZONE_ACTIVE_FILE:
+    return "VMSTAT_NR_ZONE_ACTIVE_FILE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_ZONE_INACTIVE_ANON:
+    return "VMSTAT_NR_ZONE_INACTIVE_ANON";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_ZONE_INACTIVE_FILE:
+    return "VMSTAT_NR_ZONE_INACTIVE_FILE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_ZONE_UNEVICTABLE:
+    return "VMSTAT_NR_ZONE_UNEVICTABLE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_ZONE_WRITE_PENDING:
+    return "VMSTAT_NR_ZONE_WRITE_PENDING";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_OOM_KILL:
+    return "VMSTAT_OOM_KILL";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGLAZYFREE:
+    return "VMSTAT_PGLAZYFREE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGLAZYFREED:
+    return "VMSTAT_PGLAZYFREED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGREFILL:
+    return "VMSTAT_PGREFILL";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSCAN_DIRECT:
+    return "VMSTAT_PGSCAN_DIRECT";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSCAN_KSWAPD:
+    return "VMSTAT_PGSCAN_KSWAPD";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSKIP_DMA:
+    return "VMSTAT_PGSKIP_DMA";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSKIP_MOVABLE:
+    return "VMSTAT_PGSKIP_MOVABLE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSKIP_NORMAL:
+    return "VMSTAT_PGSKIP_NORMAL";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSTEAL_DIRECT:
+    return "VMSTAT_PGSTEAL_DIRECT";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSTEAL_KSWAPD:
+    return "VMSTAT_PGSTEAL_KSWAPD";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_SWAP_RA:
+    return "VMSTAT_SWAP_RA";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_SWAP_RA_HIT:
+    return "VMSTAT_SWAP_RA_HIT";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_WORKINGSET_RESTORE:
+    return "VMSTAT_WORKINGSET_RESTORE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_ALLOCSTALL_DEVICE:
+    return "VMSTAT_ALLOCSTALL_DEVICE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_ALLOCSTALL_DMA32:
+    return "VMSTAT_ALLOCSTALL_DMA32";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_BALLOON_DEFLATE:
+    return "VMSTAT_BALLOON_DEFLATE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_BALLOON_INFLATE:
+    return "VMSTAT_BALLOON_INFLATE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_BALLOON_MIGRATE:
+    return "VMSTAT_BALLOON_MIGRATE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_CMA_ALLOC_FAIL:
+    return "VMSTAT_CMA_ALLOC_FAIL";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_CMA_ALLOC_SUCCESS:
+    return "VMSTAT_CMA_ALLOC_SUCCESS";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_FILE_HUGEPAGES:
+    return "VMSTAT_NR_FILE_HUGEPAGES";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_FILE_PMDMAPPED:
+    return "VMSTAT_NR_FILE_PMDMAPPED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_FOLL_PIN_ACQUIRED:
+    return "VMSTAT_NR_FOLL_PIN_ACQUIRED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_FOLL_PIN_RELEASED:
+    return "VMSTAT_NR_FOLL_PIN_RELEASED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_SEC_PAGE_TABLE_PAGES:
+    return "VMSTAT_NR_SEC_PAGE_TABLE_PAGES";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_SHADOW_CALL_STACK:
+    return "VMSTAT_NR_SHADOW_CALL_STACK";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_SWAPCACHED:
+    return "VMSTAT_NR_SWAPCACHED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_THROTTLED_WRITTEN:
+    return "VMSTAT_NR_THROTTLED_WRITTEN";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGALLOC_DEVICE:
+    return "VMSTAT_PGALLOC_DEVICE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGALLOC_DMA32:
+    return "VMSTAT_PGALLOC_DMA32";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGDEMOTE_DIRECT:
+    return "VMSTAT_PGDEMOTE_DIRECT";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGDEMOTE_KSWAPD:
+    return "VMSTAT_PGDEMOTE_KSWAPD";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGREUSE:
+    return "VMSTAT_PGREUSE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSCAN_ANON:
+    return "VMSTAT_PGSCAN_ANON";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSCAN_FILE:
+    return "VMSTAT_PGSCAN_FILE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSKIP_DEVICE:
+    return "VMSTAT_PGSKIP_DEVICE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSKIP_DMA32:
+    return "VMSTAT_PGSKIP_DMA32";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSTEAL_ANON:
+    return "VMSTAT_PGSTEAL_ANON";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSTEAL_FILE:
+    return "VMSTAT_PGSTEAL_FILE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_THP_COLLAPSE_ALLOC:
+    return "VMSTAT_THP_COLLAPSE_ALLOC";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_THP_COLLAPSE_ALLOC_FAILED:
+    return "VMSTAT_THP_COLLAPSE_ALLOC_FAILED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_THP_DEFERRED_SPLIT_PAGE:
+    return "VMSTAT_THP_DEFERRED_SPLIT_PAGE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_THP_FAULT_ALLOC:
+    return "VMSTAT_THP_FAULT_ALLOC";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_THP_FAULT_FALLBACK:
+    return "VMSTAT_THP_FAULT_FALLBACK";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_THP_FAULT_FALLBACK_CHARGE:
+    return "VMSTAT_THP_FAULT_FALLBACK_CHARGE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_THP_FILE_ALLOC:
+    return "VMSTAT_THP_FILE_ALLOC";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_THP_FILE_FALLBACK:
+    return "VMSTAT_THP_FILE_FALLBACK";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_THP_FILE_FALLBACK_CHARGE:
+    return "VMSTAT_THP_FILE_FALLBACK_CHARGE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_THP_FILE_MAPPED:
+    return "VMSTAT_THP_FILE_MAPPED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_THP_MIGRATION_FAIL:
+    return "VMSTAT_THP_MIGRATION_FAIL";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_THP_MIGRATION_SPLIT:
+    return "VMSTAT_THP_MIGRATION_SPLIT";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_THP_MIGRATION_SUCCESS:
+    return "VMSTAT_THP_MIGRATION_SUCCESS";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_THP_SCAN_EXCEED_NONE_PTE:
+    return "VMSTAT_THP_SCAN_EXCEED_NONE_PTE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_THP_SCAN_EXCEED_SHARE_PTE:
+    return "VMSTAT_THP_SCAN_EXCEED_SHARE_PTE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_THP_SCAN_EXCEED_SWAP_PTE:
+    return "VMSTAT_THP_SCAN_EXCEED_SWAP_PTE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_THP_SPLIT_PAGE:
+    return "VMSTAT_THP_SPLIT_PAGE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_THP_SPLIT_PAGE_FAILED:
+    return "VMSTAT_THP_SPLIT_PAGE_FAILED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_THP_SPLIT_PMD:
+    return "VMSTAT_THP_SPLIT_PMD";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_THP_SWPOUT:
+    return "VMSTAT_THP_SWPOUT";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_THP_SWPOUT_FALLBACK:
+    return "VMSTAT_THP_SWPOUT_FALLBACK";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_THP_ZERO_PAGE_ALLOC:
+    return "VMSTAT_THP_ZERO_PAGE_ALLOC";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_THP_ZERO_PAGE_ALLOC_FAILED:
+    return "VMSTAT_THP_ZERO_PAGE_ALLOC_FAILED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_VMA_LOCK_ABORT:
+    return "VMSTAT_VMA_LOCK_ABORT";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_VMA_LOCK_MISS:
+    return "VMSTAT_VMA_LOCK_MISS";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_VMA_LOCK_RETRY:
+    return "VMSTAT_VMA_LOCK_RETRY";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_VMA_LOCK_SUCCESS:
+    return "VMSTAT_VMA_LOCK_SUCCESS";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_WORKINGSET_ACTIVATE_ANON:
+    return "VMSTAT_WORKINGSET_ACTIVATE_ANON";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_WORKINGSET_ACTIVATE_FILE:
+    return "VMSTAT_WORKINGSET_ACTIVATE_FILE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_WORKINGSET_NODES:
+    return "VMSTAT_WORKINGSET_NODES";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_WORKINGSET_REFAULT_ANON:
+    return "VMSTAT_WORKINGSET_REFAULT_ANON";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_WORKINGSET_REFAULT_FILE:
+    return "VMSTAT_WORKINGSET_REFAULT_FILE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_WORKINGSET_RESTORE_ANON:
+    return "VMSTAT_WORKINGSET_RESTORE_ANON";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_WORKINGSET_RESTORE_FILE:
+    return "VMSTAT_WORKINGSET_RESTORE_FILE";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/common/trace_stats.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACE_STATS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACE_STATS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class TraceStats_BufferStats;
+class TraceStats_FilterStats;
+class TraceStats_WriterStats;
+namespace perfetto_pbzero_enum_TraceStats {
+enum FinalFlushOutcome : int32_t;
+}  // namespace perfetto_pbzero_enum_TraceStats
+using TraceStats_FinalFlushOutcome = perfetto_pbzero_enum_TraceStats::FinalFlushOutcome;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_TraceStats {
+enum FinalFlushOutcome : int32_t {
+  FINAL_FLUSH_UNSPECIFIED = 0,
+  FINAL_FLUSH_SUCCEEDED = 1,
+  FINAL_FLUSH_FAILED = 2,
+};
+} // namespace perfetto_pbzero_enum_TraceStats
+using TraceStats_FinalFlushOutcome = perfetto_pbzero_enum_TraceStats::FinalFlushOutcome;
+
+
+constexpr TraceStats_FinalFlushOutcome TraceStats_FinalFlushOutcome_MIN = TraceStats_FinalFlushOutcome::FINAL_FLUSH_UNSPECIFIED;
+constexpr TraceStats_FinalFlushOutcome TraceStats_FinalFlushOutcome_MAX = TraceStats_FinalFlushOutcome::FINAL_FLUSH_FAILED;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* TraceStats_FinalFlushOutcome_Name(::perfetto::protos::pbzero::TraceStats_FinalFlushOutcome value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::TraceStats_FinalFlushOutcome::FINAL_FLUSH_UNSPECIFIED:
+    return "FINAL_FLUSH_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::TraceStats_FinalFlushOutcome::FINAL_FLUSH_SUCCEEDED:
+    return "FINAL_FLUSH_SUCCEEDED";
+
+  case ::perfetto::protos::pbzero::TraceStats_FinalFlushOutcome::FINAL_FLUSH_FAILED:
+    return "FINAL_FLUSH_FAILED";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class TraceStats_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/18, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TraceStats_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TraceStats_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TraceStats_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_buffer_stats() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> buffer_stats() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_chunk_payload_histogram_def() const { return at<17>().valid(); }
+  ::protozero::RepeatedFieldIterator<int64_t> chunk_payload_histogram_def() const { return GetRepeated<int64_t>(17); }
+  bool has_writer_stats() const { return at<18>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> writer_stats() const { return GetRepeated<::protozero::ConstBytes>(18); }
+  bool has_producers_connected() const { return at<2>().valid(); }
+  uint32_t producers_connected() const { return at<2>().as_uint32(); }
+  bool has_producers_seen() const { return at<3>().valid(); }
+  uint64_t producers_seen() const { return at<3>().as_uint64(); }
+  bool has_data_sources_registered() const { return at<4>().valid(); }
+  uint32_t data_sources_registered() const { return at<4>().as_uint32(); }
+  bool has_data_sources_seen() const { return at<5>().valid(); }
+  uint64_t data_sources_seen() const { return at<5>().as_uint64(); }
+  bool has_tracing_sessions() const { return at<6>().valid(); }
+  uint32_t tracing_sessions() const { return at<6>().as_uint32(); }
+  bool has_total_buffers() const { return at<7>().valid(); }
+  uint32_t total_buffers() const { return at<7>().as_uint32(); }
+  bool has_chunks_discarded() const { return at<8>().valid(); }
+  uint64_t chunks_discarded() const { return at<8>().as_uint64(); }
+  bool has_patches_discarded() const { return at<9>().valid(); }
+  uint64_t patches_discarded() const { return at<9>().as_uint64(); }
+  bool has_invalid_packets() const { return at<10>().valid(); }
+  uint64_t invalid_packets() const { return at<10>().as_uint64(); }
+  bool has_filter_stats() const { return at<11>().valid(); }
+  ::protozero::ConstBytes filter_stats() const { return at<11>().as_bytes(); }
+  bool has_flushes_requested() const { return at<12>().valid(); }
+  uint64_t flushes_requested() const { return at<12>().as_uint64(); }
+  bool has_flushes_succeeded() const { return at<13>().valid(); }
+  uint64_t flushes_succeeded() const { return at<13>().as_uint64(); }
+  bool has_flushes_failed() const { return at<14>().valid(); }
+  uint64_t flushes_failed() const { return at<14>().as_uint64(); }
+  bool has_final_flush_outcome() const { return at<15>().valid(); }
+  int32_t final_flush_outcome() const { return at<15>().as_int32(); }
+};
+
+class TraceStats : public ::protozero::Message {
+ public:
+  using Decoder = TraceStats_Decoder;
+  enum : int32_t {
+    kBufferStatsFieldNumber = 1,
+    kChunkPayloadHistogramDefFieldNumber = 17,
+    kWriterStatsFieldNumber = 18,
+    kProducersConnectedFieldNumber = 2,
+    kProducersSeenFieldNumber = 3,
+    kDataSourcesRegisteredFieldNumber = 4,
+    kDataSourcesSeenFieldNumber = 5,
+    kTracingSessionsFieldNumber = 6,
+    kTotalBuffersFieldNumber = 7,
+    kChunksDiscardedFieldNumber = 8,
+    kPatchesDiscardedFieldNumber = 9,
+    kInvalidPacketsFieldNumber = 10,
+    kFilterStatsFieldNumber = 11,
+    kFlushesRequestedFieldNumber = 12,
+    kFlushesSucceededFieldNumber = 13,
+    kFlushesFailedFieldNumber = 14,
+    kFinalFlushOutcomeFieldNumber = 15,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceStats"; }
+
+  using BufferStats = ::perfetto::protos::pbzero::TraceStats_BufferStats;
+  using WriterStats = ::perfetto::protos::pbzero::TraceStats_WriterStats;
+  using FilterStats = ::perfetto::protos::pbzero::TraceStats_FilterStats;
+
+  using FinalFlushOutcome = ::perfetto::protos::pbzero::TraceStats_FinalFlushOutcome;
+  static inline const char* FinalFlushOutcome_Name(FinalFlushOutcome value) {
+    return ::perfetto::protos::pbzero::TraceStats_FinalFlushOutcome_Name(value);
+  }
+  static inline const FinalFlushOutcome FINAL_FLUSH_UNSPECIFIED = FinalFlushOutcome::FINAL_FLUSH_UNSPECIFIED;
+  static inline const FinalFlushOutcome FINAL_FLUSH_SUCCEEDED = FinalFlushOutcome::FINAL_FLUSH_SUCCEEDED;
+  static inline const FinalFlushOutcome FINAL_FLUSH_FAILED = FinalFlushOutcome::FINAL_FLUSH_FAILED;
+
+  using FieldMetadata_BufferStats =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceStats_BufferStats,
+      TraceStats>;
+
+  static constexpr FieldMetadata_BufferStats kBufferStats{};
+  template <typename T = TraceStats_BufferStats> T* add_buffer_stats() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_ChunkPayloadHistogramDef =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TraceStats>;
+
+  static constexpr FieldMetadata_ChunkPayloadHistogramDef kChunkPayloadHistogramDef{};
+  void add_chunk_payload_histogram_def(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChunkPayloadHistogramDef::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_WriterStats =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceStats_WriterStats,
+      TraceStats>;
+
+  static constexpr FieldMetadata_WriterStats kWriterStats{};
+  template <typename T = TraceStats_WriterStats> T* add_writer_stats() {
+    return BeginNestedMessage<T>(18);
+  }
+
+
+  using FieldMetadata_ProducersConnected =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TraceStats>;
+
+  static constexpr FieldMetadata_ProducersConnected kProducersConnected{};
+  void set_producers_connected(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProducersConnected::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_ProducersSeen =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats>;
+
+  static constexpr FieldMetadata_ProducersSeen kProducersSeen{};
+  void set_producers_seen(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProducersSeen::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_DataSourcesRegistered =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TraceStats>;
+
+  static constexpr FieldMetadata_DataSourcesRegistered kDataSourcesRegistered{};
+  void set_data_sources_registered(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DataSourcesRegistered::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_DataSourcesSeen =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats>;
+
+  static constexpr FieldMetadata_DataSourcesSeen kDataSourcesSeen{};
+  void set_data_sources_seen(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DataSourcesSeen::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_TracingSessions =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TraceStats>;
+
+  static constexpr FieldMetadata_TracingSessions kTracingSessions{};
+  void set_tracing_sessions(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TracingSessions::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_TotalBuffers =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TraceStats>;
+
+  static constexpr FieldMetadata_TotalBuffers kTotalBuffers{};
+  void set_total_buffers(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TotalBuffers::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_ChunksDiscarded =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats>;
+
+  static constexpr FieldMetadata_ChunksDiscarded kChunksDiscarded{};
+  void set_chunks_discarded(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChunksDiscarded::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_PatchesDiscarded =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats>;
+
+  static constexpr FieldMetadata_PatchesDiscarded kPatchesDiscarded{};
+  void set_patches_discarded(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PatchesDiscarded::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_InvalidPackets =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats>;
+
+  static constexpr FieldMetadata_InvalidPackets kInvalidPackets{};
+  void set_invalid_packets(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InvalidPackets::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_FilterStats =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceStats_FilterStats,
+      TraceStats>;
+
+  static constexpr FieldMetadata_FilterStats kFilterStats{};
+  template <typename T = TraceStats_FilterStats> T* set_filter_stats() {
+    return BeginNestedMessage<T>(11);
+  }
+
+
+  using FieldMetadata_FlushesRequested =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats>;
+
+  static constexpr FieldMetadata_FlushesRequested kFlushesRequested{};
+  void set_flushes_requested(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FlushesRequested::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_FlushesSucceeded =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats>;
+
+  static constexpr FieldMetadata_FlushesSucceeded kFlushesSucceeded{};
+  void set_flushes_succeeded(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FlushesSucceeded::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_FlushesFailed =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats>;
+
+  static constexpr FieldMetadata_FlushesFailed kFlushesFailed{};
+  void set_flushes_failed(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FlushesFailed::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_FinalFlushOutcome =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      TraceStats_FinalFlushOutcome,
+      TraceStats>;
+
+  static constexpr FieldMetadata_FinalFlushOutcome kFinalFlushOutcome{};
+  void set_final_flush_outcome(TraceStats_FinalFlushOutcome value) {
+    static constexpr uint32_t field_id = FieldMetadata_FinalFlushOutcome::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);
+  }
+};
+
+class TraceStats_FilterStats_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/20, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TraceStats_FilterStats_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TraceStats_FilterStats_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TraceStats_FilterStats_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_input_packets() const { return at<1>().valid(); }
+  uint64_t input_packets() const { return at<1>().as_uint64(); }
+  bool has_input_bytes() const { return at<2>().valid(); }
+  uint64_t input_bytes() const { return at<2>().as_uint64(); }
+  bool has_output_bytes() const { return at<3>().valid(); }
+  uint64_t output_bytes() const { return at<3>().as_uint64(); }
+  bool has_errors() const { return at<4>().valid(); }
+  uint64_t errors() const { return at<4>().as_uint64(); }
+  bool has_time_taken_ns() const { return at<5>().valid(); }
+  uint64_t time_taken_ns() const { return at<5>().as_uint64(); }
+  bool has_bytes_discarded_per_buffer() const { return at<20>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> bytes_discarded_per_buffer() const { return GetRepeated<uint64_t>(20); }
+};
+
+class TraceStats_FilterStats : public ::protozero::Message {
+ public:
+  using Decoder = TraceStats_FilterStats_Decoder;
+  enum : int32_t {
+    kInputPacketsFieldNumber = 1,
+    kInputBytesFieldNumber = 2,
+    kOutputBytesFieldNumber = 3,
+    kErrorsFieldNumber = 4,
+    kTimeTakenNsFieldNumber = 5,
+    kBytesDiscardedPerBufferFieldNumber = 20,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceStats.FilterStats"; }
+
+
+  using FieldMetadata_InputPackets =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_FilterStats>;
+
+  static constexpr FieldMetadata_InputPackets kInputPackets{};
+  void set_input_packets(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InputPackets::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_InputBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_FilterStats>;
+
+  static constexpr FieldMetadata_InputBytes kInputBytes{};
+  void set_input_bytes(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InputBytes::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_OutputBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_FilterStats>;
+
+  static constexpr FieldMetadata_OutputBytes kOutputBytes{};
+  void set_output_bytes(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OutputBytes::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_Errors =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_FilterStats>;
+
+  static constexpr FieldMetadata_Errors kErrors{};
+  void set_errors(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Errors::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_TimeTakenNs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_FilterStats>;
+
+  static constexpr FieldMetadata_TimeTakenNs kTimeTakenNs{};
+  void set_time_taken_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimeTakenNs::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_BytesDiscardedPerBuffer =
+    ::protozero::proto_utils::FieldMetadata<
+      20,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_FilterStats>;
+
+  static constexpr FieldMetadata_BytesDiscardedPerBuffer kBytesDiscardedPerBuffer{};
+  void add_bytes_discarded_per_buffer(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BytesDiscardedPerBuffer::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 TraceStats_WriterStats_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TraceStats_WriterStats_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TraceStats_WriterStats_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TraceStats_WriterStats_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_sequence_id() const { return at<1>().valid(); }
+  uint64_t sequence_id() const { return at<1>().as_uint64(); }
+  bool has_buffer() const { return at<4>().valid(); }
+  uint32_t buffer() const { return at<4>().as_uint32(); }
+  bool has_chunk_payload_histogram_counts() const { return at<2>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, uint64_t> chunk_payload_histogram_counts(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, uint64_t>(2, parse_error_ptr); }
+  bool has_chunk_payload_histogram_sum() const { return at<3>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, int64_t> chunk_payload_histogram_sum(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, int64_t>(3, parse_error_ptr); }
+};
+
+class TraceStats_WriterStats : public ::protozero::Message {
+ public:
+  using Decoder = TraceStats_WriterStats_Decoder;
+  enum : int32_t {
+    kSequenceIdFieldNumber = 1,
+    kBufferFieldNumber = 4,
+    kChunkPayloadHistogramCountsFieldNumber = 2,
+    kChunkPayloadHistogramSumFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceStats.WriterStats"; }
+
+
+  using FieldMetadata_SequenceId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_WriterStats>;
+
+  static constexpr FieldMetadata_SequenceId kSequenceId{};
+  void set_sequence_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SequenceId::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_Buffer =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TraceStats_WriterStats>;
+
+  static constexpr FieldMetadata_Buffer kBuffer{};
+  void set_buffer(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Buffer::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_ChunkPayloadHistogramCounts =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_WriterStats>;
+
+  static constexpr FieldMetadata_ChunkPayloadHistogramCounts kChunkPayloadHistogramCounts{};
+  void set_chunk_payload_histogram_counts(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_ChunkPayloadHistogramCounts::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_ChunkPayloadHistogramSum =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TraceStats_WriterStats>;
+
+  static constexpr FieldMetadata_ChunkPayloadHistogramSum kChunkPayloadHistogramSum{};
+  void set_chunk_payload_histogram_sum(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_ChunkPayloadHistogramSum::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+};
+
+class TraceStats_BufferStats_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/19, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TraceStats_BufferStats_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TraceStats_BufferStats_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TraceStats_BufferStats_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_buffer_size() const { return at<12>().valid(); }
+  uint64_t buffer_size() const { return at<12>().as_uint64(); }
+  bool has_bytes_written() const { return at<1>().valid(); }
+  uint64_t bytes_written() const { return at<1>().as_uint64(); }
+  bool has_bytes_overwritten() const { return at<13>().valid(); }
+  uint64_t bytes_overwritten() const { return at<13>().as_uint64(); }
+  bool has_bytes_read() const { return at<14>().valid(); }
+  uint64_t bytes_read() const { return at<14>().as_uint64(); }
+  bool has_padding_bytes_written() const { return at<15>().valid(); }
+  uint64_t padding_bytes_written() const { return at<15>().as_uint64(); }
+  bool has_padding_bytes_cleared() const { return at<16>().valid(); }
+  uint64_t padding_bytes_cleared() const { return at<16>().as_uint64(); }
+  bool has_chunks_written() const { return at<2>().valid(); }
+  uint64_t chunks_written() const { return at<2>().as_uint64(); }
+  bool has_chunks_rewritten() const { return at<10>().valid(); }
+  uint64_t chunks_rewritten() const { return at<10>().as_uint64(); }
+  bool has_chunks_overwritten() const { return at<3>().valid(); }
+  uint64_t chunks_overwritten() const { return at<3>().as_uint64(); }
+  bool has_chunks_discarded() const { return at<18>().valid(); }
+  uint64_t chunks_discarded() const { return at<18>().as_uint64(); }
+  bool has_chunks_read() const { return at<17>().valid(); }
+  uint64_t chunks_read() const { return at<17>().as_uint64(); }
+  bool has_chunks_committed_out_of_order() const { return at<11>().valid(); }
+  uint64_t chunks_committed_out_of_order() const { return at<11>().as_uint64(); }
+  bool has_write_wrap_count() const { return at<4>().valid(); }
+  uint64_t write_wrap_count() const { return at<4>().as_uint64(); }
+  bool has_patches_succeeded() const { return at<5>().valid(); }
+  uint64_t patches_succeeded() const { return at<5>().as_uint64(); }
+  bool has_patches_failed() const { return at<6>().valid(); }
+  uint64_t patches_failed() const { return at<6>().as_uint64(); }
+  bool has_readaheads_succeeded() const { return at<7>().valid(); }
+  uint64_t readaheads_succeeded() const { return at<7>().as_uint64(); }
+  bool has_readaheads_failed() const { return at<8>().valid(); }
+  uint64_t readaheads_failed() const { return at<8>().as_uint64(); }
+  bool has_abi_violations() const { return at<9>().valid(); }
+  uint64_t abi_violations() const { return at<9>().as_uint64(); }
+  bool has_trace_writer_packet_loss() const { return at<19>().valid(); }
+  uint64_t trace_writer_packet_loss() const { return at<19>().as_uint64(); }
+};
+
+class TraceStats_BufferStats : public ::protozero::Message {
+ public:
+  using Decoder = TraceStats_BufferStats_Decoder;
+  enum : int32_t {
+    kBufferSizeFieldNumber = 12,
+    kBytesWrittenFieldNumber = 1,
+    kBytesOverwrittenFieldNumber = 13,
+    kBytesReadFieldNumber = 14,
+    kPaddingBytesWrittenFieldNumber = 15,
+    kPaddingBytesClearedFieldNumber = 16,
+    kChunksWrittenFieldNumber = 2,
+    kChunksRewrittenFieldNumber = 10,
+    kChunksOverwrittenFieldNumber = 3,
+    kChunksDiscardedFieldNumber = 18,
+    kChunksReadFieldNumber = 17,
+    kChunksCommittedOutOfOrderFieldNumber = 11,
+    kWriteWrapCountFieldNumber = 4,
+    kPatchesSucceededFieldNumber = 5,
+    kPatchesFailedFieldNumber = 6,
+    kReadaheadsSucceededFieldNumber = 7,
+    kReadaheadsFailedFieldNumber = 8,
+    kAbiViolationsFieldNumber = 9,
+    kTraceWriterPacketLossFieldNumber = 19,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceStats.BufferStats"; }
+
+
+  using FieldMetadata_BufferSize =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_BufferSize kBufferSize{};
+  void set_buffer_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BufferSize::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_BytesWritten =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_BytesWritten kBytesWritten{};
+  void set_bytes_written(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BytesWritten::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_BytesOverwritten =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_BytesOverwritten kBytesOverwritten{};
+  void set_bytes_overwritten(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BytesOverwritten::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_BytesRead =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_BytesRead kBytesRead{};
+  void set_bytes_read(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BytesRead::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_PaddingBytesWritten =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_PaddingBytesWritten kPaddingBytesWritten{};
+  void set_padding_bytes_written(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PaddingBytesWritten::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_PaddingBytesCleared =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_PaddingBytesCleared kPaddingBytesCleared{};
+  void set_padding_bytes_cleared(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PaddingBytesCleared::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_ChunksWritten =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_ChunksWritten kChunksWritten{};
+  void set_chunks_written(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChunksWritten::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_ChunksRewritten =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_ChunksRewritten kChunksRewritten{};
+  void set_chunks_rewritten(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChunksRewritten::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_ChunksOverwritten =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_ChunksOverwritten kChunksOverwritten{};
+  void set_chunks_overwritten(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChunksOverwritten::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_ChunksDiscarded =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_ChunksDiscarded kChunksDiscarded{};
+  void set_chunks_discarded(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChunksDiscarded::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_ChunksRead =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_ChunksRead kChunksRead{};
+  void set_chunks_read(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChunksRead::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_ChunksCommittedOutOfOrder =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_ChunksCommittedOutOfOrder kChunksCommittedOutOfOrder{};
+  void set_chunks_committed_out_of_order(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChunksCommittedOutOfOrder::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_WriteWrapCount =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_WriteWrapCount kWriteWrapCount{};
+  void set_write_wrap_count(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_WriteWrapCount::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_PatchesSucceeded =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_PatchesSucceeded kPatchesSucceeded{};
+  void set_patches_succeeded(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PatchesSucceeded::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_PatchesFailed =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_PatchesFailed kPatchesFailed{};
+  void set_patches_failed(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PatchesFailed::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_ReadaheadsSucceeded =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_ReadaheadsSucceeded kReadaheadsSucceeded{};
+  void set_readaheads_succeeded(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReadaheadsSucceeded::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_ReadaheadsFailed =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_ReadaheadsFailed kReadaheadsFailed{};
+  void set_readaheads_failed(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReadaheadsFailed::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_AbiViolations =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_AbiViolations kAbiViolations{};
+  void set_abi_violations(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AbiViolations::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_TraceWriterPacketLoss =
+    ::protozero::proto_utils::FieldMetadata<
+      19,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_TraceWriterPacketLoss kTraceWriterPacketLoss{};
+  void set_trace_writer_packet_loss(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TraceWriterPacketLoss::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/common/tracing_service_capabilities.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_CAPABILITIES_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_CAPABILITIES_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+namespace perfetto_pbzero_enum_ObservableEvents {
+enum Type : int32_t;
+}  // namespace perfetto_pbzero_enum_ObservableEvents
+using ObservableEvents_Type = perfetto_pbzero_enum_ObservableEvents::Type;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class TracingServiceCapabilities_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TracingServiceCapabilities_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TracingServiceCapabilities_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TracingServiceCapabilities_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_has_query_capabilities() const { return at<1>().valid(); }
+  bool has_query_capabilities() const { return at<1>().as_bool(); }
+  bool has_observable_events() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> observable_events() const { return GetRepeated<int32_t>(2); }
+  bool has_has_trace_config_output_path() const { return at<3>().valid(); }
+  bool has_trace_config_output_path() const { return at<3>().as_bool(); }
+  bool has_has_clone_session() const { return at<4>().valid(); }
+  bool has_clone_session() const { return at<4>().as_bool(); }
+};
+
+class TracingServiceCapabilities : public ::protozero::Message {
+ public:
+  using Decoder = TracingServiceCapabilities_Decoder;
+  enum : int32_t {
+    kHasQueryCapabilitiesFieldNumber = 1,
+    kObservableEventsFieldNumber = 2,
+    kHasTraceConfigOutputPathFieldNumber = 3,
+    kHasCloneSessionFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TracingServiceCapabilities"; }
+
+
+  using FieldMetadata_HasQueryCapabilities =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TracingServiceCapabilities>;
+
+  static constexpr FieldMetadata_HasQueryCapabilities kHasQueryCapabilities{};
+  void set_has_query_capabilities(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_HasQueryCapabilities::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_ObservableEvents =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ObservableEvents_Type,
+      TracingServiceCapabilities>;
+
+  static constexpr FieldMetadata_ObservableEvents kObservableEvents{};
+  void add_observable_events(ObservableEvents_Type value) {
+    static constexpr uint32_t field_id = FieldMetadata_ObservableEvents::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_HasTraceConfigOutputPath =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TracingServiceCapabilities>;
+
+  static constexpr FieldMetadata_HasTraceConfigOutputPath kHasTraceConfigOutputPath{};
+  void set_has_trace_config_output_path(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_HasTraceConfigOutputPath::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_HasCloneSession =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TracingServiceCapabilities>;
+
+  static constexpr FieldMetadata_HasCloneSession kHasCloneSession{};
+  void set_has_clone_session(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_HasCloneSession::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/common/tracing_service_state.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_STATE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_STATE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class DataSourceDescriptor;
+class TracingServiceState_DataSource;
+class TracingServiceState_Producer;
+class TracingServiceState_TracingSession;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class TracingServiceState_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TracingServiceState_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TracingServiceState_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TracingServiceState_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_producers() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> producers() 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_tracing_sessions() const { return at<6>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> tracing_sessions() const { return GetRepeated<::protozero::ConstBytes>(6); }
+  bool has_supports_tracing_sessions() const { return at<7>().valid(); }
+  bool supports_tracing_sessions() const { return at<7>().as_bool(); }
+  bool has_num_sessions() const { return at<3>().valid(); }
+  int32_t num_sessions() const { return at<3>().as_int32(); }
+  bool has_num_sessions_started() const { return at<4>().valid(); }
+  int32_t num_sessions_started() const { return at<4>().as_int32(); }
+  bool has_tracing_service_version() const { return at<5>().valid(); }
+  ::protozero::ConstChars tracing_service_version() const { return at<5>().as_string(); }
+};
+
+class TracingServiceState : public ::protozero::Message {
+ public:
+  using Decoder = TracingServiceState_Decoder;
+  enum : int32_t {
+    kProducersFieldNumber = 1,
+    kDataSourcesFieldNumber = 2,
+    kTracingSessionsFieldNumber = 6,
+    kSupportsTracingSessionsFieldNumber = 7,
+    kNumSessionsFieldNumber = 3,
+    kNumSessionsStartedFieldNumber = 4,
+    kTracingServiceVersionFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TracingServiceState"; }
+
+  using Producer = ::perfetto::protos::pbzero::TracingServiceState_Producer;
+  using DataSource = ::perfetto::protos::pbzero::TracingServiceState_DataSource;
+  using TracingSession = ::perfetto::protos::pbzero::TracingServiceState_TracingSession;
+
+  using FieldMetadata_Producers =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TracingServiceState_Producer,
+      TracingServiceState>;
+
+  static constexpr FieldMetadata_Producers kProducers{};
+  template <typename T = TracingServiceState_Producer> T* add_producers() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_DataSources =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TracingServiceState_DataSource,
+      TracingServiceState>;
+
+  static constexpr FieldMetadata_DataSources kDataSources{};
+  template <typename T = TracingServiceState_DataSource> T* add_data_sources() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_TracingSessions =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TracingServiceState_TracingSession,
+      TracingServiceState>;
+
+  static constexpr FieldMetadata_TracingSessions kTracingSessions{};
+  template <typename T = TracingServiceState_TracingSession> T* add_tracing_sessions() {
+    return BeginNestedMessage<T>(6);
+  }
+
+
+  using FieldMetadata_SupportsTracingSessions =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TracingServiceState>;
+
+  static constexpr FieldMetadata_SupportsTracingSessions kSupportsTracingSessions{};
+  void set_supports_tracing_sessions(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_SupportsTracingSessions::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_NumSessions =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TracingServiceState>;
+
+  static constexpr FieldMetadata_NumSessions kNumSessions{};
+  void set_num_sessions(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NumSessions::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_NumSessionsStarted =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TracingServiceState>;
+
+  static constexpr FieldMetadata_NumSessionsStarted kNumSessionsStarted{};
+  void set_num_sessions_started(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NumSessionsStarted::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_TracingServiceVersion =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TracingServiceState>;
+
+  static constexpr FieldMetadata_TracingServiceVersion kTracingServiceVersion{};
+  void set_tracing_service_version(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TracingServiceVersion::kFieldId, data, size);
+  }
+  void set_tracing_service_version(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_TracingServiceVersion::kFieldId, chars.data, chars.size);
+  }
+  void set_tracing_service_version(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_TracingServiceVersion::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 TracingServiceState_TracingSession_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/11, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TracingServiceState_TracingSession_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TracingServiceState_TracingSession_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TracingServiceState_TracingSession_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  uint64_t id() const { return at<1>().as_uint64(); }
+  bool has_consumer_uid() const { return at<2>().valid(); }
+  int32_t consumer_uid() const { return at<2>().as_int32(); }
+  bool has_state() const { return at<3>().valid(); }
+  ::protozero::ConstChars state() const { return at<3>().as_string(); }
+  bool has_unique_session_name() const { return at<4>().valid(); }
+  ::protozero::ConstChars unique_session_name() const { return at<4>().as_string(); }
+  bool has_buffer_size_kb() const { return at<5>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint32_t> buffer_size_kb() const { return GetRepeated<uint32_t>(5); }
+  bool has_duration_ms() const { return at<6>().valid(); }
+  uint32_t duration_ms() const { return at<6>().as_uint32(); }
+  bool has_num_data_sources() const { return at<7>().valid(); }
+  uint32_t num_data_sources() const { return at<7>().as_uint32(); }
+  bool has_start_realtime_ns() const { return at<8>().valid(); }
+  int64_t start_realtime_ns() const { return at<8>().as_int64(); }
+  bool has_bugreport_score() const { return at<9>().valid(); }
+  int32_t bugreport_score() const { return at<9>().as_int32(); }
+  bool has_bugreport_filename() const { return at<10>().valid(); }
+  ::protozero::ConstChars bugreport_filename() const { return at<10>().as_string(); }
+  bool has_is_started() const { return at<11>().valid(); }
+  bool is_started() const { return at<11>().as_bool(); }
+};
+
+class TracingServiceState_TracingSession : public ::protozero::Message {
+ public:
+  using Decoder = TracingServiceState_TracingSession_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kConsumerUidFieldNumber = 2,
+    kStateFieldNumber = 3,
+    kUniqueSessionNameFieldNumber = 4,
+    kBufferSizeKbFieldNumber = 5,
+    kDurationMsFieldNumber = 6,
+    kNumDataSourcesFieldNumber = 7,
+    kStartRealtimeNsFieldNumber = 8,
+    kBugreportScoreFieldNumber = 9,
+    kBugreportFilenameFieldNumber = 10,
+    kIsStartedFieldNumber = 11,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TracingServiceState.TracingSession"; }
+
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TracingServiceState_TracingSession>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::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_ConsumerUid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TracingServiceState_TracingSession>;
+
+  static constexpr FieldMetadata_ConsumerUid kConsumerUid{};
+  void set_consumer_uid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ConsumerUid::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_State =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TracingServiceState_TracingSession>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_State::kFieldId, data, size);
+  }
+  void set_state(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_State::kFieldId, chars.data, chars.size);
+  }
+  void set_state(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::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_UniqueSessionName =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TracingServiceState_TracingSession>;
+
+  static constexpr FieldMetadata_UniqueSessionName kUniqueSessionName{};
+  void set_unique_session_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_UniqueSessionName::kFieldId, data, size);
+  }
+  void set_unique_session_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_UniqueSessionName::kFieldId, chars.data, chars.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_BufferSizeKb =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TracingServiceState_TracingSession>;
+
+  static constexpr FieldMetadata_BufferSizeKb kBufferSizeKb{};
+  void add_buffer_size_kb(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BufferSizeKb::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_DurationMs =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TracingServiceState_TracingSession>;
+
+  static constexpr FieldMetadata_DurationMs kDurationMs{};
+  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_NumDataSources =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TracingServiceState_TracingSession>;
+
+  static constexpr FieldMetadata_NumDataSources kNumDataSources{};
+  void set_num_data_sources(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NumDataSources::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_StartRealtimeNs =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TracingServiceState_TracingSession>;
+
+  static constexpr FieldMetadata_StartRealtimeNs kStartRealtimeNs{};
+  void set_start_realtime_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StartRealtimeNs::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_BugreportScore =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TracingServiceState_TracingSession>;
+
+  static constexpr FieldMetadata_BugreportScore kBugreportScore{};
+  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_BugreportFilename =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TracingServiceState_TracingSession>;
+
+  static constexpr FieldMetadata_BugreportFilename kBugreportFilename{};
+  void set_bugreport_filename(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_BugreportFilename::kFieldId, data, size);
+  }
+  void set_bugreport_filename(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_BugreportFilename::kFieldId, chars.data, chars.size);
+  }
+  void set_bugreport_filename(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_BugreportFilename::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_IsStarted =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TracingServiceState_TracingSession>;
+
+  static constexpr FieldMetadata_IsStarted kIsStarted{};
+  void set_is_started(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsStarted::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 TracingServiceState_DataSource_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TracingServiceState_DataSource_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TracingServiceState_DataSource_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TracingServiceState_DataSource_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ds_descriptor() const { return at<1>().valid(); }
+  ::protozero::ConstBytes ds_descriptor() const { return at<1>().as_bytes(); }
+  bool has_producer_id() const { return at<2>().valid(); }
+  int32_t producer_id() const { return at<2>().as_int32(); }
+};
+
+class TracingServiceState_DataSource : public ::protozero::Message {
+ public:
+  using Decoder = TracingServiceState_DataSource_Decoder;
+  enum : int32_t {
+    kDsDescriptorFieldNumber = 1,
+    kProducerIdFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TracingServiceState.DataSource"; }
+
+
+  using FieldMetadata_DsDescriptor =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DataSourceDescriptor,
+      TracingServiceState_DataSource>;
+
+  static constexpr FieldMetadata_DsDescriptor kDsDescriptor{};
+  template <typename T = DataSourceDescriptor> T* set_ds_descriptor() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_ProducerId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TracingServiceState_DataSource>;
+
+  static constexpr FieldMetadata_ProducerId kProducerId{};
+  void set_producer_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProducerId::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);
+  }
+};
+
+class TracingServiceState_Producer_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TracingServiceState_Producer_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TracingServiceState_Producer_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TracingServiceState_Producer_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  int32_t id() const { return at<1>().as_int32(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+  bool has_pid() const { return at<5>().valid(); }
+  int32_t pid() const { return at<5>().as_int32(); }
+  bool has_uid() const { return at<3>().valid(); }
+  int32_t uid() const { return at<3>().as_int32(); }
+  bool has_sdk_version() const { return at<4>().valid(); }
+  ::protozero::ConstChars sdk_version() const { return at<4>().as_string(); }
+};
+
+class TracingServiceState_Producer : public ::protozero::Message {
+ public:
+  using Decoder = TracingServiceState_Producer_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kNameFieldNumber = 2,
+    kPidFieldNumber = 5,
+    kUidFieldNumber = 3,
+    kSdkVersionFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TracingServiceState.Producer"; }
+
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TracingServiceState_Producer>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TracingServiceState_Producer>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TracingServiceState_Producer>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_Uid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TracingServiceState_Producer>;
+
+  static constexpr FieldMetadata_Uid kUid{};
+  void set_uid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Uid::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_SdkVersion =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TracingServiceState_Producer>;
+
+  static constexpr FieldMetadata_SdkVersion kSdkVersion{};
+  void set_sdk_version(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_SdkVersion::kFieldId, data, size);
+  }
+  void set_sdk_version(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_SdkVersion::kFieldId, chars.data, chars.size);
+  }
+  void set_sdk_version(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_SdkVersion::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/common/track_event_descriptor.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACK_EVENT_DESCRIPTOR_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACK_EVENT_DESCRIPTOR_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class TrackEventCategory;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class TrackEventDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TrackEventDescriptor_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrackEventDescriptor_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrackEventDescriptor_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_available_categories() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> available_categories() const { return GetRepeated<::protozero::ConstBytes>(1); }
+};
+
+class TrackEventDescriptor : public ::protozero::Message {
+ public:
+  using Decoder = TrackEventDescriptor_Decoder;
+  enum : int32_t {
+    kAvailableCategoriesFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrackEventDescriptor"; }
+
+
+  using FieldMetadata_AvailableCategories =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrackEventCategory,
+      TrackEventDescriptor>;
+
+  static constexpr FieldMetadata_AvailableCategories kAvailableCategories{};
+  template <typename T = TrackEventCategory> T* add_available_categories() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+class TrackEventCategory_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TrackEventCategory_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrackEventCategory_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrackEventCategory_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_description() const { return at<2>().valid(); }
+  ::protozero::ConstChars description() const { return at<2>().as_string(); }
+  bool has_tags() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> tags() const { return GetRepeated<::protozero::ConstChars>(3); }
+};
+
+class TrackEventCategory : public ::protozero::Message {
+ public:
+  using Decoder = TrackEventCategory_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kDescriptionFieldNumber = 2,
+    kTagsFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrackEventCategory"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrackEventCategory>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Description =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrackEventCategory>;
+
+  static constexpr FieldMetadata_Description kDescription{};
+  void set_description(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Description::kFieldId, data, size);
+  }
+  void set_description(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Description::kFieldId, chars.data, chars.size);
+  }
+  void set_description(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Description::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_Tags =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrackEventCategory>;
+
+  static constexpr FieldMetadata_Tags kTags{};
+  void add_tags(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Tags::kFieldId, data, size);
+  }
+  void add_tags(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Tags::kFieldId, chars.data, chars.size);
+  }
+  void add_tags(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tags::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/android_game_intervention_list_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_GAME_INTERVENTION_LIST_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_GAME_INTERVENTION_LIST_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class AndroidGameInterventionListConfig;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT AndroidGameInterventionListConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kPackageNameFilterFieldNumber = 1,
+  };
+
+  AndroidGameInterventionListConfig();
+  ~AndroidGameInterventionListConfig() override;
+  AndroidGameInterventionListConfig(AndroidGameInterventionListConfig&&) noexcept;
+  AndroidGameInterventionListConfig& operator=(AndroidGameInterventionListConfig&&);
+  AndroidGameInterventionListConfig(const AndroidGameInterventionListConfig&);
+  AndroidGameInterventionListConfig& operator=(const AndroidGameInterventionListConfig&);
+  bool operator==(const AndroidGameInterventionListConfig&) const;
+  bool operator!=(const AndroidGameInterventionListConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<std::string>& package_name_filter() const { return package_name_filter_; }
+  std::vector<std::string>* mutable_package_name_filter() { return &package_name_filter_; }
+  int package_name_filter_size() const { return static_cast<int>(package_name_filter_.size()); }
+  void clear_package_name_filter() { package_name_filter_.clear(); }
+  void add_package_name_filter(std::string value) { package_name_filter_.emplace_back(value); }
+  std::string* add_package_name_filter() { package_name_filter_.emplace_back(); return &package_name_filter_.back(); }
+
+ private:
+  std::vector<std::string> package_name_filter_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_GAME_INTERVENTION_LIST_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/android_input_event_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_INPUT_EVENT_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_INPUT_EVENT_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class AndroidInputEventConfig;
+class AndroidInputEventConfig_TraceRule;
+enum AndroidInputEventConfig_TraceMode : int;
+enum AndroidInputEventConfig_TraceLevel : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum AndroidInputEventConfig_TraceMode : int {
+  AndroidInputEventConfig_TraceMode_TRACE_MODE_TRACE_ALL = 0,
+  AndroidInputEventConfig_TraceMode_TRACE_MODE_USE_RULES = 1,
+};
+enum AndroidInputEventConfig_TraceLevel : int {
+  AndroidInputEventConfig_TraceLevel_TRACE_LEVEL_NONE = 0,
+  AndroidInputEventConfig_TraceLevel_TRACE_LEVEL_REDACTED = 1,
+  AndroidInputEventConfig_TraceLevel_TRACE_LEVEL_COMPLETE = 2,
+};
+
+class PERFETTO_EXPORT_COMPONENT AndroidInputEventConfig : public ::protozero::CppMessageObj {
+ public:
+  using TraceRule = AndroidInputEventConfig_TraceRule;
+  using TraceMode = AndroidInputEventConfig_TraceMode;
+  static constexpr auto TRACE_MODE_TRACE_ALL = AndroidInputEventConfig_TraceMode_TRACE_MODE_TRACE_ALL;
+  static constexpr auto TRACE_MODE_USE_RULES = AndroidInputEventConfig_TraceMode_TRACE_MODE_USE_RULES;
+  static constexpr auto TraceMode_MIN = AndroidInputEventConfig_TraceMode_TRACE_MODE_TRACE_ALL;
+  static constexpr auto TraceMode_MAX = AndroidInputEventConfig_TraceMode_TRACE_MODE_USE_RULES;
+  using TraceLevel = AndroidInputEventConfig_TraceLevel;
+  static constexpr auto TRACE_LEVEL_NONE = AndroidInputEventConfig_TraceLevel_TRACE_LEVEL_NONE;
+  static constexpr auto TRACE_LEVEL_REDACTED = AndroidInputEventConfig_TraceLevel_TRACE_LEVEL_REDACTED;
+  static constexpr auto TRACE_LEVEL_COMPLETE = AndroidInputEventConfig_TraceLevel_TRACE_LEVEL_COMPLETE;
+  static constexpr auto TraceLevel_MIN = AndroidInputEventConfig_TraceLevel_TRACE_LEVEL_NONE;
+  static constexpr auto TraceLevel_MAX = AndroidInputEventConfig_TraceLevel_TRACE_LEVEL_COMPLETE;
+  enum FieldNumbers {
+    kModeFieldNumber = 1,
+    kRulesFieldNumber = 2,
+    kTraceDispatcherInputEventsFieldNumber = 3,
+    kTraceDispatcherWindowDispatchFieldNumber = 4,
+  };
+
+  AndroidInputEventConfig();
+  ~AndroidInputEventConfig() override;
+  AndroidInputEventConfig(AndroidInputEventConfig&&) noexcept;
+  AndroidInputEventConfig& operator=(AndroidInputEventConfig&&);
+  AndroidInputEventConfig(const AndroidInputEventConfig&);
+  AndroidInputEventConfig& operator=(const AndroidInputEventConfig&);
+  bool operator==(const AndroidInputEventConfig&) const;
+  bool operator!=(const AndroidInputEventConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_mode() const { return _has_field_[1]; }
+  AndroidInputEventConfig_TraceMode mode() const { return mode_; }
+  void set_mode(AndroidInputEventConfig_TraceMode value) { mode_ = value; _has_field_.set(1); }
+
+  const std::vector<AndroidInputEventConfig_TraceRule>& rules() const { return rules_; }
+  std::vector<AndroidInputEventConfig_TraceRule>* mutable_rules() { return &rules_; }
+  int rules_size() const;
+  void clear_rules();
+  AndroidInputEventConfig_TraceRule* add_rules();
+
+  bool has_trace_dispatcher_input_events() const { return _has_field_[3]; }
+  bool trace_dispatcher_input_events() const { return trace_dispatcher_input_events_; }
+  void set_trace_dispatcher_input_events(bool value) { trace_dispatcher_input_events_ = value; _has_field_.set(3); }
+
+  bool has_trace_dispatcher_window_dispatch() const { return _has_field_[4]; }
+  bool trace_dispatcher_window_dispatch() const { return trace_dispatcher_window_dispatch_; }
+  void set_trace_dispatcher_window_dispatch(bool value) { trace_dispatcher_window_dispatch_ = value; _has_field_.set(4); }
+
+ private:
+  AndroidInputEventConfig_TraceMode mode_{};
+  std::vector<AndroidInputEventConfig_TraceRule> rules_;
+  bool trace_dispatcher_input_events_{};
+  bool trace_dispatcher_window_dispatch_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<5> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT AndroidInputEventConfig_TraceRule : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kTraceLevelFieldNumber = 1,
+    kMatchAllPackagesFieldNumber = 2,
+    kMatchAnyPackagesFieldNumber = 3,
+    kMatchSecureFieldNumber = 4,
+    kMatchImeConnectionActiveFieldNumber = 5,
+  };
+
+  AndroidInputEventConfig_TraceRule();
+  ~AndroidInputEventConfig_TraceRule() override;
+  AndroidInputEventConfig_TraceRule(AndroidInputEventConfig_TraceRule&&) noexcept;
+  AndroidInputEventConfig_TraceRule& operator=(AndroidInputEventConfig_TraceRule&&);
+  AndroidInputEventConfig_TraceRule(const AndroidInputEventConfig_TraceRule&);
+  AndroidInputEventConfig_TraceRule& operator=(const AndroidInputEventConfig_TraceRule&);
+  bool operator==(const AndroidInputEventConfig_TraceRule&) const;
+  bool operator!=(const AndroidInputEventConfig_TraceRule& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_trace_level() const { return _has_field_[1]; }
+  AndroidInputEventConfig_TraceLevel trace_level() const { return trace_level_; }
+  void set_trace_level(AndroidInputEventConfig_TraceLevel value) { trace_level_ = value; _has_field_.set(1); }
+
+  const std::vector<std::string>& match_all_packages() const { return match_all_packages_; }
+  std::vector<std::string>* mutable_match_all_packages() { return &match_all_packages_; }
+  int match_all_packages_size() const { return static_cast<int>(match_all_packages_.size()); }
+  void clear_match_all_packages() { match_all_packages_.clear(); }
+  void add_match_all_packages(std::string value) { match_all_packages_.emplace_back(value); }
+  std::string* add_match_all_packages() { match_all_packages_.emplace_back(); return &match_all_packages_.back(); }
+
+  const std::vector<std::string>& match_any_packages() const { return match_any_packages_; }
+  std::vector<std::string>* mutable_match_any_packages() { return &match_any_packages_; }
+  int match_any_packages_size() const { return static_cast<int>(match_any_packages_.size()); }
+  void clear_match_any_packages() { match_any_packages_.clear(); }
+  void add_match_any_packages(std::string value) { match_any_packages_.emplace_back(value); }
+  std::string* add_match_any_packages() { match_any_packages_.emplace_back(); return &match_any_packages_.back(); }
+
+  bool has_match_secure() const { return _has_field_[4]; }
+  bool match_secure() const { return match_secure_; }
+  void set_match_secure(bool value) { match_secure_ = value; _has_field_.set(4); }
+
+  bool has_match_ime_connection_active() const { return _has_field_[5]; }
+  bool match_ime_connection_active() const { return match_ime_connection_active_; }
+  void set_match_ime_connection_active(bool value) { match_ime_connection_active_ = value; _has_field_.set(5); }
+
+ private:
+  AndroidInputEventConfig_TraceLevel trace_level_{};
+  std::vector<std::string> match_all_packages_;
+  std::vector<std::string> match_any_packages_;
+  bool match_secure_{};
+  bool match_ime_connection_active_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<6> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_INPUT_EVENT_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/android_log_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_LOG_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_LOG_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class AndroidLogConfig;
+enum AndroidLogId : int;
+enum AndroidLogPriority : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT AndroidLogConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kLogIdsFieldNumber = 1,
+    kMinPrioFieldNumber = 3,
+    kFilterTagsFieldNumber = 4,
+  };
+
+  AndroidLogConfig();
+  ~AndroidLogConfig() override;
+  AndroidLogConfig(AndroidLogConfig&&) noexcept;
+  AndroidLogConfig& operator=(AndroidLogConfig&&);
+  AndroidLogConfig(const AndroidLogConfig&);
+  AndroidLogConfig& operator=(const AndroidLogConfig&);
+  bool operator==(const AndroidLogConfig&) const;
+  bool operator!=(const AndroidLogConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<AndroidLogId>& log_ids() const { return log_ids_; }
+  std::vector<AndroidLogId>* mutable_log_ids() { return &log_ids_; }
+  int log_ids_size() const { return static_cast<int>(log_ids_.size()); }
+  void clear_log_ids() { log_ids_.clear(); }
+  void add_log_ids(AndroidLogId value) { log_ids_.emplace_back(value); }
+  AndroidLogId* add_log_ids() { log_ids_.emplace_back(); return &log_ids_.back(); }
+
+  bool has_min_prio() const { return _has_field_[3]; }
+  AndroidLogPriority min_prio() const { return min_prio_; }
+  void set_min_prio(AndroidLogPriority value) { min_prio_ = value; _has_field_.set(3); }
+
+  const std::vector<std::string>& filter_tags() const { return filter_tags_; }
+  std::vector<std::string>* mutable_filter_tags() { return &filter_tags_; }
+  int filter_tags_size() const { return static_cast<int>(filter_tags_.size()); }
+  void clear_filter_tags() { filter_tags_.clear(); }
+  void add_filter_tags(std::string value) { filter_tags_.emplace_back(value); }
+  std::string* add_filter_tags() { filter_tags_.emplace_back(); return &filter_tags_.back(); }
+
+ private:
+  std::vector<AndroidLogId> log_ids_;
+  AndroidLogPriority min_prio_{};
+  std::vector<std::string> filter_tags_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<5> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_LOG_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/android_polled_state_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_POLLED_STATE_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_POLLED_STATE_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class AndroidPolledStateConfig;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT AndroidPolledStateConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kPollMsFieldNumber = 1,
+  };
+
+  AndroidPolledStateConfig();
+  ~AndroidPolledStateConfig() override;
+  AndroidPolledStateConfig(AndroidPolledStateConfig&&) noexcept;
+  AndroidPolledStateConfig& operator=(AndroidPolledStateConfig&&);
+  AndroidPolledStateConfig(const AndroidPolledStateConfig&);
+  AndroidPolledStateConfig& operator=(const AndroidPolledStateConfig&);
+  bool operator==(const AndroidPolledStateConfig&) const;
+  bool operator!=(const AndroidPolledStateConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_poll_ms() const { return _has_field_[1]; }
+  uint32_t poll_ms() const { return poll_ms_; }
+  void set_poll_ms(uint32_t value) { poll_ms_ = value; _has_field_.set(1); }
+
+ private:
+  uint32_t poll_ms_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_POLLED_STATE_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/android_sdk_sysprop_guard_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_SDK_SYSPROP_GUARD_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_SDK_SYSPROP_GUARD_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class AndroidSdkSyspropGuardConfig;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT AndroidSdkSyspropGuardConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kSurfaceflingerSkiaTrackEventsFieldNumber = 1,
+    kHwuiSkiaTrackEventsFieldNumber = 2,
+    kHwuiPackageNameFilterFieldNumber = 3,
+  };
+
+  AndroidSdkSyspropGuardConfig();
+  ~AndroidSdkSyspropGuardConfig() override;
+  AndroidSdkSyspropGuardConfig(AndroidSdkSyspropGuardConfig&&) noexcept;
+  AndroidSdkSyspropGuardConfig& operator=(AndroidSdkSyspropGuardConfig&&);
+  AndroidSdkSyspropGuardConfig(const AndroidSdkSyspropGuardConfig&);
+  AndroidSdkSyspropGuardConfig& operator=(const AndroidSdkSyspropGuardConfig&);
+  bool operator==(const AndroidSdkSyspropGuardConfig&) const;
+  bool operator!=(const AndroidSdkSyspropGuardConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_surfaceflinger_skia_track_events() const { return _has_field_[1]; }
+  bool surfaceflinger_skia_track_events() const { return surfaceflinger_skia_track_events_; }
+  void set_surfaceflinger_skia_track_events(bool value) { surfaceflinger_skia_track_events_ = value; _has_field_.set(1); }
+
+  bool has_hwui_skia_track_events() const { return _has_field_[2]; }
+  bool hwui_skia_track_events() const { return hwui_skia_track_events_; }
+  void set_hwui_skia_track_events(bool value) { hwui_skia_track_events_ = value; _has_field_.set(2); }
+
+  const std::vector<std::string>& hwui_package_name_filter() const { return hwui_package_name_filter_; }
+  std::vector<std::string>* mutable_hwui_package_name_filter() { return &hwui_package_name_filter_; }
+  int hwui_package_name_filter_size() const { return static_cast<int>(hwui_package_name_filter_.size()); }
+  void clear_hwui_package_name_filter() { hwui_package_name_filter_.clear(); }
+  void add_hwui_package_name_filter(std::string value) { hwui_package_name_filter_.emplace_back(value); }
+  std::string* add_hwui_package_name_filter() { hwui_package_name_filter_.emplace_back(); return &hwui_package_name_filter_.back(); }
+
+ private:
+  bool surfaceflinger_skia_track_events_{};
+  bool hwui_skia_track_events_{};
+  std::vector<std::string> hwui_package_name_filter_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_SDK_SYSPROP_GUARD_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/android_system_property_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_SYSTEM_PROPERTY_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_SYSTEM_PROPERTY_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class AndroidSystemPropertyConfig;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT AndroidSystemPropertyConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kPollMsFieldNumber = 1,
+    kPropertyNameFieldNumber = 2,
+  };
+
+  AndroidSystemPropertyConfig();
+  ~AndroidSystemPropertyConfig() override;
+  AndroidSystemPropertyConfig(AndroidSystemPropertyConfig&&) noexcept;
+  AndroidSystemPropertyConfig& operator=(AndroidSystemPropertyConfig&&);
+  AndroidSystemPropertyConfig(const AndroidSystemPropertyConfig&);
+  AndroidSystemPropertyConfig& operator=(const AndroidSystemPropertyConfig&);
+  bool operator==(const AndroidSystemPropertyConfig&) const;
+  bool operator!=(const AndroidSystemPropertyConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_poll_ms() const { return _has_field_[1]; }
+  uint32_t poll_ms() const { return poll_ms_; }
+  void set_poll_ms(uint32_t value) { poll_ms_ = value; _has_field_.set(1); }
+
+  const std::vector<std::string>& property_name() const { return property_name_; }
+  std::vector<std::string>* mutable_property_name() { return &property_name_; }
+  int property_name_size() const { return static_cast<int>(property_name_.size()); }
+  void clear_property_name() { property_name_.clear(); }
+  void add_property_name(std::string value) { property_name_.emplace_back(value); }
+  std::string* add_property_name() { property_name_.emplace_back(); return &property_name_.back(); }
+
+ private:
+  uint32_t poll_ms_{};
+  std::vector<std::string> property_name_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_SYSTEM_PROPERTY_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/network_trace_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_NETWORK_TRACE_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_NETWORK_TRACE_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class NetworkPacketTraceConfig;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT NetworkPacketTraceConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kPollMsFieldNumber = 1,
+    kAggregationThresholdFieldNumber = 2,
+    kInternLimitFieldNumber = 3,
+    kDropLocalPortFieldNumber = 4,
+    kDropRemotePortFieldNumber = 5,
+    kDropTcpFlagsFieldNumber = 6,
+  };
+
+  NetworkPacketTraceConfig();
+  ~NetworkPacketTraceConfig() override;
+  NetworkPacketTraceConfig(NetworkPacketTraceConfig&&) noexcept;
+  NetworkPacketTraceConfig& operator=(NetworkPacketTraceConfig&&);
+  NetworkPacketTraceConfig(const NetworkPacketTraceConfig&);
+  NetworkPacketTraceConfig& operator=(const NetworkPacketTraceConfig&);
+  bool operator==(const NetworkPacketTraceConfig&) const;
+  bool operator!=(const NetworkPacketTraceConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_poll_ms() const { return _has_field_[1]; }
+  uint32_t poll_ms() const { return poll_ms_; }
+  void set_poll_ms(uint32_t value) { poll_ms_ = value; _has_field_.set(1); }
+
+  bool has_aggregation_threshold() const { return _has_field_[2]; }
+  uint32_t aggregation_threshold() const { return aggregation_threshold_; }
+  void set_aggregation_threshold(uint32_t value) { aggregation_threshold_ = value; _has_field_.set(2); }
+
+  bool has_intern_limit() const { return _has_field_[3]; }
+  uint32_t intern_limit() const { return intern_limit_; }
+  void set_intern_limit(uint32_t value) { intern_limit_ = value; _has_field_.set(3); }
+
+  bool has_drop_local_port() const { return _has_field_[4]; }
+  bool drop_local_port() const { return drop_local_port_; }
+  void set_drop_local_port(bool value) { drop_local_port_ = value; _has_field_.set(4); }
+
+  bool has_drop_remote_port() const { return _has_field_[5]; }
+  bool drop_remote_port() const { return drop_remote_port_; }
+  void set_drop_remote_port(bool value) { drop_remote_port_ = value; _has_field_.set(5); }
+
+  bool has_drop_tcp_flags() const { return _has_field_[6]; }
+  bool drop_tcp_flags() const { return drop_tcp_flags_; }
+  void set_drop_tcp_flags(bool value) { drop_tcp_flags_ = value; _has_field_.set(6); }
+
+ private:
+  uint32_t poll_ms_{};
+  uint32_t aggregation_threshold_{};
+  uint32_t intern_limit_{};
+  bool drop_local_port_{};
+  bool drop_remote_port_{};
+  bool drop_tcp_flags_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<7> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_NETWORK_TRACE_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/packages_list_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_PACKAGES_LIST_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_PACKAGES_LIST_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class PackagesListConfig;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT PackagesListConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kPackageNameFilterFieldNumber = 1,
+  };
+
+  PackagesListConfig();
+  ~PackagesListConfig() override;
+  PackagesListConfig(PackagesListConfig&&) noexcept;
+  PackagesListConfig& operator=(PackagesListConfig&&);
+  PackagesListConfig(const PackagesListConfig&);
+  PackagesListConfig& operator=(const PackagesListConfig&);
+  bool operator==(const PackagesListConfig&) const;
+  bool operator!=(const PackagesListConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<std::string>& package_name_filter() const { return package_name_filter_; }
+  std::vector<std::string>* mutable_package_name_filter() { return &package_name_filter_; }
+  int package_name_filter_size() const { return static_cast<int>(package_name_filter_.size()); }
+  void clear_package_name_filter() { package_name_filter_.clear(); }
+  void add_package_name_filter(std::string value) { package_name_filter_.emplace_back(value); }
+  std::string* add_package_name_filter() { package_name_filter_.emplace_back(); return &package_name_filter_.back(); }
+
+ private:
+  std::vector<std::string> package_name_filter_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_PACKAGES_LIST_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/pixel_modem_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_PIXEL_MODEM_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_PIXEL_MODEM_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class PixelModemConfig;
+enum PixelModemConfig_EventGroup : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum PixelModemConfig_EventGroup : int {
+  PixelModemConfig_EventGroup_EVENT_GROUP_UNKNOWN = 0,
+  PixelModemConfig_EventGroup_EVENT_GROUP_LOW_BANDWIDTH = 1,
+  PixelModemConfig_EventGroup_EVENT_GROUP_HIGH_AND_LOW_BANDWIDTH = 2,
+};
+
+class PERFETTO_EXPORT_COMPONENT PixelModemConfig : public ::protozero::CppMessageObj {
+ public:
+  using EventGroup = PixelModemConfig_EventGroup;
+  static constexpr auto EVENT_GROUP_UNKNOWN = PixelModemConfig_EventGroup_EVENT_GROUP_UNKNOWN;
+  static constexpr auto EVENT_GROUP_LOW_BANDWIDTH = PixelModemConfig_EventGroup_EVENT_GROUP_LOW_BANDWIDTH;
+  static constexpr auto EVENT_GROUP_HIGH_AND_LOW_BANDWIDTH = PixelModemConfig_EventGroup_EVENT_GROUP_HIGH_AND_LOW_BANDWIDTH;
+  static constexpr auto EventGroup_MIN = PixelModemConfig_EventGroup_EVENT_GROUP_UNKNOWN;
+  static constexpr auto EventGroup_MAX = PixelModemConfig_EventGroup_EVENT_GROUP_HIGH_AND_LOW_BANDWIDTH;
+  enum FieldNumbers {
+    kEventGroupFieldNumber = 1,
+    kPigweedHashAllowListFieldNumber = 2,
+    kPigweedHashDenyListFieldNumber = 3,
+  };
+
+  PixelModemConfig();
+  ~PixelModemConfig() override;
+  PixelModemConfig(PixelModemConfig&&) noexcept;
+  PixelModemConfig& operator=(PixelModemConfig&&);
+  PixelModemConfig(const PixelModemConfig&);
+  PixelModemConfig& operator=(const PixelModemConfig&);
+  bool operator==(const PixelModemConfig&) const;
+  bool operator!=(const PixelModemConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_event_group() const { return _has_field_[1]; }
+  PixelModemConfig_EventGroup event_group() const { return event_group_; }
+  void set_event_group(PixelModemConfig_EventGroup value) { event_group_ = value; _has_field_.set(1); }
+
+  const std::vector<int64_t>& pigweed_hash_allow_list() const { return pigweed_hash_allow_list_; }
+  std::vector<int64_t>* mutable_pigweed_hash_allow_list() { return &pigweed_hash_allow_list_; }
+  int pigweed_hash_allow_list_size() const { return static_cast<int>(pigweed_hash_allow_list_.size()); }
+  void clear_pigweed_hash_allow_list() { pigweed_hash_allow_list_.clear(); }
+  void add_pigweed_hash_allow_list(int64_t value) { pigweed_hash_allow_list_.emplace_back(value); }
+  int64_t* add_pigweed_hash_allow_list() { pigweed_hash_allow_list_.emplace_back(); return &pigweed_hash_allow_list_.back(); }
+
+  const std::vector<int64_t>& pigweed_hash_deny_list() const { return pigweed_hash_deny_list_; }
+  std::vector<int64_t>* mutable_pigweed_hash_deny_list() { return &pigweed_hash_deny_list_; }
+  int pigweed_hash_deny_list_size() const { return static_cast<int>(pigweed_hash_deny_list_.size()); }
+  void clear_pigweed_hash_deny_list() { pigweed_hash_deny_list_.clear(); }
+  void add_pigweed_hash_deny_list(int64_t value) { pigweed_hash_deny_list_.emplace_back(value); }
+  int64_t* add_pigweed_hash_deny_list() { pigweed_hash_deny_list_.emplace_back(); return &pigweed_hash_deny_list_.back(); }
+
+ private:
+  PixelModemConfig_EventGroup event_group_{};
+  std::vector<int64_t> pigweed_hash_allow_list_;
+  std::vector<int64_t> pigweed_hash_deny_list_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_PIXEL_MODEM_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/protolog_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_PROTOLOG_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_PROTOLOG_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ProtoLogGroup;
+class ProtoLogConfig;
+enum ProtoLogLevel : int;
+enum ProtoLogConfig_TracingMode : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum ProtoLogConfig_TracingMode : int {
+  ProtoLogConfig_TracingMode_DEFAULT = 0,
+  ProtoLogConfig_TracingMode_ENABLE_ALL = 1,
+};
+
+class PERFETTO_EXPORT_COMPONENT ProtoLogGroup : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kGroupNameFieldNumber = 1,
+    kLogFromFieldNumber = 2,
+    kCollectStacktraceFieldNumber = 3,
+  };
+
+  ProtoLogGroup();
+  ~ProtoLogGroup() override;
+  ProtoLogGroup(ProtoLogGroup&&) noexcept;
+  ProtoLogGroup& operator=(ProtoLogGroup&&);
+  ProtoLogGroup(const ProtoLogGroup&);
+  ProtoLogGroup& operator=(const ProtoLogGroup&);
+  bool operator==(const ProtoLogGroup&) const;
+  bool operator!=(const ProtoLogGroup& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_group_name() const { return _has_field_[1]; }
+  const std::string& group_name() const { return group_name_; }
+  void set_group_name(const std::string& value) { group_name_ = value; _has_field_.set(1); }
+
+  bool has_log_from() const { return _has_field_[2]; }
+  ProtoLogLevel log_from() const { return log_from_; }
+  void set_log_from(ProtoLogLevel value) { log_from_ = value; _has_field_.set(2); }
+
+  bool has_collect_stacktrace() const { return _has_field_[3]; }
+  bool collect_stacktrace() const { return collect_stacktrace_; }
+  void set_collect_stacktrace(bool value) { collect_stacktrace_ = value; _has_field_.set(3); }
+
+ private:
+  std::string group_name_{};
+  ProtoLogLevel log_from_{};
+  bool collect_stacktrace_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT ProtoLogConfig : public ::protozero::CppMessageObj {
+ public:
+  using TracingMode = ProtoLogConfig_TracingMode;
+  static constexpr auto DEFAULT = ProtoLogConfig_TracingMode_DEFAULT;
+  static constexpr auto ENABLE_ALL = ProtoLogConfig_TracingMode_ENABLE_ALL;
+  static constexpr auto TracingMode_MIN = ProtoLogConfig_TracingMode_DEFAULT;
+  static constexpr auto TracingMode_MAX = ProtoLogConfig_TracingMode_ENABLE_ALL;
+  enum FieldNumbers {
+    kGroupOverridesFieldNumber = 1,
+    kTracingModeFieldNumber = 2,
+  };
+
+  ProtoLogConfig();
+  ~ProtoLogConfig() override;
+  ProtoLogConfig(ProtoLogConfig&&) noexcept;
+  ProtoLogConfig& operator=(ProtoLogConfig&&);
+  ProtoLogConfig(const ProtoLogConfig&);
+  ProtoLogConfig& operator=(const ProtoLogConfig&);
+  bool operator==(const ProtoLogConfig&) const;
+  bool operator!=(const ProtoLogConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<ProtoLogGroup>& group_overrides() const { return group_overrides_; }
+  std::vector<ProtoLogGroup>* mutable_group_overrides() { return &group_overrides_; }
+  int group_overrides_size() const;
+  void clear_group_overrides();
+  ProtoLogGroup* add_group_overrides();
+
+  bool has_tracing_mode() const { return _has_field_[2]; }
+  ProtoLogConfig_TracingMode tracing_mode() const { return tracing_mode_; }
+  void set_tracing_mode(ProtoLogConfig_TracingMode value) { tracing_mode_ = value; _has_field_.set(2); }
+
+ private:
+  std::vector<ProtoLogGroup> group_overrides_;
+  ProtoLogConfig_TracingMode tracing_mode_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_PROTOLOG_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/surfaceflinger_layers_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_SURFACEFLINGER_LAYERS_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_SURFACEFLINGER_LAYERS_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class SurfaceFlingerLayersConfig;
+enum SurfaceFlingerLayersConfig_Mode : int;
+enum SurfaceFlingerLayersConfig_TraceFlag : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum SurfaceFlingerLayersConfig_Mode : int {
+  SurfaceFlingerLayersConfig_Mode_MODE_UNSPECIFIED = 0,
+  SurfaceFlingerLayersConfig_Mode_MODE_ACTIVE = 1,
+  SurfaceFlingerLayersConfig_Mode_MODE_GENERATED = 2,
+  SurfaceFlingerLayersConfig_Mode_MODE_DUMP = 3,
+  SurfaceFlingerLayersConfig_Mode_MODE_GENERATED_BUGREPORT_ONLY = 4,
+};
+enum SurfaceFlingerLayersConfig_TraceFlag : int {
+  SurfaceFlingerLayersConfig_TraceFlag_TRACE_FLAG_UNSPECIFIED = 0,
+  SurfaceFlingerLayersConfig_TraceFlag_TRACE_FLAG_INPUT = 2,
+  SurfaceFlingerLayersConfig_TraceFlag_TRACE_FLAG_COMPOSITION = 4,
+  SurfaceFlingerLayersConfig_TraceFlag_TRACE_FLAG_EXTRA = 8,
+  SurfaceFlingerLayersConfig_TraceFlag_TRACE_FLAG_HWC = 16,
+  SurfaceFlingerLayersConfig_TraceFlag_TRACE_FLAG_BUFFERS = 32,
+  SurfaceFlingerLayersConfig_TraceFlag_TRACE_FLAG_VIRTUAL_DISPLAYS = 64,
+  SurfaceFlingerLayersConfig_TraceFlag_TRACE_FLAG_ALL = 14,
+};
+
+class PERFETTO_EXPORT_COMPONENT SurfaceFlingerLayersConfig : public ::protozero::CppMessageObj {
+ public:
+  using Mode = SurfaceFlingerLayersConfig_Mode;
+  static constexpr auto MODE_UNSPECIFIED = SurfaceFlingerLayersConfig_Mode_MODE_UNSPECIFIED;
+  static constexpr auto MODE_ACTIVE = SurfaceFlingerLayersConfig_Mode_MODE_ACTIVE;
+  static constexpr auto MODE_GENERATED = SurfaceFlingerLayersConfig_Mode_MODE_GENERATED;
+  static constexpr auto MODE_DUMP = SurfaceFlingerLayersConfig_Mode_MODE_DUMP;
+  static constexpr auto MODE_GENERATED_BUGREPORT_ONLY = SurfaceFlingerLayersConfig_Mode_MODE_GENERATED_BUGREPORT_ONLY;
+  static constexpr auto Mode_MIN = SurfaceFlingerLayersConfig_Mode_MODE_UNSPECIFIED;
+  static constexpr auto Mode_MAX = SurfaceFlingerLayersConfig_Mode_MODE_GENERATED_BUGREPORT_ONLY;
+  using TraceFlag = SurfaceFlingerLayersConfig_TraceFlag;
+  static constexpr auto TRACE_FLAG_UNSPECIFIED = SurfaceFlingerLayersConfig_TraceFlag_TRACE_FLAG_UNSPECIFIED;
+  static constexpr auto TRACE_FLAG_INPUT = SurfaceFlingerLayersConfig_TraceFlag_TRACE_FLAG_INPUT;
+  static constexpr auto TRACE_FLAG_COMPOSITION = SurfaceFlingerLayersConfig_TraceFlag_TRACE_FLAG_COMPOSITION;
+  static constexpr auto TRACE_FLAG_EXTRA = SurfaceFlingerLayersConfig_TraceFlag_TRACE_FLAG_EXTRA;
+  static constexpr auto TRACE_FLAG_HWC = SurfaceFlingerLayersConfig_TraceFlag_TRACE_FLAG_HWC;
+  static constexpr auto TRACE_FLAG_BUFFERS = SurfaceFlingerLayersConfig_TraceFlag_TRACE_FLAG_BUFFERS;
+  static constexpr auto TRACE_FLAG_VIRTUAL_DISPLAYS = SurfaceFlingerLayersConfig_TraceFlag_TRACE_FLAG_VIRTUAL_DISPLAYS;
+  static constexpr auto TRACE_FLAG_ALL = SurfaceFlingerLayersConfig_TraceFlag_TRACE_FLAG_ALL;
+  static constexpr auto TraceFlag_MIN = SurfaceFlingerLayersConfig_TraceFlag_TRACE_FLAG_UNSPECIFIED;
+  static constexpr auto TraceFlag_MAX = SurfaceFlingerLayersConfig_TraceFlag_TRACE_FLAG_VIRTUAL_DISPLAYS;
+  enum FieldNumbers {
+    kModeFieldNumber = 1,
+    kTraceFlagsFieldNumber = 2,
+  };
+
+  SurfaceFlingerLayersConfig();
+  ~SurfaceFlingerLayersConfig() override;
+  SurfaceFlingerLayersConfig(SurfaceFlingerLayersConfig&&) noexcept;
+  SurfaceFlingerLayersConfig& operator=(SurfaceFlingerLayersConfig&&);
+  SurfaceFlingerLayersConfig(const SurfaceFlingerLayersConfig&);
+  SurfaceFlingerLayersConfig& operator=(const SurfaceFlingerLayersConfig&);
+  bool operator==(const SurfaceFlingerLayersConfig&) const;
+  bool operator!=(const SurfaceFlingerLayersConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_mode() const { return _has_field_[1]; }
+  SurfaceFlingerLayersConfig_Mode mode() const { return mode_; }
+  void set_mode(SurfaceFlingerLayersConfig_Mode value) { mode_ = value; _has_field_.set(1); }
+
+  const std::vector<SurfaceFlingerLayersConfig_TraceFlag>& trace_flags() const { return trace_flags_; }
+  std::vector<SurfaceFlingerLayersConfig_TraceFlag>* mutable_trace_flags() { return &trace_flags_; }
+  int trace_flags_size() const { return static_cast<int>(trace_flags_.size()); }
+  void clear_trace_flags() { trace_flags_.clear(); }
+  void add_trace_flags(SurfaceFlingerLayersConfig_TraceFlag value) { trace_flags_.emplace_back(value); }
+  SurfaceFlingerLayersConfig_TraceFlag* add_trace_flags() { trace_flags_.emplace_back(); return &trace_flags_.back(); }
+
+ private:
+  SurfaceFlingerLayersConfig_Mode mode_{};
+  std::vector<SurfaceFlingerLayersConfig_TraceFlag> trace_flags_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_SURFACEFLINGER_LAYERS_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/surfaceflinger_transactions_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_SURFACEFLINGER_TRANSACTIONS_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_SURFACEFLINGER_TRANSACTIONS_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class SurfaceFlingerTransactionsConfig;
+enum SurfaceFlingerTransactionsConfig_Mode : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum SurfaceFlingerTransactionsConfig_Mode : int {
+  SurfaceFlingerTransactionsConfig_Mode_MODE_UNSPECIFIED = 0,
+  SurfaceFlingerTransactionsConfig_Mode_MODE_CONTINUOUS = 1,
+  SurfaceFlingerTransactionsConfig_Mode_MODE_ACTIVE = 2,
+};
+
+class PERFETTO_EXPORT_COMPONENT SurfaceFlingerTransactionsConfig : public ::protozero::CppMessageObj {
+ public:
+  using Mode = SurfaceFlingerTransactionsConfig_Mode;
+  static constexpr auto MODE_UNSPECIFIED = SurfaceFlingerTransactionsConfig_Mode_MODE_UNSPECIFIED;
+  static constexpr auto MODE_CONTINUOUS = SurfaceFlingerTransactionsConfig_Mode_MODE_CONTINUOUS;
+  static constexpr auto MODE_ACTIVE = SurfaceFlingerTransactionsConfig_Mode_MODE_ACTIVE;
+  static constexpr auto Mode_MIN = SurfaceFlingerTransactionsConfig_Mode_MODE_UNSPECIFIED;
+  static constexpr auto Mode_MAX = SurfaceFlingerTransactionsConfig_Mode_MODE_ACTIVE;
+  enum FieldNumbers {
+    kModeFieldNumber = 1,
+  };
+
+  SurfaceFlingerTransactionsConfig();
+  ~SurfaceFlingerTransactionsConfig() override;
+  SurfaceFlingerTransactionsConfig(SurfaceFlingerTransactionsConfig&&) noexcept;
+  SurfaceFlingerTransactionsConfig& operator=(SurfaceFlingerTransactionsConfig&&);
+  SurfaceFlingerTransactionsConfig(const SurfaceFlingerTransactionsConfig&);
+  SurfaceFlingerTransactionsConfig& operator=(const SurfaceFlingerTransactionsConfig&);
+  bool operator==(const SurfaceFlingerTransactionsConfig&) const;
+  bool operator!=(const SurfaceFlingerTransactionsConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_mode() const { return _has_field_[1]; }
+  SurfaceFlingerTransactionsConfig_Mode mode() const { return mode_; }
+  void set_mode(SurfaceFlingerTransactionsConfig_Mode value) { mode_ = value; _has_field_.set(1); }
+
+ private:
+  SurfaceFlingerTransactionsConfig_Mode mode_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_SURFACEFLINGER_TRANSACTIONS_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/ftrace/ftrace_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_FTRACE_FTRACE_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_FTRACE_FTRACE_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class FtraceConfig;
+class FtraceConfig_PrintFilter;
+class FtraceConfig_PrintFilter_Rule;
+class FtraceConfig_PrintFilter_Rule_AtraceMessage;
+class FtraceConfig_CompactSchedConfig;
+enum FtraceConfig_KsymsMemPolicy : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum FtraceConfig_KsymsMemPolicy : int {
+  FtraceConfig_KsymsMemPolicy_KSYMS_UNSPECIFIED = 0,
+  FtraceConfig_KsymsMemPolicy_KSYMS_CLEANUP_ON_STOP = 1,
+  FtraceConfig_KsymsMemPolicy_KSYMS_RETAIN = 2,
+};
+
+class PERFETTO_EXPORT_COMPONENT FtraceConfig : public ::protozero::CppMessageObj {
+ public:
+  using CompactSchedConfig = FtraceConfig_CompactSchedConfig;
+  using PrintFilter = FtraceConfig_PrintFilter;
+  using KsymsMemPolicy = FtraceConfig_KsymsMemPolicy;
+  static constexpr auto KSYMS_UNSPECIFIED = FtraceConfig_KsymsMemPolicy_KSYMS_UNSPECIFIED;
+  static constexpr auto KSYMS_CLEANUP_ON_STOP = FtraceConfig_KsymsMemPolicy_KSYMS_CLEANUP_ON_STOP;
+  static constexpr auto KSYMS_RETAIN = FtraceConfig_KsymsMemPolicy_KSYMS_RETAIN;
+  static constexpr auto KsymsMemPolicy_MIN = FtraceConfig_KsymsMemPolicy_KSYMS_UNSPECIFIED;
+  static constexpr auto KsymsMemPolicy_MAX = FtraceConfig_KsymsMemPolicy_KSYMS_RETAIN;
+  enum FieldNumbers {
+    kFtraceEventsFieldNumber = 1,
+    kAtraceCategoriesFieldNumber = 2,
+    kAtraceAppsFieldNumber = 3,
+    kBufferSizeKbFieldNumber = 10,
+    kDrainPeriodMsFieldNumber = 11,
+    kDrainBufferPercentFieldNumber = 26,
+    kCompactSchedFieldNumber = 12,
+    kPrintFilterFieldNumber = 22,
+    kSymbolizeKsymsFieldNumber = 13,
+    kKsymsMemPolicyFieldNumber = 17,
+    kInitializeKsymsSynchronouslyForTestingFieldNumber = 14,
+    kThrottleRssStatFieldNumber = 15,
+    kDisableGenericEventsFieldNumber = 16,
+    kSyscallEventsFieldNumber = 18,
+    kEnableFunctionGraphFieldNumber = 19,
+    kFunctionFiltersFieldNumber = 20,
+    kFunctionGraphRootsFieldNumber = 21,
+    kPreserveFtraceBufferFieldNumber = 23,
+    kUseMonotonicRawClockFieldNumber = 24,
+    kInstanceNameFieldNumber = 25,
+    kBufferSizeLowerBoundFieldNumber = 27,
+  };
+
+  FtraceConfig();
+  ~FtraceConfig() override;
+  FtraceConfig(FtraceConfig&&) noexcept;
+  FtraceConfig& operator=(FtraceConfig&&);
+  FtraceConfig(const FtraceConfig&);
+  FtraceConfig& operator=(const FtraceConfig&);
+  bool operator==(const FtraceConfig&) const;
+  bool operator!=(const FtraceConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<std::string>& ftrace_events() const { return ftrace_events_; }
+  std::vector<std::string>* mutable_ftrace_events() { return &ftrace_events_; }
+  int ftrace_events_size() const { return static_cast<int>(ftrace_events_.size()); }
+  void clear_ftrace_events() { ftrace_events_.clear(); }
+  void add_ftrace_events(std::string value) { ftrace_events_.emplace_back(value); }
+  std::string* add_ftrace_events() { ftrace_events_.emplace_back(); return &ftrace_events_.back(); }
+
+  const std::vector<std::string>& atrace_categories() const { return atrace_categories_; }
+  std::vector<std::string>* mutable_atrace_categories() { return &atrace_categories_; }
+  int atrace_categories_size() const { return static_cast<int>(atrace_categories_.size()); }
+  void clear_atrace_categories() { atrace_categories_.clear(); }
+  void add_atrace_categories(std::string value) { atrace_categories_.emplace_back(value); }
+  std::string* add_atrace_categories() { atrace_categories_.emplace_back(); return &atrace_categories_.back(); }
+
+  const std::vector<std::string>& atrace_apps() const { return atrace_apps_; }
+  std::vector<std::string>* mutable_atrace_apps() { return &atrace_apps_; }
+  int atrace_apps_size() const { return static_cast<int>(atrace_apps_.size()); }
+  void clear_atrace_apps() { atrace_apps_.clear(); }
+  void add_atrace_apps(std::string value) { atrace_apps_.emplace_back(value); }
+  std::string* add_atrace_apps() { atrace_apps_.emplace_back(); return &atrace_apps_.back(); }
+
+  bool has_buffer_size_kb() const { return _has_field_[10]; }
+  uint32_t buffer_size_kb() const { return buffer_size_kb_; }
+  void set_buffer_size_kb(uint32_t value) { buffer_size_kb_ = value; _has_field_.set(10); }
+
+  bool has_drain_period_ms() const { return _has_field_[11]; }
+  uint32_t drain_period_ms() const { return drain_period_ms_; }
+  void set_drain_period_ms(uint32_t value) { drain_period_ms_ = value; _has_field_.set(11); }
+
+  bool has_drain_buffer_percent() const { return _has_field_[26]; }
+  uint32_t drain_buffer_percent() const { return drain_buffer_percent_; }
+  void set_drain_buffer_percent(uint32_t value) { drain_buffer_percent_ = value; _has_field_.set(26); }
+
+  bool has_compact_sched() const { return _has_field_[12]; }
+  const FtraceConfig_CompactSchedConfig& compact_sched() const { return *compact_sched_; }
+  FtraceConfig_CompactSchedConfig* mutable_compact_sched() { _has_field_.set(12); return compact_sched_.get(); }
+
+  bool has_print_filter() const { return _has_field_[22]; }
+  const FtraceConfig_PrintFilter& print_filter() const { return *print_filter_; }
+  FtraceConfig_PrintFilter* mutable_print_filter() { _has_field_.set(22); return print_filter_.get(); }
+
+  bool has_symbolize_ksyms() const { return _has_field_[13]; }
+  bool symbolize_ksyms() const { return symbolize_ksyms_; }
+  void set_symbolize_ksyms(bool value) { symbolize_ksyms_ = value; _has_field_.set(13); }
+
+  bool has_ksyms_mem_policy() const { return _has_field_[17]; }
+  FtraceConfig_KsymsMemPolicy ksyms_mem_policy() const { return ksyms_mem_policy_; }
+  void set_ksyms_mem_policy(FtraceConfig_KsymsMemPolicy value) { ksyms_mem_policy_ = value; _has_field_.set(17); }
+
+  bool has_initialize_ksyms_synchronously_for_testing() const { return _has_field_[14]; }
+  bool initialize_ksyms_synchronously_for_testing() const { return initialize_ksyms_synchronously_for_testing_; }
+  void set_initialize_ksyms_synchronously_for_testing(bool value) { initialize_ksyms_synchronously_for_testing_ = value; _has_field_.set(14); }
+
+  bool has_throttle_rss_stat() const { return _has_field_[15]; }
+  bool throttle_rss_stat() const { return throttle_rss_stat_; }
+  void set_throttle_rss_stat(bool value) { throttle_rss_stat_ = value; _has_field_.set(15); }
+
+  bool has_disable_generic_events() const { return _has_field_[16]; }
+  bool disable_generic_events() const { return disable_generic_events_; }
+  void set_disable_generic_events(bool value) { disable_generic_events_ = value; _has_field_.set(16); }
+
+  const std::vector<std::string>& syscall_events() const { return syscall_events_; }
+  std::vector<std::string>* mutable_syscall_events() { return &syscall_events_; }
+  int syscall_events_size() const { return static_cast<int>(syscall_events_.size()); }
+  void clear_syscall_events() { syscall_events_.clear(); }
+  void add_syscall_events(std::string value) { syscall_events_.emplace_back(value); }
+  std::string* add_syscall_events() { syscall_events_.emplace_back(); return &syscall_events_.back(); }
+
+  bool has_enable_function_graph() const { return _has_field_[19]; }
+  bool enable_function_graph() const { return enable_function_graph_; }
+  void set_enable_function_graph(bool value) { enable_function_graph_ = value; _has_field_.set(19); }
+
+  const std::vector<std::string>& function_filters() const { return function_filters_; }
+  std::vector<std::string>* mutable_function_filters() { return &function_filters_; }
+  int function_filters_size() const { return static_cast<int>(function_filters_.size()); }
+  void clear_function_filters() { function_filters_.clear(); }
+  void add_function_filters(std::string value) { function_filters_.emplace_back(value); }
+  std::string* add_function_filters() { function_filters_.emplace_back(); return &function_filters_.back(); }
+
+  const std::vector<std::string>& function_graph_roots() const { return function_graph_roots_; }
+  std::vector<std::string>* mutable_function_graph_roots() { return &function_graph_roots_; }
+  int function_graph_roots_size() const { return static_cast<int>(function_graph_roots_.size()); }
+  void clear_function_graph_roots() { function_graph_roots_.clear(); }
+  void add_function_graph_roots(std::string value) { function_graph_roots_.emplace_back(value); }
+  std::string* add_function_graph_roots() { function_graph_roots_.emplace_back(); return &function_graph_roots_.back(); }
+
+  bool has_preserve_ftrace_buffer() const { return _has_field_[23]; }
+  bool preserve_ftrace_buffer() const { return preserve_ftrace_buffer_; }
+  void set_preserve_ftrace_buffer(bool value) { preserve_ftrace_buffer_ = value; _has_field_.set(23); }
+
+  bool has_use_monotonic_raw_clock() const { return _has_field_[24]; }
+  bool use_monotonic_raw_clock() const { return use_monotonic_raw_clock_; }
+  void set_use_monotonic_raw_clock(bool value) { use_monotonic_raw_clock_ = value; _has_field_.set(24); }
+
+  bool has_instance_name() const { return _has_field_[25]; }
+  const std::string& instance_name() const { return instance_name_; }
+  void set_instance_name(const std::string& value) { instance_name_ = value; _has_field_.set(25); }
+
+  bool has_buffer_size_lower_bound() const { return _has_field_[27]; }
+  bool buffer_size_lower_bound() const { return buffer_size_lower_bound_; }
+  void set_buffer_size_lower_bound(bool value) { buffer_size_lower_bound_ = value; _has_field_.set(27); }
+
+ private:
+  std::vector<std::string> ftrace_events_;
+  std::vector<std::string> atrace_categories_;
+  std::vector<std::string> atrace_apps_;
+  uint32_t buffer_size_kb_{};
+  uint32_t drain_period_ms_{};
+  uint32_t drain_buffer_percent_{};
+  ::protozero::CopyablePtr<FtraceConfig_CompactSchedConfig> compact_sched_;
+  ::protozero::CopyablePtr<FtraceConfig_PrintFilter> print_filter_;
+  bool symbolize_ksyms_{};
+  FtraceConfig_KsymsMemPolicy ksyms_mem_policy_{};
+  bool initialize_ksyms_synchronously_for_testing_{};
+  bool throttle_rss_stat_{};
+  bool disable_generic_events_{};
+  std::vector<std::string> syscall_events_;
+  bool enable_function_graph_{};
+  std::vector<std::string> function_filters_;
+  std::vector<std::string> function_graph_roots_;
+  bool preserve_ftrace_buffer_{};
+  bool use_monotonic_raw_clock_{};
+  std::string instance_name_{};
+  bool buffer_size_lower_bound_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<28> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT FtraceConfig_PrintFilter : public ::protozero::CppMessageObj {
+ public:
+  using Rule = FtraceConfig_PrintFilter_Rule;
+  enum FieldNumbers {
+    kRulesFieldNumber = 1,
+  };
+
+  FtraceConfig_PrintFilter();
+  ~FtraceConfig_PrintFilter() override;
+  FtraceConfig_PrintFilter(FtraceConfig_PrintFilter&&) noexcept;
+  FtraceConfig_PrintFilter& operator=(FtraceConfig_PrintFilter&&);
+  FtraceConfig_PrintFilter(const FtraceConfig_PrintFilter&);
+  FtraceConfig_PrintFilter& operator=(const FtraceConfig_PrintFilter&);
+  bool operator==(const FtraceConfig_PrintFilter&) const;
+  bool operator!=(const FtraceConfig_PrintFilter& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<FtraceConfig_PrintFilter_Rule>& rules() const { return rules_; }
+  std::vector<FtraceConfig_PrintFilter_Rule>* mutable_rules() { return &rules_; }
+  int rules_size() const;
+  void clear_rules();
+  FtraceConfig_PrintFilter_Rule* add_rules();
+
+ private:
+  std::vector<FtraceConfig_PrintFilter_Rule> rules_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT FtraceConfig_PrintFilter_Rule : public ::protozero::CppMessageObj {
+ public:
+  using AtraceMessage = FtraceConfig_PrintFilter_Rule_AtraceMessage;
+  enum FieldNumbers {
+    kPrefixFieldNumber = 1,
+    kAtraceMsgFieldNumber = 3,
+    kAllowFieldNumber = 2,
+  };
+
+  FtraceConfig_PrintFilter_Rule();
+  ~FtraceConfig_PrintFilter_Rule() override;
+  FtraceConfig_PrintFilter_Rule(FtraceConfig_PrintFilter_Rule&&) noexcept;
+  FtraceConfig_PrintFilter_Rule& operator=(FtraceConfig_PrintFilter_Rule&&);
+  FtraceConfig_PrintFilter_Rule(const FtraceConfig_PrintFilter_Rule&);
+  FtraceConfig_PrintFilter_Rule& operator=(const FtraceConfig_PrintFilter_Rule&);
+  bool operator==(const FtraceConfig_PrintFilter_Rule&) const;
+  bool operator!=(const FtraceConfig_PrintFilter_Rule& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_prefix() const { return _has_field_[1]; }
+  const std::string& prefix() const { return prefix_; }
+  void set_prefix(const std::string& value) { prefix_ = value; _has_field_.set(1); }
+
+  bool has_atrace_msg() const { return _has_field_[3]; }
+  const FtraceConfig_PrintFilter_Rule_AtraceMessage& atrace_msg() const { return *atrace_msg_; }
+  FtraceConfig_PrintFilter_Rule_AtraceMessage* mutable_atrace_msg() { _has_field_.set(3); return atrace_msg_.get(); }
+
+  bool has_allow() const { return _has_field_[2]; }
+  bool allow() const { return allow_; }
+  void set_allow(bool value) { allow_ = value; _has_field_.set(2); }
+
+ private:
+  std::string prefix_{};
+  ::protozero::CopyablePtr<FtraceConfig_PrintFilter_Rule_AtraceMessage> atrace_msg_;
+  bool allow_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT FtraceConfig_PrintFilter_Rule_AtraceMessage : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kTypeFieldNumber = 1,
+    kPrefixFieldNumber = 2,
+  };
+
+  FtraceConfig_PrintFilter_Rule_AtraceMessage();
+  ~FtraceConfig_PrintFilter_Rule_AtraceMessage() override;
+  FtraceConfig_PrintFilter_Rule_AtraceMessage(FtraceConfig_PrintFilter_Rule_AtraceMessage&&) noexcept;
+  FtraceConfig_PrintFilter_Rule_AtraceMessage& operator=(FtraceConfig_PrintFilter_Rule_AtraceMessage&&);
+  FtraceConfig_PrintFilter_Rule_AtraceMessage(const FtraceConfig_PrintFilter_Rule_AtraceMessage&);
+  FtraceConfig_PrintFilter_Rule_AtraceMessage& operator=(const FtraceConfig_PrintFilter_Rule_AtraceMessage&);
+  bool operator==(const FtraceConfig_PrintFilter_Rule_AtraceMessage&) const;
+  bool operator!=(const FtraceConfig_PrintFilter_Rule_AtraceMessage& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_type() const { return _has_field_[1]; }
+  const std::string& type() const { return type_; }
+  void set_type(const std::string& value) { type_ = value; _has_field_.set(1); }
+
+  bool has_prefix() const { return _has_field_[2]; }
+  const std::string& prefix() const { return prefix_; }
+  void set_prefix(const std::string& value) { prefix_ = value; _has_field_.set(2); }
+
+ private:
+  std::string type_{};
+  std::string prefix_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT FtraceConfig_CompactSchedConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kEnabledFieldNumber = 1,
+  };
+
+  FtraceConfig_CompactSchedConfig();
+  ~FtraceConfig_CompactSchedConfig() override;
+  FtraceConfig_CompactSchedConfig(FtraceConfig_CompactSchedConfig&&) noexcept;
+  FtraceConfig_CompactSchedConfig& operator=(FtraceConfig_CompactSchedConfig&&);
+  FtraceConfig_CompactSchedConfig(const FtraceConfig_CompactSchedConfig&);
+  FtraceConfig_CompactSchedConfig& operator=(const FtraceConfig_CompactSchedConfig&);
+  bool operator==(const FtraceConfig_CompactSchedConfig&) const;
+  bool operator!=(const FtraceConfig_CompactSchedConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_enabled() const { return _has_field_[1]; }
+  bool enabled() const { return enabled_; }
+  void set_enabled(bool value) { enabled_ = value; _has_field_.set(1); }
+
+ private:
+  bool enabled_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_FTRACE_FTRACE_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/gpu/gpu_counter_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_GPU_COUNTER_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_GPU_COUNTER_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class GpuCounterConfig;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT GpuCounterConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kCounterPeriodNsFieldNumber = 1,
+    kCounterIdsFieldNumber = 2,
+    kInstrumentedSamplingFieldNumber = 3,
+    kFixGpuClockFieldNumber = 4,
+  };
+
+  GpuCounterConfig();
+  ~GpuCounterConfig() override;
+  GpuCounterConfig(GpuCounterConfig&&) noexcept;
+  GpuCounterConfig& operator=(GpuCounterConfig&&);
+  GpuCounterConfig(const GpuCounterConfig&);
+  GpuCounterConfig& operator=(const GpuCounterConfig&);
+  bool operator==(const GpuCounterConfig&) const;
+  bool operator!=(const GpuCounterConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_counter_period_ns() const { return _has_field_[1]; }
+  uint64_t counter_period_ns() const { return counter_period_ns_; }
+  void set_counter_period_ns(uint64_t value) { counter_period_ns_ = value; _has_field_.set(1); }
+
+  const std::vector<uint32_t>& counter_ids() const { return counter_ids_; }
+  std::vector<uint32_t>* mutable_counter_ids() { return &counter_ids_; }
+  int counter_ids_size() const { return static_cast<int>(counter_ids_.size()); }
+  void clear_counter_ids() { counter_ids_.clear(); }
+  void add_counter_ids(uint32_t value) { counter_ids_.emplace_back(value); }
+  uint32_t* add_counter_ids() { counter_ids_.emplace_back(); return &counter_ids_.back(); }
+
+  bool has_instrumented_sampling() const { return _has_field_[3]; }
+  bool instrumented_sampling() const { return instrumented_sampling_; }
+  void set_instrumented_sampling(bool value) { instrumented_sampling_ = value; _has_field_.set(3); }
+
+  bool has_fix_gpu_clock() const { return _has_field_[4]; }
+  bool fix_gpu_clock() const { return fix_gpu_clock_; }
+  void set_fix_gpu_clock(bool value) { fix_gpu_clock_ = value; _has_field_.set(4); }
+
+ private:
+  uint64_t counter_period_ns_{};
+  std::vector<uint32_t> counter_ids_;
+  bool instrumented_sampling_{};
+  bool fix_gpu_clock_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<5> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_GPU_COUNTER_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/gpu/vulkan_memory_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_VULKAN_MEMORY_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_VULKAN_MEMORY_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class VulkanMemoryConfig;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT VulkanMemoryConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kTrackDriverMemoryUsageFieldNumber = 1,
+    kTrackDeviceMemoryUsageFieldNumber = 2,
+  };
+
+  VulkanMemoryConfig();
+  ~VulkanMemoryConfig() override;
+  VulkanMemoryConfig(VulkanMemoryConfig&&) noexcept;
+  VulkanMemoryConfig& operator=(VulkanMemoryConfig&&);
+  VulkanMemoryConfig(const VulkanMemoryConfig&);
+  VulkanMemoryConfig& operator=(const VulkanMemoryConfig&);
+  bool operator==(const VulkanMemoryConfig&) const;
+  bool operator!=(const VulkanMemoryConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_track_driver_memory_usage() const { return _has_field_[1]; }
+  bool track_driver_memory_usage() const { return track_driver_memory_usage_; }
+  void set_track_driver_memory_usage(bool value) { track_driver_memory_usage_ = value; _has_field_.set(1); }
+
+  bool has_track_device_memory_usage() const { return _has_field_[2]; }
+  bool track_device_memory_usage() const { return track_device_memory_usage_; }
+  void set_track_device_memory_usage(bool value) { track_device_memory_usage_ = value; _has_field_.set(2); }
+
+ private:
+  bool track_driver_memory_usage_{};
+  bool track_device_memory_usage_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_VULKAN_MEMORY_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/inode_file/inode_file_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INODE_FILE_INODE_FILE_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INODE_FILE_INODE_FILE_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class InodeFileConfig;
+class InodeFileConfig_MountPointMappingEntry;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT InodeFileConfig : public ::protozero::CppMessageObj {
+ public:
+  using MountPointMappingEntry = InodeFileConfig_MountPointMappingEntry;
+  enum FieldNumbers {
+    kScanIntervalMsFieldNumber = 1,
+    kScanDelayMsFieldNumber = 2,
+    kScanBatchSizeFieldNumber = 3,
+    kDoNotScanFieldNumber = 4,
+    kScanMountPointsFieldNumber = 5,
+    kMountPointMappingFieldNumber = 6,
+  };
+
+  InodeFileConfig();
+  ~InodeFileConfig() override;
+  InodeFileConfig(InodeFileConfig&&) noexcept;
+  InodeFileConfig& operator=(InodeFileConfig&&);
+  InodeFileConfig(const InodeFileConfig&);
+  InodeFileConfig& operator=(const InodeFileConfig&);
+  bool operator==(const InodeFileConfig&) const;
+  bool operator!=(const InodeFileConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_scan_interval_ms() const { return _has_field_[1]; }
+  uint32_t scan_interval_ms() const { return scan_interval_ms_; }
+  void set_scan_interval_ms(uint32_t value) { scan_interval_ms_ = value; _has_field_.set(1); }
+
+  bool has_scan_delay_ms() const { return _has_field_[2]; }
+  uint32_t scan_delay_ms() const { return scan_delay_ms_; }
+  void set_scan_delay_ms(uint32_t value) { scan_delay_ms_ = value; _has_field_.set(2); }
+
+  bool has_scan_batch_size() const { return _has_field_[3]; }
+  uint32_t scan_batch_size() const { return scan_batch_size_; }
+  void set_scan_batch_size(uint32_t value) { scan_batch_size_ = value; _has_field_.set(3); }
+
+  bool has_do_not_scan() const { return _has_field_[4]; }
+  bool do_not_scan() const { return do_not_scan_; }
+  void set_do_not_scan(bool value) { do_not_scan_ = value; _has_field_.set(4); }
+
+  const std::vector<std::string>& scan_mount_points() const { return scan_mount_points_; }
+  std::vector<std::string>* mutable_scan_mount_points() { return &scan_mount_points_; }
+  int scan_mount_points_size() const { return static_cast<int>(scan_mount_points_.size()); }
+  void clear_scan_mount_points() { scan_mount_points_.clear(); }
+  void add_scan_mount_points(std::string value) { scan_mount_points_.emplace_back(value); }
+  std::string* add_scan_mount_points() { scan_mount_points_.emplace_back(); return &scan_mount_points_.back(); }
+
+  const std::vector<InodeFileConfig_MountPointMappingEntry>& mount_point_mapping() const { return mount_point_mapping_; }
+  std::vector<InodeFileConfig_MountPointMappingEntry>* mutable_mount_point_mapping() { return &mount_point_mapping_; }
+  int mount_point_mapping_size() const;
+  void clear_mount_point_mapping();
+  InodeFileConfig_MountPointMappingEntry* add_mount_point_mapping();
+
+ private:
+  uint32_t scan_interval_ms_{};
+  uint32_t scan_delay_ms_{};
+  uint32_t scan_batch_size_{};
+  bool do_not_scan_{};
+  std::vector<std::string> scan_mount_points_;
+  std::vector<InodeFileConfig_MountPointMappingEntry> mount_point_mapping_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<7> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT InodeFileConfig_MountPointMappingEntry : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kMountpointFieldNumber = 1,
+    kScanRootsFieldNumber = 2,
+  };
+
+  InodeFileConfig_MountPointMappingEntry();
+  ~InodeFileConfig_MountPointMappingEntry() override;
+  InodeFileConfig_MountPointMappingEntry(InodeFileConfig_MountPointMappingEntry&&) noexcept;
+  InodeFileConfig_MountPointMappingEntry& operator=(InodeFileConfig_MountPointMappingEntry&&);
+  InodeFileConfig_MountPointMappingEntry(const InodeFileConfig_MountPointMappingEntry&);
+  InodeFileConfig_MountPointMappingEntry& operator=(const InodeFileConfig_MountPointMappingEntry&);
+  bool operator==(const InodeFileConfig_MountPointMappingEntry&) const;
+  bool operator!=(const InodeFileConfig_MountPointMappingEntry& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_mountpoint() const { return _has_field_[1]; }
+  const std::string& mountpoint() const { return mountpoint_; }
+  void set_mountpoint(const std::string& value) { mountpoint_ = value; _has_field_.set(1); }
+
+  const std::vector<std::string>& scan_roots() const { return scan_roots_; }
+  std::vector<std::string>* mutable_scan_roots() { return &scan_roots_; }
+  int scan_roots_size() const { return static_cast<int>(scan_roots_.size()); }
+  void clear_scan_roots() { scan_roots_.clear(); }
+  void add_scan_roots(std::string value) { scan_roots_.emplace_back(value); }
+  std::string* add_scan_roots() { scan_roots_.emplace_back(); return &scan_roots_.back(); }
+
+ private:
+  std::string mountpoint_{};
+  std::vector<std::string> scan_roots_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INODE_FILE_INODE_FILE_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/interceptors/console_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INTERCEPTORS_CONSOLE_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INTERCEPTORS_CONSOLE_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ConsoleConfig;
+enum ConsoleConfig_Output : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum ConsoleConfig_Output : int {
+  ConsoleConfig_Output_OUTPUT_UNSPECIFIED = 0,
+  ConsoleConfig_Output_OUTPUT_STDOUT = 1,
+  ConsoleConfig_Output_OUTPUT_STDERR = 2,
+};
+
+class PERFETTO_EXPORT_COMPONENT ConsoleConfig : public ::protozero::CppMessageObj {
+ public:
+  using Output = ConsoleConfig_Output;
+  static constexpr auto OUTPUT_UNSPECIFIED = ConsoleConfig_Output_OUTPUT_UNSPECIFIED;
+  static constexpr auto OUTPUT_STDOUT = ConsoleConfig_Output_OUTPUT_STDOUT;
+  static constexpr auto OUTPUT_STDERR = ConsoleConfig_Output_OUTPUT_STDERR;
+  static constexpr auto Output_MIN = ConsoleConfig_Output_OUTPUT_UNSPECIFIED;
+  static constexpr auto Output_MAX = ConsoleConfig_Output_OUTPUT_STDERR;
+  enum FieldNumbers {
+    kOutputFieldNumber = 1,
+    kEnableColorsFieldNumber = 2,
+  };
+
+  ConsoleConfig();
+  ~ConsoleConfig() override;
+  ConsoleConfig(ConsoleConfig&&) noexcept;
+  ConsoleConfig& operator=(ConsoleConfig&&);
+  ConsoleConfig(const ConsoleConfig&);
+  ConsoleConfig& operator=(const ConsoleConfig&);
+  bool operator==(const ConsoleConfig&) const;
+  bool operator!=(const ConsoleConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_output() const { return _has_field_[1]; }
+  ConsoleConfig_Output output() const { return output_; }
+  void set_output(ConsoleConfig_Output value) { output_ = value; _has_field_.set(1); }
+
+  bool has_enable_colors() const { return _has_field_[2]; }
+  bool enable_colors() const { return enable_colors_; }
+  void set_enable_colors(bool value) { enable_colors_ = value; _has_field_.set(2); }
+
+ private:
+  ConsoleConfig_Output output_{};
+  bool enable_colors_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INTERCEPTORS_CONSOLE_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/power/android_power_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_POWER_ANDROID_POWER_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_POWER_ANDROID_POWER_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class AndroidPowerConfig;
+enum AndroidPowerConfig_BatteryCounters : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum AndroidPowerConfig_BatteryCounters : int {
+  AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_UNSPECIFIED = 0,
+  AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CHARGE = 1,
+  AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CAPACITY_PERCENT = 2,
+  AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CURRENT = 3,
+  AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CURRENT_AVG = 4,
+  AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_VOLTAGE = 5,
+};
+
+class PERFETTO_EXPORT_COMPONENT AndroidPowerConfig : public ::protozero::CppMessageObj {
+ public:
+  using BatteryCounters = AndroidPowerConfig_BatteryCounters;
+  static constexpr auto BATTERY_COUNTER_UNSPECIFIED = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_UNSPECIFIED;
+  static constexpr auto BATTERY_COUNTER_CHARGE = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CHARGE;
+  static constexpr auto BATTERY_COUNTER_CAPACITY_PERCENT = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CAPACITY_PERCENT;
+  static constexpr auto BATTERY_COUNTER_CURRENT = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CURRENT;
+  static constexpr auto BATTERY_COUNTER_CURRENT_AVG = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CURRENT_AVG;
+  static constexpr auto BATTERY_COUNTER_VOLTAGE = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_VOLTAGE;
+  static constexpr auto BatteryCounters_MIN = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_UNSPECIFIED;
+  static constexpr auto BatteryCounters_MAX = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_VOLTAGE;
+  enum FieldNumbers {
+    kBatteryPollMsFieldNumber = 1,
+    kBatteryCountersFieldNumber = 2,
+    kCollectPowerRailsFieldNumber = 3,
+    kCollectEnergyEstimationBreakdownFieldNumber = 4,
+    kCollectEntityStateResidencyFieldNumber = 5,
+  };
+
+  AndroidPowerConfig();
+  ~AndroidPowerConfig() override;
+  AndroidPowerConfig(AndroidPowerConfig&&) noexcept;
+  AndroidPowerConfig& operator=(AndroidPowerConfig&&);
+  AndroidPowerConfig(const AndroidPowerConfig&);
+  AndroidPowerConfig& operator=(const AndroidPowerConfig&);
+  bool operator==(const AndroidPowerConfig&) const;
+  bool operator!=(const AndroidPowerConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_battery_poll_ms() const { return _has_field_[1]; }
+  uint32_t battery_poll_ms() const { return battery_poll_ms_; }
+  void set_battery_poll_ms(uint32_t value) { battery_poll_ms_ = value; _has_field_.set(1); }
+
+  const std::vector<AndroidPowerConfig_BatteryCounters>& battery_counters() const { return battery_counters_; }
+  std::vector<AndroidPowerConfig_BatteryCounters>* mutable_battery_counters() { return &battery_counters_; }
+  int battery_counters_size() const { return static_cast<int>(battery_counters_.size()); }
+  void clear_battery_counters() { battery_counters_.clear(); }
+  void add_battery_counters(AndroidPowerConfig_BatteryCounters value) { battery_counters_.emplace_back(value); }
+  AndroidPowerConfig_BatteryCounters* add_battery_counters() { battery_counters_.emplace_back(); return &battery_counters_.back(); }
+
+  bool has_collect_power_rails() const { return _has_field_[3]; }
+  bool collect_power_rails() const { return collect_power_rails_; }
+  void set_collect_power_rails(bool value) { collect_power_rails_ = value; _has_field_.set(3); }
+
+  bool has_collect_energy_estimation_breakdown() const { return _has_field_[4]; }
+  bool collect_energy_estimation_breakdown() const { return collect_energy_estimation_breakdown_; }
+  void set_collect_energy_estimation_breakdown(bool value) { collect_energy_estimation_breakdown_ = value; _has_field_.set(4); }
+
+  bool has_collect_entity_state_residency() const { return _has_field_[5]; }
+  bool collect_entity_state_residency() const { return collect_entity_state_residency_; }
+  void set_collect_entity_state_residency(bool value) { collect_entity_state_residency_ = value; _has_field_.set(5); }
+
+ private:
+  uint32_t battery_poll_ms_{};
+  std::vector<AndroidPowerConfig_BatteryCounters> battery_counters_;
+  bool collect_power_rails_{};
+  bool collect_energy_estimation_breakdown_{};
+  bool collect_entity_state_residency_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<6> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_POWER_ANDROID_POWER_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/process_stats/process_stats_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROCESS_STATS_PROCESS_STATS_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROCESS_STATS_PROCESS_STATS_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ProcessStatsConfig;
+enum ProcessStatsConfig_Quirks : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum ProcessStatsConfig_Quirks : int {
+  ProcessStatsConfig_Quirks_QUIRKS_UNSPECIFIED = 0,
+  ProcessStatsConfig_Quirks_DISABLE_INITIAL_DUMP = 1,
+  ProcessStatsConfig_Quirks_DISABLE_ON_DEMAND = 2,
+};
+
+class PERFETTO_EXPORT_COMPONENT ProcessStatsConfig : public ::protozero::CppMessageObj {
+ public:
+  using Quirks = ProcessStatsConfig_Quirks;
+  static constexpr auto QUIRKS_UNSPECIFIED = ProcessStatsConfig_Quirks_QUIRKS_UNSPECIFIED;
+  static constexpr auto DISABLE_INITIAL_DUMP = ProcessStatsConfig_Quirks_DISABLE_INITIAL_DUMP;
+  static constexpr auto DISABLE_ON_DEMAND = ProcessStatsConfig_Quirks_DISABLE_ON_DEMAND;
+  static constexpr auto Quirks_MIN = ProcessStatsConfig_Quirks_QUIRKS_UNSPECIFIED;
+  static constexpr auto Quirks_MAX = ProcessStatsConfig_Quirks_DISABLE_ON_DEMAND;
+  enum FieldNumbers {
+    kQuirksFieldNumber = 1,
+    kScanAllProcessesOnStartFieldNumber = 2,
+    kRecordThreadNamesFieldNumber = 3,
+    kProcStatsPollMsFieldNumber = 4,
+    kProcStatsCacheTtlMsFieldNumber = 6,
+    kResolveProcessFdsFieldNumber = 9,
+    kScanSmapsRollupFieldNumber = 10,
+    kRecordProcessAgeFieldNumber = 11,
+    kRecordProcessRuntimeFieldNumber = 12,
+  };
+
+  ProcessStatsConfig();
+  ~ProcessStatsConfig() override;
+  ProcessStatsConfig(ProcessStatsConfig&&) noexcept;
+  ProcessStatsConfig& operator=(ProcessStatsConfig&&);
+  ProcessStatsConfig(const ProcessStatsConfig&);
+  ProcessStatsConfig& operator=(const ProcessStatsConfig&);
+  bool operator==(const ProcessStatsConfig&) const;
+  bool operator!=(const ProcessStatsConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<ProcessStatsConfig_Quirks>& quirks() const { return quirks_; }
+  std::vector<ProcessStatsConfig_Quirks>* mutable_quirks() { return &quirks_; }
+  int quirks_size() const { return static_cast<int>(quirks_.size()); }
+  void clear_quirks() { quirks_.clear(); }
+  void add_quirks(ProcessStatsConfig_Quirks value) { quirks_.emplace_back(value); }
+  ProcessStatsConfig_Quirks* add_quirks() { quirks_.emplace_back(); return &quirks_.back(); }
+
+  bool has_scan_all_processes_on_start() const { return _has_field_[2]; }
+  bool scan_all_processes_on_start() const { return scan_all_processes_on_start_; }
+  void set_scan_all_processes_on_start(bool value) { scan_all_processes_on_start_ = value; _has_field_.set(2); }
+
+  bool has_record_thread_names() const { return _has_field_[3]; }
+  bool record_thread_names() const { return record_thread_names_; }
+  void set_record_thread_names(bool value) { record_thread_names_ = value; _has_field_.set(3); }
+
+  bool has_proc_stats_poll_ms() const { return _has_field_[4]; }
+  uint32_t proc_stats_poll_ms() const { return proc_stats_poll_ms_; }
+  void set_proc_stats_poll_ms(uint32_t value) { proc_stats_poll_ms_ = value; _has_field_.set(4); }
+
+  bool has_proc_stats_cache_ttl_ms() const { return _has_field_[6]; }
+  uint32_t proc_stats_cache_ttl_ms() const { return proc_stats_cache_ttl_ms_; }
+  void set_proc_stats_cache_ttl_ms(uint32_t value) { proc_stats_cache_ttl_ms_ = value; _has_field_.set(6); }
+
+  bool has_resolve_process_fds() const { return _has_field_[9]; }
+  bool resolve_process_fds() const { return resolve_process_fds_; }
+  void set_resolve_process_fds(bool value) { resolve_process_fds_ = value; _has_field_.set(9); }
+
+  bool has_scan_smaps_rollup() const { return _has_field_[10]; }
+  bool scan_smaps_rollup() const { return scan_smaps_rollup_; }
+  void set_scan_smaps_rollup(bool value) { scan_smaps_rollup_ = value; _has_field_.set(10); }
+
+  bool has_record_process_age() const { return _has_field_[11]; }
+  bool record_process_age() const { return record_process_age_; }
+  void set_record_process_age(bool value) { record_process_age_ = value; _has_field_.set(11); }
+
+  bool has_record_process_runtime() const { return _has_field_[12]; }
+  bool record_process_runtime() const { return record_process_runtime_; }
+  void set_record_process_runtime(bool value) { record_process_runtime_ = value; _has_field_.set(12); }
+
+ private:
+  std::vector<ProcessStatsConfig_Quirks> quirks_;
+  bool scan_all_processes_on_start_{};
+  bool record_thread_names_{};
+  uint32_t proc_stats_poll_ms_{};
+  uint32_t proc_stats_cache_ttl_ms_{};
+  bool resolve_process_fds_{};
+  bool scan_smaps_rollup_{};
+  bool record_process_age_{};
+  bool record_process_runtime_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<13> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROCESS_STATS_PROCESS_STATS_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/profiling/heapprofd_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_HEAPPROFD_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_HEAPPROFD_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class HeapprofdConfig;
+class HeapprofdConfig_ContinuousDumpConfig;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT HeapprofdConfig : public ::protozero::CppMessageObj {
+ public:
+  using ContinuousDumpConfig = HeapprofdConfig_ContinuousDumpConfig;
+  enum FieldNumbers {
+    kSamplingIntervalBytesFieldNumber = 1,
+    kAdaptiveSamplingShmemThresholdFieldNumber = 24,
+    kAdaptiveSamplingMaxSamplingIntervalBytesFieldNumber = 25,
+    kProcessCmdlineFieldNumber = 2,
+    kPidFieldNumber = 4,
+    kTargetInstalledByFieldNumber = 26,
+    kHeapsFieldNumber = 20,
+    kExcludeHeapsFieldNumber = 27,
+    kStreamAllocationsFieldNumber = 23,
+    kHeapSamplingIntervalsFieldNumber = 22,
+    kAllHeapsFieldNumber = 21,
+    kAllFieldNumber = 5,
+    kMinAnonymousMemoryKbFieldNumber = 15,
+    kMaxHeapprofdMemoryKbFieldNumber = 16,
+    kMaxHeapprofdCpuSecsFieldNumber = 17,
+    kSkipSymbolPrefixFieldNumber = 7,
+    kContinuousDumpConfigFieldNumber = 6,
+    kShmemSizeBytesFieldNumber = 8,
+    kBlockClientFieldNumber = 9,
+    kBlockClientTimeoutUsFieldNumber = 14,
+    kNoStartupFieldNumber = 10,
+    kNoRunningFieldNumber = 11,
+    kDumpAtMaxFieldNumber = 13,
+    kDisableForkTeardownFieldNumber = 18,
+    kDisableVforkDetectionFieldNumber = 19,
+  };
+
+  HeapprofdConfig();
+  ~HeapprofdConfig() override;
+  HeapprofdConfig(HeapprofdConfig&&) noexcept;
+  HeapprofdConfig& operator=(HeapprofdConfig&&);
+  HeapprofdConfig(const HeapprofdConfig&);
+  HeapprofdConfig& operator=(const HeapprofdConfig&);
+  bool operator==(const HeapprofdConfig&) const;
+  bool operator!=(const HeapprofdConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_sampling_interval_bytes() const { return _has_field_[1]; }
+  uint64_t sampling_interval_bytes() const { return sampling_interval_bytes_; }
+  void set_sampling_interval_bytes(uint64_t value) { sampling_interval_bytes_ = value; _has_field_.set(1); }
+
+  bool has_adaptive_sampling_shmem_threshold() const { return _has_field_[24]; }
+  uint64_t adaptive_sampling_shmem_threshold() const { return adaptive_sampling_shmem_threshold_; }
+  void set_adaptive_sampling_shmem_threshold(uint64_t value) { adaptive_sampling_shmem_threshold_ = value; _has_field_.set(24); }
+
+  bool has_adaptive_sampling_max_sampling_interval_bytes() const { return _has_field_[25]; }
+  uint64_t adaptive_sampling_max_sampling_interval_bytes() const { return adaptive_sampling_max_sampling_interval_bytes_; }
+  void set_adaptive_sampling_max_sampling_interval_bytes(uint64_t value) { adaptive_sampling_max_sampling_interval_bytes_ = value; _has_field_.set(25); }
+
+  const std::vector<std::string>& process_cmdline() const { return process_cmdline_; }
+  std::vector<std::string>* mutable_process_cmdline() { return &process_cmdline_; }
+  int process_cmdline_size() const { return static_cast<int>(process_cmdline_.size()); }
+  void clear_process_cmdline() { process_cmdline_.clear(); }
+  void add_process_cmdline(std::string value) { process_cmdline_.emplace_back(value); }
+  std::string* add_process_cmdline() { process_cmdline_.emplace_back(); return &process_cmdline_.back(); }
+
+  const std::vector<uint64_t>& pid() const { return pid_; }
+  std::vector<uint64_t>* mutable_pid() { return &pid_; }
+  int pid_size() const { return static_cast<int>(pid_.size()); }
+  void clear_pid() { pid_.clear(); }
+  void add_pid(uint64_t value) { pid_.emplace_back(value); }
+  uint64_t* add_pid() { pid_.emplace_back(); return &pid_.back(); }
+
+  const std::vector<std::string>& target_installed_by() const { return target_installed_by_; }
+  std::vector<std::string>* mutable_target_installed_by() { return &target_installed_by_; }
+  int target_installed_by_size() const { return static_cast<int>(target_installed_by_.size()); }
+  void clear_target_installed_by() { target_installed_by_.clear(); }
+  void add_target_installed_by(std::string value) { target_installed_by_.emplace_back(value); }
+  std::string* add_target_installed_by() { target_installed_by_.emplace_back(); return &target_installed_by_.back(); }
+
+  const std::vector<std::string>& heaps() const { return heaps_; }
+  std::vector<std::string>* mutable_heaps() { return &heaps_; }
+  int heaps_size() const { return static_cast<int>(heaps_.size()); }
+  void clear_heaps() { heaps_.clear(); }
+  void add_heaps(std::string value) { heaps_.emplace_back(value); }
+  std::string* add_heaps() { heaps_.emplace_back(); return &heaps_.back(); }
+
+  const std::vector<std::string>& exclude_heaps() const { return exclude_heaps_; }
+  std::vector<std::string>* mutable_exclude_heaps() { return &exclude_heaps_; }
+  int exclude_heaps_size() const { return static_cast<int>(exclude_heaps_.size()); }
+  void clear_exclude_heaps() { exclude_heaps_.clear(); }
+  void add_exclude_heaps(std::string value) { exclude_heaps_.emplace_back(value); }
+  std::string* add_exclude_heaps() { exclude_heaps_.emplace_back(); return &exclude_heaps_.back(); }
+
+  bool has_stream_allocations() const { return _has_field_[23]; }
+  bool stream_allocations() const { return stream_allocations_; }
+  void set_stream_allocations(bool value) { stream_allocations_ = value; _has_field_.set(23); }
+
+  const std::vector<uint64_t>& heap_sampling_intervals() const { return heap_sampling_intervals_; }
+  std::vector<uint64_t>* mutable_heap_sampling_intervals() { return &heap_sampling_intervals_; }
+  int heap_sampling_intervals_size() const { return static_cast<int>(heap_sampling_intervals_.size()); }
+  void clear_heap_sampling_intervals() { heap_sampling_intervals_.clear(); }
+  void add_heap_sampling_intervals(uint64_t value) { heap_sampling_intervals_.emplace_back(value); }
+  uint64_t* add_heap_sampling_intervals() { heap_sampling_intervals_.emplace_back(); return &heap_sampling_intervals_.back(); }
+
+  bool has_all_heaps() const { return _has_field_[21]; }
+  bool all_heaps() const { return all_heaps_; }
+  void set_all_heaps(bool value) { all_heaps_ = value; _has_field_.set(21); }
+
+  bool has_all() const { return _has_field_[5]; }
+  bool all() const { return all_; }
+  void set_all(bool value) { all_ = value; _has_field_.set(5); }
+
+  bool has_min_anonymous_memory_kb() const { return _has_field_[15]; }
+  uint32_t min_anonymous_memory_kb() const { return min_anonymous_memory_kb_; }
+  void set_min_anonymous_memory_kb(uint32_t value) { min_anonymous_memory_kb_ = value; _has_field_.set(15); }
+
+  bool has_max_heapprofd_memory_kb() const { return _has_field_[16]; }
+  uint32_t max_heapprofd_memory_kb() const { return max_heapprofd_memory_kb_; }
+  void set_max_heapprofd_memory_kb(uint32_t value) { max_heapprofd_memory_kb_ = value; _has_field_.set(16); }
+
+  bool has_max_heapprofd_cpu_secs() const { return _has_field_[17]; }
+  uint64_t max_heapprofd_cpu_secs() const { return max_heapprofd_cpu_secs_; }
+  void set_max_heapprofd_cpu_secs(uint64_t value) { max_heapprofd_cpu_secs_ = value; _has_field_.set(17); }
+
+  const std::vector<std::string>& skip_symbol_prefix() const { return skip_symbol_prefix_; }
+  std::vector<std::string>* mutable_skip_symbol_prefix() { return &skip_symbol_prefix_; }
+  int skip_symbol_prefix_size() const { return static_cast<int>(skip_symbol_prefix_.size()); }
+  void clear_skip_symbol_prefix() { skip_symbol_prefix_.clear(); }
+  void add_skip_symbol_prefix(std::string value) { skip_symbol_prefix_.emplace_back(value); }
+  std::string* add_skip_symbol_prefix() { skip_symbol_prefix_.emplace_back(); return &skip_symbol_prefix_.back(); }
+
+  bool has_continuous_dump_config() const { return _has_field_[6]; }
+  const HeapprofdConfig_ContinuousDumpConfig& continuous_dump_config() const { return *continuous_dump_config_; }
+  HeapprofdConfig_ContinuousDumpConfig* mutable_continuous_dump_config() { _has_field_.set(6); return continuous_dump_config_.get(); }
+
+  bool has_shmem_size_bytes() const { return _has_field_[8]; }
+  uint64_t shmem_size_bytes() const { return shmem_size_bytes_; }
+  void set_shmem_size_bytes(uint64_t value) { shmem_size_bytes_ = value; _has_field_.set(8); }
+
+  bool has_block_client() const { return _has_field_[9]; }
+  bool block_client() const { return block_client_; }
+  void set_block_client(bool value) { block_client_ = value; _has_field_.set(9); }
+
+  bool has_block_client_timeout_us() const { return _has_field_[14]; }
+  uint32_t block_client_timeout_us() const { return block_client_timeout_us_; }
+  void set_block_client_timeout_us(uint32_t value) { block_client_timeout_us_ = value; _has_field_.set(14); }
+
+  bool has_no_startup() const { return _has_field_[10]; }
+  bool no_startup() const { return no_startup_; }
+  void set_no_startup(bool value) { no_startup_ = value; _has_field_.set(10); }
+
+  bool has_no_running() const { return _has_field_[11]; }
+  bool no_running() const { return no_running_; }
+  void set_no_running(bool value) { no_running_ = value; _has_field_.set(11); }
+
+  bool has_dump_at_max() const { return _has_field_[13]; }
+  bool dump_at_max() const { return dump_at_max_; }
+  void set_dump_at_max(bool value) { dump_at_max_ = value; _has_field_.set(13); }
+
+  bool has_disable_fork_teardown() const { return _has_field_[18]; }
+  bool disable_fork_teardown() const { return disable_fork_teardown_; }
+  void set_disable_fork_teardown(bool value) { disable_fork_teardown_ = value; _has_field_.set(18); }
+
+  bool has_disable_vfork_detection() const { return _has_field_[19]; }
+  bool disable_vfork_detection() const { return disable_vfork_detection_; }
+  void set_disable_vfork_detection(bool value) { disable_vfork_detection_ = value; _has_field_.set(19); }
+
+ private:
+  uint64_t sampling_interval_bytes_{};
+  uint64_t adaptive_sampling_shmem_threshold_{};
+  uint64_t adaptive_sampling_max_sampling_interval_bytes_{};
+  std::vector<std::string> process_cmdline_;
+  std::vector<uint64_t> pid_;
+  std::vector<std::string> target_installed_by_;
+  std::vector<std::string> heaps_;
+  std::vector<std::string> exclude_heaps_;
+  bool stream_allocations_{};
+  std::vector<uint64_t> heap_sampling_intervals_;
+  bool all_heaps_{};
+  bool all_{};
+  uint32_t min_anonymous_memory_kb_{};
+  uint32_t max_heapprofd_memory_kb_{};
+  uint64_t max_heapprofd_cpu_secs_{};
+  std::vector<std::string> skip_symbol_prefix_;
+  ::protozero::CopyablePtr<HeapprofdConfig_ContinuousDumpConfig> continuous_dump_config_;
+  uint64_t shmem_size_bytes_{};
+  bool block_client_{};
+  uint32_t block_client_timeout_us_{};
+  bool no_startup_{};
+  bool no_running_{};
+  bool dump_at_max_{};
+  bool disable_fork_teardown_{};
+  bool disable_vfork_detection_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<28> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT HeapprofdConfig_ContinuousDumpConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDumpPhaseMsFieldNumber = 5,
+    kDumpIntervalMsFieldNumber = 6,
+  };
+
+  HeapprofdConfig_ContinuousDumpConfig();
+  ~HeapprofdConfig_ContinuousDumpConfig() override;
+  HeapprofdConfig_ContinuousDumpConfig(HeapprofdConfig_ContinuousDumpConfig&&) noexcept;
+  HeapprofdConfig_ContinuousDumpConfig& operator=(HeapprofdConfig_ContinuousDumpConfig&&);
+  HeapprofdConfig_ContinuousDumpConfig(const HeapprofdConfig_ContinuousDumpConfig&);
+  HeapprofdConfig_ContinuousDumpConfig& operator=(const HeapprofdConfig_ContinuousDumpConfig&);
+  bool operator==(const HeapprofdConfig_ContinuousDumpConfig&) const;
+  bool operator!=(const HeapprofdConfig_ContinuousDumpConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_dump_phase_ms() const { return _has_field_[5]; }
+  uint32_t dump_phase_ms() const { return dump_phase_ms_; }
+  void set_dump_phase_ms(uint32_t value) { dump_phase_ms_ = value; _has_field_.set(5); }
+
+  bool has_dump_interval_ms() const { return _has_field_[6]; }
+  uint32_t dump_interval_ms() const { return dump_interval_ms_; }
+  void set_dump_interval_ms(uint32_t value) { dump_interval_ms_ = value; _has_field_.set(6); }
+
+ private:
+  uint32_t dump_phase_ms_{};
+  uint32_t dump_interval_ms_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<7> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_HEAPPROFD_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/profiling/java_hprof_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_JAVA_HPROF_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_JAVA_HPROF_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class JavaHprofConfig;
+class JavaHprofConfig_ContinuousDumpConfig;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT JavaHprofConfig : public ::protozero::CppMessageObj {
+ public:
+  using ContinuousDumpConfig = JavaHprofConfig_ContinuousDumpConfig;
+  enum FieldNumbers {
+    kProcessCmdlineFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kTargetInstalledByFieldNumber = 7,
+    kContinuousDumpConfigFieldNumber = 3,
+    kMinAnonymousMemoryKbFieldNumber = 4,
+    kDumpSmapsFieldNumber = 5,
+    kIgnoredTypesFieldNumber = 6,
+  };
+
+  JavaHprofConfig();
+  ~JavaHprofConfig() override;
+  JavaHprofConfig(JavaHprofConfig&&) noexcept;
+  JavaHprofConfig& operator=(JavaHprofConfig&&);
+  JavaHprofConfig(const JavaHprofConfig&);
+  JavaHprofConfig& operator=(const JavaHprofConfig&);
+  bool operator==(const JavaHprofConfig&) const;
+  bool operator!=(const JavaHprofConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<std::string>& process_cmdline() const { return process_cmdline_; }
+  std::vector<std::string>* mutable_process_cmdline() { return &process_cmdline_; }
+  int process_cmdline_size() const { return static_cast<int>(process_cmdline_.size()); }
+  void clear_process_cmdline() { process_cmdline_.clear(); }
+  void add_process_cmdline(std::string value) { process_cmdline_.emplace_back(value); }
+  std::string* add_process_cmdline() { process_cmdline_.emplace_back(); return &process_cmdline_.back(); }
+
+  const std::vector<uint64_t>& pid() const { return pid_; }
+  std::vector<uint64_t>* mutable_pid() { return &pid_; }
+  int pid_size() const { return static_cast<int>(pid_.size()); }
+  void clear_pid() { pid_.clear(); }
+  void add_pid(uint64_t value) { pid_.emplace_back(value); }
+  uint64_t* add_pid() { pid_.emplace_back(); return &pid_.back(); }
+
+  const std::vector<std::string>& target_installed_by() const { return target_installed_by_; }
+  std::vector<std::string>* mutable_target_installed_by() { return &target_installed_by_; }
+  int target_installed_by_size() const { return static_cast<int>(target_installed_by_.size()); }
+  void clear_target_installed_by() { target_installed_by_.clear(); }
+  void add_target_installed_by(std::string value) { target_installed_by_.emplace_back(value); }
+  std::string* add_target_installed_by() { target_installed_by_.emplace_back(); return &target_installed_by_.back(); }
+
+  bool has_continuous_dump_config() const { return _has_field_[3]; }
+  const JavaHprofConfig_ContinuousDumpConfig& continuous_dump_config() const { return *continuous_dump_config_; }
+  JavaHprofConfig_ContinuousDumpConfig* mutable_continuous_dump_config() { _has_field_.set(3); return continuous_dump_config_.get(); }
+
+  bool has_min_anonymous_memory_kb() const { return _has_field_[4]; }
+  uint32_t min_anonymous_memory_kb() const { return min_anonymous_memory_kb_; }
+  void set_min_anonymous_memory_kb(uint32_t value) { min_anonymous_memory_kb_ = value; _has_field_.set(4); }
+
+  bool has_dump_smaps() const { return _has_field_[5]; }
+  bool dump_smaps() const { return dump_smaps_; }
+  void set_dump_smaps(bool value) { dump_smaps_ = value; _has_field_.set(5); }
+
+  const std::vector<std::string>& ignored_types() const { return ignored_types_; }
+  std::vector<std::string>* mutable_ignored_types() { return &ignored_types_; }
+  int ignored_types_size() const { return static_cast<int>(ignored_types_.size()); }
+  void clear_ignored_types() { ignored_types_.clear(); }
+  void add_ignored_types(std::string value) { ignored_types_.emplace_back(value); }
+  std::string* add_ignored_types() { ignored_types_.emplace_back(); return &ignored_types_.back(); }
+
+ private:
+  std::vector<std::string> process_cmdline_;
+  std::vector<uint64_t> pid_;
+  std::vector<std::string> target_installed_by_;
+  ::protozero::CopyablePtr<JavaHprofConfig_ContinuousDumpConfig> continuous_dump_config_;
+  uint32_t min_anonymous_memory_kb_{};
+  bool dump_smaps_{};
+  std::vector<std::string> ignored_types_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<8> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT JavaHprofConfig_ContinuousDumpConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDumpPhaseMsFieldNumber = 1,
+    kDumpIntervalMsFieldNumber = 2,
+    kScanPidsOnlyOnStartFieldNumber = 3,
+  };
+
+  JavaHprofConfig_ContinuousDumpConfig();
+  ~JavaHprofConfig_ContinuousDumpConfig() override;
+  JavaHprofConfig_ContinuousDumpConfig(JavaHprofConfig_ContinuousDumpConfig&&) noexcept;
+  JavaHprofConfig_ContinuousDumpConfig& operator=(JavaHprofConfig_ContinuousDumpConfig&&);
+  JavaHprofConfig_ContinuousDumpConfig(const JavaHprofConfig_ContinuousDumpConfig&);
+  JavaHprofConfig_ContinuousDumpConfig& operator=(const JavaHprofConfig_ContinuousDumpConfig&);
+  bool operator==(const JavaHprofConfig_ContinuousDumpConfig&) const;
+  bool operator!=(const JavaHprofConfig_ContinuousDumpConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_dump_phase_ms() const { return _has_field_[1]; }
+  uint32_t dump_phase_ms() const { return dump_phase_ms_; }
+  void set_dump_phase_ms(uint32_t value) { dump_phase_ms_ = value; _has_field_.set(1); }
+
+  bool has_dump_interval_ms() const { return _has_field_[2]; }
+  uint32_t dump_interval_ms() const { return dump_interval_ms_; }
+  void set_dump_interval_ms(uint32_t value) { dump_interval_ms_ = value; _has_field_.set(2); }
+
+  bool has_scan_pids_only_on_start() const { return _has_field_[3]; }
+  bool scan_pids_only_on_start() const { return scan_pids_only_on_start_; }
+  void set_scan_pids_only_on_start(bool value) { scan_pids_only_on_start_ = value; _has_field_.set(3); }
+
+ private:
+  uint32_t dump_phase_ms_{};
+  uint32_t dump_interval_ms_{};
+  bool scan_pids_only_on_start_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_JAVA_HPROF_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/profiling/perf_event_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_PERF_EVENT_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_PERF_EVENT_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class PerfEventConfig;
+class PerfEventConfig_CallstackSampling;
+class PerfEventConfig_Scope;
+class PerfEvents_Timebase;
+class PerfEvents_RawEvent;
+class PerfEvents_Tracepoint;
+enum PerfEventConfig_UnwindMode : int;
+enum PerfEvents_Counter : int;
+enum PerfEvents_PerfClock : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum PerfEventConfig_UnwindMode : int {
+  PerfEventConfig_UnwindMode_UNWIND_UNKNOWN = 0,
+  PerfEventConfig_UnwindMode_UNWIND_SKIP = 1,
+  PerfEventConfig_UnwindMode_UNWIND_DWARF = 2,
+};
+
+class PERFETTO_EXPORT_COMPONENT PerfEventConfig : public ::protozero::CppMessageObj {
+ public:
+  using CallstackSampling = PerfEventConfig_CallstackSampling;
+  using Scope = PerfEventConfig_Scope;
+  using UnwindMode = PerfEventConfig_UnwindMode;
+  static constexpr auto UNWIND_UNKNOWN = PerfEventConfig_UnwindMode_UNWIND_UNKNOWN;
+  static constexpr auto UNWIND_SKIP = PerfEventConfig_UnwindMode_UNWIND_SKIP;
+  static constexpr auto UNWIND_DWARF = PerfEventConfig_UnwindMode_UNWIND_DWARF;
+  static constexpr auto UnwindMode_MIN = PerfEventConfig_UnwindMode_UNWIND_UNKNOWN;
+  static constexpr auto UnwindMode_MAX = PerfEventConfig_UnwindMode_UNWIND_DWARF;
+  enum FieldNumbers {
+    kTimebaseFieldNumber = 15,
+    kCallstackSamplingFieldNumber = 16,
+    kRingBufferReadPeriodMsFieldNumber = 8,
+    kRingBufferPagesFieldNumber = 3,
+    kMaxEnqueuedFootprintKbFieldNumber = 17,
+    kMaxDaemonMemoryKbFieldNumber = 13,
+    kRemoteDescriptorTimeoutMsFieldNumber = 9,
+    kUnwindStateClearPeriodMsFieldNumber = 10,
+    kTargetInstalledByFieldNumber = 18,
+    kAllCpusFieldNumber = 1,
+    kSamplingFrequencyFieldNumber = 2,
+    kKernelFramesFieldNumber = 12,
+    kTargetPidFieldNumber = 4,
+    kTargetCmdlineFieldNumber = 5,
+    kExcludePidFieldNumber = 6,
+    kExcludeCmdlineFieldNumber = 7,
+    kAdditionalCmdlineCountFieldNumber = 11,
+  };
+
+  PerfEventConfig();
+  ~PerfEventConfig() override;
+  PerfEventConfig(PerfEventConfig&&) noexcept;
+  PerfEventConfig& operator=(PerfEventConfig&&);
+  PerfEventConfig(const PerfEventConfig&);
+  PerfEventConfig& operator=(const PerfEventConfig&);
+  bool operator==(const PerfEventConfig&) const;
+  bool operator!=(const PerfEventConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_timebase() const { return _has_field_[15]; }
+  const PerfEvents_Timebase& timebase() const { return *timebase_; }
+  PerfEvents_Timebase* mutable_timebase() { _has_field_.set(15); return timebase_.get(); }
+
+  bool has_callstack_sampling() const { return _has_field_[16]; }
+  const PerfEventConfig_CallstackSampling& callstack_sampling() const { return *callstack_sampling_; }
+  PerfEventConfig_CallstackSampling* mutable_callstack_sampling() { _has_field_.set(16); return callstack_sampling_.get(); }
+
+  bool has_ring_buffer_read_period_ms() const { return _has_field_[8]; }
+  uint32_t ring_buffer_read_period_ms() const { return ring_buffer_read_period_ms_; }
+  void set_ring_buffer_read_period_ms(uint32_t value) { ring_buffer_read_period_ms_ = value; _has_field_.set(8); }
+
+  bool has_ring_buffer_pages() const { return _has_field_[3]; }
+  uint32_t ring_buffer_pages() const { return ring_buffer_pages_; }
+  void set_ring_buffer_pages(uint32_t value) { ring_buffer_pages_ = value; _has_field_.set(3); }
+
+  bool has_max_enqueued_footprint_kb() const { return _has_field_[17]; }
+  uint64_t max_enqueued_footprint_kb() const { return max_enqueued_footprint_kb_; }
+  void set_max_enqueued_footprint_kb(uint64_t value) { max_enqueued_footprint_kb_ = value; _has_field_.set(17); }
+
+  bool has_max_daemon_memory_kb() const { return _has_field_[13]; }
+  uint32_t max_daemon_memory_kb() const { return max_daemon_memory_kb_; }
+  void set_max_daemon_memory_kb(uint32_t value) { max_daemon_memory_kb_ = value; _has_field_.set(13); }
+
+  bool has_remote_descriptor_timeout_ms() const { return _has_field_[9]; }
+  uint32_t remote_descriptor_timeout_ms() const { return remote_descriptor_timeout_ms_; }
+  void set_remote_descriptor_timeout_ms(uint32_t value) { remote_descriptor_timeout_ms_ = value; _has_field_.set(9); }
+
+  bool has_unwind_state_clear_period_ms() const { return _has_field_[10]; }
+  uint32_t unwind_state_clear_period_ms() const { return unwind_state_clear_period_ms_; }
+  void set_unwind_state_clear_period_ms(uint32_t value) { unwind_state_clear_period_ms_ = value; _has_field_.set(10); }
+
+  const std::vector<std::string>& target_installed_by() const { return target_installed_by_; }
+  std::vector<std::string>* mutable_target_installed_by() { return &target_installed_by_; }
+  int target_installed_by_size() const { return static_cast<int>(target_installed_by_.size()); }
+  void clear_target_installed_by() { target_installed_by_.clear(); }
+  void add_target_installed_by(std::string value) { target_installed_by_.emplace_back(value); }
+  std::string* add_target_installed_by() { target_installed_by_.emplace_back(); return &target_installed_by_.back(); }
+
+  bool has_all_cpus() const { return _has_field_[1]; }
+  bool all_cpus() const { return all_cpus_; }
+  void set_all_cpus(bool value) { all_cpus_ = value; _has_field_.set(1); }
+
+  bool has_sampling_frequency() const { return _has_field_[2]; }
+  uint32_t sampling_frequency() const { return sampling_frequency_; }
+  void set_sampling_frequency(uint32_t value) { sampling_frequency_ = value; _has_field_.set(2); }
+
+  bool has_kernel_frames() const { return _has_field_[12]; }
+  bool kernel_frames() const { return kernel_frames_; }
+  void set_kernel_frames(bool value) { kernel_frames_ = value; _has_field_.set(12); }
+
+  const std::vector<int32_t>& target_pid() const { return target_pid_; }
+  std::vector<int32_t>* mutable_target_pid() { return &target_pid_; }
+  int target_pid_size() const { return static_cast<int>(target_pid_.size()); }
+  void clear_target_pid() { target_pid_.clear(); }
+  void add_target_pid(int32_t value) { target_pid_.emplace_back(value); }
+  int32_t* add_target_pid() { target_pid_.emplace_back(); return &target_pid_.back(); }
+
+  const std::vector<std::string>& target_cmdline() const { return target_cmdline_; }
+  std::vector<std::string>* mutable_target_cmdline() { return &target_cmdline_; }
+  int target_cmdline_size() const { return static_cast<int>(target_cmdline_.size()); }
+  void clear_target_cmdline() { target_cmdline_.clear(); }
+  void add_target_cmdline(std::string value) { target_cmdline_.emplace_back(value); }
+  std::string* add_target_cmdline() { target_cmdline_.emplace_back(); return &target_cmdline_.back(); }
+
+  const std::vector<int32_t>& exclude_pid() const { return exclude_pid_; }
+  std::vector<int32_t>* mutable_exclude_pid() { return &exclude_pid_; }
+  int exclude_pid_size() const { return static_cast<int>(exclude_pid_.size()); }
+  void clear_exclude_pid() { exclude_pid_.clear(); }
+  void add_exclude_pid(int32_t value) { exclude_pid_.emplace_back(value); }
+  int32_t* add_exclude_pid() { exclude_pid_.emplace_back(); return &exclude_pid_.back(); }
+
+  const std::vector<std::string>& exclude_cmdline() const { return exclude_cmdline_; }
+  std::vector<std::string>* mutable_exclude_cmdline() { return &exclude_cmdline_; }
+  int exclude_cmdline_size() const { return static_cast<int>(exclude_cmdline_.size()); }
+  void clear_exclude_cmdline() { exclude_cmdline_.clear(); }
+  void add_exclude_cmdline(std::string value) { exclude_cmdline_.emplace_back(value); }
+  std::string* add_exclude_cmdline() { exclude_cmdline_.emplace_back(); return &exclude_cmdline_.back(); }
+
+  bool has_additional_cmdline_count() const { return _has_field_[11]; }
+  uint32_t additional_cmdline_count() const { return additional_cmdline_count_; }
+  void set_additional_cmdline_count(uint32_t value) { additional_cmdline_count_ = value; _has_field_.set(11); }
+
+ private:
+  ::protozero::CopyablePtr<PerfEvents_Timebase> timebase_;
+  ::protozero::CopyablePtr<PerfEventConfig_CallstackSampling> callstack_sampling_;
+  uint32_t ring_buffer_read_period_ms_{};
+  uint32_t ring_buffer_pages_{};
+  uint64_t max_enqueued_footprint_kb_{};
+  uint32_t max_daemon_memory_kb_{};
+  uint32_t remote_descriptor_timeout_ms_{};
+  uint32_t unwind_state_clear_period_ms_{};
+  std::vector<std::string> target_installed_by_;
+  bool all_cpus_{};
+  uint32_t sampling_frequency_{};
+  bool kernel_frames_{};
+  std::vector<int32_t> target_pid_;
+  std::vector<std::string> target_cmdline_;
+  std::vector<int32_t> exclude_pid_;
+  std::vector<std::string> exclude_cmdline_;
+  uint32_t additional_cmdline_count_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<19> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT PerfEventConfig_CallstackSampling : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kScopeFieldNumber = 1,
+    kKernelFramesFieldNumber = 2,
+    kUserFramesFieldNumber = 3,
+  };
+
+  PerfEventConfig_CallstackSampling();
+  ~PerfEventConfig_CallstackSampling() override;
+  PerfEventConfig_CallstackSampling(PerfEventConfig_CallstackSampling&&) noexcept;
+  PerfEventConfig_CallstackSampling& operator=(PerfEventConfig_CallstackSampling&&);
+  PerfEventConfig_CallstackSampling(const PerfEventConfig_CallstackSampling&);
+  PerfEventConfig_CallstackSampling& operator=(const PerfEventConfig_CallstackSampling&);
+  bool operator==(const PerfEventConfig_CallstackSampling&) const;
+  bool operator!=(const PerfEventConfig_CallstackSampling& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_scope() const { return _has_field_[1]; }
+  const PerfEventConfig_Scope& scope() const { return *scope_; }
+  PerfEventConfig_Scope* mutable_scope() { _has_field_.set(1); return scope_.get(); }
+
+  bool has_kernel_frames() const { return _has_field_[2]; }
+  bool kernel_frames() const { return kernel_frames_; }
+  void set_kernel_frames(bool value) { kernel_frames_ = value; _has_field_.set(2); }
+
+  bool has_user_frames() const { return _has_field_[3]; }
+  PerfEventConfig_UnwindMode user_frames() const { return user_frames_; }
+  void set_user_frames(PerfEventConfig_UnwindMode value) { user_frames_ = value; _has_field_.set(3); }
+
+ private:
+  ::protozero::CopyablePtr<PerfEventConfig_Scope> scope_;
+  bool kernel_frames_{};
+  PerfEventConfig_UnwindMode user_frames_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT PerfEventConfig_Scope : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kTargetPidFieldNumber = 1,
+    kTargetCmdlineFieldNumber = 2,
+    kExcludePidFieldNumber = 3,
+    kExcludeCmdlineFieldNumber = 4,
+    kAdditionalCmdlineCountFieldNumber = 5,
+    kProcessShardCountFieldNumber = 6,
+  };
+
+  PerfEventConfig_Scope();
+  ~PerfEventConfig_Scope() override;
+  PerfEventConfig_Scope(PerfEventConfig_Scope&&) noexcept;
+  PerfEventConfig_Scope& operator=(PerfEventConfig_Scope&&);
+  PerfEventConfig_Scope(const PerfEventConfig_Scope&);
+  PerfEventConfig_Scope& operator=(const PerfEventConfig_Scope&);
+  bool operator==(const PerfEventConfig_Scope&) const;
+  bool operator!=(const PerfEventConfig_Scope& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<int32_t>& target_pid() const { return target_pid_; }
+  std::vector<int32_t>* mutable_target_pid() { return &target_pid_; }
+  int target_pid_size() const { return static_cast<int>(target_pid_.size()); }
+  void clear_target_pid() { target_pid_.clear(); }
+  void add_target_pid(int32_t value) { target_pid_.emplace_back(value); }
+  int32_t* add_target_pid() { target_pid_.emplace_back(); return &target_pid_.back(); }
+
+  const std::vector<std::string>& target_cmdline() const { return target_cmdline_; }
+  std::vector<std::string>* mutable_target_cmdline() { return &target_cmdline_; }
+  int target_cmdline_size() const { return static_cast<int>(target_cmdline_.size()); }
+  void clear_target_cmdline() { target_cmdline_.clear(); }
+  void add_target_cmdline(std::string value) { target_cmdline_.emplace_back(value); }
+  std::string* add_target_cmdline() { target_cmdline_.emplace_back(); return &target_cmdline_.back(); }
+
+  const std::vector<int32_t>& exclude_pid() const { return exclude_pid_; }
+  std::vector<int32_t>* mutable_exclude_pid() { return &exclude_pid_; }
+  int exclude_pid_size() const { return static_cast<int>(exclude_pid_.size()); }
+  void clear_exclude_pid() { exclude_pid_.clear(); }
+  void add_exclude_pid(int32_t value) { exclude_pid_.emplace_back(value); }
+  int32_t* add_exclude_pid() { exclude_pid_.emplace_back(); return &exclude_pid_.back(); }
+
+  const std::vector<std::string>& exclude_cmdline() const { return exclude_cmdline_; }
+  std::vector<std::string>* mutable_exclude_cmdline() { return &exclude_cmdline_; }
+  int exclude_cmdline_size() const { return static_cast<int>(exclude_cmdline_.size()); }
+  void clear_exclude_cmdline() { exclude_cmdline_.clear(); }
+  void add_exclude_cmdline(std::string value) { exclude_cmdline_.emplace_back(value); }
+  std::string* add_exclude_cmdline() { exclude_cmdline_.emplace_back(); return &exclude_cmdline_.back(); }
+
+  bool has_additional_cmdline_count() const { return _has_field_[5]; }
+  uint32_t additional_cmdline_count() const { return additional_cmdline_count_; }
+  void set_additional_cmdline_count(uint32_t value) { additional_cmdline_count_ = value; _has_field_.set(5); }
+
+  bool has_process_shard_count() const { return _has_field_[6]; }
+  uint32_t process_shard_count() const { return process_shard_count_; }
+  void set_process_shard_count(uint32_t value) { process_shard_count_ = value; _has_field_.set(6); }
+
+ private:
+  std::vector<int32_t> target_pid_;
+  std::vector<std::string> target_cmdline_;
+  std::vector<int32_t> exclude_pid_;
+  std::vector<std::string> exclude_cmdline_;
+  uint32_t additional_cmdline_count_{};
+  uint32_t process_shard_count_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<7> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_PERF_EVENT_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/statsd/atom_ids.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STATSD_ATOM_IDS_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STATSD_ATOM_IDS_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum AtomId : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum AtomId : int {
+  ATOM_UNSPECIFIED = 0,
+  ATOM_BLE_SCAN_STATE_CHANGED = 2,
+  ATOM_PROCESS_STATE_CHANGED = 3,
+  ATOM_BLE_SCAN_RESULT_RECEIVED = 4,
+  ATOM_SENSOR_STATE_CHANGED = 5,
+  ATOM_GPS_SCAN_STATE_CHANGED = 6,
+  ATOM_SYNC_STATE_CHANGED = 7,
+  ATOM_SCHEDULED_JOB_STATE_CHANGED = 8,
+  ATOM_SCREEN_BRIGHTNESS_CHANGED = 9,
+  ATOM_WAKELOCK_STATE_CHANGED = 10,
+  ATOM_LONG_PARTIAL_WAKELOCK_STATE_CHANGED = 11,
+  ATOM_MOBILE_RADIO_POWER_STATE_CHANGED = 12,
+  ATOM_WIFI_RADIO_POWER_STATE_CHANGED = 13,
+  ATOM_ACTIVITY_MANAGER_SLEEP_STATE_CHANGED = 14,
+  ATOM_MEMORY_FACTOR_STATE_CHANGED = 15,
+  ATOM_EXCESSIVE_CPU_USAGE_REPORTED = 16,
+  ATOM_CACHED_KILL_REPORTED = 17,
+  ATOM_PROCESS_MEMORY_STAT_REPORTED = 18,
+  ATOM_LAUNCHER_EVENT = 19,
+  ATOM_BATTERY_SAVER_MODE_STATE_CHANGED = 20,
+  ATOM_DEVICE_IDLE_MODE_STATE_CHANGED = 21,
+  ATOM_DEVICE_IDLING_MODE_STATE_CHANGED = 22,
+  ATOM_AUDIO_STATE_CHANGED = 23,
+  ATOM_MEDIA_CODEC_STATE_CHANGED = 24,
+  ATOM_CAMERA_STATE_CHANGED = 25,
+  ATOM_FLASHLIGHT_STATE_CHANGED = 26,
+  ATOM_UID_PROCESS_STATE_CHANGED = 27,
+  ATOM_PROCESS_LIFE_CYCLE_STATE_CHANGED = 28,
+  ATOM_SCREEN_STATE_CHANGED = 29,
+  ATOM_BATTERY_LEVEL_CHANGED = 30,
+  ATOM_CHARGING_STATE_CHANGED = 31,
+  ATOM_PLUGGED_STATE_CHANGED = 32,
+  ATOM_INTERACTIVE_STATE_CHANGED = 33,
+  ATOM_TOUCH_EVENT_REPORTED = 34,
+  ATOM_WAKEUP_ALARM_OCCURRED = 35,
+  ATOM_KERNEL_WAKEUP_REPORTED = 36,
+  ATOM_WIFI_LOCK_STATE_CHANGED = 37,
+  ATOM_WIFI_SIGNAL_STRENGTH_CHANGED = 38,
+  ATOM_WIFI_SCAN_STATE_CHANGED = 39,
+  ATOM_PHONE_SIGNAL_STRENGTH_CHANGED = 40,
+  ATOM_SETTING_CHANGED = 41,
+  ATOM_ACTIVITY_FOREGROUND_STATE_CHANGED = 42,
+  ATOM_ISOLATED_UID_CHANGED = 43,
+  ATOM_PACKET_WAKEUP_OCCURRED = 44,
+  ATOM_WALL_CLOCK_TIME_SHIFTED = 45,
+  ATOM_ANOMALY_DETECTED = 46,
+  ATOM_APP_BREADCRUMB_REPORTED = 47,
+  ATOM_APP_START_OCCURRED = 48,
+  ATOM_APP_START_CANCELED = 49,
+  ATOM_APP_START_FULLY_DRAWN = 50,
+  ATOM_LMK_KILL_OCCURRED = 51,
+  ATOM_PICTURE_IN_PICTURE_STATE_CHANGED = 52,
+  ATOM_WIFI_MULTICAST_LOCK_STATE_CHANGED = 53,
+  ATOM_LMK_STATE_CHANGED = 54,
+  ATOM_APP_START_MEMORY_STATE_CAPTURED = 55,
+  ATOM_SHUTDOWN_SEQUENCE_REPORTED = 56,
+  ATOM_BOOT_SEQUENCE_REPORTED = 57,
+  ATOM_DAVEY_OCCURRED = 58,
+  ATOM_OVERLAY_STATE_CHANGED = 59,
+  ATOM_FOREGROUND_SERVICE_STATE_CHANGED = 60,
+  ATOM_CALL_STATE_CHANGED = 61,
+  ATOM_KEYGUARD_STATE_CHANGED = 62,
+  ATOM_KEYGUARD_BOUNCER_STATE_CHANGED = 63,
+  ATOM_KEYGUARD_BOUNCER_PASSWORD_ENTERED = 64,
+  ATOM_APP_DIED = 65,
+  ATOM_RESOURCE_CONFIGURATION_CHANGED = 66,
+  ATOM_BLUETOOTH_ENABLED_STATE_CHANGED = 67,
+  ATOM_BLUETOOTH_CONNECTION_STATE_CHANGED = 68,
+  ATOM_GPS_SIGNAL_QUALITY_CHANGED = 69,
+  ATOM_USB_CONNECTOR_STATE_CHANGED = 70,
+  ATOM_SPEAKER_IMPEDANCE_REPORTED = 71,
+  ATOM_HARDWARE_FAILED = 72,
+  ATOM_PHYSICAL_DROP_DETECTED = 73,
+  ATOM_CHARGE_CYCLES_REPORTED = 74,
+  ATOM_MOBILE_CONNECTION_STATE_CHANGED = 75,
+  ATOM_MOBILE_RADIO_TECHNOLOGY_CHANGED = 76,
+  ATOM_USB_DEVICE_ATTACHED = 77,
+  ATOM_APP_CRASH_OCCURRED = 78,
+  ATOM_ANR_OCCURRED = 79,
+  ATOM_WTF_OCCURRED = 80,
+  ATOM_LOW_MEM_REPORTED = 81,
+  ATOM_GENERIC_ATOM = 82,
+  ATOM_VIBRATOR_STATE_CHANGED = 84,
+  ATOM_DEFERRED_JOB_STATS_REPORTED = 85,
+  ATOM_THERMAL_THROTTLING = 86,
+  ATOM_BIOMETRIC_ACQUIRED = 87,
+  ATOM_BIOMETRIC_AUTHENTICATED = 88,
+  ATOM_BIOMETRIC_ERROR_OCCURRED = 89,
+  ATOM_UI_EVENT_REPORTED = 90,
+  ATOM_BATTERY_HEALTH_SNAPSHOT = 91,
+  ATOM_SLOW_IO = 92,
+  ATOM_BATTERY_CAUSED_SHUTDOWN = 93,
+  ATOM_PHONE_SERVICE_STATE_CHANGED = 94,
+  ATOM_PHONE_STATE_CHANGED = 95,
+  ATOM_USER_RESTRICTION_CHANGED = 96,
+  ATOM_SETTINGS_UI_CHANGED = 97,
+  ATOM_CONNECTIVITY_STATE_CHANGED = 98,
+  ATOM_SERVICE_STATE_CHANGED = 99,
+  ATOM_SERVICE_LAUNCH_REPORTED = 100,
+  ATOM_FLAG_FLIP_UPDATE_OCCURRED = 101,
+  ATOM_BINARY_PUSH_STATE_CHANGED = 102,
+  ATOM_DEVICE_POLICY_EVENT = 103,
+  ATOM_DOCS_UI_FILE_OP_CANCELED = 104,
+  ATOM_DOCS_UI_FILE_OP_COPY_MOVE_MODE_REPORTED = 105,
+  ATOM_DOCS_UI_FILE_OP_FAILURE = 106,
+  ATOM_DOCS_UI_PROVIDER_FILE_OP = 107,
+  ATOM_DOCS_UI_INVALID_SCOPED_ACCESS_REQUEST = 108,
+  ATOM_DOCS_UI_LAUNCH_REPORTED = 109,
+  ATOM_DOCS_UI_ROOT_VISITED = 110,
+  ATOM_DOCS_UI_STARTUP_MS = 111,
+  ATOM_DOCS_UI_USER_ACTION_REPORTED = 112,
+  ATOM_WIFI_ENABLED_STATE_CHANGED = 113,
+  ATOM_WIFI_RUNNING_STATE_CHANGED = 114,
+  ATOM_APP_COMPACTED = 115,
+  ATOM_NETWORK_DNS_EVENT_REPORTED = 116,
+  ATOM_DOCS_UI_PICKER_LAUNCHED_FROM_REPORTED = 117,
+  ATOM_DOCS_UI_PICK_RESULT_REPORTED = 118,
+  ATOM_DOCS_UI_SEARCH_MODE_REPORTED = 119,
+  ATOM_DOCS_UI_SEARCH_TYPE_REPORTED = 120,
+  ATOM_DATA_STALL_EVENT = 121,
+  ATOM_RESCUE_PARTY_RESET_REPORTED = 122,
+  ATOM_SIGNED_CONFIG_REPORTED = 123,
+  ATOM_GNSS_NI_EVENT_REPORTED = 124,
+  ATOM_BLUETOOTH_LINK_LAYER_CONNECTION_EVENT = 125,
+  ATOM_BLUETOOTH_ACL_CONNECTION_STATE_CHANGED = 126,
+  ATOM_BLUETOOTH_SCO_CONNECTION_STATE_CHANGED = 127,
+  ATOM_APP_DOWNGRADED = 128,
+  ATOM_APP_OPTIMIZED_AFTER_DOWNGRADED = 129,
+  ATOM_LOW_STORAGE_STATE_CHANGED = 130,
+  ATOM_GNSS_NFW_NOTIFICATION_REPORTED = 131,
+  ATOM_GNSS_CONFIGURATION_REPORTED = 132,
+  ATOM_USB_PORT_OVERHEAT_EVENT_REPORTED = 133,
+  ATOM_NFC_ERROR_OCCURRED = 134,
+  ATOM_NFC_STATE_CHANGED = 135,
+  ATOM_NFC_BEAM_OCCURRED = 136,
+  ATOM_NFC_CARDEMULATION_OCCURRED = 137,
+  ATOM_NFC_TAG_OCCURRED = 138,
+  ATOM_NFC_HCE_TRANSACTION_OCCURRED = 139,
+  ATOM_SE_STATE_CHANGED = 140,
+  ATOM_SE_OMAPI_REPORTED = 141,
+  ATOM_BROADCAST_DISPATCH_LATENCY_REPORTED = 142,
+  ATOM_ATTENTION_MANAGER_SERVICE_RESULT_REPORTED = 143,
+  ATOM_ADB_CONNECTION_CHANGED = 144,
+  ATOM_SPEECH_DSP_STAT_REPORTED = 145,
+  ATOM_USB_CONTAMINANT_REPORTED = 146,
+  ATOM_WATCHDOG_ROLLBACK_OCCURRED = 147,
+  ATOM_BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED = 148,
+  ATOM_BUBBLE_UI_CHANGED = 149,
+  ATOM_SCHEDULED_JOB_CONSTRAINT_CHANGED = 150,
+  ATOM_BLUETOOTH_ACTIVE_DEVICE_CHANGED = 151,
+  ATOM_BLUETOOTH_A2DP_PLAYBACK_STATE_CHANGED = 152,
+  ATOM_BLUETOOTH_A2DP_CODEC_CONFIG_CHANGED = 153,
+  ATOM_BLUETOOTH_A2DP_CODEC_CAPABILITY_CHANGED = 154,
+  ATOM_BLUETOOTH_A2DP_AUDIO_UNDERRUN_REPORTED = 155,
+  ATOM_BLUETOOTH_A2DP_AUDIO_OVERRUN_REPORTED = 156,
+  ATOM_BLUETOOTH_DEVICE_RSSI_REPORTED = 157,
+  ATOM_BLUETOOTH_DEVICE_FAILED_CONTACT_COUNTER_REPORTED = 158,
+  ATOM_BLUETOOTH_DEVICE_TX_POWER_LEVEL_REPORTED = 159,
+  ATOM_BLUETOOTH_HCI_TIMEOUT_REPORTED = 160,
+  ATOM_BLUETOOTH_QUALITY_REPORT_REPORTED = 161,
+  ATOM_BLUETOOTH_DEVICE_INFO_REPORTED = 162,
+  ATOM_BLUETOOTH_REMOTE_VERSION_INFO_REPORTED = 163,
+  ATOM_BLUETOOTH_SDP_ATTRIBUTE_REPORTED = 164,
+  ATOM_BLUETOOTH_BOND_STATE_CHANGED = 165,
+  ATOM_BLUETOOTH_CLASSIC_PAIRING_EVENT_REPORTED = 166,
+  ATOM_BLUETOOTH_SMP_PAIRING_EVENT_REPORTED = 167,
+  ATOM_SCREEN_TIMEOUT_EXTENSION_REPORTED = 168,
+  ATOM_PROCESS_START_TIME = 169,
+  ATOM_PERMISSION_GRANT_REQUEST_RESULT_REPORTED = 170,
+  ATOM_BLUETOOTH_SOCKET_CONNECTION_STATE_CHANGED = 171,
+  ATOM_DEVICE_IDENTIFIER_ACCESS_DENIED = 172,
+  ATOM_BUBBLE_DEVELOPER_ERROR_REPORTED = 173,
+  ATOM_ASSIST_GESTURE_STAGE_REPORTED = 174,
+  ATOM_ASSIST_GESTURE_FEEDBACK_REPORTED = 175,
+  ATOM_ASSIST_GESTURE_PROGRESS_REPORTED = 176,
+  ATOM_TOUCH_GESTURE_CLASSIFIED = 177,
+  ATOM_HIDDEN_API_USED = 178,
+  ATOM_STYLE_UI_CHANGED = 179,
+  ATOM_PRIVACY_INDICATORS_INTERACTED = 180,
+  ATOM_APP_INSTALL_ON_EXTERNAL_STORAGE_REPORTED = 181,
+  ATOM_NETWORK_STACK_REPORTED = 182,
+  ATOM_APP_MOVED_STORAGE_REPORTED = 183,
+  ATOM_BIOMETRIC_ENROLLED = 184,
+  ATOM_SYSTEM_SERVER_WATCHDOG_OCCURRED = 185,
+  ATOM_TOMB_STONE_OCCURRED = 186,
+  ATOM_BLUETOOTH_CLASS_OF_DEVICE_REPORTED = 187,
+  ATOM_INTELLIGENCE_EVENT_REPORTED = 188,
+  ATOM_THERMAL_THROTTLING_SEVERITY_STATE_CHANGED = 189,
+  ATOM_ROLE_REQUEST_RESULT_REPORTED = 190,
+  ATOM_MEDIAMETRICS_AUDIOPOLICY_REPORTED = 191,
+  ATOM_MEDIAMETRICS_AUDIORECORD_REPORTED = 192,
+  ATOM_MEDIAMETRICS_AUDIOTHREAD_REPORTED = 193,
+  ATOM_MEDIAMETRICS_AUDIOTRACK_REPORTED = 194,
+  ATOM_MEDIAMETRICS_CODEC_REPORTED = 195,
+  ATOM_MEDIAMETRICS_DRM_WIDEVINE_REPORTED = 196,
+  ATOM_MEDIAMETRICS_EXTRACTOR_REPORTED = 197,
+  ATOM_MEDIAMETRICS_MEDIADRM_REPORTED = 198,
+  ATOM_MEDIAMETRICS_NUPLAYER_REPORTED = 199,
+  ATOM_MEDIAMETRICS_RECORDER_REPORTED = 200,
+  ATOM_MEDIAMETRICS_DRMMANAGER_REPORTED = 201,
+  ATOM_CAR_POWER_STATE_CHANGED = 203,
+  ATOM_GARAGE_MODE_INFO = 204,
+  ATOM_TEST_ATOM_REPORTED = 205,
+  ATOM_CONTENT_CAPTURE_CALLER_MISMATCH_REPORTED = 206,
+  ATOM_CONTENT_CAPTURE_SERVICE_EVENTS = 207,
+  ATOM_CONTENT_CAPTURE_SESSION_EVENTS = 208,
+  ATOM_CONTENT_CAPTURE_FLUSHED = 209,
+  ATOM_LOCATION_MANAGER_API_USAGE_REPORTED = 210,
+  ATOM_REVIEW_PERMISSIONS_FRAGMENT_RESULT_REPORTED = 211,
+  ATOM_RUNTIME_PERMISSIONS_UPGRADE_RESULT = 212,
+  ATOM_GRANT_PERMISSIONS_ACTIVITY_BUTTON_ACTIONS = 213,
+  ATOM_LOCATION_ACCESS_CHECK_NOTIFICATION_ACTION = 214,
+  ATOM_APP_PERMISSION_FRAGMENT_ACTION_REPORTED = 215,
+  ATOM_APP_PERMISSION_FRAGMENT_VIEWED = 216,
+  ATOM_APP_PERMISSIONS_FRAGMENT_VIEWED = 217,
+  ATOM_PERMISSION_APPS_FRAGMENT_VIEWED = 218,
+  ATOM_TEXT_SELECTION_EVENT = 219,
+  ATOM_TEXT_LINKIFY_EVENT = 220,
+  ATOM_CONVERSATION_ACTIONS_EVENT = 221,
+  ATOM_LANGUAGE_DETECTION_EVENT = 222,
+  ATOM_EXCLUSION_RECT_STATE_CHANGED = 223,
+  ATOM_BACK_GESTURE_REPORTED_REPORTED = 224,
+  ATOM_UPDATE_ENGINE_UPDATE_ATTEMPT_REPORTED = 225,
+  ATOM_UPDATE_ENGINE_SUCCESSFUL_UPDATE_REPORTED = 226,
+  ATOM_CAMERA_ACTION_EVENT = 227,
+  ATOM_APP_COMPATIBILITY_CHANGE_REPORTED = 228,
+  ATOM_PERFETTO_UPLOADED = 229,
+  ATOM_VMS_CLIENT_CONNECTION_STATE_CHANGED = 230,
+  ATOM_MEDIA_PROVIDER_SCAN_OCCURRED = 233,
+  ATOM_MEDIA_CONTENT_DELETED = 234,
+  ATOM_MEDIA_PROVIDER_PERMISSION_REQUESTED = 235,
+  ATOM_MEDIA_PROVIDER_SCHEMA_CHANGED = 236,
+  ATOM_MEDIA_PROVIDER_IDLE_MAINTENANCE_FINISHED = 237,
+  ATOM_REBOOT_ESCROW_RECOVERY_REPORTED = 238,
+  ATOM_BOOT_TIME_EVENT_DURATION_REPORTED = 239,
+  ATOM_BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED = 240,
+  ATOM_BOOT_TIME_EVENT_UTC_TIME_REPORTED = 241,
+  ATOM_BOOT_TIME_EVENT_ERROR_CODE_REPORTED = 242,
+  ATOM_USERSPACE_REBOOT_REPORTED = 243,
+  ATOM_NOTIFICATION_REPORTED = 244,
+  ATOM_NOTIFICATION_PANEL_REPORTED = 245,
+  ATOM_NOTIFICATION_CHANNEL_MODIFIED = 246,
+  ATOM_INTEGRITY_CHECK_RESULT_REPORTED = 247,
+  ATOM_INTEGRITY_RULES_PUSHED = 248,
+  ATOM_CB_MESSAGE_REPORTED = 249,
+  ATOM_CB_MESSAGE_ERROR = 250,
+  ATOM_WIFI_HEALTH_STAT_REPORTED = 251,
+  ATOM_WIFI_FAILURE_STAT_REPORTED = 252,
+  ATOM_WIFI_CONNECTION_RESULT_REPORTED = 253,
+  ATOM_APP_FREEZE_CHANGED = 254,
+  ATOM_SNAPSHOT_MERGE_REPORTED = 255,
+  ATOM_FOREGROUND_SERVICE_APP_OP_SESSION_ENDED = 256,
+  ATOM_DISPLAY_JANK_REPORTED = 257,
+  ATOM_APP_STANDBY_BUCKET_CHANGED = 258,
+  ATOM_SHARESHEET_STARTED = 259,
+  ATOM_RANKING_SELECTED = 260,
+  ATOM_TVSETTINGS_UI_INTERACTED = 261,
+  ATOM_LAUNCHER_SNAPSHOT = 262,
+  ATOM_PACKAGE_INSTALLER_V2_REPORTED = 263,
+  ATOM_USER_LIFECYCLE_JOURNEY_REPORTED = 264,
+  ATOM_USER_LIFECYCLE_EVENT_OCCURRED = 265,
+  ATOM_ACCESSIBILITY_SHORTCUT_REPORTED = 266,
+  ATOM_ACCESSIBILITY_SERVICE_REPORTED = 267,
+  ATOM_DOCS_UI_DRAG_AND_DROP_REPORTED = 268,
+  ATOM_APP_USAGE_EVENT_OCCURRED = 269,
+  ATOM_AUTO_REVOKE_NOTIFICATION_CLICKED = 270,
+  ATOM_AUTO_REVOKE_FRAGMENT_APP_VIEWED = 271,
+  ATOM_AUTO_REVOKED_APP_INTERACTION = 272,
+  ATOM_APP_PERMISSION_GROUPS_FRAGMENT_AUTO_REVOKE_ACTION = 273,
+  ATOM_EVS_USAGE_STATS_REPORTED = 274,
+  ATOM_AUDIO_POWER_USAGE_DATA_REPORTED = 275,
+  ATOM_TV_TUNER_STATE_CHANGED = 276,
+  ATOM_MEDIAOUTPUT_OP_SWITCH_REPORTED = 277,
+  ATOM_CB_MESSAGE_FILTERED = 278,
+  ATOM_TV_TUNER_DVR_STATUS = 279,
+  ATOM_TV_CAS_SESSION_OPEN_STATUS = 280,
+  ATOM_ASSISTANT_INVOCATION_REPORTED = 281,
+  ATOM_DISPLAY_WAKE_REPORTED = 282,
+  ATOM_CAR_USER_HAL_MODIFY_USER_REQUEST_REPORTED = 283,
+  ATOM_CAR_USER_HAL_MODIFY_USER_RESPONSE_REPORTED = 284,
+  ATOM_CAR_USER_HAL_POST_SWITCH_RESPONSE_REPORTED = 285,
+  ATOM_CAR_USER_HAL_INITIAL_USER_INFO_REQUEST_REPORTED = 286,
+  ATOM_CAR_USER_HAL_INITIAL_USER_INFO_RESPONSE_REPORTED = 287,
+  ATOM_CAR_USER_HAL_USER_ASSOCIATION_REQUEST_REPORTED = 288,
+  ATOM_CAR_USER_HAL_SET_USER_ASSOCIATION_RESPONSE_REPORTED = 289,
+  ATOM_NETWORK_IP_PROVISIONING_REPORTED = 290,
+  ATOM_NETWORK_DHCP_RENEW_REPORTED = 291,
+  ATOM_NETWORK_VALIDATION_REPORTED = 292,
+  ATOM_NETWORK_STACK_QUIRK_REPORTED = 293,
+  ATOM_MEDIAMETRICS_AUDIORECORDDEVICEUSAGE_REPORTED = 294,
+  ATOM_MEDIAMETRICS_AUDIOTHREADDEVICEUSAGE_REPORTED = 295,
+  ATOM_MEDIAMETRICS_AUDIOTRACKDEVICEUSAGE_REPORTED = 296,
+  ATOM_MEDIAMETRICS_AUDIODEVICECONNECTION_REPORTED = 297,
+  ATOM_BLOB_COMMITTED = 298,
+  ATOM_BLOB_LEASED = 299,
+  ATOM_BLOB_OPENED = 300,
+  ATOM_CONTACTS_PROVIDER_STATUS_REPORTED = 301,
+  ATOM_KEYSTORE_KEY_EVENT_REPORTED = 302,
+  ATOM_NETWORK_TETHERING_REPORTED = 303,
+  ATOM_IME_TOUCH_REPORTED = 304,
+  ATOM_UI_INTERACTION_FRAME_INFO_REPORTED = 305,
+  ATOM_UI_ACTION_LATENCY_REPORTED = 306,
+  ATOM_WIFI_DISCONNECT_REPORTED = 307,
+  ATOM_WIFI_CONNECTION_STATE_CHANGED = 308,
+  ATOM_HDMI_CEC_ACTIVE_SOURCE_CHANGED = 309,
+  ATOM_HDMI_CEC_MESSAGE_REPORTED = 310,
+  ATOM_AIRPLANE_MODE = 311,
+  ATOM_MODEM_RESTART = 312,
+  ATOM_CARRIER_ID_MISMATCH_REPORTED = 313,
+  ATOM_CARRIER_ID_TABLE_UPDATED = 314,
+  ATOM_DATA_STALL_RECOVERY_REPORTED = 315,
+  ATOM_MEDIAMETRICS_MEDIAPARSER_REPORTED = 316,
+  ATOM_TLS_HANDSHAKE_REPORTED = 317,
+  ATOM_TEXT_CLASSIFIER_API_USAGE_REPORTED = 318,
+  ATOM_CAR_WATCHDOG_KILL_STATS_REPORTED = 319,
+  ATOM_MEDIAMETRICS_PLAYBACK_REPORTED = 320,
+  ATOM_MEDIA_NETWORK_INFO_CHANGED = 321,
+  ATOM_MEDIA_PLAYBACK_STATE_CHANGED = 322,
+  ATOM_MEDIA_PLAYBACK_ERROR_REPORTED = 323,
+  ATOM_MEDIA_PLAYBACK_TRACK_CHANGED = 324,
+  ATOM_WIFI_SCAN_REPORTED = 325,
+  ATOM_WIFI_PNO_SCAN_REPORTED = 326,
+  ATOM_TIF_TUNE_CHANGED = 327,
+  ATOM_AUTO_ROTATE_REPORTED = 328,
+  ATOM_PERFETTO_TRIGGER = 329,
+  ATOM_TRANSCODING_DATA = 330,
+  ATOM_IMS_SERVICE_ENTITLEMENT_UPDATED = 331,
+  ATOM_DEVICE_ROTATED = 333,
+  ATOM_SIM_SPECIFIC_SETTINGS_RESTORED = 334,
+  ATOM_TEXT_CLASSIFIER_DOWNLOAD_REPORTED = 335,
+  ATOM_PIN_STORAGE_EVENT = 336,
+  ATOM_FACE_DOWN_REPORTED = 337,
+  ATOM_BLUETOOTH_HAL_CRASH_REASON_REPORTED = 338,
+  ATOM_REBOOT_ESCROW_PREPARATION_REPORTED = 339,
+  ATOM_REBOOT_ESCROW_LSKF_CAPTURE_REPORTED = 340,
+  ATOM_REBOOT_ESCROW_REBOOT_REPORTED = 341,
+  ATOM_BINDER_LATENCY_REPORTED = 342,
+  ATOM_MEDIAMETRICS_AAUDIOSTREAM_REPORTED = 343,
+  ATOM_MEDIA_TRANSCODING_SESSION_ENDED = 344,
+  ATOM_MAGNIFICATION_USAGE_REPORTED = 345,
+  ATOM_MAGNIFICATION_MODE_WITH_IME_ON_REPORTED = 346,
+  ATOM_APP_SEARCH_CALL_STATS_REPORTED = 347,
+  ATOM_APP_SEARCH_PUT_DOCUMENT_STATS_REPORTED = 348,
+  ATOM_DEVICE_CONTROL_CHANGED = 349,
+  ATOM_DEVICE_STATE_CHANGED = 350,
+  ATOM_INPUTDEVICE_REGISTERED = 351,
+  ATOM_SMARTSPACE_CARD_REPORTED = 352,
+  ATOM_AUTH_PROMPT_AUTHENTICATE_INVOKED = 353,
+  ATOM_AUTH_MANAGER_CAN_AUTHENTICATE_INVOKED = 354,
+  ATOM_AUTH_ENROLL_ACTION_INVOKED = 355,
+  ATOM_AUTH_DEPRECATED_API_USED = 356,
+  ATOM_UNATTENDED_REBOOT_OCCURRED = 357,
+  ATOM_LONG_REBOOT_BLOCKING_REPORTED = 358,
+  ATOM_LOCATION_TIME_ZONE_PROVIDER_STATE_CHANGED = 359,
+  ATOM_FDTRACK_EVENT_OCCURRED = 364,
+  ATOM_TIMEOUT_AUTO_EXTENDED_REPORTED = 365,
+  ATOM_ALARM_BATCH_DELIVERED = 367,
+  ATOM_ALARM_SCHEDULED = 368,
+  ATOM_CAR_WATCHDOG_IO_OVERUSE_STATS_REPORTED = 369,
+  ATOM_USER_LEVEL_HIBERNATION_STATE_CHANGED = 370,
+  ATOM_APP_SEARCH_INITIALIZE_STATS_REPORTED = 371,
+  ATOM_APP_SEARCH_QUERY_STATS_REPORTED = 372,
+  ATOM_APP_PROCESS_DIED = 373,
+  ATOM_NETWORK_IP_REACHABILITY_MONITOR_REPORTED = 374,
+  ATOM_SLOW_INPUT_EVENT_REPORTED = 375,
+  ATOM_ANR_OCCURRED_PROCESSING_STARTED = 376,
+  ATOM_APP_SEARCH_REMOVE_STATS_REPORTED = 377,
+  ATOM_MEDIA_CODEC_REPORTED = 378,
+  ATOM_PERMISSION_USAGE_FRAGMENT_INTERACTION = 379,
+  ATOM_PERMISSION_DETAILS_INTERACTION = 380,
+  ATOM_PRIVACY_SENSOR_TOGGLE_INTERACTION = 381,
+  ATOM_PRIVACY_TOGGLE_DIALOG_INTERACTION = 382,
+  ATOM_APP_SEARCH_OPTIMIZE_STATS_REPORTED = 383,
+  ATOM_NON_A11Y_TOOL_SERVICE_WARNING_REPORT = 384,
+  ATOM_APP_SEARCH_SET_SCHEMA_STATS_REPORTED = 385,
+  ATOM_APP_COMPAT_STATE_CHANGED = 386,
+  ATOM_SIZE_COMPAT_RESTART_BUTTON_EVENT_REPORTED = 387,
+  ATOM_SPLITSCREEN_UI_CHANGED = 388,
+  ATOM_NETWORK_DNS_HANDSHAKE_REPORTED = 389,
+  ATOM_BLUETOOTH_CODE_PATH_COUNTER = 390,
+  ATOM_BLUETOOTH_LE_BATCH_SCAN_REPORT_DELAY = 392,
+  ATOM_ACCESSIBILITY_FLOATING_MENU_UI_CHANGED = 393,
+  ATOM_NEURALNETWORKS_COMPILATION_COMPLETED = 394,
+  ATOM_NEURALNETWORKS_EXECUTION_COMPLETED = 395,
+  ATOM_NEURALNETWORKS_COMPILATION_FAILED = 396,
+  ATOM_NEURALNETWORKS_EXECUTION_FAILED = 397,
+  ATOM_CONTEXT_HUB_BOOTED = 398,
+  ATOM_CONTEXT_HUB_RESTARTED = 399,
+  ATOM_CONTEXT_HUB_LOADED_NANOAPP_SNAPSHOT_REPORTED = 400,
+  ATOM_CHRE_CODE_DOWNLOAD_TRANSACTED = 401,
+  ATOM_UWB_SESSION_INITED = 402,
+  ATOM_UWB_SESSION_CLOSED = 403,
+  ATOM_UWB_FIRST_RANGING_RECEIVED = 404,
+  ATOM_UWB_RANGING_MEASUREMENT_RECEIVED = 405,
+  ATOM_TEXT_CLASSIFIER_DOWNLOAD_WORK_SCHEDULED = 406,
+  ATOM_TEXT_CLASSIFIER_DOWNLOAD_WORK_COMPLETED = 407,
+  ATOM_CLIPBOARD_CLEARED = 408,
+  ATOM_VM_CREATION_REQUESTED = 409,
+  ATOM_NEARBY_DEVICE_SCAN_STATE_CHANGED = 410,
+  ATOM_CAMERA_COMPAT_CONTROL_EVENT_REPORTED = 411,
+  ATOM_APPLICATION_LOCALES_CHANGED = 412,
+  ATOM_MEDIAMETRICS_AUDIOTRACKSTATUS_REPORTED = 413,
+  ATOM_FOLD_STATE_DURATION_REPORTED = 414,
+  ATOM_LOCATION_TIME_ZONE_PROVIDER_CONTROLLER_STATE_CHANGED = 415,
+  ATOM_DISPLAY_HBM_STATE_CHANGED = 416,
+  ATOM_DISPLAY_HBM_BRIGHTNESS_CHANGED = 417,
+  ATOM_PERSISTENT_URI_PERMISSIONS_FLUSHED = 418,
+  ATOM_EARLY_BOOT_COMP_OS_ARTIFACTS_CHECK_REPORTED = 419,
+  ATOM_VBMETA_DIGEST_REPORTED = 420,
+  ATOM_APEX_INFO_GATHERED = 421,
+  ATOM_PVM_INFO_GATHERED = 422,
+  ATOM_WEAR_SETTINGS_UI_INTERACTED = 423,
+  ATOM_TRACING_SERVICE_REPORT_EVENT = 424,
+  ATOM_MEDIAMETRICS_AUDIORECORDSTATUS_REPORTED = 425,
+  ATOM_LAUNCHER_LATENCY = 426,
+  ATOM_DROPBOX_ENTRY_DROPPED = 427,
+  ATOM_WIFI_P2P_CONNECTION_REPORTED = 428,
+  ATOM_GAME_STATE_CHANGED = 429,
+  ATOM_HOTWORD_DETECTOR_CREATE_REQUESTED = 430,
+  ATOM_HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED = 431,
+  ATOM_HOTWORD_DETECTION_SERVICE_RESTARTED = 432,
+  ATOM_HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED = 433,
+  ATOM_HOTWORD_DETECTOR_EVENTS = 434,
+  ATOM_AD_SERVICES_API_CALLED = 435,
+  ATOM_AD_SERVICES_MESUREMENT_REPORTS_UPLOADED = 436,
+  ATOM_BOOT_COMPLETED_BROADCAST_COMPLETION_LATENCY_REPORTED = 437,
+  ATOM_CONTACTS_INDEXER_UPDATE_STATS_REPORTED = 440,
+  ATOM_APP_BACKGROUND_RESTRICTIONS_INFO = 441,
+  ATOM_MMS_SMS_PROVIDER_GET_THREAD_ID_FAILED = 442,
+  ATOM_MMS_SMS_DATABASE_HELPER_ON_UPGRADE_FAILED = 443,
+  ATOM_PERMISSION_REMINDER_NOTIFICATION_INTERACTED = 444,
+  ATOM_RECENT_PERMISSION_DECISIONS_INTERACTED = 445,
+  ATOM_GNSS_PSDS_DOWNLOAD_REPORTED = 446,
+  ATOM_LE_AUDIO_CONNECTION_SESSION_REPORTED = 447,
+  ATOM_LE_AUDIO_BROADCAST_SESSION_REPORTED = 448,
+  ATOM_DREAM_UI_EVENT_REPORTED = 449,
+  ATOM_TASK_MANAGER_EVENT_REPORTED = 450,
+  ATOM_CDM_ASSOCIATION_ACTION = 451,
+  ATOM_MAGNIFICATION_TRIPLE_TAP_AND_HOLD_ACTIVATED_SESSION_REPORTED = 452,
+  ATOM_MAGNIFICATION_FOLLOW_TYPING_FOCUS_ACTIVATED_SESSION_REPORTED = 453,
+  ATOM_ACCESSIBILITY_TEXT_READING_OPTIONS_CHANGED = 454,
+  ATOM_WIFI_SETUP_FAILURE_CRASH_REPORTED = 455,
+  ATOM_UWB_DEVICE_ERROR_REPORTED = 456,
+  ATOM_ISOLATED_COMPILATION_SCHEDULED = 457,
+  ATOM_ISOLATED_COMPILATION_ENDED = 458,
+  ATOM_ONS_OPPORTUNISTIC_ESIM_PROVISIONING_COMPLETE = 459,
+  ATOM_SYSTEM_SERVER_PRE_WATCHDOG_OCCURRED = 460,
+  ATOM_TELEPHONY_ANOMALY_DETECTED = 461,
+  ATOM_LETTERBOX_POSITION_CHANGED = 462,
+  ATOM_REMOTE_KEY_PROVISIONING_ATTEMPT = 463,
+  ATOM_REMOTE_KEY_PROVISIONING_NETWORK_INFO = 464,
+  ATOM_REMOTE_KEY_PROVISIONING_TIMING = 465,
+  ATOM_MEDIAOUTPUT_OP_INTERACTION_REPORT = 466,
+  ATOM_SYNC_EXEMPTION_OCCURRED = 468,
+  ATOM_AUTOFILL_PRESENTATION_EVENT_REPORTED = 469,
+  ATOM_DOCK_STATE_CHANGED = 470,
+  ATOM_SAFETY_SOURCE_STATE_COLLECTED = 471,
+  ATOM_SAFETY_CENTER_SYSTEM_EVENT_REPORTED = 472,
+  ATOM_SAFETY_CENTER_INTERACTION_REPORTED = 473,
+  ATOM_SETTINGS_PROVIDER_SETTING_CHANGED = 474,
+  ATOM_BROADCAST_DELIVERY_EVENT_REPORTED = 475,
+  ATOM_SERVICE_REQUEST_EVENT_REPORTED = 476,
+  ATOM_PROVIDER_ACQUISITION_EVENT_REPORTED = 477,
+  ATOM_BLUETOOTH_DEVICE_NAME_REPORTED = 478,
+  ATOM_CB_CONFIG_UPDATED = 479,
+  ATOM_CB_MODULE_ERROR_REPORTED = 480,
+  ATOM_CB_SERVICE_FEATURE_CHANGED = 481,
+  ATOM_CB_RECEIVER_FEATURE_CHANGED = 482,
+  ATOM_JSSCRIPTENGINE_LATENCY_REPORTED = 483,
+  ATOM_PRIVACY_SIGNAL_NOTIFICATION_INTERACTION = 484,
+  ATOM_PRIVACY_SIGNAL_ISSUE_CARD_INTERACTION = 485,
+  ATOM_PRIVACY_SIGNALS_JOB_FAILURE = 486,
+  ATOM_VIBRATION_REPORTED = 487,
+  ATOM_UWB_RANGING_START = 489,
+  ATOM_MOBILE_DATA_DOWNLOAD_FILE_GROUP_STATUS_REPORTED = 490,
+  ATOM_APP_COMPACTED_V2 = 491,
+  ATOM_AD_SERVICES_SETTINGS_USAGE_REPORTED = 493,
+  ATOM_DISPLAY_BRIGHTNESS_CHANGED = 494,
+  ATOM_ACTIVITY_ACTION_BLOCKED = 495,
+  ATOM_BACKGROUND_FETCH_PROCESS_REPORTED = 496,
+  ATOM_UPDATE_CUSTOM_AUDIENCE_PROCESS_REPORTED = 497,
+  ATOM_RUN_AD_BIDDING_PROCESS_REPORTED = 498,
+  ATOM_RUN_AD_SCORING_PROCESS_REPORTED = 499,
+  ATOM_RUN_AD_SELECTION_PROCESS_REPORTED = 500,
+  ATOM_RUN_AD_BIDDING_PER_CA_PROCESS_REPORTED = 501,
+  ATOM_MOBILE_DATA_DOWNLOAD_DOWNLOAD_RESULT_REPORTED = 502,
+  ATOM_MOBILE_DATA_DOWNLOAD_FILE_GROUP_STORAGE_STATS_REPORTED = 503,
+  ATOM_NETWORK_DNS_SERVER_SUPPORT_REPORTED = 504,
+  ATOM_VM_BOOTED = 505,
+  ATOM_VM_EXITED = 506,
+  ATOM_AMBIENT_BRIGHTNESS_STATS_REPORTED = 507,
+  ATOM_MEDIAMETRICS_SPATIALIZERCAPABILITIES_REPORTED = 508,
+  ATOM_MEDIAMETRICS_SPATIALIZERDEVICEENABLED_REPORTED = 509,
+  ATOM_MEDIAMETRICS_HEADTRACKERDEVICEENABLED_REPORTED = 510,
+  ATOM_MEDIAMETRICS_HEADTRACKERDEVICESUPPORTED_REPORTED = 511,
+  ATOM_AD_SERVICES_MEASUREMENT_REGISTRATIONS = 512,
+  ATOM_HEARING_AID_INFO_REPORTED = 513,
+  ATOM_DEVICE_WIDE_JOB_CONSTRAINT_CHANGED = 514,
+  ATOM_AMBIENT_MODE_CHANGED = 515,
+  ATOM_ANR_LATENCY_REPORTED = 516,
+  ATOM_RESOURCE_API_INFO = 517,
+  ATOM_SYSTEM_DEFAULT_NETWORK_CHANGED = 518,
+  ATOM_IWLAN_SETUP_DATA_CALL_RESULT_REPORTED = 519,
+  ATOM_IWLAN_PDN_DISCONNECTED_REASON_REPORTED = 520,
+  ATOM_AIRPLANE_MODE_SESSION_REPORTED = 521,
+  ATOM_VM_CPU_STATUS_REPORTED = 522,
+  ATOM_VM_MEM_STATUS_REPORTED = 523,
+  ATOM_PACKAGE_INSTALLATION_SESSION_REPORTED = 524,
+  ATOM_DEFAULT_NETWORK_REMATCH_INFO = 525,
+  ATOM_NETWORK_SELECTION_PERFORMANCE = 526,
+  ATOM_NETWORK_NSD_REPORTED = 527,
+  ATOM_BLUETOOTH_DISCONNECTION_REASON_REPORTED = 529,
+  ATOM_BLUETOOTH_LOCAL_VERSIONS_REPORTED = 530,
+  ATOM_BLUETOOTH_REMOTE_SUPPORTED_FEATURES_REPORTED = 531,
+  ATOM_BLUETOOTH_LOCAL_SUPPORTED_FEATURES_REPORTED = 532,
+  ATOM_BLUETOOTH_GATT_APP_INFO = 533,
+  ATOM_BRIGHTNESS_CONFIGURATION_UPDATED = 534,
+  ATOM_AD_SERVICES_GET_TOPICS_REPORTED = 535,
+  ATOM_AD_SERVICES_EPOCH_COMPUTATION_GET_TOP_TOPICS_REPORTED = 536,
+  ATOM_AD_SERVICES_EPOCH_COMPUTATION_CLASSIFIER_REPORTED = 537,
+  ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_LAUNCHED = 538,
+  ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_FINISHED = 539,
+  ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_CONNECTION_REPORTED = 540,
+  ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_DEVICE_SCAN_TRIGGERED = 541,
+  ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_FIRST_DEVICE_SCAN_LATENCY = 542,
+  ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_CONNECT_DEVICE_LATENCY = 543,
+  ATOM_PACKAGE_MANAGER_SNAPSHOT_REPORTED = 544,
+  ATOM_PACKAGE_MANAGER_APPS_FILTER_CACHE_BUILD_REPORTED = 545,
+  ATOM_PACKAGE_MANAGER_APPS_FILTER_CACHE_UPDATE_REPORTED = 546,
+  ATOM_LAUNCHER_IMPRESSION_EVENT = 547,
+  ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_ALL_DEVICES_SCAN_LATENCY = 549,
+  ATOM_WS_WATCH_FACE_EDITED = 551,
+  ATOM_WS_WATCH_FACE_FAVORITE_ACTION_REPORTED = 552,
+  ATOM_WS_WATCH_FACE_SET_ACTION_REPORTED = 553,
+  ATOM_PACKAGE_UNINSTALLATION_REPORTED = 554,
+  ATOM_GAME_MODE_CHANGED = 555,
+  ATOM_GAME_MODE_CONFIGURATION_CHANGED = 556,
+  ATOM_BEDTIME_MODE_STATE_CHANGED = 557,
+  ATOM_NETWORK_SLICE_SESSION_ENDED = 558,
+  ATOM_NETWORK_SLICE_DAILY_DATA_USAGE_REPORTED = 559,
+  ATOM_NFC_TAG_TYPE_OCCURRED = 560,
+  ATOM_NFC_AID_CONFLICT_OCCURRED = 561,
+  ATOM_NFC_READER_CONFLICT_OCCURRED = 562,
+  ATOM_WS_TILE_LIST_CHANGED = 563,
+  ATOM_GET_TYPE_ACCESSED_WITHOUT_PERMISSION = 564,
+  ATOM_MOBILE_BUNDLED_APP_INFO_GATHERED = 566,
+  ATOM_WS_WATCH_FACE_COMPLICATION_SET_CHANGED = 567,
+  ATOM_MEDIA_DRM_CREATED = 568,
+  ATOM_MEDIA_DRM_ERRORED = 569,
+  ATOM_MEDIA_DRM_SESSION_OPENED = 570,
+  ATOM_MEDIA_DRM_SESSION_CLOSED = 571,
+  ATOM_USER_SELECTED_RESOLUTION = 572,
+  ATOM_UNSAFE_INTENT_EVENT_REPORTED = 573,
+  ATOM_PERFORMANCE_HINT_SESSION_REPORTED = 574,
+  ATOM_MEDIAMETRICS_MIDI_DEVICE_CLOSE_REPORTED = 576,
+  ATOM_BIOMETRIC_TOUCH_REPORTED = 577,
+  ATOM_HOTWORD_AUDIO_EGRESS_EVENT_REPORTED = 578,
+  ATOM_APP_SEARCH_SCHEMA_MIGRATION_STATS_REPORTED = 579,
+  ATOM_LOCATION_ENABLED_STATE_CHANGED = 580,
+  ATOM_IME_REQUEST_FINISHED = 581,
+  ATOM_USB_COMPLIANCE_WARNINGS_REPORTED = 582,
+  ATOM_APP_SUPPORTED_LOCALES_CHANGED = 583,
+  ATOM_GRAMMATICAL_INFLECTION_CHANGED = 584,
+  ATOM_MEDIA_PROVIDER_VOLUME_RECOVERY_REPORTED = 586,
+  ATOM_BIOMETRIC_PROPERTIES_COLLECTED = 587,
+  ATOM_KERNEL_WAKEUP_ATTRIBUTED = 588,
+  ATOM_SCREEN_STATE_CHANGED_V2 = 589,
+  ATOM_WS_BACKUP_ACTION_REPORTED = 590,
+  ATOM_WS_RESTORE_ACTION_REPORTED = 591,
+  ATOM_DEVICE_LOG_ACCESS_EVENT_REPORTED = 592,
+  ATOM_MEDIA_SESSION_UPDATED = 594,
+  ATOM_WEAR_OOBE_STATE_CHANGED = 595,
+  ATOM_WS_NOTIFICATION_UPDATED = 596,
+  ATOM_NETWORK_VALIDATION_FAILURE_STATS_DAILY_REPORTED = 601,
+  ATOM_WS_COMPLICATION_TAPPED = 602,
+  ATOM_WS_WEAR_TIME_SESSION = 610,
+  ATOM_WIFI_BYTES_TRANSFER = 10000,
+  ATOM_WIFI_BYTES_TRANSFER_BY_FG_BG = 10001,
+  ATOM_MOBILE_BYTES_TRANSFER = 10002,
+  ATOM_MOBILE_BYTES_TRANSFER_BY_FG_BG = 10003,
+  ATOM_BLUETOOTH_BYTES_TRANSFER = 10006,
+  ATOM_KERNEL_WAKELOCK = 10004,
+  ATOM_SUBSYSTEM_SLEEP_STATE = 10005,
+  ATOM_CPU_TIME_PER_UID = 10009,
+  ATOM_CPU_TIME_PER_UID_FREQ = 10010,
+  ATOM_WIFI_ACTIVITY_INFO = 10011,
+  ATOM_MODEM_ACTIVITY_INFO = 10012,
+  ATOM_BLUETOOTH_ACTIVITY_INFO = 10007,
+  ATOM_PROCESS_MEMORY_STATE = 10013,
+  ATOM_SYSTEM_ELAPSED_REALTIME = 10014,
+  ATOM_SYSTEM_UPTIME = 10015,
+  ATOM_CPU_ACTIVE_TIME = 10016,
+  ATOM_CPU_CLUSTER_TIME = 10017,
+  ATOM_DISK_SPACE = 10018,
+  ATOM_REMAINING_BATTERY_CAPACITY = 10019,
+  ATOM_FULL_BATTERY_CAPACITY = 10020,
+  ATOM_TEMPERATURE = 10021,
+  ATOM_BINDER_CALLS = 10022,
+  ATOM_BINDER_CALLS_EXCEPTIONS = 10023,
+  ATOM_LOOPER_STATS = 10024,
+  ATOM_DISK_STATS = 10025,
+  ATOM_DIRECTORY_USAGE = 10026,
+  ATOM_APP_SIZE = 10027,
+  ATOM_CATEGORY_SIZE = 10028,
+  ATOM_PROC_STATS = 10029,
+  ATOM_BATTERY_VOLTAGE = 10030,
+  ATOM_NUM_FINGERPRINTS_ENROLLED = 10031,
+  ATOM_DISK_IO = 10032,
+  ATOM_POWER_PROFILE = 10033,
+  ATOM_PROC_STATS_PKG_PROC = 10034,
+  ATOM_PROCESS_CPU_TIME = 10035,
+  ATOM_CPU_TIME_PER_THREAD_FREQ = 10037,
+  ATOM_ON_DEVICE_POWER_MEASUREMENT = 10038,
+  ATOM_DEVICE_CALCULATED_POWER_USE = 10039,
+  ATOM_PROCESS_MEMORY_HIGH_WATER_MARK = 10042,
+  ATOM_BATTERY_LEVEL = 10043,
+  ATOM_BUILD_INFORMATION = 10044,
+  ATOM_BATTERY_CYCLE_COUNT = 10045,
+  ATOM_DEBUG_ELAPSED_CLOCK = 10046,
+  ATOM_DEBUG_FAILING_ELAPSED_CLOCK = 10047,
+  ATOM_NUM_FACES_ENROLLED = 10048,
+  ATOM_ROLE_HOLDER = 10049,
+  ATOM_DANGEROUS_PERMISSION_STATE = 10050,
+  ATOM_TRAIN_INFO = 10051,
+  ATOM_TIME_ZONE_DATA_INFO = 10052,
+  ATOM_EXTERNAL_STORAGE_INFO = 10053,
+  ATOM_GPU_STATS_GLOBAL_INFO = 10054,
+  ATOM_GPU_STATS_APP_INFO = 10055,
+  ATOM_SYSTEM_ION_HEAP_SIZE = 10056,
+  ATOM_APPS_ON_EXTERNAL_STORAGE_INFO = 10057,
+  ATOM_FACE_SETTINGS = 10058,
+  ATOM_COOLING_DEVICE = 10059,
+  ATOM_APP_OPS = 10060,
+  ATOM_PROCESS_SYSTEM_ION_HEAP_SIZE = 10061,
+  ATOM_SURFACEFLINGER_STATS_GLOBAL_INFO = 10062,
+  ATOM_SURFACEFLINGER_STATS_LAYER_INFO = 10063,
+  ATOM_PROCESS_MEMORY_SNAPSHOT = 10064,
+  ATOM_VMS_CLIENT_STATS = 10065,
+  ATOM_NOTIFICATION_REMOTE_VIEWS = 10066,
+  ATOM_DANGEROUS_PERMISSION_STATE_SAMPLED = 10067,
+  ATOM_GRAPHICS_STATS = 10068,
+  ATOM_RUNTIME_APP_OP_ACCESS = 10069,
+  ATOM_ION_HEAP_SIZE = 10070,
+  ATOM_PACKAGE_NOTIFICATION_PREFERENCES = 10071,
+  ATOM_PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES = 10072,
+  ATOM_PACKAGE_NOTIFICATION_CHANNEL_GROUP_PREFERENCES = 10073,
+  ATOM_GNSS_STATS = 10074,
+  ATOM_ATTRIBUTED_APP_OPS = 10075,
+  ATOM_VOICE_CALL_SESSION = 10076,
+  ATOM_VOICE_CALL_RAT_USAGE = 10077,
+  ATOM_SIM_SLOT_STATE = 10078,
+  ATOM_SUPPORTED_RADIO_ACCESS_FAMILY = 10079,
+  ATOM_SETTING_SNAPSHOT = 10080,
+  ATOM_BLOB_INFO = 10081,
+  ATOM_DATA_USAGE_BYTES_TRANSFER = 10082,
+  ATOM_BYTES_TRANSFER_BY_TAG_AND_METERED = 10083,
+  ATOM_DND_MODE_RULE = 10084,
+  ATOM_GENERAL_EXTERNAL_STORAGE_ACCESS_STATS = 10085,
+  ATOM_INCOMING_SMS = 10086,
+  ATOM_OUTGOING_SMS = 10087,
+  ATOM_CARRIER_ID_TABLE_VERSION = 10088,
+  ATOM_DATA_CALL_SESSION = 10089,
+  ATOM_CELLULAR_SERVICE_STATE = 10090,
+  ATOM_CELLULAR_DATA_SERVICE_SWITCH = 10091,
+  ATOM_SYSTEM_MEMORY = 10092,
+  ATOM_IMS_REGISTRATION_TERMINATION = 10093,
+  ATOM_IMS_REGISTRATION_STATS = 10094,
+  ATOM_CPU_TIME_PER_CLUSTER_FREQ = 10095,
+  ATOM_CPU_CYCLES_PER_UID_CLUSTER = 10096,
+  ATOM_DEVICE_ROTATED_DATA = 10097,
+  ATOM_CPU_CYCLES_PER_THREAD_GROUP_CLUSTER = 10098,
+  ATOM_MEDIA_DRM_ACTIVITY_INFO = 10099,
+  ATOM_OEM_MANAGED_BYTES_TRANSFER = 10100,
+  ATOM_GNSS_POWER_STATS = 10101,
+  ATOM_TIME_ZONE_DETECTOR_STATE = 10102,
+  ATOM_KEYSTORE2_STORAGE_STATS = 10103,
+  ATOM_RKP_POOL_STATS = 10104,
+  ATOM_PROCESS_DMABUF_MEMORY = 10105,
+  ATOM_PENDING_ALARM_INFO = 10106,
+  ATOM_USER_LEVEL_HIBERNATED_APPS = 10107,
+  ATOM_LAUNCHER_LAYOUT_SNAPSHOT = 10108,
+  ATOM_GLOBAL_HIBERNATED_APPS = 10109,
+  ATOM_INPUT_EVENT_LATENCY_SKETCH = 10110,
+  ATOM_BATTERY_USAGE_STATS_BEFORE_RESET = 10111,
+  ATOM_BATTERY_USAGE_STATS_SINCE_RESET = 10112,
+  ATOM_BATTERY_USAGE_STATS_SINCE_RESET_USING_POWER_PROFILE_MODEL = 10113,
+  ATOM_INSTALLED_INCREMENTAL_PACKAGE = 10114,
+  ATOM_TELEPHONY_NETWORK_REQUESTS = 10115,
+  ATOM_APP_SEARCH_STORAGE_INFO = 10116,
+  ATOM_VMSTAT = 10117,
+  ATOM_KEYSTORE2_KEY_CREATION_WITH_GENERAL_INFO = 10118,
+  ATOM_KEYSTORE2_KEY_CREATION_WITH_AUTH_INFO = 10119,
+  ATOM_KEYSTORE2_KEY_CREATION_WITH_PURPOSE_AND_MODES_INFO = 10120,
+  ATOM_KEYSTORE2_ATOM_WITH_OVERFLOW = 10121,
+  ATOM_KEYSTORE2_KEY_OPERATION_WITH_PURPOSE_AND_MODES_INFO = 10122,
+  ATOM_KEYSTORE2_KEY_OPERATION_WITH_GENERAL_INFO = 10123,
+  ATOM_RKP_ERROR_STATS = 10124,
+  ATOM_KEYSTORE2_CRASH_STATS = 10125,
+  ATOM_VENDOR_APEX_INFO = 10126,
+  ATOM_ACCESSIBILITY_SHORTCUT_STATS = 10127,
+  ATOM_ACCESSIBILITY_FLOATING_MENU_STATS = 10128,
+  ATOM_DATA_USAGE_BYTES_TRANSFER_V2 = 10129,
+  ATOM_MEDIA_CAPABILITIES = 10130,
+  ATOM_CAR_WATCHDOG_SYSTEM_IO_USAGE_SUMMARY = 10131,
+  ATOM_CAR_WATCHDOG_UID_IO_USAGE_SUMMARY = 10132,
+  ATOM_IMS_REGISTRATION_FEATURE_TAG_STATS = 10133,
+  ATOM_RCS_CLIENT_PROVISIONING_STATS = 10134,
+  ATOM_RCS_ACS_PROVISIONING_STATS = 10135,
+  ATOM_SIP_DELEGATE_STATS = 10136,
+  ATOM_SIP_TRANSPORT_FEATURE_TAG_STATS = 10137,
+  ATOM_SIP_MESSAGE_RESPONSE = 10138,
+  ATOM_SIP_TRANSPORT_SESSION = 10139,
+  ATOM_IMS_DEDICATED_BEARER_LISTENER_EVENT = 10140,
+  ATOM_IMS_DEDICATED_BEARER_EVENT = 10141,
+  ATOM_IMS_REGISTRATION_SERVICE_DESC_STATS = 10142,
+  ATOM_UCE_EVENT_STATS = 10143,
+  ATOM_PRESENCE_NOTIFY_EVENT = 10144,
+  ATOM_GBA_EVENT = 10145,
+  ATOM_PER_SIM_STATUS = 10146,
+  ATOM_GPU_WORK_PER_UID = 10147,
+  ATOM_PERSISTENT_URI_PERMISSIONS_AMOUNT_PER_PACKAGE = 10148,
+  ATOM_SIGNED_PARTITION_INFO = 10149,
+  ATOM_PINNED_FILE_SIZES_PER_PACKAGE = 10150,
+  ATOM_PENDING_INTENTS_PER_PACKAGE = 10151,
+  ATOM_USER_INFO = 10152,
+  ATOM_TELEPHONY_NETWORK_REQUESTS_V2 = 10153,
+  ATOM_DEVICE_TELEPHONY_PROPERTIES = 10154,
+  ATOM_REMOTE_KEY_PROVISIONING_ERROR_COUNTS = 10155,
+  ATOM_SAFETY_STATE = 10156,
+  ATOM_INCOMING_MMS = 10157,
+  ATOM_OUTGOING_MMS = 10158,
+  ATOM_MULTI_USER_INFO = 10160,
+  ATOM_NETWORK_BPF_MAP_INFO = 10161,
+  ATOM_OUTGOING_SHORT_CODE_SMS = 10162,
+  ATOM_CONNECTIVITY_STATE_SAMPLE = 10163,
+  ATOM_NETWORK_SELECTION_REMATCH_REASONS_INFO = 10164,
+  ATOM_GAME_MODE_INFO = 10165,
+  ATOM_GAME_MODE_CONFIGURATION = 10166,
+  ATOM_GAME_MODE_LISTENER = 10167,
+  ATOM_NETWORK_SLICE_REQUEST_COUNT = 10168,
+  ATOM_WS_TILE_SNAPSHOT = 10169,
+  ATOM_WS_ACTIVE_WATCH_FACE_COMPLICATION_SET_SNAPSHOT = 10170,
+  ATOM_PROCESS_STATE = 10171,
+  ATOM_PROCESS_ASSOCIATION = 10172,
+  ATOM_ADPF_SYSTEM_COMPONENT_INFO = 10173,
+  ATOM_NOTIFICATION_MEMORY_USE = 10174,
+  ATOM_HDR_CAPABILITIES = 10175,
+  ATOM_WS_FAVOURITE_WATCH_FACE_LIST_SNAPSHOT = 10176,
+  ATOM_WIFI_AWARE_NDP_REPORTED = 638,
+  ATOM_WIFI_AWARE_ATTACH_REPORTED = 639,
+  ATOM_WIFI_SELF_RECOVERY_TRIGGERED = 661,
+  ATOM_SOFT_AP_STARTED = 680,
+  ATOM_SOFT_AP_STOPPED = 681,
+  ATOM_WIFI_LOCK_RELEASED = 687,
+  ATOM_WIFI_LOCK_DEACTIVATED = 688,
+  ATOM_WIFI_CONFIG_SAVED = 689,
+  ATOM_WIFI_AWARE_RESOURCE_USING_CHANGED = 690,
+  ATOM_WIFI_AWARE_HAL_API_CALLED = 691,
+  ATOM_WIFI_LOCAL_ONLY_REQUEST_RECEIVED = 692,
+  ATOM_WIFI_LOCAL_ONLY_REQUEST_SCAN_TRIGGERED = 693,
+  ATOM_WIFI_THREAD_TASK_EXECUTED = 694,
+  ATOM_WIFI_STATE_CHANGED = 700,
+  ATOM_WIFI_AWARE_CAPABILITIES = 10190,
+  ATOM_WIFI_MODULE_INFO = 10193,
+  ATOM_SETTINGS_SPA_REPORTED = 622,
+  ATOM_EXPRESS_EVENT_REPORTED = 528,
+  ATOM_EXPRESS_HISTOGRAM_SAMPLE_REPORTED = 593,
+  ATOM_EXPRESS_UID_EVENT_REPORTED = 644,
+  ATOM_EXPRESS_UID_HISTOGRAM_SAMPLE_REPORTED = 658,
+  ATOM_PERMISSION_RATIONALE_DIALOG_VIEWED = 645,
+  ATOM_PERMISSION_RATIONALE_DIALOG_ACTION_REPORTED = 646,
+  ATOM_APP_DATA_SHARING_UPDATES_NOTIFICATION_INTERACTION = 647,
+  ATOM_APP_DATA_SHARING_UPDATES_FRAGMENT_VIEWED = 648,
+  ATOM_APP_DATA_SHARING_UPDATES_FRAGMENT_ACTION_REPORTED = 649,
+  ATOM_WS_INCOMING_CALL_ACTION_REPORTED = 626,
+  ATOM_WS_CALL_DISCONNECTION_REPORTED = 627,
+  ATOM_WS_CALL_DURATION_REPORTED = 628,
+  ATOM_WS_CALL_USER_EXPERIENCE_LATENCY_REPORTED = 629,
+  ATOM_WS_CALL_INTERACTION_REPORTED = 630,
+  ATOM_FULL_SCREEN_INTENT_LAUNCHED = 631,
+  ATOM_BAL_ALLOWED = 632,
+  ATOM_IN_TASK_ACTIVITY_STARTED = 685,
+  ATOM_CACHED_APPS_HIGH_WATERMARK = 10189,
+  ATOM_ODREFRESH_REPORTED = 366,
+  ATOM_ODSIGN_REPORTED = 548,
+  ATOM_ART_DATUM_REPORTED = 332,
+  ATOM_ART_DEVICE_DATUM_REPORTED = 550,
+  ATOM_ART_DATUM_DELTA_REPORTED = 565,
+  ATOM_BACKGROUND_DEXOPT_JOB_ENDED = 467,
+  ATOM_WEAR_ADAPTIVE_SUSPEND_STATS_REPORTED = 619,
+  ATOM_WEAR_POWER_ANOMALY_SERVICE_OPERATIONAL_STATS_REPORTED = 620,
+  ATOM_WEAR_POWER_ANOMALY_SERVICE_EVENT_STATS_REPORTED = 621,
+  ATOM_EMERGENCY_STATE_CHANGED = 633,
+  ATOM_DND_STATE_CHANGED = 657,
+  ATOM_MTE_STATE = 10181,
+  ATOM_AD_SERVICES_BACK_COMPAT_GET_TOPICS_REPORTED = 598,
+  ATOM_AD_SERVICES_BACK_COMPAT_EPOCH_COMPUTATION_CLASSIFIER_REPORTED = 599,
+  ATOM_AD_SERVICES_MEASUREMENT_DEBUG_KEYS = 640,
+  ATOM_AD_SERVICES_ERROR_REPORTED = 662,
+  ATOM_AD_SERVICES_BACKGROUND_JOBS_EXECUTION_REPORTED = 663,
+  ATOM_AD_SERVICES_MEASUREMENT_DELAYED_SOURCE_REGISTRATION = 673,
+  ATOM_AD_SERVICES_MEASUREMENT_ATTRIBUTION = 674,
+  ATOM_AD_SERVICES_MEASUREMENT_JOBS = 675,
+  ATOM_AD_SERVICES_MEASUREMENT_WIPEOUT = 676,
+  ATOM_AD_SERVICES_CONSENT_MIGRATED = 702,
+  ATOM_RKPD_POOL_STATS = 664,
+  ATOM_RKPD_CLIENT_OPERATION = 665,
+  ATOM_AUTOFILL_UI_EVENT_REPORTED = 603,
+  ATOM_AUTOFILL_FILL_REQUEST_REPORTED = 604,
+  ATOM_AUTOFILL_FILL_RESPONSE_REPORTED = 605,
+  ATOM_AUTOFILL_SAVE_EVENT_REPORTED = 606,
+  ATOM_AUTOFILL_SESSION_COMMITTED = 607,
+  ATOM_AUTOFILL_FIELD_CLASSIFICATION_EVENT_REPORTED = 659,
+  ATOM_TEST_EXTENSION_ATOM_REPORTED = 660,
+  ATOM_TEST_RESTRICTED_ATOM_REPORTED = 672,
+  ATOM_STATS_SOCKET_LOSS_REPORTED = 752,
+  ATOM_PLUGIN_INITIALIZED = 655,
+  ATOM_TV_LOW_POWER_STANDBY_POLICY = 679,
+  ATOM_LOCKSCREEN_SHORTCUT_SELECTED = 611,
+  ATOM_LOCKSCREEN_SHORTCUT_TRIGGERED = 612,
+  ATOM_EMERGENCY_NUMBERS_INFO = 10180,
+  ATOM_QUALIFIED_RAT_LIST_CHANGED = 634,
+  ATOM_QNS_IMS_CALL_DROP_STATS = 635,
+  ATOM_QNS_FALLBACK_RESTRICTION_CHANGED = 636,
+  ATOM_QNS_RAT_PREFERENCE_MISMATCH_INFO = 10177,
+  ATOM_QNS_HANDOVER_TIME_MILLIS = 10178,
+  ATOM_QNS_HANDOVER_PINGPONG = 10179,
+  ATOM_SATELLITE_CONTROLLER = 10182,
+  ATOM_SATELLITE_SESSION = 10183,
+  ATOM_SATELLITE_INCOMING_DATAGRAM = 10184,
+  ATOM_SATELLITE_OUTGOING_DATAGRAM = 10185,
+  ATOM_SATELLITE_PROVISION = 10186,
+  ATOM_SATELLITE_SOS_MESSAGE_RECOMMENDER = 10187,
+  ATOM_IKE_SESSION_TERMINATED = 678,
+  ATOM_IKE_LIVENESS_CHECK_SESSION_VALIDATED = 760,
+  ATOM_BLUETOOTH_HASHED_DEVICE_NAME_REPORTED = 613,
+  ATOM_BLUETOOTH_L2CAP_COC_CLIENT_CONNECTION = 614,
+  ATOM_BLUETOOTH_L2CAP_COC_SERVER_CONNECTION = 615,
+  ATOM_BLUETOOTH_LE_SESSION_CONNECTED = 656,
+  ATOM_RESTRICTED_BLUETOOTH_DEVICE_NAME_REPORTED = 666,
+  ATOM_BLUETOOTH_PROFILE_CONNECTION_ATTEMPTED = 696,
+  ATOM_HEALTH_CONNECT_UI_IMPRESSION = 623,
+  ATOM_HEALTH_CONNECT_UI_INTERACTION = 624,
+  ATOM_HEALTH_CONNECT_APP_OPENED_REPORTED = 625,
+  ATOM_HEALTH_CONNECT_API_CALLED = 616,
+  ATOM_HEALTH_CONNECT_USAGE_STATS = 617,
+  ATOM_HEALTH_CONNECT_STORAGE_STATS = 618,
+  ATOM_HEALTH_CONNECT_API_INVOKED = 643,
+  ATOM_EXERCISE_ROUTE_API_CALLED = 654,
+  ATOM_ATOM_9999 = 9999,
+  ATOM_ATOM_99999 = 99999,
+  ATOM_THREADNETWORK_TELEMETRY_DATA_REPORTED = 738,
+  ATOM_THREADNETWORK_TOPO_ENTRY_REPEATED = 739,
+  ATOM_THREADNETWORK_DEVICE_INFO_REPORTED = 740,
+  ATOM_EMERGENCY_NUMBER_DIALED = 637,
+  ATOM_SANDBOX_API_CALLED = 488,
+  ATOM_SANDBOX_ACTIVITY_EVENT_OCCURRED = 735,
+  ATOM_SANDBOX_SDK_STORAGE = 10159,
+  ATOM_CRONET_ENGINE_CREATED = 703,
+  ATOM_CRONET_TRAFFIC_REPORTED = 704,
+  ATOM_CRONET_ENGINE_BUILDER_INITIALIZED = 762,
+  ATOM_CRONET_HTTP_FLAGS_INITIALIZED = 763,
+  ATOM_CRONET_INITIALIZED = 764,
+  ATOM_DAILY_KEEPALIVE_INFO_REPORTED = 650,
+  ATOM_IP_CLIENT_RA_INFO_REPORTED = 778,
+  ATOM_APF_SESSION_INFO_REPORTED = 777,
+  ATOM_CREDENTIAL_MANAGER_API_CALLED = 585,
+  ATOM_CREDENTIAL_MANAGER_INIT_PHASE_REPORTED = 651,
+  ATOM_CREDENTIAL_MANAGER_CANDIDATE_PHASE_REPORTED = 652,
+  ATOM_CREDENTIAL_MANAGER_FINAL_PHASE_REPORTED = 653,
+  ATOM_CREDENTIAL_MANAGER_TOTAL_REPORTED = 667,
+  ATOM_CREDENTIAL_MANAGER_FINALNOUID_REPORTED = 668,
+  ATOM_CREDENTIAL_MANAGER_GET_REPORTED = 669,
+  ATOM_CREDENTIAL_MANAGER_AUTH_CLICK_REPORTED = 670,
+  ATOM_CREDENTIAL_MANAGER_APIV2_CALLED = 671,
+  ATOM_UWB_ACTIVITY_INFO = 10188,
+  ATOM_MEDIA_ACTION_REPORTED = 608,
+  ATOM_MEDIA_CONTROLS_LAUNCHED = 609,
+  ATOM_MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED = 600,
+  ATOM_MEDIA_CODEC_STARTED = 641,
+  ATOM_MEDIA_CODEC_STOPPED = 642,
+  ATOM_MEDIA_CODEC_RENDERED = 684,
+};
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STATSD_ATOM_IDS_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/statsd/statsd_tracing_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STATSD_STATSD_TRACING_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STATSD_STATSD_TRACING_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class StatsdPullAtomConfig;
+class StatsdTracingConfig;
+enum AtomId : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT StatsdPullAtomConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kPullAtomIdFieldNumber = 1,
+    kRawPullAtomIdFieldNumber = 2,
+    kPullFrequencyMsFieldNumber = 3,
+    kPackagesFieldNumber = 4,
+  };
+
+  StatsdPullAtomConfig();
+  ~StatsdPullAtomConfig() override;
+  StatsdPullAtomConfig(StatsdPullAtomConfig&&) noexcept;
+  StatsdPullAtomConfig& operator=(StatsdPullAtomConfig&&);
+  StatsdPullAtomConfig(const StatsdPullAtomConfig&);
+  StatsdPullAtomConfig& operator=(const StatsdPullAtomConfig&);
+  bool operator==(const StatsdPullAtomConfig&) const;
+  bool operator!=(const StatsdPullAtomConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<AtomId>& pull_atom_id() const { return pull_atom_id_; }
+  std::vector<AtomId>* mutable_pull_atom_id() { return &pull_atom_id_; }
+  int pull_atom_id_size() const { return static_cast<int>(pull_atom_id_.size()); }
+  void clear_pull_atom_id() { pull_atom_id_.clear(); }
+  void add_pull_atom_id(AtomId value) { pull_atom_id_.emplace_back(value); }
+  AtomId* add_pull_atom_id() { pull_atom_id_.emplace_back(); return &pull_atom_id_.back(); }
+
+  const std::vector<int32_t>& raw_pull_atom_id() const { return raw_pull_atom_id_; }
+  std::vector<int32_t>* mutable_raw_pull_atom_id() { return &raw_pull_atom_id_; }
+  int raw_pull_atom_id_size() const { return static_cast<int>(raw_pull_atom_id_.size()); }
+  void clear_raw_pull_atom_id() { raw_pull_atom_id_.clear(); }
+  void add_raw_pull_atom_id(int32_t value) { raw_pull_atom_id_.emplace_back(value); }
+  int32_t* add_raw_pull_atom_id() { raw_pull_atom_id_.emplace_back(); return &raw_pull_atom_id_.back(); }
+
+  bool has_pull_frequency_ms() const { return _has_field_[3]; }
+  int32_t pull_frequency_ms() const { return pull_frequency_ms_; }
+  void set_pull_frequency_ms(int32_t value) { pull_frequency_ms_ = value; _has_field_.set(3); }
+
+  const std::vector<std::string>& packages() const { return packages_; }
+  std::vector<std::string>* mutable_packages() { return &packages_; }
+  int packages_size() const { return static_cast<int>(packages_.size()); }
+  void clear_packages() { packages_.clear(); }
+  void add_packages(std::string value) { packages_.emplace_back(value); }
+  std::string* add_packages() { packages_.emplace_back(); return &packages_.back(); }
+
+ private:
+  std::vector<AtomId> pull_atom_id_;
+  std::vector<int32_t> raw_pull_atom_id_;
+  int32_t pull_frequency_ms_{};
+  std::vector<std::string> packages_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<5> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT StatsdTracingConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kPushAtomIdFieldNumber = 1,
+    kRawPushAtomIdFieldNumber = 2,
+    kPullConfigFieldNumber = 3,
+  };
+
+  StatsdTracingConfig();
+  ~StatsdTracingConfig() override;
+  StatsdTracingConfig(StatsdTracingConfig&&) noexcept;
+  StatsdTracingConfig& operator=(StatsdTracingConfig&&);
+  StatsdTracingConfig(const StatsdTracingConfig&);
+  StatsdTracingConfig& operator=(const StatsdTracingConfig&);
+  bool operator==(const StatsdTracingConfig&) const;
+  bool operator!=(const StatsdTracingConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<AtomId>& push_atom_id() const { return push_atom_id_; }
+  std::vector<AtomId>* mutable_push_atom_id() { return &push_atom_id_; }
+  int push_atom_id_size() const { return static_cast<int>(push_atom_id_.size()); }
+  void clear_push_atom_id() { push_atom_id_.clear(); }
+  void add_push_atom_id(AtomId value) { push_atom_id_.emplace_back(value); }
+  AtomId* add_push_atom_id() { push_atom_id_.emplace_back(); return &push_atom_id_.back(); }
+
+  const std::vector<int32_t>& raw_push_atom_id() const { return raw_push_atom_id_; }
+  std::vector<int32_t>* mutable_raw_push_atom_id() { return &raw_push_atom_id_; }
+  int raw_push_atom_id_size() const { return static_cast<int>(raw_push_atom_id_.size()); }
+  void clear_raw_push_atom_id() { raw_push_atom_id_.clear(); }
+  void add_raw_push_atom_id(int32_t value) { raw_push_atom_id_.emplace_back(value); }
+  int32_t* add_raw_push_atom_id() { raw_push_atom_id_.emplace_back(); return &raw_push_atom_id_.back(); }
+
+  const std::vector<StatsdPullAtomConfig>& pull_config() const { return pull_config_; }
+  std::vector<StatsdPullAtomConfig>* mutable_pull_config() { return &pull_config_; }
+  int pull_config_size() const;
+  void clear_pull_config();
+  StatsdPullAtomConfig* add_pull_config();
+
+ private:
+  std::vector<AtomId> push_atom_id_;
+  std::vector<int32_t> raw_push_atom_id_;
+  std::vector<StatsdPullAtomConfig> pull_config_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STATSD_STATSD_TRACING_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/sys_stats/sys_stats_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_SYS_STATS_SYS_STATS_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_SYS_STATS_SYS_STATS_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class SysStatsConfig;
+enum SysStatsConfig_StatCounters : int;
+enum MeminfoCounters : int;
+enum VmstatCounters : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum SysStatsConfig_StatCounters : int {
+  SysStatsConfig_StatCounters_STAT_UNSPECIFIED = 0,
+  SysStatsConfig_StatCounters_STAT_CPU_TIMES = 1,
+  SysStatsConfig_StatCounters_STAT_IRQ_COUNTS = 2,
+  SysStatsConfig_StatCounters_STAT_SOFTIRQ_COUNTS = 3,
+  SysStatsConfig_StatCounters_STAT_FORK_COUNT = 4,
+};
+
+class PERFETTO_EXPORT_COMPONENT SysStatsConfig : public ::protozero::CppMessageObj {
+ public:
+  using StatCounters = SysStatsConfig_StatCounters;
+  static constexpr auto STAT_UNSPECIFIED = SysStatsConfig_StatCounters_STAT_UNSPECIFIED;
+  static constexpr auto STAT_CPU_TIMES = SysStatsConfig_StatCounters_STAT_CPU_TIMES;
+  static constexpr auto STAT_IRQ_COUNTS = SysStatsConfig_StatCounters_STAT_IRQ_COUNTS;
+  static constexpr auto STAT_SOFTIRQ_COUNTS = SysStatsConfig_StatCounters_STAT_SOFTIRQ_COUNTS;
+  static constexpr auto STAT_FORK_COUNT = SysStatsConfig_StatCounters_STAT_FORK_COUNT;
+  static constexpr auto StatCounters_MIN = SysStatsConfig_StatCounters_STAT_UNSPECIFIED;
+  static constexpr auto StatCounters_MAX = SysStatsConfig_StatCounters_STAT_FORK_COUNT;
+  enum FieldNumbers {
+    kMeminfoPeriodMsFieldNumber = 1,
+    kMeminfoCountersFieldNumber = 2,
+    kVmstatPeriodMsFieldNumber = 3,
+    kVmstatCountersFieldNumber = 4,
+    kStatPeriodMsFieldNumber = 5,
+    kStatCountersFieldNumber = 6,
+    kDevfreqPeriodMsFieldNumber = 7,
+    kCpufreqPeriodMsFieldNumber = 8,
+    kBuddyinfoPeriodMsFieldNumber = 9,
+    kDiskstatPeriodMsFieldNumber = 10,
+    kPsiPeriodMsFieldNumber = 11,
+  };
+
+  SysStatsConfig();
+  ~SysStatsConfig() override;
+  SysStatsConfig(SysStatsConfig&&) noexcept;
+  SysStatsConfig& operator=(SysStatsConfig&&);
+  SysStatsConfig(const SysStatsConfig&);
+  SysStatsConfig& operator=(const SysStatsConfig&);
+  bool operator==(const SysStatsConfig&) const;
+  bool operator!=(const SysStatsConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_meminfo_period_ms() const { return _has_field_[1]; }
+  uint32_t meminfo_period_ms() const { return meminfo_period_ms_; }
+  void set_meminfo_period_ms(uint32_t value) { meminfo_period_ms_ = value; _has_field_.set(1); }
+
+  const std::vector<MeminfoCounters>& meminfo_counters() const { return meminfo_counters_; }
+  std::vector<MeminfoCounters>* mutable_meminfo_counters() { return &meminfo_counters_; }
+  int meminfo_counters_size() const { return static_cast<int>(meminfo_counters_.size()); }
+  void clear_meminfo_counters() { meminfo_counters_.clear(); }
+  void add_meminfo_counters(MeminfoCounters value) { meminfo_counters_.emplace_back(value); }
+  MeminfoCounters* add_meminfo_counters() { meminfo_counters_.emplace_back(); return &meminfo_counters_.back(); }
+
+  bool has_vmstat_period_ms() const { return _has_field_[3]; }
+  uint32_t vmstat_period_ms() const { return vmstat_period_ms_; }
+  void set_vmstat_period_ms(uint32_t value) { vmstat_period_ms_ = value; _has_field_.set(3); }
+
+  const std::vector<VmstatCounters>& vmstat_counters() const { return vmstat_counters_; }
+  std::vector<VmstatCounters>* mutable_vmstat_counters() { return &vmstat_counters_; }
+  int vmstat_counters_size() const { return static_cast<int>(vmstat_counters_.size()); }
+  void clear_vmstat_counters() { vmstat_counters_.clear(); }
+  void add_vmstat_counters(VmstatCounters value) { vmstat_counters_.emplace_back(value); }
+  VmstatCounters* add_vmstat_counters() { vmstat_counters_.emplace_back(); return &vmstat_counters_.back(); }
+
+  bool has_stat_period_ms() const { return _has_field_[5]; }
+  uint32_t stat_period_ms() const { return stat_period_ms_; }
+  void set_stat_period_ms(uint32_t value) { stat_period_ms_ = value; _has_field_.set(5); }
+
+  const std::vector<SysStatsConfig_StatCounters>& stat_counters() const { return stat_counters_; }
+  std::vector<SysStatsConfig_StatCounters>* mutable_stat_counters() { return &stat_counters_; }
+  int stat_counters_size() const { return static_cast<int>(stat_counters_.size()); }
+  void clear_stat_counters() { stat_counters_.clear(); }
+  void add_stat_counters(SysStatsConfig_StatCounters value) { stat_counters_.emplace_back(value); }
+  SysStatsConfig_StatCounters* add_stat_counters() { stat_counters_.emplace_back(); return &stat_counters_.back(); }
+
+  bool has_devfreq_period_ms() const { return _has_field_[7]; }
+  uint32_t devfreq_period_ms() const { return devfreq_period_ms_; }
+  void set_devfreq_period_ms(uint32_t value) { devfreq_period_ms_ = value; _has_field_.set(7); }
+
+  bool has_cpufreq_period_ms() const { return _has_field_[8]; }
+  uint32_t cpufreq_period_ms() const { return cpufreq_period_ms_; }
+  void set_cpufreq_period_ms(uint32_t value) { cpufreq_period_ms_ = value; _has_field_.set(8); }
+
+  bool has_buddyinfo_period_ms() const { return _has_field_[9]; }
+  uint32_t buddyinfo_period_ms() const { return buddyinfo_period_ms_; }
+  void set_buddyinfo_period_ms(uint32_t value) { buddyinfo_period_ms_ = value; _has_field_.set(9); }
+
+  bool has_diskstat_period_ms() const { return _has_field_[10]; }
+  uint32_t diskstat_period_ms() const { return diskstat_period_ms_; }
+  void set_diskstat_period_ms(uint32_t value) { diskstat_period_ms_ = value; _has_field_.set(10); }
+
+  bool has_psi_period_ms() const { return _has_field_[11]; }
+  uint32_t psi_period_ms() const { return psi_period_ms_; }
+  void set_psi_period_ms(uint32_t value) { psi_period_ms_ = value; _has_field_.set(11); }
+
+ private:
+  uint32_t meminfo_period_ms_{};
+  std::vector<MeminfoCounters> meminfo_counters_;
+  uint32_t vmstat_period_ms_{};
+  std::vector<VmstatCounters> vmstat_counters_;
+  uint32_t stat_period_ms_{};
+  std::vector<SysStatsConfig_StatCounters> stat_counters_;
+  uint32_t devfreq_period_ms_{};
+  uint32_t cpufreq_period_ms_{};
+  uint32_t buddyinfo_period_ms_{};
+  uint32_t diskstat_period_ms_{};
+  uint32_t psi_period_ms_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<12> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_SYS_STATS_SYS_STATS_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/system_info/system_info.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_SYSTEM_INFO_SYSTEM_INFO_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_SYSTEM_INFO_SYSTEM_INFO_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class SystemInfoConfig;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT SystemInfoConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  SystemInfoConfig();
+  ~SystemInfoConfig() override;
+  SystemInfoConfig(SystemInfoConfig&&) noexcept;
+  SystemInfoConfig& operator=(SystemInfoConfig&&);
+  SystemInfoConfig(const SystemInfoConfig&);
+  SystemInfoConfig& operator=(const SystemInfoConfig&);
+  bool operator==(const SystemInfoConfig&) const;
+  bool operator!=(const SystemInfoConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_SYSTEM_INFO_SYSTEM_INFO_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/chrome/chrome_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_CHROME_CHROME_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_CHROME_CHROME_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ChromeConfig;
+enum ChromeConfig_ClientPriority : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum ChromeConfig_ClientPriority : int {
+  ChromeConfig_ClientPriority_UNKNOWN = 0,
+  ChromeConfig_ClientPriority_BACKGROUND = 1,
+  ChromeConfig_ClientPriority_USER_INITIATED = 2,
+};
+
+class PERFETTO_EXPORT_COMPONENT ChromeConfig : public ::protozero::CppMessageObj {
+ public:
+  using ClientPriority = ChromeConfig_ClientPriority;
+  static constexpr auto UNKNOWN = ChromeConfig_ClientPriority_UNKNOWN;
+  static constexpr auto BACKGROUND = ChromeConfig_ClientPriority_BACKGROUND;
+  static constexpr auto USER_INITIATED = ChromeConfig_ClientPriority_USER_INITIATED;
+  static constexpr auto ClientPriority_MIN = ChromeConfig_ClientPriority_UNKNOWN;
+  static constexpr auto ClientPriority_MAX = ChromeConfig_ClientPriority_USER_INITIATED;
+  enum FieldNumbers {
+    kTraceConfigFieldNumber = 1,
+    kPrivacyFilteringEnabledFieldNumber = 2,
+    kConvertToLegacyJsonFieldNumber = 3,
+    kClientPriorityFieldNumber = 4,
+    kJsonAgentLabelFilterFieldNumber = 5,
+  };
+
+  ChromeConfig();
+  ~ChromeConfig() override;
+  ChromeConfig(ChromeConfig&&) noexcept;
+  ChromeConfig& operator=(ChromeConfig&&);
+  ChromeConfig(const ChromeConfig&);
+  ChromeConfig& operator=(const ChromeConfig&);
+  bool operator==(const ChromeConfig&) const;
+  bool operator!=(const ChromeConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_trace_config() const { return _has_field_[1]; }
+  const std::string& trace_config() const { return trace_config_; }
+  void set_trace_config(const std::string& value) { trace_config_ = value; _has_field_.set(1); }
+
+  bool has_privacy_filtering_enabled() const { return _has_field_[2]; }
+  bool privacy_filtering_enabled() const { return privacy_filtering_enabled_; }
+  void set_privacy_filtering_enabled(bool value) { privacy_filtering_enabled_ = value; _has_field_.set(2); }
+
+  bool has_convert_to_legacy_json() const { return _has_field_[3]; }
+  bool convert_to_legacy_json() const { return convert_to_legacy_json_; }
+  void set_convert_to_legacy_json(bool value) { convert_to_legacy_json_ = value; _has_field_.set(3); }
+
+  bool has_client_priority() const { return _has_field_[4]; }
+  ChromeConfig_ClientPriority client_priority() const { return client_priority_; }
+  void set_client_priority(ChromeConfig_ClientPriority value) { client_priority_ = value; _has_field_.set(4); }
+
+  bool has_json_agent_label_filter() const { return _has_field_[5]; }
+  const std::string& json_agent_label_filter() const { return json_agent_label_filter_; }
+  void set_json_agent_label_filter(const std::string& value) { json_agent_label_filter_ = value; _has_field_.set(5); }
+
+ private:
+  std::string trace_config_{};
+  bool privacy_filtering_enabled_{};
+  bool convert_to_legacy_json_{};
+  ChromeConfig_ClientPriority client_priority_{};
+  std::string json_agent_label_filter_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<6> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_CHROME_CHROME_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/chrome/scenario_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_CHROME_SCENARIO_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_CHROME_SCENARIO_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class TracingTriggerRulesConfig;
+class TriggerRule;
+class TriggerRule_RepeatingInterval;
+class TriggerRule_HistogramTrigger;
+class ChromeFieldTracingConfig;
+class ScenarioConfig;
+class NestedScenarioConfig;
+class TraceConfig;
+class TraceConfig_CmdTraceStartDelay;
+class TraceConfig_AndroidReportConfig;
+class TraceConfig_TraceFilter;
+class TraceConfig_TraceFilter_StringFilterChain;
+class TraceConfig_TraceFilter_StringFilterRule;
+class TraceConfig_IncidentReportConfig;
+class TraceConfig_IncrementalStateConfig;
+class TraceConfig_TriggerConfig;
+class TraceConfig_TriggerConfig_Trigger;
+class TraceConfig_GuardrailOverrides;
+class TraceConfig_StatsdMetadata;
+class TraceConfig_ProducerConfig;
+class TraceConfig_BuiltinDataSource;
+class TraceConfig_DataSource;
+class DataSourceConfig;
+class TestConfig;
+class TestConfig_DummyFields;
+class InterceptorConfig;
+class ConsoleConfig;
+class ChromeConfig;
+class SystemInfoConfig;
+class TraceConfig_BufferConfig;
+enum TraceConfig_LockdownModeOperation : int;
+enum TraceConfig_CompressionType : int;
+enum TraceConfig_StatsdLogging : int;
+enum TraceConfig_TraceFilter_StringFilterPolicy : int;
+enum TraceConfig_TriggerConfig_TriggerMode : int;
+enum BuiltinClock : int;
+enum DataSourceConfig_SessionInitiator : int;
+enum ConsoleConfig_Output : int;
+enum ChromeConfig_ClientPriority : int;
+enum TraceConfig_BufferConfig_FillPolicy : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT TracingTriggerRulesConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kRulesFieldNumber = 1,
+  };
+
+  TracingTriggerRulesConfig();
+  ~TracingTriggerRulesConfig() override;
+  TracingTriggerRulesConfig(TracingTriggerRulesConfig&&) noexcept;
+  TracingTriggerRulesConfig& operator=(TracingTriggerRulesConfig&&);
+  TracingTriggerRulesConfig(const TracingTriggerRulesConfig&);
+  TracingTriggerRulesConfig& operator=(const TracingTriggerRulesConfig&);
+  bool operator==(const TracingTriggerRulesConfig&) const;
+  bool operator!=(const TracingTriggerRulesConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<TriggerRule>& rules() const { return rules_; }
+  std::vector<TriggerRule>* mutable_rules() { return &rules_; }
+  int rules_size() const;
+  void clear_rules();
+  TriggerRule* add_rules();
+
+ private:
+  std::vector<TriggerRule> rules_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TriggerRule : public ::protozero::CppMessageObj {
+ public:
+  using HistogramTrigger = TriggerRule_HistogramTrigger;
+  using RepeatingInterval = TriggerRule_RepeatingInterval;
+  enum FieldNumbers {
+    kNameFieldNumber = 1,
+    kTriggerChanceFieldNumber = 2,
+    kDelayMsFieldNumber = 3,
+    kActivationDelayMsFieldNumber = 8,
+    kManualTriggerNameFieldNumber = 4,
+    kHistogramFieldNumber = 5,
+    kRepeatingIntervalFieldNumber = 6,
+  };
+
+  TriggerRule();
+  ~TriggerRule() override;
+  TriggerRule(TriggerRule&&) noexcept;
+  TriggerRule& operator=(TriggerRule&&);
+  TriggerRule(const TriggerRule&);
+  TriggerRule& operator=(const TriggerRule&);
+  bool operator==(const TriggerRule&) const;
+  bool operator!=(const TriggerRule& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name() const { return _has_field_[1]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
+
+  bool has_trigger_chance() const { return _has_field_[2]; }
+  float trigger_chance() const { return trigger_chance_; }
+  void set_trigger_chance(float value) { trigger_chance_ = value; _has_field_.set(2); }
+
+  bool has_delay_ms() const { return _has_field_[3]; }
+  uint64_t delay_ms() const { return delay_ms_; }
+  void set_delay_ms(uint64_t value) { delay_ms_ = value; _has_field_.set(3); }
+
+  bool has_activation_delay_ms() const { return _has_field_[8]; }
+  uint64_t activation_delay_ms() const { return activation_delay_ms_; }
+  void set_activation_delay_ms(uint64_t value) { activation_delay_ms_ = value; _has_field_.set(8); }
+
+  bool has_manual_trigger_name() const { return _has_field_[4]; }
+  const std::string& manual_trigger_name() const { return manual_trigger_name_; }
+  void set_manual_trigger_name(const std::string& value) { manual_trigger_name_ = value; _has_field_.set(4); }
+
+  bool has_histogram() const { return _has_field_[5]; }
+  const TriggerRule_HistogramTrigger& histogram() const { return *histogram_; }
+  TriggerRule_HistogramTrigger* mutable_histogram() { _has_field_.set(5); return histogram_.get(); }
+
+  bool has_repeating_interval() const { return _has_field_[6]; }
+  const TriggerRule_RepeatingInterval& repeating_interval() const { return *repeating_interval_; }
+  TriggerRule_RepeatingInterval* mutable_repeating_interval() { _has_field_.set(6); return repeating_interval_.get(); }
+
+ private:
+  std::string name_{};
+  float trigger_chance_{};
+  uint64_t delay_ms_{};
+  uint64_t activation_delay_ms_{};
+  std::string manual_trigger_name_{};
+  ::protozero::CopyablePtr<TriggerRule_HistogramTrigger> histogram_;
+  ::protozero::CopyablePtr<TriggerRule_RepeatingInterval> repeating_interval_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<9> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TriggerRule_RepeatingInterval : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kPeriodMsFieldNumber = 1,
+    kRandomizedFieldNumber = 2,
+  };
+
+  TriggerRule_RepeatingInterval();
+  ~TriggerRule_RepeatingInterval() override;
+  TriggerRule_RepeatingInterval(TriggerRule_RepeatingInterval&&) noexcept;
+  TriggerRule_RepeatingInterval& operator=(TriggerRule_RepeatingInterval&&);
+  TriggerRule_RepeatingInterval(const TriggerRule_RepeatingInterval&);
+  TriggerRule_RepeatingInterval& operator=(const TriggerRule_RepeatingInterval&);
+  bool operator==(const TriggerRule_RepeatingInterval&) const;
+  bool operator!=(const TriggerRule_RepeatingInterval& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_period_ms() const { return _has_field_[1]; }
+  uint64_t period_ms() const { return period_ms_; }
+  void set_period_ms(uint64_t value) { period_ms_ = value; _has_field_.set(1); }
+
+  bool has_randomized() const { return _has_field_[2]; }
+  bool randomized() const { return randomized_; }
+  void set_randomized(bool value) { randomized_ = value; _has_field_.set(2); }
+
+ private:
+  uint64_t period_ms_{};
+  bool randomized_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TriggerRule_HistogramTrigger : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kHistogramNameFieldNumber = 1,
+    kMinValueFieldNumber = 2,
+    kMaxValueFieldNumber = 3,
+  };
+
+  TriggerRule_HistogramTrigger();
+  ~TriggerRule_HistogramTrigger() override;
+  TriggerRule_HistogramTrigger(TriggerRule_HistogramTrigger&&) noexcept;
+  TriggerRule_HistogramTrigger& operator=(TriggerRule_HistogramTrigger&&);
+  TriggerRule_HistogramTrigger(const TriggerRule_HistogramTrigger&);
+  TriggerRule_HistogramTrigger& operator=(const TriggerRule_HistogramTrigger&);
+  bool operator==(const TriggerRule_HistogramTrigger&) const;
+  bool operator!=(const TriggerRule_HistogramTrigger& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_histogram_name() const { return _has_field_[1]; }
+  const std::string& histogram_name() const { return histogram_name_; }
+  void set_histogram_name(const std::string& value) { histogram_name_ = value; _has_field_.set(1); }
+
+  bool has_min_value() const { return _has_field_[2]; }
+  int64_t min_value() const { return min_value_; }
+  void set_min_value(int64_t value) { min_value_ = value; _has_field_.set(2); }
+
+  bool has_max_value() const { return _has_field_[3]; }
+  int64_t max_value() const { return max_value_; }
+  void set_max_value(int64_t value) { max_value_ = value; _has_field_.set(3); }
+
+ private:
+  std::string histogram_name_{};
+  int64_t min_value_{};
+  int64_t max_value_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT ChromeFieldTracingConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kScenariosFieldNumber = 1,
+  };
+
+  ChromeFieldTracingConfig();
+  ~ChromeFieldTracingConfig() override;
+  ChromeFieldTracingConfig(ChromeFieldTracingConfig&&) noexcept;
+  ChromeFieldTracingConfig& operator=(ChromeFieldTracingConfig&&);
+  ChromeFieldTracingConfig(const ChromeFieldTracingConfig&);
+  ChromeFieldTracingConfig& operator=(const ChromeFieldTracingConfig&);
+  bool operator==(const ChromeFieldTracingConfig&) const;
+  bool operator!=(const ChromeFieldTracingConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<ScenarioConfig>& scenarios() const { return scenarios_; }
+  std::vector<ScenarioConfig>* mutable_scenarios() { return &scenarios_; }
+  int scenarios_size() const;
+  void clear_scenarios();
+  ScenarioConfig* add_scenarios();
+
+ private:
+  std::vector<ScenarioConfig> scenarios_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT ScenarioConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kScenarioNameFieldNumber = 1,
+    kStartRulesFieldNumber = 2,
+    kStopRulesFieldNumber = 3,
+    kUploadRulesFieldNumber = 4,
+    kSetupRulesFieldNumber = 5,
+    kTraceConfigFieldNumber = 6,
+    kNestedScenariosFieldNumber = 7,
+  };
+
+  ScenarioConfig();
+  ~ScenarioConfig() override;
+  ScenarioConfig(ScenarioConfig&&) noexcept;
+  ScenarioConfig& operator=(ScenarioConfig&&);
+  ScenarioConfig(const ScenarioConfig&);
+  ScenarioConfig& operator=(const ScenarioConfig&);
+  bool operator==(const ScenarioConfig&) const;
+  bool operator!=(const ScenarioConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_scenario_name() const { return _has_field_[1]; }
+  const std::string& scenario_name() const { return scenario_name_; }
+  void set_scenario_name(const std::string& value) { scenario_name_ = value; _has_field_.set(1); }
+
+  const std::vector<TriggerRule>& start_rules() const { return start_rules_; }
+  std::vector<TriggerRule>* mutable_start_rules() { return &start_rules_; }
+  int start_rules_size() const;
+  void clear_start_rules();
+  TriggerRule* add_start_rules();
+
+  const std::vector<TriggerRule>& stop_rules() const { return stop_rules_; }
+  std::vector<TriggerRule>* mutable_stop_rules() { return &stop_rules_; }
+  int stop_rules_size() const;
+  void clear_stop_rules();
+  TriggerRule* add_stop_rules();
+
+  const std::vector<TriggerRule>& upload_rules() const { return upload_rules_; }
+  std::vector<TriggerRule>* mutable_upload_rules() { return &upload_rules_; }
+  int upload_rules_size() const;
+  void clear_upload_rules();
+  TriggerRule* add_upload_rules();
+
+  const std::vector<TriggerRule>& setup_rules() const { return setup_rules_; }
+  std::vector<TriggerRule>* mutable_setup_rules() { return &setup_rules_; }
+  int setup_rules_size() const;
+  void clear_setup_rules();
+  TriggerRule* add_setup_rules();
+
+  bool has_trace_config() const { return _has_field_[6]; }
+  const TraceConfig& trace_config() const { return *trace_config_; }
+  TraceConfig* mutable_trace_config() { _has_field_.set(6); return trace_config_.get(); }
+
+  const std::vector<NestedScenarioConfig>& nested_scenarios() const { return nested_scenarios_; }
+  std::vector<NestedScenarioConfig>* mutable_nested_scenarios() { return &nested_scenarios_; }
+  int nested_scenarios_size() const;
+  void clear_nested_scenarios();
+  NestedScenarioConfig* add_nested_scenarios();
+
+ private:
+  std::string scenario_name_{};
+  std::vector<TriggerRule> start_rules_;
+  std::vector<TriggerRule> stop_rules_;
+  std::vector<TriggerRule> upload_rules_;
+  std::vector<TriggerRule> setup_rules_;
+  ::protozero::CopyablePtr<TraceConfig> trace_config_;
+  std::vector<NestedScenarioConfig> nested_scenarios_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<8> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT NestedScenarioConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kScenarioNameFieldNumber = 1,
+    kStartRulesFieldNumber = 2,
+    kStopRulesFieldNumber = 3,
+    kUploadRulesFieldNumber = 4,
+  };
+
+  NestedScenarioConfig();
+  ~NestedScenarioConfig() override;
+  NestedScenarioConfig(NestedScenarioConfig&&) noexcept;
+  NestedScenarioConfig& operator=(NestedScenarioConfig&&);
+  NestedScenarioConfig(const NestedScenarioConfig&);
+  NestedScenarioConfig& operator=(const NestedScenarioConfig&);
+  bool operator==(const NestedScenarioConfig&) const;
+  bool operator!=(const NestedScenarioConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_scenario_name() const { return _has_field_[1]; }
+  const std::string& scenario_name() const { return scenario_name_; }
+  void set_scenario_name(const std::string& value) { scenario_name_ = value; _has_field_.set(1); }
+
+  const std::vector<TriggerRule>& start_rules() const { return start_rules_; }
+  std::vector<TriggerRule>* mutable_start_rules() { return &start_rules_; }
+  int start_rules_size() const;
+  void clear_start_rules();
+  TriggerRule* add_start_rules();
+
+  const std::vector<TriggerRule>& stop_rules() const { return stop_rules_; }
+  std::vector<TriggerRule>* mutable_stop_rules() { return &stop_rules_; }
+  int stop_rules_size() const;
+  void clear_stop_rules();
+  TriggerRule* add_stop_rules();
+
+  const std::vector<TriggerRule>& upload_rules() const { return upload_rules_; }
+  std::vector<TriggerRule>* mutable_upload_rules() { return &upload_rules_; }
+  int upload_rules_size() const;
+  void clear_upload_rules();
+  TriggerRule* add_upload_rules();
+
+ private:
+  std::string scenario_name_{};
+  std::vector<TriggerRule> start_rules_;
+  std::vector<TriggerRule> stop_rules_;
+  std::vector<TriggerRule> upload_rules_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<5> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_CHROME_SCENARIO_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/chrome/v8_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_CHROME_V8_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_CHROME_V8_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class V8Config;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT V8Config : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kLogScriptSourcesFieldNumber = 1,
+    kLogInstructionsFieldNumber = 2,
+  };
+
+  V8Config();
+  ~V8Config() override;
+  V8Config(V8Config&&) noexcept;
+  V8Config& operator=(V8Config&&);
+  V8Config(const V8Config&);
+  V8Config& operator=(const V8Config&);
+  bool operator==(const V8Config&) const;
+  bool operator!=(const V8Config& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_log_script_sources() const { return _has_field_[1]; }
+  bool log_script_sources() const { return log_script_sources_; }
+  void set_log_script_sources(bool value) { log_script_sources_ = value; _has_field_.set(1); }
+
+  bool has_log_instructions() const { return _has_field_[2]; }
+  bool log_instructions() const { return log_instructions_; }
+  void set_log_instructions(bool value) { log_instructions_ = value; _has_field_.set(2); }
+
+ private:
+  bool log_script_sources_{};
+  bool log_instructions_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_CHROME_V8_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/etw/etw_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ETW_ETW_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ETW_ETW_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class EtwConfig;
+enum EtwConfig_KernelFlag : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum EtwConfig_KernelFlag : int {
+  EtwConfig_KernelFlag_CSWITCH = 0,
+  EtwConfig_KernelFlag_DISPATCHER = 1,
+};
+
+class PERFETTO_EXPORT_COMPONENT EtwConfig : public ::protozero::CppMessageObj {
+ public:
+  using KernelFlag = EtwConfig_KernelFlag;
+  static constexpr auto CSWITCH = EtwConfig_KernelFlag_CSWITCH;
+  static constexpr auto DISPATCHER = EtwConfig_KernelFlag_DISPATCHER;
+  static constexpr auto KernelFlag_MIN = EtwConfig_KernelFlag_CSWITCH;
+  static constexpr auto KernelFlag_MAX = EtwConfig_KernelFlag_DISPATCHER;
+  enum FieldNumbers {
+    kKernelFlagsFieldNumber = 1,
+  };
+
+  EtwConfig();
+  ~EtwConfig() override;
+  EtwConfig(EtwConfig&&) noexcept;
+  EtwConfig& operator=(EtwConfig&&);
+  EtwConfig(const EtwConfig&);
+  EtwConfig& operator=(const EtwConfig&);
+  bool operator==(const EtwConfig&) const;
+  bool operator!=(const EtwConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<EtwConfig_KernelFlag>& kernel_flags() const { return kernel_flags_; }
+  std::vector<EtwConfig_KernelFlag>* mutable_kernel_flags() { return &kernel_flags_; }
+  int kernel_flags_size() const { return static_cast<int>(kernel_flags_.size()); }
+  void clear_kernel_flags() { kernel_flags_.clear(); }
+  void add_kernel_flags(EtwConfig_KernelFlag value) { kernel_flags_.emplace_back(value); }
+  EtwConfig_KernelFlag* add_kernel_flags() { kernel_flags_.emplace_back(); return &kernel_flags_.back(); }
+
+ private:
+  std::vector<EtwConfig_KernelFlag> kernel_flags_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ETW_ETW_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/interceptor_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INTERCEPTOR_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INTERCEPTOR_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class InterceptorConfig;
+class ConsoleConfig;
+enum ConsoleConfig_Output : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT InterceptorConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kNameFieldNumber = 1,
+    kConsoleConfigFieldNumber = 100,
+  };
+
+  InterceptorConfig();
+  ~InterceptorConfig() override;
+  InterceptorConfig(InterceptorConfig&&) noexcept;
+  InterceptorConfig& operator=(InterceptorConfig&&);
+  InterceptorConfig(const InterceptorConfig&);
+  InterceptorConfig& operator=(const InterceptorConfig&);
+  bool operator==(const InterceptorConfig&) const;
+  bool operator!=(const InterceptorConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name() const { return _has_field_[1]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
+
+  bool has_console_config() const { return _has_field_[100]; }
+  const ConsoleConfig& console_config() const { return *console_config_; }
+  ConsoleConfig* mutable_console_config() { _has_field_.set(100); return console_config_.get(); }
+
+ private:
+  std::string name_{};
+  ::protozero::CopyablePtr<ConsoleConfig> console_config_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<101> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INTERCEPTOR_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/stress_test_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STRESS_TEST_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STRESS_TEST_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class StressTestConfig;
+class StressTestConfig_WriterTiming;
+class TraceConfig;
+class TraceConfig_CmdTraceStartDelay;
+class TraceConfig_AndroidReportConfig;
+class TraceConfig_TraceFilter;
+class TraceConfig_TraceFilter_StringFilterChain;
+class TraceConfig_TraceFilter_StringFilterRule;
+class TraceConfig_IncidentReportConfig;
+class TraceConfig_IncrementalStateConfig;
+class TraceConfig_TriggerConfig;
+class TraceConfig_TriggerConfig_Trigger;
+class TraceConfig_GuardrailOverrides;
+class TraceConfig_StatsdMetadata;
+class TraceConfig_ProducerConfig;
+class TraceConfig_BuiltinDataSource;
+class TraceConfig_DataSource;
+class DataSourceConfig;
+class TestConfig;
+class TestConfig_DummyFields;
+class InterceptorConfig;
+class ConsoleConfig;
+class ChromeConfig;
+class SystemInfoConfig;
+class TraceConfig_BufferConfig;
+enum TraceConfig_LockdownModeOperation : int;
+enum TraceConfig_CompressionType : int;
+enum TraceConfig_StatsdLogging : int;
+enum TraceConfig_TraceFilter_StringFilterPolicy : int;
+enum TraceConfig_TriggerConfig_TriggerMode : int;
+enum BuiltinClock : int;
+enum DataSourceConfig_SessionInitiator : int;
+enum ConsoleConfig_Output : int;
+enum ChromeConfig_ClientPriority : int;
+enum TraceConfig_BufferConfig_FillPolicy : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT StressTestConfig : public ::protozero::CppMessageObj {
+ public:
+  using WriterTiming = StressTestConfig_WriterTiming;
+  enum FieldNumbers {
+    kTraceConfigFieldNumber = 1,
+    kShmemSizeKbFieldNumber = 2,
+    kShmemPageSizeKbFieldNumber = 3,
+    kNumProcessesFieldNumber = 4,
+    kNumThreadsFieldNumber = 5,
+    kMaxEventsFieldNumber = 6,
+    kNestingFieldNumber = 7,
+    kSteadyStateTimingsFieldNumber = 8,
+    kBurstPeriodMsFieldNumber = 9,
+    kBurstDurationMsFieldNumber = 10,
+    kBurstTimingsFieldNumber = 11,
+  };
+
+  StressTestConfig();
+  ~StressTestConfig() override;
+  StressTestConfig(StressTestConfig&&) noexcept;
+  StressTestConfig& operator=(StressTestConfig&&);
+  StressTestConfig(const StressTestConfig&);
+  StressTestConfig& operator=(const StressTestConfig&);
+  bool operator==(const StressTestConfig&) const;
+  bool operator!=(const StressTestConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_trace_config() const { return _has_field_[1]; }
+  const TraceConfig& trace_config() const { return *trace_config_; }
+  TraceConfig* mutable_trace_config() { _has_field_.set(1); return trace_config_.get(); }
+
+  bool has_shmem_size_kb() const { return _has_field_[2]; }
+  uint32_t shmem_size_kb() const { return shmem_size_kb_; }
+  void set_shmem_size_kb(uint32_t value) { shmem_size_kb_ = value; _has_field_.set(2); }
+
+  bool has_shmem_page_size_kb() const { return _has_field_[3]; }
+  uint32_t shmem_page_size_kb() const { return shmem_page_size_kb_; }
+  void set_shmem_page_size_kb(uint32_t value) { shmem_page_size_kb_ = value; _has_field_.set(3); }
+
+  bool has_num_processes() const { return _has_field_[4]; }
+  uint32_t num_processes() const { return num_processes_; }
+  void set_num_processes(uint32_t value) { num_processes_ = value; _has_field_.set(4); }
+
+  bool has_num_threads() const { return _has_field_[5]; }
+  uint32_t num_threads() const { return num_threads_; }
+  void set_num_threads(uint32_t value) { num_threads_ = value; _has_field_.set(5); }
+
+  bool has_max_events() const { return _has_field_[6]; }
+  uint32_t max_events() const { return max_events_; }
+  void set_max_events(uint32_t value) { max_events_ = value; _has_field_.set(6); }
+
+  bool has_nesting() const { return _has_field_[7]; }
+  uint32_t nesting() const { return nesting_; }
+  void set_nesting(uint32_t value) { nesting_ = value; _has_field_.set(7); }
+
+  bool has_steady_state_timings() const { return _has_field_[8]; }
+  const StressTestConfig_WriterTiming& steady_state_timings() const { return *steady_state_timings_; }
+  StressTestConfig_WriterTiming* mutable_steady_state_timings() { _has_field_.set(8); return steady_state_timings_.get(); }
+
+  bool has_burst_period_ms() const { return _has_field_[9]; }
+  uint32_t burst_period_ms() const { return burst_period_ms_; }
+  void set_burst_period_ms(uint32_t value) { burst_period_ms_ = value; _has_field_.set(9); }
+
+  bool has_burst_duration_ms() const { return _has_field_[10]; }
+  uint32_t burst_duration_ms() const { return burst_duration_ms_; }
+  void set_burst_duration_ms(uint32_t value) { burst_duration_ms_ = value; _has_field_.set(10); }
+
+  bool has_burst_timings() const { return _has_field_[11]; }
+  const StressTestConfig_WriterTiming& burst_timings() const { return *burst_timings_; }
+  StressTestConfig_WriterTiming* mutable_burst_timings() { _has_field_.set(11); return burst_timings_.get(); }
+
+ private:
+  ::protozero::CopyablePtr<TraceConfig> trace_config_;
+  uint32_t shmem_size_kb_{};
+  uint32_t shmem_page_size_kb_{};
+  uint32_t num_processes_{};
+  uint32_t num_threads_{};
+  uint32_t max_events_{};
+  uint32_t nesting_{};
+  ::protozero::CopyablePtr<StressTestConfig_WriterTiming> steady_state_timings_;
+  uint32_t burst_period_ms_{};
+  uint32_t burst_duration_ms_{};
+  ::protozero::CopyablePtr<StressTestConfig_WriterTiming> burst_timings_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<12> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT StressTestConfig_WriterTiming : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kPayloadMeanFieldNumber = 1,
+    kPayloadStddevFieldNumber = 2,
+    kRateMeanFieldNumber = 3,
+    kRateStddevFieldNumber = 4,
+    kPayloadWriteTimeMsFieldNumber = 5,
+  };
+
+  StressTestConfig_WriterTiming();
+  ~StressTestConfig_WriterTiming() override;
+  StressTestConfig_WriterTiming(StressTestConfig_WriterTiming&&) noexcept;
+  StressTestConfig_WriterTiming& operator=(StressTestConfig_WriterTiming&&);
+  StressTestConfig_WriterTiming(const StressTestConfig_WriterTiming&);
+  StressTestConfig_WriterTiming& operator=(const StressTestConfig_WriterTiming&);
+  bool operator==(const StressTestConfig_WriterTiming&) const;
+  bool operator!=(const StressTestConfig_WriterTiming& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_payload_mean() const { return _has_field_[1]; }
+  double payload_mean() const { return payload_mean_; }
+  void set_payload_mean(double value) { payload_mean_ = value; _has_field_.set(1); }
+
+  bool has_payload_stddev() const { return _has_field_[2]; }
+  double payload_stddev() const { return payload_stddev_; }
+  void set_payload_stddev(double value) { payload_stddev_ = value; _has_field_.set(2); }
+
+  bool has_rate_mean() const { return _has_field_[3]; }
+  double rate_mean() const { return rate_mean_; }
+  void set_rate_mean(double value) { rate_mean_ = value; _has_field_.set(3); }
+
+  bool has_rate_stddev() const { return _has_field_[4]; }
+  double rate_stddev() const { return rate_stddev_; }
+  void set_rate_stddev(double value) { rate_stddev_ = value; _has_field_.set(4); }
+
+  bool has_payload_write_time_ms() const { return _has_field_[5]; }
+  uint32_t payload_write_time_ms() const { return payload_write_time_ms_; }
+  void set_payload_write_time_ms(uint32_t value) { payload_write_time_ms_ = value; _has_field_.set(5); }
+
+ private:
+  double payload_mean_{};
+  double payload_stddev_{};
+  double rate_mean_{};
+  double rate_stddev_{};
+  uint32_t payload_write_time_ms_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<6> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STRESS_TEST_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/test_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TEST_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TEST_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class TestConfig;
+class TestConfig_DummyFields;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT TestConfig : public ::protozero::CppMessageObj {
+ public:
+  using DummyFields = TestConfig_DummyFields;
+  enum FieldNumbers {
+    kMessageCountFieldNumber = 1,
+    kMaxMessagesPerSecondFieldNumber = 2,
+    kSeedFieldNumber = 3,
+    kMessageSizeFieldNumber = 4,
+    kSendBatchOnRegisterFieldNumber = 5,
+    kDummyFieldsFieldNumber = 6,
+  };
+
+  TestConfig();
+  ~TestConfig() override;
+  TestConfig(TestConfig&&) noexcept;
+  TestConfig& operator=(TestConfig&&);
+  TestConfig(const TestConfig&);
+  TestConfig& operator=(const TestConfig&);
+  bool operator==(const TestConfig&) const;
+  bool operator!=(const TestConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_message_count() const { return _has_field_[1]; }
+  uint32_t message_count() const { return message_count_; }
+  void set_message_count(uint32_t value) { message_count_ = value; _has_field_.set(1); }
+
+  bool has_max_messages_per_second() const { return _has_field_[2]; }
+  uint32_t max_messages_per_second() const { return max_messages_per_second_; }
+  void set_max_messages_per_second(uint32_t value) { max_messages_per_second_ = value; _has_field_.set(2); }
+
+  bool has_seed() const { return _has_field_[3]; }
+  uint32_t seed() const { return seed_; }
+  void set_seed(uint32_t value) { seed_ = value; _has_field_.set(3); }
+
+  bool has_message_size() const { return _has_field_[4]; }
+  uint32_t message_size() const { return message_size_; }
+  void set_message_size(uint32_t value) { message_size_ = value; _has_field_.set(4); }
+
+  bool has_send_batch_on_register() const { return _has_field_[5]; }
+  bool send_batch_on_register() const { return send_batch_on_register_; }
+  void set_send_batch_on_register(bool value) { send_batch_on_register_ = value; _has_field_.set(5); }
+
+  bool has_dummy_fields() const { return _has_field_[6]; }
+  const TestConfig_DummyFields& dummy_fields() const { return *dummy_fields_; }
+  TestConfig_DummyFields* mutable_dummy_fields() { _has_field_.set(6); return dummy_fields_.get(); }
+
+ private:
+  uint32_t message_count_{};
+  uint32_t max_messages_per_second_{};
+  uint32_t seed_{};
+  uint32_t message_size_{};
+  bool send_batch_on_register_{};
+  ::protozero::CopyablePtr<TestConfig_DummyFields> dummy_fields_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<7> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TestConfig_DummyFields : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kFieldUint32FieldNumber = 1,
+    kFieldInt32FieldNumber = 2,
+    kFieldUint64FieldNumber = 3,
+    kFieldInt64FieldNumber = 4,
+    kFieldFixed64FieldNumber = 5,
+    kFieldSfixed64FieldNumber = 6,
+    kFieldFixed32FieldNumber = 7,
+    kFieldSfixed32FieldNumber = 8,
+    kFieldDoubleFieldNumber = 9,
+    kFieldFloatFieldNumber = 10,
+    kFieldSint64FieldNumber = 11,
+    kFieldSint32FieldNumber = 12,
+    kFieldStringFieldNumber = 13,
+    kFieldBytesFieldNumber = 14,
+  };
+
+  TestConfig_DummyFields();
+  ~TestConfig_DummyFields() override;
+  TestConfig_DummyFields(TestConfig_DummyFields&&) noexcept;
+  TestConfig_DummyFields& operator=(TestConfig_DummyFields&&);
+  TestConfig_DummyFields(const TestConfig_DummyFields&);
+  TestConfig_DummyFields& operator=(const TestConfig_DummyFields&);
+  bool operator==(const TestConfig_DummyFields&) const;
+  bool operator!=(const TestConfig_DummyFields& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_field_uint32() const { return _has_field_[1]; }
+  uint32_t field_uint32() const { return field_uint32_; }
+  void set_field_uint32(uint32_t value) { field_uint32_ = value; _has_field_.set(1); }
+
+  bool has_field_int32() const { return _has_field_[2]; }
+  int32_t field_int32() const { return field_int32_; }
+  void set_field_int32(int32_t value) { field_int32_ = value; _has_field_.set(2); }
+
+  bool has_field_uint64() const { return _has_field_[3]; }
+  uint64_t field_uint64() const { return field_uint64_; }
+  void set_field_uint64(uint64_t value) { field_uint64_ = value; _has_field_.set(3); }
+
+  bool has_field_int64() const { return _has_field_[4]; }
+  int64_t field_int64() const { return field_int64_; }
+  void set_field_int64(int64_t value) { field_int64_ = value; _has_field_.set(4); }
+
+  bool has_field_fixed64() const { return _has_field_[5]; }
+  uint64_t field_fixed64() const { return field_fixed64_; }
+  void set_field_fixed64(uint64_t value) { field_fixed64_ = value; _has_field_.set(5); }
+
+  bool has_field_sfixed64() const { return _has_field_[6]; }
+  int64_t field_sfixed64() const { return field_sfixed64_; }
+  void set_field_sfixed64(int64_t value) { field_sfixed64_ = value; _has_field_.set(6); }
+
+  bool has_field_fixed32() const { return _has_field_[7]; }
+  uint32_t field_fixed32() const { return field_fixed32_; }
+  void set_field_fixed32(uint32_t value) { field_fixed32_ = value; _has_field_.set(7); }
+
+  bool has_field_sfixed32() const { return _has_field_[8]; }
+  int32_t field_sfixed32() const { return field_sfixed32_; }
+  void set_field_sfixed32(int32_t value) { field_sfixed32_ = value; _has_field_.set(8); }
+
+  bool has_field_double() const { return _has_field_[9]; }
+  double field_double() const { return field_double_; }
+  void set_field_double(double value) { field_double_ = value; _has_field_.set(9); }
+
+  bool has_field_float() const { return _has_field_[10]; }
+  float field_float() const { return field_float_; }
+  void set_field_float(float value) { field_float_ = value; _has_field_.set(10); }
+
+  bool has_field_sint64() const { return _has_field_[11]; }
+  int64_t field_sint64() const { return field_sint64_; }
+  void set_field_sint64(int64_t value) { field_sint64_ = value; _has_field_.set(11); }
+
+  bool has_field_sint32() const { return _has_field_[12]; }
+  int32_t field_sint32() const { return field_sint32_; }
+  void set_field_sint32(int32_t value) { field_sint32_ = value; _has_field_.set(12); }
+
+  bool has_field_string() const { return _has_field_[13]; }
+  const std::string& field_string() const { return field_string_; }
+  void set_field_string(const std::string& value) { field_string_ = value; _has_field_.set(13); }
+
+  bool has_field_bytes() const { return _has_field_[14]; }
+  const std::string& field_bytes() const { return field_bytes_; }
+  void set_field_bytes(const std::string& value) { field_bytes_ = value; _has_field_.set(14); }
+  void set_field_bytes(const void* p, size_t s) { field_bytes_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(14); }
+
+ private:
+  uint32_t field_uint32_{};
+  int32_t field_int32_{};
+  uint64_t field_uint64_{};
+  int64_t field_int64_{};
+  uint64_t field_fixed64_{};
+  int64_t field_sfixed64_{};
+  uint32_t field_fixed32_{};
+  int32_t field_sfixed32_{};
+  double field_double_{};
+  float field_float_{};
+  int64_t field_sint64_{};
+  int32_t field_sint32_{};
+  std::string field_string_{};
+  std::string field_bytes_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<15> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TEST_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/android_game_intervention_list_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_GAME_INTERVENTION_LIST_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_GAME_INTERVENTION_LIST_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class AndroidGameInterventionListConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AndroidGameInterventionListConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidGameInterventionListConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidGameInterventionListConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_package_name_filter() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> package_name_filter() const { return GetRepeated<::protozero::ConstChars>(1); }
+};
+
+class AndroidGameInterventionListConfig : public ::protozero::Message {
+ public:
+  using Decoder = AndroidGameInterventionListConfig_Decoder;
+  enum : int32_t {
+    kPackageNameFilterFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidGameInterventionListConfig"; }
+
+
+  using FieldMetadata_PackageNameFilter =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidGameInterventionListConfig>;
+
+  static constexpr FieldMetadata_PackageNameFilter kPackageNameFilter{};
+  void add_package_name_filter(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_PackageNameFilter::kFieldId, data, size);
+  }
+  void add_package_name_filter(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_PackageNameFilter::kFieldId, chars.data, chars.size);
+  }
+  void add_package_name_filter(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_PackageNameFilter::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/android_input_event_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_INPUT_EVENT_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_INPUT_EVENT_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class AndroidInputEventConfig_TraceRule;
+namespace perfetto_pbzero_enum_AndroidInputEventConfig {
+enum TraceLevel : int32_t;
+}  // namespace perfetto_pbzero_enum_AndroidInputEventConfig
+using AndroidInputEventConfig_TraceLevel = perfetto_pbzero_enum_AndroidInputEventConfig::TraceLevel;
+namespace perfetto_pbzero_enum_AndroidInputEventConfig {
+enum TraceMode : int32_t;
+}  // namespace perfetto_pbzero_enum_AndroidInputEventConfig
+using AndroidInputEventConfig_TraceMode = perfetto_pbzero_enum_AndroidInputEventConfig::TraceMode;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_AndroidInputEventConfig {
+enum TraceMode : int32_t {
+  TRACE_MODE_TRACE_ALL = 0,
+  TRACE_MODE_USE_RULES = 1,
+};
+} // namespace perfetto_pbzero_enum_AndroidInputEventConfig
+using AndroidInputEventConfig_TraceMode = perfetto_pbzero_enum_AndroidInputEventConfig::TraceMode;
+
+
+constexpr AndroidInputEventConfig_TraceMode AndroidInputEventConfig_TraceMode_MIN = AndroidInputEventConfig_TraceMode::TRACE_MODE_TRACE_ALL;
+constexpr AndroidInputEventConfig_TraceMode AndroidInputEventConfig_TraceMode_MAX = AndroidInputEventConfig_TraceMode::TRACE_MODE_USE_RULES;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* AndroidInputEventConfig_TraceMode_Name(::perfetto::protos::pbzero::AndroidInputEventConfig_TraceMode value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::AndroidInputEventConfig_TraceMode::TRACE_MODE_TRACE_ALL:
+    return "TRACE_MODE_TRACE_ALL";
+
+  case ::perfetto::protos::pbzero::AndroidInputEventConfig_TraceMode::TRACE_MODE_USE_RULES:
+    return "TRACE_MODE_USE_RULES";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_AndroidInputEventConfig {
+enum TraceLevel : int32_t {
+  TRACE_LEVEL_NONE = 0,
+  TRACE_LEVEL_REDACTED = 1,
+  TRACE_LEVEL_COMPLETE = 2,
+};
+} // namespace perfetto_pbzero_enum_AndroidInputEventConfig
+using AndroidInputEventConfig_TraceLevel = perfetto_pbzero_enum_AndroidInputEventConfig::TraceLevel;
+
+
+constexpr AndroidInputEventConfig_TraceLevel AndroidInputEventConfig_TraceLevel_MIN = AndroidInputEventConfig_TraceLevel::TRACE_LEVEL_NONE;
+constexpr AndroidInputEventConfig_TraceLevel AndroidInputEventConfig_TraceLevel_MAX = AndroidInputEventConfig_TraceLevel::TRACE_LEVEL_COMPLETE;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* AndroidInputEventConfig_TraceLevel_Name(::perfetto::protos::pbzero::AndroidInputEventConfig_TraceLevel value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::AndroidInputEventConfig_TraceLevel::TRACE_LEVEL_NONE:
+    return "TRACE_LEVEL_NONE";
+
+  case ::perfetto::protos::pbzero::AndroidInputEventConfig_TraceLevel::TRACE_LEVEL_REDACTED:
+    return "TRACE_LEVEL_REDACTED";
+
+  case ::perfetto::protos::pbzero::AndroidInputEventConfig_TraceLevel::TRACE_LEVEL_COMPLETE:
+    return "TRACE_LEVEL_COMPLETE";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class AndroidInputEventConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AndroidInputEventConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidInputEventConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidInputEventConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_mode() const { return at<1>().valid(); }
+  int32_t mode() const { return at<1>().as_int32(); }
+  bool has_rules() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> rules() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_trace_dispatcher_input_events() const { return at<3>().valid(); }
+  bool trace_dispatcher_input_events() const { return at<3>().as_bool(); }
+  bool has_trace_dispatcher_window_dispatch() const { return at<4>().valid(); }
+  bool trace_dispatcher_window_dispatch() const { return at<4>().as_bool(); }
+};
+
+class AndroidInputEventConfig : public ::protozero::Message {
+ public:
+  using Decoder = AndroidInputEventConfig_Decoder;
+  enum : int32_t {
+    kModeFieldNumber = 1,
+    kRulesFieldNumber = 2,
+    kTraceDispatcherInputEventsFieldNumber = 3,
+    kTraceDispatcherWindowDispatchFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidInputEventConfig"; }
+
+  using TraceRule = ::perfetto::protos::pbzero::AndroidInputEventConfig_TraceRule;
+
+  using TraceMode = ::perfetto::protos::pbzero::AndroidInputEventConfig_TraceMode;
+  static inline const char* TraceMode_Name(TraceMode value) {
+    return ::perfetto::protos::pbzero::AndroidInputEventConfig_TraceMode_Name(value);
+  }
+
+  using TraceLevel = ::perfetto::protos::pbzero::AndroidInputEventConfig_TraceLevel;
+  static inline const char* TraceLevel_Name(TraceLevel value) {
+    return ::perfetto::protos::pbzero::AndroidInputEventConfig_TraceLevel_Name(value);
+  }
+  static inline const TraceMode TRACE_MODE_TRACE_ALL = TraceMode::TRACE_MODE_TRACE_ALL;
+  static inline const TraceMode TRACE_MODE_USE_RULES = TraceMode::TRACE_MODE_USE_RULES;
+  static inline const TraceLevel TRACE_LEVEL_NONE = TraceLevel::TRACE_LEVEL_NONE;
+  static inline const TraceLevel TRACE_LEVEL_REDACTED = TraceLevel::TRACE_LEVEL_REDACTED;
+  static inline const TraceLevel TRACE_LEVEL_COMPLETE = TraceLevel::TRACE_LEVEL_COMPLETE;
+
+  using FieldMetadata_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      AndroidInputEventConfig_TraceMode,
+      AndroidInputEventConfig>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(AndroidInputEventConfig_TraceMode value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::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_Rules =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidInputEventConfig_TraceRule,
+      AndroidInputEventConfig>;
+
+  static constexpr FieldMetadata_Rules kRules{};
+  template <typename T = AndroidInputEventConfig_TraceRule> T* add_rules() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_TraceDispatcherInputEvents =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      AndroidInputEventConfig>;
+
+  static constexpr FieldMetadata_TraceDispatcherInputEvents kTraceDispatcherInputEvents{};
+  void set_trace_dispatcher_input_events(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_TraceDispatcherInputEvents::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_TraceDispatcherWindowDispatch =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      AndroidInputEventConfig>;
+
+  static constexpr FieldMetadata_TraceDispatcherWindowDispatch kTraceDispatcherWindowDispatch{};
+  void set_trace_dispatcher_window_dispatch(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_TraceDispatcherWindowDispatch::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 AndroidInputEventConfig_TraceRule_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AndroidInputEventConfig_TraceRule_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidInputEventConfig_TraceRule_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidInputEventConfig_TraceRule_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_trace_level() const { return at<1>().valid(); }
+  int32_t trace_level() const { return at<1>().as_int32(); }
+  bool has_match_all_packages() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> match_all_packages() const { return GetRepeated<::protozero::ConstChars>(2); }
+  bool has_match_any_packages() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> match_any_packages() const { return GetRepeated<::protozero::ConstChars>(3); }
+  bool has_match_secure() const { return at<4>().valid(); }
+  bool match_secure() const { return at<4>().as_bool(); }
+  bool has_match_ime_connection_active() const { return at<5>().valid(); }
+  bool match_ime_connection_active() const { return at<5>().as_bool(); }
+};
+
+class AndroidInputEventConfig_TraceRule : public ::protozero::Message {
+ public:
+  using Decoder = AndroidInputEventConfig_TraceRule_Decoder;
+  enum : int32_t {
+    kTraceLevelFieldNumber = 1,
+    kMatchAllPackagesFieldNumber = 2,
+    kMatchAnyPackagesFieldNumber = 3,
+    kMatchSecureFieldNumber = 4,
+    kMatchImeConnectionActiveFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidInputEventConfig.TraceRule"; }
+
+
+  using FieldMetadata_TraceLevel =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      AndroidInputEventConfig_TraceLevel,
+      AndroidInputEventConfig_TraceRule>;
+
+  static constexpr FieldMetadata_TraceLevel kTraceLevel{};
+  void set_trace_level(AndroidInputEventConfig_TraceLevel value) {
+    static constexpr uint32_t field_id = FieldMetadata_TraceLevel::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_MatchAllPackages =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidInputEventConfig_TraceRule>;
+
+  static constexpr FieldMetadata_MatchAllPackages kMatchAllPackages{};
+  void add_match_all_packages(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_MatchAllPackages::kFieldId, data, size);
+  }
+  void add_match_all_packages(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_MatchAllPackages::kFieldId, chars.data, chars.size);
+  }
+  void add_match_all_packages(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_MatchAllPackages::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_MatchAnyPackages =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidInputEventConfig_TraceRule>;
+
+  static constexpr FieldMetadata_MatchAnyPackages kMatchAnyPackages{};
+  void add_match_any_packages(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_MatchAnyPackages::kFieldId, data, size);
+  }
+  void add_match_any_packages(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_MatchAnyPackages::kFieldId, chars.data, chars.size);
+  }
+  void add_match_any_packages(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_MatchAnyPackages::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_MatchSecure =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      AndroidInputEventConfig_TraceRule>;
+
+  static constexpr FieldMetadata_MatchSecure kMatchSecure{};
+  void set_match_secure(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_MatchSecure::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_MatchImeConnectionActive =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      AndroidInputEventConfig_TraceRule>;
+
+  static constexpr FieldMetadata_MatchImeConnectionActive kMatchImeConnectionActive{};
+  void set_match_ime_connection_active(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_MatchImeConnectionActive::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/android_log_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_LOG_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_LOG_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+enum AndroidLogId : int32_t;
+enum AndroidLogPriority : int32_t;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class AndroidLogConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AndroidLogConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidLogConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidLogConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_log_ids() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> log_ids() const { return GetRepeated<int32_t>(1); }
+  bool has_min_prio() const { return at<3>().valid(); }
+  int32_t min_prio() const { return at<3>().as_int32(); }
+  bool has_filter_tags() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> filter_tags() const { return GetRepeated<::protozero::ConstChars>(4); }
+};
+
+class AndroidLogConfig : public ::protozero::Message {
+ public:
+  using Decoder = AndroidLogConfig_Decoder;
+  enum : int32_t {
+    kLogIdsFieldNumber = 1,
+    kMinPrioFieldNumber = 3,
+    kFilterTagsFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidLogConfig"; }
+
+
+  using FieldMetadata_LogIds =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      AndroidLogId,
+      AndroidLogConfig>;
+
+  static constexpr FieldMetadata_LogIds kLogIds{};
+  void add_log_ids(AndroidLogId value) {
+    static constexpr uint32_t field_id = FieldMetadata_LogIds::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_MinPrio =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      AndroidLogPriority,
+      AndroidLogConfig>;
+
+  static constexpr FieldMetadata_MinPrio kMinPrio{};
+  void set_min_prio(AndroidLogPriority value) {
+    static constexpr uint32_t field_id = FieldMetadata_MinPrio::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_FilterTags =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidLogConfig>;
+
+  static constexpr FieldMetadata_FilterTags kFilterTags{};
+  void add_filter_tags(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_FilterTags::kFieldId, data, size);
+  }
+  void add_filter_tags(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_FilterTags::kFieldId, chars.data, chars.size);
+  }
+  void add_filter_tags(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_FilterTags::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/android_polled_state_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_POLLED_STATE_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_POLLED_STATE_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class AndroidPolledStateConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AndroidPolledStateConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidPolledStateConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidPolledStateConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_poll_ms() const { return at<1>().valid(); }
+  uint32_t poll_ms() const { return at<1>().as_uint32(); }
+};
+
+class AndroidPolledStateConfig : public ::protozero::Message {
+ public:
+  using Decoder = AndroidPolledStateConfig_Decoder;
+  enum : int32_t {
+    kPollMsFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidPolledStateConfig"; }
+
+
+  using FieldMetadata_PollMs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AndroidPolledStateConfig>;
+
+  static constexpr FieldMetadata_PollMs kPollMs{};
+  void set_poll_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PollMs::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/android_sdk_sysprop_guard_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_SDK_SYSPROP_GUARD_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_SDK_SYSPROP_GUARD_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class AndroidSdkSyspropGuardConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AndroidSdkSyspropGuardConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidSdkSyspropGuardConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidSdkSyspropGuardConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_surfaceflinger_skia_track_events() const { return at<1>().valid(); }
+  bool surfaceflinger_skia_track_events() const { return at<1>().as_bool(); }
+  bool has_hwui_skia_track_events() const { return at<2>().valid(); }
+  bool hwui_skia_track_events() const { return at<2>().as_bool(); }
+  bool has_hwui_package_name_filter() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> hwui_package_name_filter() const { return GetRepeated<::protozero::ConstChars>(3); }
+};
+
+class AndroidSdkSyspropGuardConfig : public ::protozero::Message {
+ public:
+  using Decoder = AndroidSdkSyspropGuardConfig_Decoder;
+  enum : int32_t {
+    kSurfaceflingerSkiaTrackEventsFieldNumber = 1,
+    kHwuiSkiaTrackEventsFieldNumber = 2,
+    kHwuiPackageNameFilterFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidSdkSyspropGuardConfig"; }
+
+
+  using FieldMetadata_SurfaceflingerSkiaTrackEvents =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      AndroidSdkSyspropGuardConfig>;
+
+  static constexpr FieldMetadata_SurfaceflingerSkiaTrackEvents kSurfaceflingerSkiaTrackEvents{};
+  void set_surfaceflinger_skia_track_events(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_SurfaceflingerSkiaTrackEvents::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_HwuiSkiaTrackEvents =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      AndroidSdkSyspropGuardConfig>;
+
+  static constexpr FieldMetadata_HwuiSkiaTrackEvents kHwuiSkiaTrackEvents{};
+  void set_hwui_skia_track_events(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_HwuiSkiaTrackEvents::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_HwuiPackageNameFilter =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidSdkSyspropGuardConfig>;
+
+  static constexpr FieldMetadata_HwuiPackageNameFilter kHwuiPackageNameFilter{};
+  void add_hwui_package_name_filter(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HwuiPackageNameFilter::kFieldId, data, size);
+  }
+  void add_hwui_package_name_filter(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_HwuiPackageNameFilter::kFieldId, chars.data, chars.size);
+  }
+  void add_hwui_package_name_filter(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_HwuiPackageNameFilter::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/android_system_property_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_SYSTEM_PROPERTY_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_SYSTEM_PROPERTY_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class AndroidSystemPropertyConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AndroidSystemPropertyConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidSystemPropertyConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidSystemPropertyConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_poll_ms() const { return at<1>().valid(); }
+  uint32_t poll_ms() const { return at<1>().as_uint32(); }
+  bool has_property_name() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> property_name() const { return GetRepeated<::protozero::ConstChars>(2); }
+};
+
+class AndroidSystemPropertyConfig : public ::protozero::Message {
+ public:
+  using Decoder = AndroidSystemPropertyConfig_Decoder;
+  enum : int32_t {
+    kPollMsFieldNumber = 1,
+    kPropertyNameFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidSystemPropertyConfig"; }
+
+
+  using FieldMetadata_PollMs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AndroidSystemPropertyConfig>;
+
+  static constexpr FieldMetadata_PollMs kPollMs{};
+  void set_poll_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PollMs::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_PropertyName =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidSystemPropertyConfig>;
+
+  static constexpr FieldMetadata_PropertyName kPropertyName{};
+  void add_property_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_PropertyName::kFieldId, data, size);
+  }
+  void add_property_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_PropertyName::kFieldId, chars.data, chars.size);
+  }
+  void add_property_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_PropertyName::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/network_trace_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_NETWORK_TRACE_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_NETWORK_TRACE_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class NetworkPacketTraceConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  NetworkPacketTraceConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit NetworkPacketTraceConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit NetworkPacketTraceConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_poll_ms() const { return at<1>().valid(); }
+  uint32_t poll_ms() const { return at<1>().as_uint32(); }
+  bool has_aggregation_threshold() const { return at<2>().valid(); }
+  uint32_t aggregation_threshold() const { return at<2>().as_uint32(); }
+  bool has_intern_limit() const { return at<3>().valid(); }
+  uint32_t intern_limit() const { return at<3>().as_uint32(); }
+  bool has_drop_local_port() const { return at<4>().valid(); }
+  bool drop_local_port() const { return at<4>().as_bool(); }
+  bool has_drop_remote_port() const { return at<5>().valid(); }
+  bool drop_remote_port() const { return at<5>().as_bool(); }
+  bool has_drop_tcp_flags() const { return at<6>().valid(); }
+  bool drop_tcp_flags() const { return at<6>().as_bool(); }
+};
+
+class NetworkPacketTraceConfig : public ::protozero::Message {
+ public:
+  using Decoder = NetworkPacketTraceConfig_Decoder;
+  enum : int32_t {
+    kPollMsFieldNumber = 1,
+    kAggregationThresholdFieldNumber = 2,
+    kInternLimitFieldNumber = 3,
+    kDropLocalPortFieldNumber = 4,
+    kDropRemotePortFieldNumber = 5,
+    kDropTcpFlagsFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.NetworkPacketTraceConfig"; }
+
+
+  using FieldMetadata_PollMs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NetworkPacketTraceConfig>;
+
+  static constexpr FieldMetadata_PollMs kPollMs{};
+  void set_poll_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PollMs::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_AggregationThreshold =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NetworkPacketTraceConfig>;
+
+  static constexpr FieldMetadata_AggregationThreshold kAggregationThreshold{};
+  void set_aggregation_threshold(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AggregationThreshold::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_InternLimit =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NetworkPacketTraceConfig>;
+
+  static constexpr FieldMetadata_InternLimit kInternLimit{};
+  void set_intern_limit(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InternLimit::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_DropLocalPort =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      NetworkPacketTraceConfig>;
+
+  static constexpr FieldMetadata_DropLocalPort kDropLocalPort{};
+  void set_drop_local_port(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DropLocalPort::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_DropRemotePort =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      NetworkPacketTraceConfig>;
+
+  static constexpr FieldMetadata_DropRemotePort kDropRemotePort{};
+  void set_drop_remote_port(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DropRemotePort::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_DropTcpFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      NetworkPacketTraceConfig>;
+
+  static constexpr FieldMetadata_DropTcpFlags kDropTcpFlags{};
+  void set_drop_tcp_flags(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DropTcpFlags::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/packages_list_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_PACKAGES_LIST_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_PACKAGES_LIST_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class PackagesListConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  PackagesListConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PackagesListConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PackagesListConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_package_name_filter() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> package_name_filter() const { return GetRepeated<::protozero::ConstChars>(1); }
+};
+
+class PackagesListConfig : public ::protozero::Message {
+ public:
+  using Decoder = PackagesListConfig_Decoder;
+  enum : int32_t {
+    kPackageNameFilterFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PackagesListConfig"; }
+
+
+  using FieldMetadata_PackageNameFilter =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PackagesListConfig>;
+
+  static constexpr FieldMetadata_PackageNameFilter kPackageNameFilter{};
+  void add_package_name_filter(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_PackageNameFilter::kFieldId, data, size);
+  }
+  void add_package_name_filter(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_PackageNameFilter::kFieldId, chars.data, chars.size);
+  }
+  void add_package_name_filter(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_PackageNameFilter::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/pixel_modem_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_PIXEL_MODEM_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_PIXEL_MODEM_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+namespace perfetto_pbzero_enum_PixelModemConfig {
+enum EventGroup : int32_t;
+}  // namespace perfetto_pbzero_enum_PixelModemConfig
+using PixelModemConfig_EventGroup = perfetto_pbzero_enum_PixelModemConfig::EventGroup;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_PixelModemConfig {
+enum EventGroup : int32_t {
+  EVENT_GROUP_UNKNOWN = 0,
+  EVENT_GROUP_LOW_BANDWIDTH = 1,
+  EVENT_GROUP_HIGH_AND_LOW_BANDWIDTH = 2,
+};
+} // namespace perfetto_pbzero_enum_PixelModemConfig
+using PixelModemConfig_EventGroup = perfetto_pbzero_enum_PixelModemConfig::EventGroup;
+
+
+constexpr PixelModemConfig_EventGroup PixelModemConfig_EventGroup_MIN = PixelModemConfig_EventGroup::EVENT_GROUP_UNKNOWN;
+constexpr PixelModemConfig_EventGroup PixelModemConfig_EventGroup_MAX = PixelModemConfig_EventGroup::EVENT_GROUP_HIGH_AND_LOW_BANDWIDTH;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* PixelModemConfig_EventGroup_Name(::perfetto::protos::pbzero::PixelModemConfig_EventGroup value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::PixelModemConfig_EventGroup::EVENT_GROUP_UNKNOWN:
+    return "EVENT_GROUP_UNKNOWN";
+
+  case ::perfetto::protos::pbzero::PixelModemConfig_EventGroup::EVENT_GROUP_LOW_BANDWIDTH:
+    return "EVENT_GROUP_LOW_BANDWIDTH";
+
+  case ::perfetto::protos::pbzero::PixelModemConfig_EventGroup::EVENT_GROUP_HIGH_AND_LOW_BANDWIDTH:
+    return "EVENT_GROUP_HIGH_AND_LOW_BANDWIDTH";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class PixelModemConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  PixelModemConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PixelModemConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PixelModemConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_event_group() const { return at<1>().valid(); }
+  int32_t event_group() const { return at<1>().as_int32(); }
+  bool has_pigweed_hash_allow_list() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<int64_t> pigweed_hash_allow_list() const { return GetRepeated<int64_t>(2); }
+  bool has_pigweed_hash_deny_list() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<int64_t> pigweed_hash_deny_list() const { return GetRepeated<int64_t>(3); }
+};
+
+class PixelModemConfig : public ::protozero::Message {
+ public:
+  using Decoder = PixelModemConfig_Decoder;
+  enum : int32_t {
+    kEventGroupFieldNumber = 1,
+    kPigweedHashAllowListFieldNumber = 2,
+    kPigweedHashDenyListFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PixelModemConfig"; }
+
+
+  using EventGroup = ::perfetto::protos::pbzero::PixelModemConfig_EventGroup;
+  static inline const char* EventGroup_Name(EventGroup value) {
+    return ::perfetto::protos::pbzero::PixelModemConfig_EventGroup_Name(value);
+  }
+  static inline const EventGroup EVENT_GROUP_UNKNOWN = EventGroup::EVENT_GROUP_UNKNOWN;
+  static inline const EventGroup EVENT_GROUP_LOW_BANDWIDTH = EventGroup::EVENT_GROUP_LOW_BANDWIDTH;
+  static inline const EventGroup EVENT_GROUP_HIGH_AND_LOW_BANDWIDTH = EventGroup::EVENT_GROUP_HIGH_AND_LOW_BANDWIDTH;
+
+  using FieldMetadata_EventGroup =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      PixelModemConfig_EventGroup,
+      PixelModemConfig>;
+
+  static constexpr FieldMetadata_EventGroup kEventGroup{};
+  void set_event_group(PixelModemConfig_EventGroup value) {
+    static constexpr uint32_t field_id = FieldMetadata_EventGroup::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_PigweedHashAllowList =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      PixelModemConfig>;
+
+  static constexpr FieldMetadata_PigweedHashAllowList kPigweedHashAllowList{};
+  void add_pigweed_hash_allow_list(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PigweedHashAllowList::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_PigweedHashDenyList =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      PixelModemConfig>;
+
+  static constexpr FieldMetadata_PigweedHashDenyList kPigweedHashDenyList{};
+  void add_pigweed_hash_deny_list(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PigweedHashDenyList::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/protolog_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_PROTOLOG_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_PROTOLOG_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class ProtoLogGroup;
+namespace perfetto_pbzero_enum_ProtoLogConfig {
+enum TracingMode : int32_t;
+}  // namespace perfetto_pbzero_enum_ProtoLogConfig
+using ProtoLogConfig_TracingMode = perfetto_pbzero_enum_ProtoLogConfig::TracingMode;
+enum ProtoLogLevel : int32_t;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_ProtoLogConfig {
+enum TracingMode : int32_t {
+  DEFAULT = 0,
+  ENABLE_ALL = 1,
+};
+} // namespace perfetto_pbzero_enum_ProtoLogConfig
+using ProtoLogConfig_TracingMode = perfetto_pbzero_enum_ProtoLogConfig::TracingMode;
+
+
+constexpr ProtoLogConfig_TracingMode ProtoLogConfig_TracingMode_MIN = ProtoLogConfig_TracingMode::DEFAULT;
+constexpr ProtoLogConfig_TracingMode ProtoLogConfig_TracingMode_MAX = ProtoLogConfig_TracingMode::ENABLE_ALL;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ProtoLogConfig_TracingMode_Name(::perfetto::protos::pbzero::ProtoLogConfig_TracingMode value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ProtoLogConfig_TracingMode::DEFAULT:
+    return "DEFAULT";
+
+  case ::perfetto::protos::pbzero::ProtoLogConfig_TracingMode::ENABLE_ALL:
+    return "ENABLE_ALL";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class ProtoLogGroup_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ProtoLogGroup_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProtoLogGroup_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProtoLogGroup_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_group_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars group_name() const { return at<1>().as_string(); }
+  bool has_log_from() const { return at<2>().valid(); }
+  int32_t log_from() const { return at<2>().as_int32(); }
+  bool has_collect_stacktrace() const { return at<3>().valid(); }
+  bool collect_stacktrace() const { return at<3>().as_bool(); }
+};
+
+class ProtoLogGroup : public ::protozero::Message {
+ public:
+  using Decoder = ProtoLogGroup_Decoder;
+  enum : int32_t {
+    kGroupNameFieldNumber = 1,
+    kLogFromFieldNumber = 2,
+    kCollectStacktraceFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProtoLogGroup"; }
+
+
+  using FieldMetadata_GroupName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ProtoLogGroup>;
+
+  static constexpr FieldMetadata_GroupName kGroupName{};
+  void set_group_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_GroupName::kFieldId, data, size);
+  }
+  void set_group_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_GroupName::kFieldId, chars.data, chars.size);
+  }
+  void set_group_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_GroupName::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_LogFrom =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ProtoLogLevel,
+      ProtoLogGroup>;
+
+  static constexpr FieldMetadata_LogFrom kLogFrom{};
+  void set_log_from(ProtoLogLevel value) {
+    static constexpr uint32_t field_id = FieldMetadata_LogFrom::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_CollectStacktrace =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ProtoLogGroup>;
+
+  static constexpr FieldMetadata_CollectStacktrace kCollectStacktrace{};
+  void set_collect_stacktrace(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_CollectStacktrace::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 ProtoLogConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ProtoLogConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProtoLogConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProtoLogConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_group_overrides() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> group_overrides() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_tracing_mode() const { return at<2>().valid(); }
+  int32_t tracing_mode() const { return at<2>().as_int32(); }
+};
+
+class ProtoLogConfig : public ::protozero::Message {
+ public:
+  using Decoder = ProtoLogConfig_Decoder;
+  enum : int32_t {
+    kGroupOverridesFieldNumber = 1,
+    kTracingModeFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProtoLogConfig"; }
+
+
+  using TracingMode = ::perfetto::protos::pbzero::ProtoLogConfig_TracingMode;
+  static inline const char* TracingMode_Name(TracingMode value) {
+    return ::perfetto::protos::pbzero::ProtoLogConfig_TracingMode_Name(value);
+  }
+  static inline const TracingMode DEFAULT = TracingMode::DEFAULT;
+  static inline const TracingMode ENABLE_ALL = TracingMode::ENABLE_ALL;
+
+  using FieldMetadata_GroupOverrides =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProtoLogGroup,
+      ProtoLogConfig>;
+
+  static constexpr FieldMetadata_GroupOverrides kGroupOverrides{};
+  template <typename T = ProtoLogGroup> T* add_group_overrides() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_TracingMode =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ProtoLogConfig_TracingMode,
+      ProtoLogConfig>;
+
+  static constexpr FieldMetadata_TracingMode kTracingMode{};
+  void set_tracing_mode(ProtoLogConfig_TracingMode value) {
+    static constexpr uint32_t field_id = FieldMetadata_TracingMode::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.
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/surfaceflinger_layers_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_SURFACEFLINGER_LAYERS_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_SURFACEFLINGER_LAYERS_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+namespace perfetto_pbzero_enum_SurfaceFlingerLayersConfig {
+enum Mode : int32_t;
+}  // namespace perfetto_pbzero_enum_SurfaceFlingerLayersConfig
+using SurfaceFlingerLayersConfig_Mode = perfetto_pbzero_enum_SurfaceFlingerLayersConfig::Mode;
+namespace perfetto_pbzero_enum_SurfaceFlingerLayersConfig {
+enum TraceFlag : int32_t;
+}  // namespace perfetto_pbzero_enum_SurfaceFlingerLayersConfig
+using SurfaceFlingerLayersConfig_TraceFlag = perfetto_pbzero_enum_SurfaceFlingerLayersConfig::TraceFlag;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_SurfaceFlingerLayersConfig {
+enum Mode : int32_t {
+  MODE_UNSPECIFIED = 0,
+  MODE_ACTIVE = 1,
+  MODE_GENERATED = 2,
+  MODE_DUMP = 3,
+  MODE_GENERATED_BUGREPORT_ONLY = 4,
+};
+} // namespace perfetto_pbzero_enum_SurfaceFlingerLayersConfig
+using SurfaceFlingerLayersConfig_Mode = perfetto_pbzero_enum_SurfaceFlingerLayersConfig::Mode;
+
+
+constexpr SurfaceFlingerLayersConfig_Mode SurfaceFlingerLayersConfig_Mode_MIN = SurfaceFlingerLayersConfig_Mode::MODE_UNSPECIFIED;
+constexpr SurfaceFlingerLayersConfig_Mode SurfaceFlingerLayersConfig_Mode_MAX = SurfaceFlingerLayersConfig_Mode::MODE_GENERATED_BUGREPORT_ONLY;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* SurfaceFlingerLayersConfig_Mode_Name(::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_Mode value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_Mode::MODE_UNSPECIFIED:
+    return "MODE_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_Mode::MODE_ACTIVE:
+    return "MODE_ACTIVE";
+
+  case ::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_Mode::MODE_GENERATED:
+    return "MODE_GENERATED";
+
+  case ::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_Mode::MODE_DUMP:
+    return "MODE_DUMP";
+
+  case ::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_Mode::MODE_GENERATED_BUGREPORT_ONLY:
+    return "MODE_GENERATED_BUGREPORT_ONLY";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_SurfaceFlingerLayersConfig {
+enum TraceFlag : int32_t {
+  TRACE_FLAG_UNSPECIFIED = 0,
+  TRACE_FLAG_INPUT = 2,
+  TRACE_FLAG_COMPOSITION = 4,
+  TRACE_FLAG_EXTRA = 8,
+  TRACE_FLAG_HWC = 16,
+  TRACE_FLAG_BUFFERS = 32,
+  TRACE_FLAG_VIRTUAL_DISPLAYS = 64,
+  TRACE_FLAG_ALL = 14,
+};
+} // namespace perfetto_pbzero_enum_SurfaceFlingerLayersConfig
+using SurfaceFlingerLayersConfig_TraceFlag = perfetto_pbzero_enum_SurfaceFlingerLayersConfig::TraceFlag;
+
+
+constexpr SurfaceFlingerLayersConfig_TraceFlag SurfaceFlingerLayersConfig_TraceFlag_MIN = SurfaceFlingerLayersConfig_TraceFlag::TRACE_FLAG_UNSPECIFIED;
+constexpr SurfaceFlingerLayersConfig_TraceFlag SurfaceFlingerLayersConfig_TraceFlag_MAX = SurfaceFlingerLayersConfig_TraceFlag::TRACE_FLAG_VIRTUAL_DISPLAYS;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* SurfaceFlingerLayersConfig_TraceFlag_Name(::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_TraceFlag value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_TraceFlag::TRACE_FLAG_UNSPECIFIED:
+    return "TRACE_FLAG_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_TraceFlag::TRACE_FLAG_INPUT:
+    return "TRACE_FLAG_INPUT";
+
+  case ::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_TraceFlag::TRACE_FLAG_COMPOSITION:
+    return "TRACE_FLAG_COMPOSITION";
+
+  case ::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_TraceFlag::TRACE_FLAG_EXTRA:
+    return "TRACE_FLAG_EXTRA";
+
+  case ::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_TraceFlag::TRACE_FLAG_HWC:
+    return "TRACE_FLAG_HWC";
+
+  case ::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_TraceFlag::TRACE_FLAG_BUFFERS:
+    return "TRACE_FLAG_BUFFERS";
+
+  case ::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_TraceFlag::TRACE_FLAG_VIRTUAL_DISPLAYS:
+    return "TRACE_FLAG_VIRTUAL_DISPLAYS";
+
+  case ::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_TraceFlag::TRACE_FLAG_ALL:
+    return "TRACE_FLAG_ALL";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class SurfaceFlingerLayersConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  SurfaceFlingerLayersConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SurfaceFlingerLayersConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SurfaceFlingerLayersConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_mode() const { return at<1>().valid(); }
+  int32_t mode() const { return at<1>().as_int32(); }
+  bool has_trace_flags() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> trace_flags() const { return GetRepeated<int32_t>(2); }
+};
+
+class SurfaceFlingerLayersConfig : public ::protozero::Message {
+ public:
+  using Decoder = SurfaceFlingerLayersConfig_Decoder;
+  enum : int32_t {
+    kModeFieldNumber = 1,
+    kTraceFlagsFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SurfaceFlingerLayersConfig"; }
+
+
+  using Mode = ::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_Mode;
+  static inline const char* Mode_Name(Mode value) {
+    return ::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_Mode_Name(value);
+  }
+
+  using TraceFlag = ::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_TraceFlag;
+  static inline const char* TraceFlag_Name(TraceFlag value) {
+    return ::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_TraceFlag_Name(value);
+  }
+  static inline const Mode MODE_UNSPECIFIED = Mode::MODE_UNSPECIFIED;
+  static inline const Mode MODE_ACTIVE = Mode::MODE_ACTIVE;
+  static inline const Mode MODE_GENERATED = Mode::MODE_GENERATED;
+  static inline const Mode MODE_DUMP = Mode::MODE_DUMP;
+  static inline const Mode MODE_GENERATED_BUGREPORT_ONLY = Mode::MODE_GENERATED_BUGREPORT_ONLY;
+  static inline const TraceFlag TRACE_FLAG_UNSPECIFIED = TraceFlag::TRACE_FLAG_UNSPECIFIED;
+  static inline const TraceFlag TRACE_FLAG_INPUT = TraceFlag::TRACE_FLAG_INPUT;
+  static inline const TraceFlag TRACE_FLAG_COMPOSITION = TraceFlag::TRACE_FLAG_COMPOSITION;
+  static inline const TraceFlag TRACE_FLAG_EXTRA = TraceFlag::TRACE_FLAG_EXTRA;
+  static inline const TraceFlag TRACE_FLAG_HWC = TraceFlag::TRACE_FLAG_HWC;
+  static inline const TraceFlag TRACE_FLAG_BUFFERS = TraceFlag::TRACE_FLAG_BUFFERS;
+  static inline const TraceFlag TRACE_FLAG_VIRTUAL_DISPLAYS = TraceFlag::TRACE_FLAG_VIRTUAL_DISPLAYS;
+  static inline const TraceFlag TRACE_FLAG_ALL = TraceFlag::TRACE_FLAG_ALL;
+
+  using FieldMetadata_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      SurfaceFlingerLayersConfig_Mode,
+      SurfaceFlingerLayersConfig>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(SurfaceFlingerLayersConfig_Mode value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::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_TraceFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      SurfaceFlingerLayersConfig_TraceFlag,
+      SurfaceFlingerLayersConfig>;
+
+  static constexpr FieldMetadata_TraceFlags kTraceFlags{};
+  void add_trace_flags(SurfaceFlingerLayersConfig_TraceFlag value) {
+    static constexpr uint32_t field_id = FieldMetadata_TraceFlags::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.
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/surfaceflinger_transactions_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_SURFACEFLINGER_TRANSACTIONS_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_SURFACEFLINGER_TRANSACTIONS_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+namespace perfetto_pbzero_enum_SurfaceFlingerTransactionsConfig {
+enum Mode : int32_t;
+}  // namespace perfetto_pbzero_enum_SurfaceFlingerTransactionsConfig
+using SurfaceFlingerTransactionsConfig_Mode = perfetto_pbzero_enum_SurfaceFlingerTransactionsConfig::Mode;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_SurfaceFlingerTransactionsConfig {
+enum Mode : int32_t {
+  MODE_UNSPECIFIED = 0,
+  MODE_CONTINUOUS = 1,
+  MODE_ACTIVE = 2,
+};
+} // namespace perfetto_pbzero_enum_SurfaceFlingerTransactionsConfig
+using SurfaceFlingerTransactionsConfig_Mode = perfetto_pbzero_enum_SurfaceFlingerTransactionsConfig::Mode;
+
+
+constexpr SurfaceFlingerTransactionsConfig_Mode SurfaceFlingerTransactionsConfig_Mode_MIN = SurfaceFlingerTransactionsConfig_Mode::MODE_UNSPECIFIED;
+constexpr SurfaceFlingerTransactionsConfig_Mode SurfaceFlingerTransactionsConfig_Mode_MAX = SurfaceFlingerTransactionsConfig_Mode::MODE_ACTIVE;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* SurfaceFlingerTransactionsConfig_Mode_Name(::perfetto::protos::pbzero::SurfaceFlingerTransactionsConfig_Mode value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::SurfaceFlingerTransactionsConfig_Mode::MODE_UNSPECIFIED:
+    return "MODE_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::SurfaceFlingerTransactionsConfig_Mode::MODE_CONTINUOUS:
+    return "MODE_CONTINUOUS";
+
+  case ::perfetto::protos::pbzero::SurfaceFlingerTransactionsConfig_Mode::MODE_ACTIVE:
+    return "MODE_ACTIVE";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class SurfaceFlingerTransactionsConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SurfaceFlingerTransactionsConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SurfaceFlingerTransactionsConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SurfaceFlingerTransactionsConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_mode() const { return at<1>().valid(); }
+  int32_t mode() const { return at<1>().as_int32(); }
+};
+
+class SurfaceFlingerTransactionsConfig : public ::protozero::Message {
+ public:
+  using Decoder = SurfaceFlingerTransactionsConfig_Decoder;
+  enum : int32_t {
+    kModeFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SurfaceFlingerTransactionsConfig"; }
+
+
+  using Mode = ::perfetto::protos::pbzero::SurfaceFlingerTransactionsConfig_Mode;
+  static inline const char* Mode_Name(Mode value) {
+    return ::perfetto::protos::pbzero::SurfaceFlingerTransactionsConfig_Mode_Name(value);
+  }
+  static inline const Mode MODE_UNSPECIFIED = Mode::MODE_UNSPECIFIED;
+  static inline const Mode MODE_CONTINUOUS = Mode::MODE_CONTINUOUS;
+  static inline const Mode MODE_ACTIVE = Mode::MODE_ACTIVE;
+
+  using FieldMetadata_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      SurfaceFlingerTransactionsConfig_Mode,
+      SurfaceFlingerTransactionsConfig>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(SurfaceFlingerTransactionsConfig_Mode value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::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.
+// gen_amalgamated begin header: gen/protos/perfetto/config/ftrace/ftrace_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_FTRACE_FTRACE_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_FTRACE_FTRACE_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class FtraceConfig_CompactSchedConfig;
+class FtraceConfig_PrintFilter;
+class FtraceConfig_PrintFilter_Rule;
+class FtraceConfig_PrintFilter_Rule_AtraceMessage;
+namespace perfetto_pbzero_enum_FtraceConfig {
+enum KsymsMemPolicy : int32_t;
+}  // namespace perfetto_pbzero_enum_FtraceConfig
+using FtraceConfig_KsymsMemPolicy = perfetto_pbzero_enum_FtraceConfig::KsymsMemPolicy;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_FtraceConfig {
+enum KsymsMemPolicy : int32_t {
+  KSYMS_UNSPECIFIED = 0,
+  KSYMS_CLEANUP_ON_STOP = 1,
+  KSYMS_RETAIN = 2,
+};
+} // namespace perfetto_pbzero_enum_FtraceConfig
+using FtraceConfig_KsymsMemPolicy = perfetto_pbzero_enum_FtraceConfig::KsymsMemPolicy;
+
+
+constexpr FtraceConfig_KsymsMemPolicy FtraceConfig_KsymsMemPolicy_MIN = FtraceConfig_KsymsMemPolicy::KSYMS_UNSPECIFIED;
+constexpr FtraceConfig_KsymsMemPolicy FtraceConfig_KsymsMemPolicy_MAX = FtraceConfig_KsymsMemPolicy::KSYMS_RETAIN;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* FtraceConfig_KsymsMemPolicy_Name(::perfetto::protos::pbzero::FtraceConfig_KsymsMemPolicy value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::FtraceConfig_KsymsMemPolicy::KSYMS_UNSPECIFIED:
+    return "KSYMS_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::FtraceConfig_KsymsMemPolicy::KSYMS_CLEANUP_ON_STOP:
+    return "KSYMS_CLEANUP_ON_STOP";
+
+  case ::perfetto::protos::pbzero::FtraceConfig_KsymsMemPolicy::KSYMS_RETAIN:
+    return "KSYMS_RETAIN";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class FtraceConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/27, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  FtraceConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FtraceConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FtraceConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ftrace_events() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> ftrace_events() const { return GetRepeated<::protozero::ConstChars>(1); }
+  bool has_atrace_categories() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> atrace_categories() const { return GetRepeated<::protozero::ConstChars>(2); }
+  bool has_atrace_apps() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> atrace_apps() const { return GetRepeated<::protozero::ConstChars>(3); }
+  bool has_buffer_size_kb() const { return at<10>().valid(); }
+  uint32_t buffer_size_kb() const { return at<10>().as_uint32(); }
+  bool has_drain_period_ms() const { return at<11>().valid(); }
+  uint32_t drain_period_ms() const { return at<11>().as_uint32(); }
+  bool has_drain_buffer_percent() const { return at<26>().valid(); }
+  uint32_t drain_buffer_percent() const { return at<26>().as_uint32(); }
+  bool has_compact_sched() const { return at<12>().valid(); }
+  ::protozero::ConstBytes compact_sched() const { return at<12>().as_bytes(); }
+  bool has_print_filter() const { return at<22>().valid(); }
+  ::protozero::ConstBytes print_filter() const { return at<22>().as_bytes(); }
+  bool has_symbolize_ksyms() const { return at<13>().valid(); }
+  bool symbolize_ksyms() const { return at<13>().as_bool(); }
+  bool has_ksyms_mem_policy() const { return at<17>().valid(); }
+  int32_t ksyms_mem_policy() const { return at<17>().as_int32(); }
+  bool has_initialize_ksyms_synchronously_for_testing() const { return at<14>().valid(); }
+  bool initialize_ksyms_synchronously_for_testing() const { return at<14>().as_bool(); }
+  bool has_throttle_rss_stat() const { return at<15>().valid(); }
+  bool throttle_rss_stat() const { return at<15>().as_bool(); }
+  bool has_disable_generic_events() const { return at<16>().valid(); }
+  bool disable_generic_events() const { return at<16>().as_bool(); }
+  bool has_syscall_events() const { return at<18>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> syscall_events() const { return GetRepeated<::protozero::ConstChars>(18); }
+  bool has_enable_function_graph() const { return at<19>().valid(); }
+  bool enable_function_graph() const { return at<19>().as_bool(); }
+  bool has_function_filters() const { return at<20>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> function_filters() const { return GetRepeated<::protozero::ConstChars>(20); }
+  bool has_function_graph_roots() const { return at<21>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> function_graph_roots() const { return GetRepeated<::protozero::ConstChars>(21); }
+  bool has_preserve_ftrace_buffer() const { return at<23>().valid(); }
+  bool preserve_ftrace_buffer() const { return at<23>().as_bool(); }
+  bool has_use_monotonic_raw_clock() const { return at<24>().valid(); }
+  bool use_monotonic_raw_clock() const { return at<24>().as_bool(); }
+  bool has_instance_name() const { return at<25>().valid(); }
+  ::protozero::ConstChars instance_name() const { return at<25>().as_string(); }
+  bool has_buffer_size_lower_bound() const { return at<27>().valid(); }
+  bool buffer_size_lower_bound() const { return at<27>().as_bool(); }
+};
+
+class FtraceConfig : public ::protozero::Message {
+ public:
+  using Decoder = FtraceConfig_Decoder;
+  enum : int32_t {
+    kFtraceEventsFieldNumber = 1,
+    kAtraceCategoriesFieldNumber = 2,
+    kAtraceAppsFieldNumber = 3,
+    kBufferSizeKbFieldNumber = 10,
+    kDrainPeriodMsFieldNumber = 11,
+    kDrainBufferPercentFieldNumber = 26,
+    kCompactSchedFieldNumber = 12,
+    kPrintFilterFieldNumber = 22,
+    kSymbolizeKsymsFieldNumber = 13,
+    kKsymsMemPolicyFieldNumber = 17,
+    kInitializeKsymsSynchronouslyForTestingFieldNumber = 14,
+    kThrottleRssStatFieldNumber = 15,
+    kDisableGenericEventsFieldNumber = 16,
+    kSyscallEventsFieldNumber = 18,
+    kEnableFunctionGraphFieldNumber = 19,
+    kFunctionFiltersFieldNumber = 20,
+    kFunctionGraphRootsFieldNumber = 21,
+    kPreserveFtraceBufferFieldNumber = 23,
+    kUseMonotonicRawClockFieldNumber = 24,
+    kInstanceNameFieldNumber = 25,
+    kBufferSizeLowerBoundFieldNumber = 27,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FtraceConfig"; }
+
+  using CompactSchedConfig = ::perfetto::protos::pbzero::FtraceConfig_CompactSchedConfig;
+  using PrintFilter = ::perfetto::protos::pbzero::FtraceConfig_PrintFilter;
+
+  using KsymsMemPolicy = ::perfetto::protos::pbzero::FtraceConfig_KsymsMemPolicy;
+  static inline const char* KsymsMemPolicy_Name(KsymsMemPolicy value) {
+    return ::perfetto::protos::pbzero::FtraceConfig_KsymsMemPolicy_Name(value);
+  }
+  static inline const KsymsMemPolicy KSYMS_UNSPECIFIED = KsymsMemPolicy::KSYMS_UNSPECIFIED;
+  static inline const KsymsMemPolicy KSYMS_CLEANUP_ON_STOP = KsymsMemPolicy::KSYMS_CLEANUP_ON_STOP;
+  static inline const KsymsMemPolicy KSYMS_RETAIN = KsymsMemPolicy::KSYMS_RETAIN;
+
+  using FieldMetadata_FtraceEvents =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_FtraceEvents kFtraceEvents{};
+  void add_ftrace_events(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_FtraceEvents::kFieldId, data, size);
+  }
+  void add_ftrace_events(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_FtraceEvents::kFieldId, chars.data, chars.size);
+  }
+  void add_ftrace_events(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_FtraceEvents::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_AtraceCategories =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_AtraceCategories kAtraceCategories{};
+  void add_atrace_categories(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_AtraceCategories::kFieldId, data, size);
+  }
+  void add_atrace_categories(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_AtraceCategories::kFieldId, chars.data, chars.size);
+  }
+  void add_atrace_categories(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_AtraceCategories::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_AtraceApps =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_AtraceApps kAtraceApps{};
+  void add_atrace_apps(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_AtraceApps::kFieldId, data, size);
+  }
+  void add_atrace_apps(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_AtraceApps::kFieldId, chars.data, chars.size);
+  }
+  void add_atrace_apps(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_AtraceApps::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_BufferSizeKb =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_BufferSizeKb kBufferSizeKb{};
+  void set_buffer_size_kb(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BufferSizeKb::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_DrainPeriodMs =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_DrainPeriodMs kDrainPeriodMs{};
+  void set_drain_period_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DrainPeriodMs::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_DrainBufferPercent =
+    ::protozero::proto_utils::FieldMetadata<
+      26,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_DrainBufferPercent kDrainBufferPercent{};
+  void set_drain_buffer_percent(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DrainBufferPercent::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_CompactSched =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FtraceConfig_CompactSchedConfig,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_CompactSched kCompactSched{};
+  template <typename T = FtraceConfig_CompactSchedConfig> T* set_compact_sched() {
+    return BeginNestedMessage<T>(12);
+  }
+
+
+  using FieldMetadata_PrintFilter =
+    ::protozero::proto_utils::FieldMetadata<
+      22,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FtraceConfig_PrintFilter,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_PrintFilter kPrintFilter{};
+  template <typename T = FtraceConfig_PrintFilter> T* set_print_filter() {
+    return BeginNestedMessage<T>(22);
+  }
+
+
+  using FieldMetadata_SymbolizeKsyms =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_SymbolizeKsyms kSymbolizeKsyms{};
+  void set_symbolize_ksyms(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_SymbolizeKsyms::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_KsymsMemPolicy =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      FtraceConfig_KsymsMemPolicy,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_KsymsMemPolicy kKsymsMemPolicy{};
+  void set_ksyms_mem_policy(FtraceConfig_KsymsMemPolicy value) {
+    static constexpr uint32_t field_id = FieldMetadata_KsymsMemPolicy::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_InitializeKsymsSynchronouslyForTesting =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_InitializeKsymsSynchronouslyForTesting kInitializeKsymsSynchronouslyForTesting{};
+  void set_initialize_ksyms_synchronously_for_testing(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_InitializeKsymsSynchronouslyForTesting::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_ThrottleRssStat =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_ThrottleRssStat kThrottleRssStat{};
+  void set_throttle_rss_stat(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ThrottleRssStat::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_DisableGenericEvents =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_DisableGenericEvents kDisableGenericEvents{};
+  void set_disable_generic_events(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DisableGenericEvents::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_SyscallEvents =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_SyscallEvents kSyscallEvents{};
+  void add_syscall_events(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_SyscallEvents::kFieldId, data, size);
+  }
+  void add_syscall_events(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_SyscallEvents::kFieldId, chars.data, chars.size);
+  }
+  void add_syscall_events(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_SyscallEvents::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_EnableFunctionGraph =
+    ::protozero::proto_utils::FieldMetadata<
+      19,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_EnableFunctionGraph kEnableFunctionGraph{};
+  void set_enable_function_graph(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_EnableFunctionGraph::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_FunctionFilters =
+    ::protozero::proto_utils::FieldMetadata<
+      20,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_FunctionFilters kFunctionFilters{};
+  void add_function_filters(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_FunctionFilters::kFieldId, data, size);
+  }
+  void add_function_filters(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_FunctionFilters::kFieldId, chars.data, chars.size);
+  }
+  void add_function_filters(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_FunctionFilters::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_FunctionGraphRoots =
+    ::protozero::proto_utils::FieldMetadata<
+      21,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_FunctionGraphRoots kFunctionGraphRoots{};
+  void add_function_graph_roots(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_FunctionGraphRoots::kFieldId, data, size);
+  }
+  void add_function_graph_roots(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_FunctionGraphRoots::kFieldId, chars.data, chars.size);
+  }
+  void add_function_graph_roots(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_FunctionGraphRoots::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_PreserveFtraceBuffer =
+    ::protozero::proto_utils::FieldMetadata<
+      23,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_PreserveFtraceBuffer kPreserveFtraceBuffer{};
+  void set_preserve_ftrace_buffer(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_PreserveFtraceBuffer::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_UseMonotonicRawClock =
+    ::protozero::proto_utils::FieldMetadata<
+      24,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_UseMonotonicRawClock kUseMonotonicRawClock{};
+  void set_use_monotonic_raw_clock(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_UseMonotonicRawClock::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_InstanceName =
+    ::protozero::proto_utils::FieldMetadata<
+      25,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_InstanceName kInstanceName{};
+  void set_instance_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_InstanceName::kFieldId, data, size);
+  }
+  void set_instance_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_InstanceName::kFieldId, chars.data, chars.size);
+  }
+  void set_instance_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_InstanceName::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_BufferSizeLowerBound =
+    ::protozero::proto_utils::FieldMetadata<
+      27,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_BufferSizeLowerBound kBufferSizeLowerBound{};
+  void set_buffer_size_lower_bound(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_BufferSizeLowerBound::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 FtraceConfig_PrintFilter_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  FtraceConfig_PrintFilter_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FtraceConfig_PrintFilter_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FtraceConfig_PrintFilter_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_rules() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> rules() const { return GetRepeated<::protozero::ConstBytes>(1); }
+};
+
+class FtraceConfig_PrintFilter : public ::protozero::Message {
+ public:
+  using Decoder = FtraceConfig_PrintFilter_Decoder;
+  enum : int32_t {
+    kRulesFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FtraceConfig.PrintFilter"; }
+
+  using Rule = ::perfetto::protos::pbzero::FtraceConfig_PrintFilter_Rule;
+
+  using FieldMetadata_Rules =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FtraceConfig_PrintFilter_Rule,
+      FtraceConfig_PrintFilter>;
+
+  static constexpr FieldMetadata_Rules kRules{};
+  template <typename T = FtraceConfig_PrintFilter_Rule> T* add_rules() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+class FtraceConfig_PrintFilter_Rule_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FtraceConfig_PrintFilter_Rule_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FtraceConfig_PrintFilter_Rule_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FtraceConfig_PrintFilter_Rule_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_prefix() const { return at<1>().valid(); }
+  ::protozero::ConstChars prefix() const { return at<1>().as_string(); }
+  bool has_atrace_msg() const { return at<3>().valid(); }
+  ::protozero::ConstBytes atrace_msg() const { return at<3>().as_bytes(); }
+  bool has_allow() const { return at<2>().valid(); }
+  bool allow() const { return at<2>().as_bool(); }
+};
+
+class FtraceConfig_PrintFilter_Rule : public ::protozero::Message {
+ public:
+  using Decoder = FtraceConfig_PrintFilter_Rule_Decoder;
+  enum : int32_t {
+    kPrefixFieldNumber = 1,
+    kAtraceMsgFieldNumber = 3,
+    kAllowFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FtraceConfig.PrintFilter.Rule"; }
+
+  using AtraceMessage = ::perfetto::protos::pbzero::FtraceConfig_PrintFilter_Rule_AtraceMessage;
+
+  using FieldMetadata_Prefix =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FtraceConfig_PrintFilter_Rule>;
+
+  static constexpr FieldMetadata_Prefix kPrefix{};
+  void set_prefix(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Prefix::kFieldId, data, size);
+  }
+  void set_prefix(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Prefix::kFieldId, chars.data, chars.size);
+  }
+  void set_prefix(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Prefix::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_AtraceMsg =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FtraceConfig_PrintFilter_Rule_AtraceMessage,
+      FtraceConfig_PrintFilter_Rule>;
+
+  static constexpr FieldMetadata_AtraceMsg kAtraceMsg{};
+  template <typename T = FtraceConfig_PrintFilter_Rule_AtraceMessage> T* set_atrace_msg() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_Allow =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FtraceConfig_PrintFilter_Rule>;
+
+  static constexpr FieldMetadata_Allow kAllow{};
+  void set_allow(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_Allow::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 FtraceConfig_PrintFilter_Rule_AtraceMessage_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FtraceConfig_PrintFilter_Rule_AtraceMessage_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FtraceConfig_PrintFilter_Rule_AtraceMessage_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FtraceConfig_PrintFilter_Rule_AtraceMessage_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_type() const { return at<1>().valid(); }
+  ::protozero::ConstChars type() const { return at<1>().as_string(); }
+  bool has_prefix() const { return at<2>().valid(); }
+  ::protozero::ConstChars prefix() const { return at<2>().as_string(); }
+};
+
+class FtraceConfig_PrintFilter_Rule_AtraceMessage : public ::protozero::Message {
+ public:
+  using Decoder = FtraceConfig_PrintFilter_Rule_AtraceMessage_Decoder;
+  enum : int32_t {
+    kTypeFieldNumber = 1,
+    kPrefixFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FtraceConfig.PrintFilter.Rule.AtraceMessage"; }
+
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FtraceConfig_PrintFilter_Rule_AtraceMessage>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Type::kFieldId, data, size);
+  }
+  void set_type(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Type::kFieldId, chars.data, chars.size);
+  }
+  void set_type(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::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_Prefix =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FtraceConfig_PrintFilter_Rule_AtraceMessage>;
+
+  static constexpr FieldMetadata_Prefix kPrefix{};
+  void set_prefix(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Prefix::kFieldId, data, size);
+  }
+  void set_prefix(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Prefix::kFieldId, chars.data, chars.size);
+  }
+  void set_prefix(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Prefix::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 FtraceConfig_CompactSchedConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FtraceConfig_CompactSchedConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FtraceConfig_CompactSchedConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FtraceConfig_CompactSchedConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_enabled() const { return at<1>().valid(); }
+  bool enabled() const { return at<1>().as_bool(); }
+};
+
+class FtraceConfig_CompactSchedConfig : public ::protozero::Message {
+ public:
+  using Decoder = FtraceConfig_CompactSchedConfig_Decoder;
+  enum : int32_t {
+    kEnabledFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FtraceConfig.CompactSchedConfig"; }
+
+
+  using FieldMetadata_Enabled =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FtraceConfig_CompactSchedConfig>;
+
+  static constexpr FieldMetadata_Enabled kEnabled{};
+  void set_enabled(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_Enabled::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/gpu/gpu_counter_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_GPU_COUNTER_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_GPU_COUNTER_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class GpuCounterConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  GpuCounterConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GpuCounterConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GpuCounterConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_counter_period_ns() const { return at<1>().valid(); }
+  uint64_t counter_period_ns() const { return at<1>().as_uint64(); }
+  bool has_counter_ids() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint32_t> counter_ids() const { return GetRepeated<uint32_t>(2); }
+  bool has_instrumented_sampling() const { return at<3>().valid(); }
+  bool instrumented_sampling() const { return at<3>().as_bool(); }
+  bool has_fix_gpu_clock() const { return at<4>().valid(); }
+  bool fix_gpu_clock() const { return at<4>().as_bool(); }
+};
+
+class GpuCounterConfig : public ::protozero::Message {
+ public:
+  using Decoder = GpuCounterConfig_Decoder;
+  enum : int32_t {
+    kCounterPeriodNsFieldNumber = 1,
+    kCounterIdsFieldNumber = 2,
+    kInstrumentedSamplingFieldNumber = 3,
+    kFixGpuClockFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GpuCounterConfig"; }
+
+
+  using FieldMetadata_CounterPeriodNs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuCounterConfig>;
+
+  static constexpr FieldMetadata_CounterPeriodNs kCounterPeriodNs{};
+  void set_counter_period_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CounterPeriodNs::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_CounterIds =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GpuCounterConfig>;
+
+  static constexpr FieldMetadata_CounterIds kCounterIds{};
+  void add_counter_ids(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CounterIds::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_InstrumentedSampling =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      GpuCounterConfig>;
+
+  static constexpr FieldMetadata_InstrumentedSampling kInstrumentedSampling{};
+  void set_instrumented_sampling(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_InstrumentedSampling::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_FixGpuClock =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      GpuCounterConfig>;
+
+  static constexpr FieldMetadata_FixGpuClock kFixGpuClock{};
+  void set_fix_gpu_clock(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_FixGpuClock::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/gpu/vulkan_memory_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_VULKAN_MEMORY_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_VULKAN_MEMORY_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class VulkanMemoryConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  VulkanMemoryConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit VulkanMemoryConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit VulkanMemoryConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_track_driver_memory_usage() const { return at<1>().valid(); }
+  bool track_driver_memory_usage() const { return at<1>().as_bool(); }
+  bool has_track_device_memory_usage() const { return at<2>().valid(); }
+  bool track_device_memory_usage() const { return at<2>().as_bool(); }
+};
+
+class VulkanMemoryConfig : public ::protozero::Message {
+ public:
+  using Decoder = VulkanMemoryConfig_Decoder;
+  enum : int32_t {
+    kTrackDriverMemoryUsageFieldNumber = 1,
+    kTrackDeviceMemoryUsageFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.VulkanMemoryConfig"; }
+
+
+  using FieldMetadata_TrackDriverMemoryUsage =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      VulkanMemoryConfig>;
+
+  static constexpr FieldMetadata_TrackDriverMemoryUsage kTrackDriverMemoryUsage{};
+  void set_track_driver_memory_usage(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_TrackDriverMemoryUsage::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_TrackDeviceMemoryUsage =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      VulkanMemoryConfig>;
+
+  static constexpr FieldMetadata_TrackDeviceMemoryUsage kTrackDeviceMemoryUsage{};
+  void set_track_device_memory_usage(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_TrackDeviceMemoryUsage::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/inode_file/inode_file_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INODE_FILE_INODE_FILE_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INODE_FILE_INODE_FILE_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class InodeFileConfig_MountPointMappingEntry;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class InodeFileConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  InodeFileConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit InodeFileConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit InodeFileConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_scan_interval_ms() const { return at<1>().valid(); }
+  uint32_t scan_interval_ms() const { return at<1>().as_uint32(); }
+  bool has_scan_delay_ms() const { return at<2>().valid(); }
+  uint32_t scan_delay_ms() const { return at<2>().as_uint32(); }
+  bool has_scan_batch_size() const { return at<3>().valid(); }
+  uint32_t scan_batch_size() const { return at<3>().as_uint32(); }
+  bool has_do_not_scan() const { return at<4>().valid(); }
+  bool do_not_scan() const { return at<4>().as_bool(); }
+  bool has_scan_mount_points() const { return at<5>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> scan_mount_points() const { return GetRepeated<::protozero::ConstChars>(5); }
+  bool has_mount_point_mapping() const { return at<6>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> mount_point_mapping() const { return GetRepeated<::protozero::ConstBytes>(6); }
+};
+
+class InodeFileConfig : public ::protozero::Message {
+ public:
+  using Decoder = InodeFileConfig_Decoder;
+  enum : int32_t {
+    kScanIntervalMsFieldNumber = 1,
+    kScanDelayMsFieldNumber = 2,
+    kScanBatchSizeFieldNumber = 3,
+    kDoNotScanFieldNumber = 4,
+    kScanMountPointsFieldNumber = 5,
+    kMountPointMappingFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.InodeFileConfig"; }
+
+  using MountPointMappingEntry = ::perfetto::protos::pbzero::InodeFileConfig_MountPointMappingEntry;
+
+  using FieldMetadata_ScanIntervalMs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      InodeFileConfig>;
+
+  static constexpr FieldMetadata_ScanIntervalMs kScanIntervalMs{};
+  void set_scan_interval_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ScanIntervalMs::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_ScanDelayMs =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      InodeFileConfig>;
+
+  static constexpr FieldMetadata_ScanDelayMs kScanDelayMs{};
+  void set_scan_delay_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ScanDelayMs::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_ScanBatchSize =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      InodeFileConfig>;
+
+  static constexpr FieldMetadata_ScanBatchSize kScanBatchSize{};
+  void set_scan_batch_size(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ScanBatchSize::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_DoNotScan =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      InodeFileConfig>;
+
+  static constexpr FieldMetadata_DoNotScan kDoNotScan{};
+  void set_do_not_scan(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DoNotScan::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_ScanMountPoints =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      InodeFileConfig>;
+
+  static constexpr FieldMetadata_ScanMountPoints kScanMountPoints{};
+  void add_scan_mount_points(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ScanMountPoints::kFieldId, data, size);
+  }
+  void add_scan_mount_points(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ScanMountPoints::kFieldId, chars.data, chars.size);
+  }
+  void add_scan_mount_points(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ScanMountPoints::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_MountPointMapping =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InodeFileConfig_MountPointMappingEntry,
+      InodeFileConfig>;
+
+  static constexpr FieldMetadata_MountPointMapping kMountPointMapping{};
+  template <typename T = InodeFileConfig_MountPointMappingEntry> T* add_mount_point_mapping() {
+    return BeginNestedMessage<T>(6);
+  }
+
+};
+
+class InodeFileConfig_MountPointMappingEntry_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  InodeFileConfig_MountPointMappingEntry_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit InodeFileConfig_MountPointMappingEntry_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit InodeFileConfig_MountPointMappingEntry_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_mountpoint() const { return at<1>().valid(); }
+  ::protozero::ConstChars mountpoint() const { return at<1>().as_string(); }
+  bool has_scan_roots() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> scan_roots() const { return GetRepeated<::protozero::ConstChars>(2); }
+};
+
+class InodeFileConfig_MountPointMappingEntry : public ::protozero::Message {
+ public:
+  using Decoder = InodeFileConfig_MountPointMappingEntry_Decoder;
+  enum : int32_t {
+    kMountpointFieldNumber = 1,
+    kScanRootsFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.InodeFileConfig.MountPointMappingEntry"; }
+
+
+  using FieldMetadata_Mountpoint =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      InodeFileConfig_MountPointMappingEntry>;
+
+  static constexpr FieldMetadata_Mountpoint kMountpoint{};
+  void set_mountpoint(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Mountpoint::kFieldId, data, size);
+  }
+  void set_mountpoint(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Mountpoint::kFieldId, chars.data, chars.size);
+  }
+  void set_mountpoint(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mountpoint::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_ScanRoots =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      InodeFileConfig_MountPointMappingEntry>;
+
+  static constexpr FieldMetadata_ScanRoots kScanRoots{};
+  void add_scan_roots(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ScanRoots::kFieldId, data, size);
+  }
+  void add_scan_roots(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ScanRoots::kFieldId, chars.data, chars.size);
+  }
+  void add_scan_roots(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ScanRoots::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/interceptors/console_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INTERCEPTORS_CONSOLE_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INTERCEPTORS_CONSOLE_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+namespace perfetto_pbzero_enum_ConsoleConfig {
+enum Output : int32_t;
+}  // namespace perfetto_pbzero_enum_ConsoleConfig
+using ConsoleConfig_Output = perfetto_pbzero_enum_ConsoleConfig::Output;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_ConsoleConfig {
+enum Output : int32_t {
+  OUTPUT_UNSPECIFIED = 0,
+  OUTPUT_STDOUT = 1,
+  OUTPUT_STDERR = 2,
+};
+} // namespace perfetto_pbzero_enum_ConsoleConfig
+using ConsoleConfig_Output = perfetto_pbzero_enum_ConsoleConfig::Output;
+
+
+constexpr ConsoleConfig_Output ConsoleConfig_Output_MIN = ConsoleConfig_Output::OUTPUT_UNSPECIFIED;
+constexpr ConsoleConfig_Output ConsoleConfig_Output_MAX = ConsoleConfig_Output::OUTPUT_STDERR;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ConsoleConfig_Output_Name(::perfetto::protos::pbzero::ConsoleConfig_Output value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ConsoleConfig_Output::OUTPUT_UNSPECIFIED:
+    return "OUTPUT_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ConsoleConfig_Output::OUTPUT_STDOUT:
+    return "OUTPUT_STDOUT";
+
+  case ::perfetto::protos::pbzero::ConsoleConfig_Output::OUTPUT_STDERR:
+    return "OUTPUT_STDERR";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class ConsoleConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ConsoleConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ConsoleConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ConsoleConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_output() const { return at<1>().valid(); }
+  int32_t output() const { return at<1>().as_int32(); }
+  bool has_enable_colors() const { return at<2>().valid(); }
+  bool enable_colors() const { return at<2>().as_bool(); }
+};
+
+class ConsoleConfig : public ::protozero::Message {
+ public:
+  using Decoder = ConsoleConfig_Decoder;
+  enum : int32_t {
+    kOutputFieldNumber = 1,
+    kEnableColorsFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ConsoleConfig"; }
+
+
+  using Output = ::perfetto::protos::pbzero::ConsoleConfig_Output;
+  static inline const char* Output_Name(Output value) {
+    return ::perfetto::protos::pbzero::ConsoleConfig_Output_Name(value);
+  }
+  static inline const Output OUTPUT_UNSPECIFIED = Output::OUTPUT_UNSPECIFIED;
+  static inline const Output OUTPUT_STDOUT = Output::OUTPUT_STDOUT;
+  static inline const Output OUTPUT_STDERR = Output::OUTPUT_STDERR;
+
+  using FieldMetadata_Output =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ConsoleConfig_Output,
+      ConsoleConfig>;
+
+  static constexpr FieldMetadata_Output kOutput{};
+  void set_output(ConsoleConfig_Output value) {
+    static constexpr uint32_t field_id = FieldMetadata_Output::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_EnableColors =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ConsoleConfig>;
+
+  static constexpr FieldMetadata_EnableColors kEnableColors{};
+  void set_enable_colors(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_EnableColors::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/power/android_power_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_POWER_ANDROID_POWER_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_POWER_ANDROID_POWER_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+namespace perfetto_pbzero_enum_AndroidPowerConfig {
+enum BatteryCounters : int32_t;
+}  // namespace perfetto_pbzero_enum_AndroidPowerConfig
+using AndroidPowerConfig_BatteryCounters = perfetto_pbzero_enum_AndroidPowerConfig::BatteryCounters;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_AndroidPowerConfig {
+enum BatteryCounters : int32_t {
+  BATTERY_COUNTER_UNSPECIFIED = 0,
+  BATTERY_COUNTER_CHARGE = 1,
+  BATTERY_COUNTER_CAPACITY_PERCENT = 2,
+  BATTERY_COUNTER_CURRENT = 3,
+  BATTERY_COUNTER_CURRENT_AVG = 4,
+  BATTERY_COUNTER_VOLTAGE = 5,
+};
+} // namespace perfetto_pbzero_enum_AndroidPowerConfig
+using AndroidPowerConfig_BatteryCounters = perfetto_pbzero_enum_AndroidPowerConfig::BatteryCounters;
+
+
+constexpr AndroidPowerConfig_BatteryCounters AndroidPowerConfig_BatteryCounters_MIN = AndroidPowerConfig_BatteryCounters::BATTERY_COUNTER_UNSPECIFIED;
+constexpr AndroidPowerConfig_BatteryCounters AndroidPowerConfig_BatteryCounters_MAX = AndroidPowerConfig_BatteryCounters::BATTERY_COUNTER_VOLTAGE;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* AndroidPowerConfig_BatteryCounters_Name(::perfetto::protos::pbzero::AndroidPowerConfig_BatteryCounters value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::AndroidPowerConfig_BatteryCounters::BATTERY_COUNTER_UNSPECIFIED:
+    return "BATTERY_COUNTER_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::AndroidPowerConfig_BatteryCounters::BATTERY_COUNTER_CHARGE:
+    return "BATTERY_COUNTER_CHARGE";
+
+  case ::perfetto::protos::pbzero::AndroidPowerConfig_BatteryCounters::BATTERY_COUNTER_CAPACITY_PERCENT:
+    return "BATTERY_COUNTER_CAPACITY_PERCENT";
+
+  case ::perfetto::protos::pbzero::AndroidPowerConfig_BatteryCounters::BATTERY_COUNTER_CURRENT:
+    return "BATTERY_COUNTER_CURRENT";
+
+  case ::perfetto::protos::pbzero::AndroidPowerConfig_BatteryCounters::BATTERY_COUNTER_CURRENT_AVG:
+    return "BATTERY_COUNTER_CURRENT_AVG";
+
+  case ::perfetto::protos::pbzero::AndroidPowerConfig_BatteryCounters::BATTERY_COUNTER_VOLTAGE:
+    return "BATTERY_COUNTER_VOLTAGE";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class AndroidPowerConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AndroidPowerConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidPowerConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidPowerConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_battery_poll_ms() const { return at<1>().valid(); }
+  uint32_t battery_poll_ms() const { return at<1>().as_uint32(); }
+  bool has_battery_counters() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> battery_counters() const { return GetRepeated<int32_t>(2); }
+  bool has_collect_power_rails() const { return at<3>().valid(); }
+  bool collect_power_rails() const { return at<3>().as_bool(); }
+  bool has_collect_energy_estimation_breakdown() const { return at<4>().valid(); }
+  bool collect_energy_estimation_breakdown() const { return at<4>().as_bool(); }
+  bool has_collect_entity_state_residency() const { return at<5>().valid(); }
+  bool collect_entity_state_residency() const { return at<5>().as_bool(); }
+};
+
+class AndroidPowerConfig : public ::protozero::Message {
+ public:
+  using Decoder = AndroidPowerConfig_Decoder;
+  enum : int32_t {
+    kBatteryPollMsFieldNumber = 1,
+    kBatteryCountersFieldNumber = 2,
+    kCollectPowerRailsFieldNumber = 3,
+    kCollectEnergyEstimationBreakdownFieldNumber = 4,
+    kCollectEntityStateResidencyFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidPowerConfig"; }
+
+
+  using BatteryCounters = ::perfetto::protos::pbzero::AndroidPowerConfig_BatteryCounters;
+  static inline const char* BatteryCounters_Name(BatteryCounters value) {
+    return ::perfetto::protos::pbzero::AndroidPowerConfig_BatteryCounters_Name(value);
+  }
+  static inline const BatteryCounters BATTERY_COUNTER_UNSPECIFIED = BatteryCounters::BATTERY_COUNTER_UNSPECIFIED;
+  static inline const BatteryCounters BATTERY_COUNTER_CHARGE = BatteryCounters::BATTERY_COUNTER_CHARGE;
+  static inline const BatteryCounters BATTERY_COUNTER_CAPACITY_PERCENT = BatteryCounters::BATTERY_COUNTER_CAPACITY_PERCENT;
+  static inline const BatteryCounters BATTERY_COUNTER_CURRENT = BatteryCounters::BATTERY_COUNTER_CURRENT;
+  static inline const BatteryCounters BATTERY_COUNTER_CURRENT_AVG = BatteryCounters::BATTERY_COUNTER_CURRENT_AVG;
+  static inline const BatteryCounters BATTERY_COUNTER_VOLTAGE = BatteryCounters::BATTERY_COUNTER_VOLTAGE;
+
+  using FieldMetadata_BatteryPollMs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AndroidPowerConfig>;
+
+  static constexpr FieldMetadata_BatteryPollMs kBatteryPollMs{};
+  void set_battery_poll_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BatteryPollMs::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_BatteryCounters =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      AndroidPowerConfig_BatteryCounters,
+      AndroidPowerConfig>;
+
+  static constexpr FieldMetadata_BatteryCounters kBatteryCounters{};
+  void add_battery_counters(AndroidPowerConfig_BatteryCounters value) {
+    static constexpr uint32_t field_id = FieldMetadata_BatteryCounters::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_CollectPowerRails =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      AndroidPowerConfig>;
+
+  static constexpr FieldMetadata_CollectPowerRails kCollectPowerRails{};
+  void set_collect_power_rails(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_CollectPowerRails::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_CollectEnergyEstimationBreakdown =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      AndroidPowerConfig>;
+
+  static constexpr FieldMetadata_CollectEnergyEstimationBreakdown kCollectEnergyEstimationBreakdown{};
+  void set_collect_energy_estimation_breakdown(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_CollectEnergyEstimationBreakdown::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_CollectEntityStateResidency =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      AndroidPowerConfig>;
+
+  static constexpr FieldMetadata_CollectEntityStateResidency kCollectEntityStateResidency{};
+  void set_collect_entity_state_residency(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_CollectEntityStateResidency::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/process_stats/process_stats_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROCESS_STATS_PROCESS_STATS_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROCESS_STATS_PROCESS_STATS_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+namespace perfetto_pbzero_enum_ProcessStatsConfig {
+enum Quirks : int32_t;
+}  // namespace perfetto_pbzero_enum_ProcessStatsConfig
+using ProcessStatsConfig_Quirks = perfetto_pbzero_enum_ProcessStatsConfig::Quirks;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_ProcessStatsConfig {
+enum Quirks : int32_t {
+  QUIRKS_UNSPECIFIED = 0,
+  DISABLE_INITIAL_DUMP = 1,
+  DISABLE_ON_DEMAND = 2,
+};
+} // namespace perfetto_pbzero_enum_ProcessStatsConfig
+using ProcessStatsConfig_Quirks = perfetto_pbzero_enum_ProcessStatsConfig::Quirks;
+
+
+constexpr ProcessStatsConfig_Quirks ProcessStatsConfig_Quirks_MIN = ProcessStatsConfig_Quirks::QUIRKS_UNSPECIFIED;
+constexpr ProcessStatsConfig_Quirks ProcessStatsConfig_Quirks_MAX = ProcessStatsConfig_Quirks::DISABLE_ON_DEMAND;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ProcessStatsConfig_Quirks_Name(::perfetto::protos::pbzero::ProcessStatsConfig_Quirks value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ProcessStatsConfig_Quirks::QUIRKS_UNSPECIFIED:
+    return "QUIRKS_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ProcessStatsConfig_Quirks::DISABLE_INITIAL_DUMP:
+    return "DISABLE_INITIAL_DUMP";
+
+  case ::perfetto::protos::pbzero::ProcessStatsConfig_Quirks::DISABLE_ON_DEMAND:
+    return "DISABLE_ON_DEMAND";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class ProcessStatsConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/12, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ProcessStatsConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProcessStatsConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProcessStatsConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_quirks() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> quirks() const { return GetRepeated<int32_t>(1); }
+  bool has_scan_all_processes_on_start() const { return at<2>().valid(); }
+  bool scan_all_processes_on_start() const { return at<2>().as_bool(); }
+  bool has_record_thread_names() const { return at<3>().valid(); }
+  bool record_thread_names() const { return at<3>().as_bool(); }
+  bool has_proc_stats_poll_ms() const { return at<4>().valid(); }
+  uint32_t proc_stats_poll_ms() const { return at<4>().as_uint32(); }
+  bool has_proc_stats_cache_ttl_ms() const { return at<6>().valid(); }
+  uint32_t proc_stats_cache_ttl_ms() const { return at<6>().as_uint32(); }
+  bool has_resolve_process_fds() const { return at<9>().valid(); }
+  bool resolve_process_fds() const { return at<9>().as_bool(); }
+  bool has_scan_smaps_rollup() const { return at<10>().valid(); }
+  bool scan_smaps_rollup() const { return at<10>().as_bool(); }
+  bool has_record_process_age() const { return at<11>().valid(); }
+  bool record_process_age() const { return at<11>().as_bool(); }
+  bool has_record_process_runtime() const { return at<12>().valid(); }
+  bool record_process_runtime() const { return at<12>().as_bool(); }
+};
+
+class ProcessStatsConfig : public ::protozero::Message {
+ public:
+  using Decoder = ProcessStatsConfig_Decoder;
+  enum : int32_t {
+    kQuirksFieldNumber = 1,
+    kScanAllProcessesOnStartFieldNumber = 2,
+    kRecordThreadNamesFieldNumber = 3,
+    kProcStatsPollMsFieldNumber = 4,
+    kProcStatsCacheTtlMsFieldNumber = 6,
+    kResolveProcessFdsFieldNumber = 9,
+    kScanSmapsRollupFieldNumber = 10,
+    kRecordProcessAgeFieldNumber = 11,
+    kRecordProcessRuntimeFieldNumber = 12,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProcessStatsConfig"; }
+
+
+  using Quirks = ::perfetto::protos::pbzero::ProcessStatsConfig_Quirks;
+  static inline const char* Quirks_Name(Quirks value) {
+    return ::perfetto::protos::pbzero::ProcessStatsConfig_Quirks_Name(value);
+  }
+  static inline const Quirks QUIRKS_UNSPECIFIED = Quirks::QUIRKS_UNSPECIFIED;
+  static inline const Quirks DISABLE_INITIAL_DUMP = Quirks::DISABLE_INITIAL_DUMP;
+  static inline const Quirks DISABLE_ON_DEMAND = Quirks::DISABLE_ON_DEMAND;
+
+  using FieldMetadata_Quirks =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ProcessStatsConfig_Quirks,
+      ProcessStatsConfig>;
+
+  static constexpr FieldMetadata_Quirks kQuirks{};
+  void add_quirks(ProcessStatsConfig_Quirks value) {
+    static constexpr uint32_t field_id = FieldMetadata_Quirks::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_ScanAllProcessesOnStart =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ProcessStatsConfig>;
+
+  static constexpr FieldMetadata_ScanAllProcessesOnStart kScanAllProcessesOnStart{};
+  void set_scan_all_processes_on_start(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ScanAllProcessesOnStart::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_RecordThreadNames =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ProcessStatsConfig>;
+
+  static constexpr FieldMetadata_RecordThreadNames kRecordThreadNames{};
+  void set_record_thread_names(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_RecordThreadNames::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_ProcStatsPollMs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ProcessStatsConfig>;
+
+  static constexpr FieldMetadata_ProcStatsPollMs kProcStatsPollMs{};
+  void set_proc_stats_poll_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProcStatsPollMs::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_ProcStatsCacheTtlMs =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ProcessStatsConfig>;
+
+  static constexpr FieldMetadata_ProcStatsCacheTtlMs kProcStatsCacheTtlMs{};
+  void set_proc_stats_cache_ttl_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProcStatsCacheTtlMs::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_ResolveProcessFds =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ProcessStatsConfig>;
+
+  static constexpr FieldMetadata_ResolveProcessFds kResolveProcessFds{};
+  void set_resolve_process_fds(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResolveProcessFds::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_ScanSmapsRollup =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ProcessStatsConfig>;
+
+  static constexpr FieldMetadata_ScanSmapsRollup kScanSmapsRollup{};
+  void set_scan_smaps_rollup(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ScanSmapsRollup::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_RecordProcessAge =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ProcessStatsConfig>;
+
+  static constexpr FieldMetadata_RecordProcessAge kRecordProcessAge{};
+  void set_record_process_age(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_RecordProcessAge::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_RecordProcessRuntime =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ProcessStatsConfig>;
+
+  static constexpr FieldMetadata_RecordProcessRuntime kRecordProcessRuntime{};
+  void set_record_process_runtime(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_RecordProcessRuntime::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/profiling/heapprofd_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_HEAPPROFD_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_HEAPPROFD_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class HeapprofdConfig_ContinuousDumpConfig;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class HeapprofdConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/27, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  HeapprofdConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit HeapprofdConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit HeapprofdConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_sampling_interval_bytes() const { return at<1>().valid(); }
+  uint64_t sampling_interval_bytes() const { return at<1>().as_uint64(); }
+  bool has_adaptive_sampling_shmem_threshold() const { return at<24>().valid(); }
+  uint64_t adaptive_sampling_shmem_threshold() const { return at<24>().as_uint64(); }
+  bool has_adaptive_sampling_max_sampling_interval_bytes() const { return at<25>().valid(); }
+  uint64_t adaptive_sampling_max_sampling_interval_bytes() const { return at<25>().as_uint64(); }
+  bool has_process_cmdline() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> process_cmdline() const { return GetRepeated<::protozero::ConstChars>(2); }
+  bool has_pid() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> pid() const { return GetRepeated<uint64_t>(4); }
+  bool has_target_installed_by() const { return at<26>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> target_installed_by() const { return GetRepeated<::protozero::ConstChars>(26); }
+  bool has_heaps() const { return at<20>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> heaps() const { return GetRepeated<::protozero::ConstChars>(20); }
+  bool has_exclude_heaps() const { return at<27>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> exclude_heaps() const { return GetRepeated<::protozero::ConstChars>(27); }
+  bool has_stream_allocations() const { return at<23>().valid(); }
+  bool stream_allocations() const { return at<23>().as_bool(); }
+  bool has_heap_sampling_intervals() const { return at<22>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> heap_sampling_intervals() const { return GetRepeated<uint64_t>(22); }
+  bool has_all_heaps() const { return at<21>().valid(); }
+  bool all_heaps() const { return at<21>().as_bool(); }
+  bool has_all() const { return at<5>().valid(); }
+  bool all() const { return at<5>().as_bool(); }
+  bool has_min_anonymous_memory_kb() const { return at<15>().valid(); }
+  uint32_t min_anonymous_memory_kb() const { return at<15>().as_uint32(); }
+  bool has_max_heapprofd_memory_kb() const { return at<16>().valid(); }
+  uint32_t max_heapprofd_memory_kb() const { return at<16>().as_uint32(); }
+  bool has_max_heapprofd_cpu_secs() const { return at<17>().valid(); }
+  uint64_t max_heapprofd_cpu_secs() const { return at<17>().as_uint64(); }
+  bool has_skip_symbol_prefix() const { return at<7>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> skip_symbol_prefix() const { return GetRepeated<::protozero::ConstChars>(7); }
+  bool has_continuous_dump_config() const { return at<6>().valid(); }
+  ::protozero::ConstBytes continuous_dump_config() const { return at<6>().as_bytes(); }
+  bool has_shmem_size_bytes() const { return at<8>().valid(); }
+  uint64_t shmem_size_bytes() const { return at<8>().as_uint64(); }
+  bool has_block_client() const { return at<9>().valid(); }
+  bool block_client() const { return at<9>().as_bool(); }
+  bool has_block_client_timeout_us() const { return at<14>().valid(); }
+  uint32_t block_client_timeout_us() const { return at<14>().as_uint32(); }
+  bool has_no_startup() const { return at<10>().valid(); }
+  bool no_startup() const { return at<10>().as_bool(); }
+  bool has_no_running() const { return at<11>().valid(); }
+  bool no_running() const { return at<11>().as_bool(); }
+  bool has_dump_at_max() const { return at<13>().valid(); }
+  bool dump_at_max() const { return at<13>().as_bool(); }
+  bool has_disable_fork_teardown() const { return at<18>().valid(); }
+  bool disable_fork_teardown() const { return at<18>().as_bool(); }
+  bool has_disable_vfork_detection() const { return at<19>().valid(); }
+  bool disable_vfork_detection() const { return at<19>().as_bool(); }
+};
+
+class HeapprofdConfig : public ::protozero::Message {
+ public:
+  using Decoder = HeapprofdConfig_Decoder;
+  enum : int32_t {
+    kSamplingIntervalBytesFieldNumber = 1,
+    kAdaptiveSamplingShmemThresholdFieldNumber = 24,
+    kAdaptiveSamplingMaxSamplingIntervalBytesFieldNumber = 25,
+    kProcessCmdlineFieldNumber = 2,
+    kPidFieldNumber = 4,
+    kTargetInstalledByFieldNumber = 26,
+    kHeapsFieldNumber = 20,
+    kExcludeHeapsFieldNumber = 27,
+    kStreamAllocationsFieldNumber = 23,
+    kHeapSamplingIntervalsFieldNumber = 22,
+    kAllHeapsFieldNumber = 21,
+    kAllFieldNumber = 5,
+    kMinAnonymousMemoryKbFieldNumber = 15,
+    kMaxHeapprofdMemoryKbFieldNumber = 16,
+    kMaxHeapprofdCpuSecsFieldNumber = 17,
+    kSkipSymbolPrefixFieldNumber = 7,
+    kContinuousDumpConfigFieldNumber = 6,
+    kShmemSizeBytesFieldNumber = 8,
+    kBlockClientFieldNumber = 9,
+    kBlockClientTimeoutUsFieldNumber = 14,
+    kNoStartupFieldNumber = 10,
+    kNoRunningFieldNumber = 11,
+    kDumpAtMaxFieldNumber = 13,
+    kDisableForkTeardownFieldNumber = 18,
+    kDisableVforkDetectionFieldNumber = 19,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.HeapprofdConfig"; }
+
+  using ContinuousDumpConfig = ::perfetto::protos::pbzero::HeapprofdConfig_ContinuousDumpConfig;
+
+  using FieldMetadata_SamplingIntervalBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_SamplingIntervalBytes kSamplingIntervalBytes{};
+  void set_sampling_interval_bytes(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SamplingIntervalBytes::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_AdaptiveSamplingShmemThreshold =
+    ::protozero::proto_utils::FieldMetadata<
+      24,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_AdaptiveSamplingShmemThreshold kAdaptiveSamplingShmemThreshold{};
+  void set_adaptive_sampling_shmem_threshold(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AdaptiveSamplingShmemThreshold::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_AdaptiveSamplingMaxSamplingIntervalBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      25,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_AdaptiveSamplingMaxSamplingIntervalBytes kAdaptiveSamplingMaxSamplingIntervalBytes{};
+  void set_adaptive_sampling_max_sampling_interval_bytes(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AdaptiveSamplingMaxSamplingIntervalBytes::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_ProcessCmdline =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_ProcessCmdline kProcessCmdline{};
+  void add_process_cmdline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ProcessCmdline::kFieldId, data, size);
+  }
+  void add_process_cmdline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ProcessCmdline::kFieldId, chars.data, chars.size);
+  }
+  void add_process_cmdline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProcessCmdline::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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void add_pid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_TargetInstalledBy =
+    ::protozero::proto_utils::FieldMetadata<
+      26,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_TargetInstalledBy kTargetInstalledBy{};
+  void add_target_installed_by(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TargetInstalledBy::kFieldId, data, size);
+  }
+  void add_target_installed_by(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_TargetInstalledBy::kFieldId, chars.data, chars.size);
+  }
+  void add_target_installed_by(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_TargetInstalledBy::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_Heaps =
+    ::protozero::proto_utils::FieldMetadata<
+      20,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_Heaps kHeaps{};
+  void add_heaps(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Heaps::kFieldId, data, size);
+  }
+  void add_heaps(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Heaps::kFieldId, chars.data, chars.size);
+  }
+  void add_heaps(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Heaps::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_ExcludeHeaps =
+    ::protozero::proto_utils::FieldMetadata<
+      27,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_ExcludeHeaps kExcludeHeaps{};
+  void add_exclude_heaps(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ExcludeHeaps::kFieldId, data, size);
+  }
+  void add_exclude_heaps(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ExcludeHeaps::kFieldId, chars.data, chars.size);
+  }
+  void add_exclude_heaps(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ExcludeHeaps::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_StreamAllocations =
+    ::protozero::proto_utils::FieldMetadata<
+      23,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_StreamAllocations kStreamAllocations{};
+  void set_stream_allocations(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_StreamAllocations::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_HeapSamplingIntervals =
+    ::protozero::proto_utils::FieldMetadata<
+      22,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_HeapSamplingIntervals kHeapSamplingIntervals{};
+  void add_heap_sampling_intervals(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_HeapSamplingIntervals::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_AllHeaps =
+    ::protozero::proto_utils::FieldMetadata<
+      21,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_AllHeaps kAllHeaps{};
+  void set_all_heaps(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_AllHeaps::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_All =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_All kAll{};
+  void set_all(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_All::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_MinAnonymousMemoryKb =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_MinAnonymousMemoryKb kMinAnonymousMemoryKb{};
+  void set_min_anonymous_memory_kb(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MinAnonymousMemoryKb::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_MaxHeapprofdMemoryKb =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_MaxHeapprofdMemoryKb kMaxHeapprofdMemoryKb{};
+  void set_max_heapprofd_memory_kb(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MaxHeapprofdMemoryKb::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_MaxHeapprofdCpuSecs =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_MaxHeapprofdCpuSecs kMaxHeapprofdCpuSecs{};
+  void set_max_heapprofd_cpu_secs(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MaxHeapprofdCpuSecs::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_SkipSymbolPrefix =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_SkipSymbolPrefix kSkipSymbolPrefix{};
+  void add_skip_symbol_prefix(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_SkipSymbolPrefix::kFieldId, data, size);
+  }
+  void add_skip_symbol_prefix(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_SkipSymbolPrefix::kFieldId, chars.data, chars.size);
+  }
+  void add_skip_symbol_prefix(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_SkipSymbolPrefix::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_ContinuousDumpConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      HeapprofdConfig_ContinuousDumpConfig,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_ContinuousDumpConfig kContinuousDumpConfig{};
+  template <typename T = HeapprofdConfig_ContinuousDumpConfig> T* set_continuous_dump_config() {
+    return BeginNestedMessage<T>(6);
+  }
+
+
+  using FieldMetadata_ShmemSizeBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_ShmemSizeBytes kShmemSizeBytes{};
+  void set_shmem_size_bytes(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ShmemSizeBytes::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_BlockClient =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_BlockClient kBlockClient{};
+  void set_block_client(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_BlockClient::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_BlockClientTimeoutUs =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_BlockClientTimeoutUs kBlockClientTimeoutUs{};
+  void set_block_client_timeout_us(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BlockClientTimeoutUs::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_NoStartup =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_NoStartup kNoStartup{};
+  void set_no_startup(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_NoStartup::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_NoRunning =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_NoRunning kNoRunning{};
+  void set_no_running(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_NoRunning::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_DumpAtMax =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_DumpAtMax kDumpAtMax{};
+  void set_dump_at_max(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DumpAtMax::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_DisableForkTeardown =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_DisableForkTeardown kDisableForkTeardown{};
+  void set_disable_fork_teardown(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DisableForkTeardown::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_DisableVforkDetection =
+    ::protozero::proto_utils::FieldMetadata<
+      19,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_DisableVforkDetection kDisableVforkDetection{};
+  void set_disable_vfork_detection(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DisableVforkDetection::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 HeapprofdConfig_ContinuousDumpConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  HeapprofdConfig_ContinuousDumpConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit HeapprofdConfig_ContinuousDumpConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit HeapprofdConfig_ContinuousDumpConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dump_phase_ms() const { return at<5>().valid(); }
+  uint32_t dump_phase_ms() const { return at<5>().as_uint32(); }
+  bool has_dump_interval_ms() const { return at<6>().valid(); }
+  uint32_t dump_interval_ms() const { return at<6>().as_uint32(); }
+};
+
+class HeapprofdConfig_ContinuousDumpConfig : public ::protozero::Message {
+ public:
+  using Decoder = HeapprofdConfig_ContinuousDumpConfig_Decoder;
+  enum : int32_t {
+    kDumpPhaseMsFieldNumber = 5,
+    kDumpIntervalMsFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.HeapprofdConfig.ContinuousDumpConfig"; }
+
+
+  using FieldMetadata_DumpPhaseMs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      HeapprofdConfig_ContinuousDumpConfig>;
+
+  static constexpr FieldMetadata_DumpPhaseMs kDumpPhaseMs{};
+  void set_dump_phase_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DumpPhaseMs::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_DumpIntervalMs =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      HeapprofdConfig_ContinuousDumpConfig>;
+
+  static constexpr FieldMetadata_DumpIntervalMs kDumpIntervalMs{};
+  void set_dump_interval_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DumpIntervalMs::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/profiling/java_hprof_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_JAVA_HPROF_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_JAVA_HPROF_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class JavaHprofConfig_ContinuousDumpConfig;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class JavaHprofConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  JavaHprofConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit JavaHprofConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit JavaHprofConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_process_cmdline() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> process_cmdline() const { return GetRepeated<::protozero::ConstChars>(1); }
+  bool has_pid() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> pid() const { return GetRepeated<uint64_t>(2); }
+  bool has_target_installed_by() const { return at<7>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> target_installed_by() const { return GetRepeated<::protozero::ConstChars>(7); }
+  bool has_continuous_dump_config() const { return at<3>().valid(); }
+  ::protozero::ConstBytes continuous_dump_config() const { return at<3>().as_bytes(); }
+  bool has_min_anonymous_memory_kb() const { return at<4>().valid(); }
+  uint32_t min_anonymous_memory_kb() const { return at<4>().as_uint32(); }
+  bool has_dump_smaps() const { return at<5>().valid(); }
+  bool dump_smaps() const { return at<5>().as_bool(); }
+  bool has_ignored_types() const { return at<6>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> ignored_types() const { return GetRepeated<::protozero::ConstChars>(6); }
+};
+
+class JavaHprofConfig : public ::protozero::Message {
+ public:
+  using Decoder = JavaHprofConfig_Decoder;
+  enum : int32_t {
+    kProcessCmdlineFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kTargetInstalledByFieldNumber = 7,
+    kContinuousDumpConfigFieldNumber = 3,
+    kMinAnonymousMemoryKbFieldNumber = 4,
+    kDumpSmapsFieldNumber = 5,
+    kIgnoredTypesFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.JavaHprofConfig"; }
+
+  using ContinuousDumpConfig = ::perfetto::protos::pbzero::JavaHprofConfig_ContinuousDumpConfig;
+
+  using FieldMetadata_ProcessCmdline =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      JavaHprofConfig>;
+
+  static constexpr FieldMetadata_ProcessCmdline kProcessCmdline{};
+  void add_process_cmdline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ProcessCmdline::kFieldId, data, size);
+  }
+  void add_process_cmdline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ProcessCmdline::kFieldId, chars.data, chars.size);
+  }
+  void add_process_cmdline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProcessCmdline::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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      JavaHprofConfig>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void add_pid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_TargetInstalledBy =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      JavaHprofConfig>;
+
+  static constexpr FieldMetadata_TargetInstalledBy kTargetInstalledBy{};
+  void add_target_installed_by(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TargetInstalledBy::kFieldId, data, size);
+  }
+  void add_target_installed_by(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_TargetInstalledBy::kFieldId, chars.data, chars.size);
+  }
+  void add_target_installed_by(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_TargetInstalledBy::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_ContinuousDumpConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      JavaHprofConfig_ContinuousDumpConfig,
+      JavaHprofConfig>;
+
+  static constexpr FieldMetadata_ContinuousDumpConfig kContinuousDumpConfig{};
+  template <typename T = JavaHprofConfig_ContinuousDumpConfig> T* set_continuous_dump_config() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_MinAnonymousMemoryKb =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      JavaHprofConfig>;
+
+  static constexpr FieldMetadata_MinAnonymousMemoryKb kMinAnonymousMemoryKb{};
+  void set_min_anonymous_memory_kb(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MinAnonymousMemoryKb::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_DumpSmaps =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      JavaHprofConfig>;
+
+  static constexpr FieldMetadata_DumpSmaps kDumpSmaps{};
+  void set_dump_smaps(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DumpSmaps::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_IgnoredTypes =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      JavaHprofConfig>;
+
+  static constexpr FieldMetadata_IgnoredTypes kIgnoredTypes{};
+  void add_ignored_types(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_IgnoredTypes::kFieldId, data, size);
+  }
+  void add_ignored_types(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_IgnoredTypes::kFieldId, chars.data, chars.size);
+  }
+  void add_ignored_types(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_IgnoredTypes::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 JavaHprofConfig_ContinuousDumpConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  JavaHprofConfig_ContinuousDumpConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit JavaHprofConfig_ContinuousDumpConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit JavaHprofConfig_ContinuousDumpConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dump_phase_ms() const { return at<1>().valid(); }
+  uint32_t dump_phase_ms() const { return at<1>().as_uint32(); }
+  bool has_dump_interval_ms() const { return at<2>().valid(); }
+  uint32_t dump_interval_ms() const { return at<2>().as_uint32(); }
+  bool has_scan_pids_only_on_start() const { return at<3>().valid(); }
+  bool scan_pids_only_on_start() const { return at<3>().as_bool(); }
+};
+
+class JavaHprofConfig_ContinuousDumpConfig : public ::protozero::Message {
+ public:
+  using Decoder = JavaHprofConfig_ContinuousDumpConfig_Decoder;
+  enum : int32_t {
+    kDumpPhaseMsFieldNumber = 1,
+    kDumpIntervalMsFieldNumber = 2,
+    kScanPidsOnlyOnStartFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.JavaHprofConfig.ContinuousDumpConfig"; }
+
+
+  using FieldMetadata_DumpPhaseMs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      JavaHprofConfig_ContinuousDumpConfig>;
+
+  static constexpr FieldMetadata_DumpPhaseMs kDumpPhaseMs{};
+  void set_dump_phase_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DumpPhaseMs::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_DumpIntervalMs =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      JavaHprofConfig_ContinuousDumpConfig>;
+
+  static constexpr FieldMetadata_DumpIntervalMs kDumpIntervalMs{};
+  void set_dump_interval_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DumpIntervalMs::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_ScanPidsOnlyOnStart =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      JavaHprofConfig_ContinuousDumpConfig>;
+
+  static constexpr FieldMetadata_ScanPidsOnlyOnStart kScanPidsOnlyOnStart{};
+  void set_scan_pids_only_on_start(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ScanPidsOnlyOnStart::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/profiling/perf_event_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_PERF_EVENT_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_PERF_EVENT_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class PerfEventConfig_CallstackSampling;
+class PerfEventConfig_Scope;
+class PerfEvents_Timebase;
+namespace perfetto_pbzero_enum_PerfEventConfig {
+enum UnwindMode : int32_t;
+}  // namespace perfetto_pbzero_enum_PerfEventConfig
+using PerfEventConfig_UnwindMode = perfetto_pbzero_enum_PerfEventConfig::UnwindMode;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_PerfEventConfig {
+enum UnwindMode : int32_t {
+  UNWIND_UNKNOWN = 0,
+  UNWIND_SKIP = 1,
+  UNWIND_DWARF = 2,
+};
+} // namespace perfetto_pbzero_enum_PerfEventConfig
+using PerfEventConfig_UnwindMode = perfetto_pbzero_enum_PerfEventConfig::UnwindMode;
+
+
+constexpr PerfEventConfig_UnwindMode PerfEventConfig_UnwindMode_MIN = PerfEventConfig_UnwindMode::UNWIND_UNKNOWN;
+constexpr PerfEventConfig_UnwindMode PerfEventConfig_UnwindMode_MAX = PerfEventConfig_UnwindMode::UNWIND_DWARF;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* PerfEventConfig_UnwindMode_Name(::perfetto::protos::pbzero::PerfEventConfig_UnwindMode value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::PerfEventConfig_UnwindMode::UNWIND_UNKNOWN:
+    return "UNWIND_UNKNOWN";
+
+  case ::perfetto::protos::pbzero::PerfEventConfig_UnwindMode::UNWIND_SKIP:
+    return "UNWIND_SKIP";
+
+  case ::perfetto::protos::pbzero::PerfEventConfig_UnwindMode::UNWIND_DWARF:
+    return "UNWIND_DWARF";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class PerfEventConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/18, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  PerfEventConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PerfEventConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PerfEventConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_timebase() const { return at<15>().valid(); }
+  ::protozero::ConstBytes timebase() const { return at<15>().as_bytes(); }
+  bool has_callstack_sampling() const { return at<16>().valid(); }
+  ::protozero::ConstBytes callstack_sampling() const { return at<16>().as_bytes(); }
+  bool has_ring_buffer_read_period_ms() const { return at<8>().valid(); }
+  uint32_t ring_buffer_read_period_ms() const { return at<8>().as_uint32(); }
+  bool has_ring_buffer_pages() const { return at<3>().valid(); }
+  uint32_t ring_buffer_pages() const { return at<3>().as_uint32(); }
+  bool has_max_enqueued_footprint_kb() const { return at<17>().valid(); }
+  uint64_t max_enqueued_footprint_kb() const { return at<17>().as_uint64(); }
+  bool has_max_daemon_memory_kb() const { return at<13>().valid(); }
+  uint32_t max_daemon_memory_kb() const { return at<13>().as_uint32(); }
+  bool has_remote_descriptor_timeout_ms() const { return at<9>().valid(); }
+  uint32_t remote_descriptor_timeout_ms() const { return at<9>().as_uint32(); }
+  bool has_unwind_state_clear_period_ms() const { return at<10>().valid(); }
+  uint32_t unwind_state_clear_period_ms() const { return at<10>().as_uint32(); }
+  bool has_target_installed_by() const { return at<18>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> target_installed_by() const { return GetRepeated<::protozero::ConstChars>(18); }
+  bool has_all_cpus() const { return at<1>().valid(); }
+  bool all_cpus() const { return at<1>().as_bool(); }
+  bool has_sampling_frequency() const { return at<2>().valid(); }
+  uint32_t sampling_frequency() const { return at<2>().as_uint32(); }
+  bool has_kernel_frames() const { return at<12>().valid(); }
+  bool kernel_frames() const { return at<12>().as_bool(); }
+  bool has_target_pid() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> target_pid() const { return GetRepeated<int32_t>(4); }
+  bool has_target_cmdline() const { return at<5>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> target_cmdline() const { return GetRepeated<::protozero::ConstChars>(5); }
+  bool has_exclude_pid() const { return at<6>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> exclude_pid() const { return GetRepeated<int32_t>(6); }
+  bool has_exclude_cmdline() const { return at<7>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> exclude_cmdline() const { return GetRepeated<::protozero::ConstChars>(7); }
+  bool has_additional_cmdline_count() const { return at<11>().valid(); }
+  uint32_t additional_cmdline_count() const { return at<11>().as_uint32(); }
+};
+
+class PerfEventConfig : public ::protozero::Message {
+ public:
+  using Decoder = PerfEventConfig_Decoder;
+  enum : int32_t {
+    kTimebaseFieldNumber = 15,
+    kCallstackSamplingFieldNumber = 16,
+    kRingBufferReadPeriodMsFieldNumber = 8,
+    kRingBufferPagesFieldNumber = 3,
+    kMaxEnqueuedFootprintKbFieldNumber = 17,
+    kMaxDaemonMemoryKbFieldNumber = 13,
+    kRemoteDescriptorTimeoutMsFieldNumber = 9,
+    kUnwindStateClearPeriodMsFieldNumber = 10,
+    kTargetInstalledByFieldNumber = 18,
+    kAllCpusFieldNumber = 1,
+    kSamplingFrequencyFieldNumber = 2,
+    kKernelFramesFieldNumber = 12,
+    kTargetPidFieldNumber = 4,
+    kTargetCmdlineFieldNumber = 5,
+    kExcludePidFieldNumber = 6,
+    kExcludeCmdlineFieldNumber = 7,
+    kAdditionalCmdlineCountFieldNumber = 11,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PerfEventConfig"; }
+
+  using CallstackSampling = ::perfetto::protos::pbzero::PerfEventConfig_CallstackSampling;
+  using Scope = ::perfetto::protos::pbzero::PerfEventConfig_Scope;
+
+  using UnwindMode = ::perfetto::protos::pbzero::PerfEventConfig_UnwindMode;
+  static inline const char* UnwindMode_Name(UnwindMode value) {
+    return ::perfetto::protos::pbzero::PerfEventConfig_UnwindMode_Name(value);
+  }
+  static inline const UnwindMode UNWIND_UNKNOWN = UnwindMode::UNWIND_UNKNOWN;
+  static inline const UnwindMode UNWIND_SKIP = UnwindMode::UNWIND_SKIP;
+  static inline const UnwindMode UNWIND_DWARF = UnwindMode::UNWIND_DWARF;
+
+  using FieldMetadata_Timebase =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PerfEvents_Timebase,
+      PerfEventConfig>;
+
+  static constexpr FieldMetadata_Timebase kTimebase{};
+  template <typename T = PerfEvents_Timebase> T* set_timebase() {
+    return BeginNestedMessage<T>(15);
+  }
+
+
+  using FieldMetadata_CallstackSampling =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PerfEventConfig_CallstackSampling,
+      PerfEventConfig>;
+
+  static constexpr FieldMetadata_CallstackSampling kCallstackSampling{};
+  template <typename T = PerfEventConfig_CallstackSampling> T* set_callstack_sampling() {
+    return BeginNestedMessage<T>(16);
+  }
+
+
+  using FieldMetadata_RingBufferReadPeriodMs =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfEventConfig>;
+
+  static constexpr FieldMetadata_RingBufferReadPeriodMs kRingBufferReadPeriodMs{};
+  void set_ring_buffer_read_period_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RingBufferReadPeriodMs::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_RingBufferPages =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfEventConfig>;
+
+  static constexpr FieldMetadata_RingBufferPages kRingBufferPages{};
+  void set_ring_buffer_pages(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RingBufferPages::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_MaxEnqueuedFootprintKb =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PerfEventConfig>;
+
+  static constexpr FieldMetadata_MaxEnqueuedFootprintKb kMaxEnqueuedFootprintKb{};
+  void set_max_enqueued_footprint_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MaxEnqueuedFootprintKb::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_MaxDaemonMemoryKb =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfEventConfig>;
+
+  static constexpr FieldMetadata_MaxDaemonMemoryKb kMaxDaemonMemoryKb{};
+  void set_max_daemon_memory_kb(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MaxDaemonMemoryKb::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_RemoteDescriptorTimeoutMs =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfEventConfig>;
+
+  static constexpr FieldMetadata_RemoteDescriptorTimeoutMs kRemoteDescriptorTimeoutMs{};
+  void set_remote_descriptor_timeout_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RemoteDescriptorTimeoutMs::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_UnwindStateClearPeriodMs =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfEventConfig>;
+
+  static constexpr FieldMetadata_UnwindStateClearPeriodMs kUnwindStateClearPeriodMs{};
+  void set_unwind_state_clear_period_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UnwindStateClearPeriodMs::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_TargetInstalledBy =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PerfEventConfig>;
+
+  static constexpr FieldMetadata_TargetInstalledBy kTargetInstalledBy{};
+  void add_target_installed_by(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TargetInstalledBy::kFieldId, data, size);
+  }
+  void add_target_installed_by(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_TargetInstalledBy::kFieldId, chars.data, chars.size);
+  }
+  void add_target_installed_by(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_TargetInstalledBy::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_AllCpus =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      PerfEventConfig>;
+
+  static constexpr FieldMetadata_AllCpus kAllCpus{};
+  void set_all_cpus(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_AllCpus::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_SamplingFrequency =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfEventConfig>;
+
+  static constexpr FieldMetadata_SamplingFrequency kSamplingFrequency{};
+  void set_sampling_frequency(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SamplingFrequency::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_KernelFrames =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      PerfEventConfig>;
+
+  static constexpr FieldMetadata_KernelFrames kKernelFrames{};
+  void set_kernel_frames(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_KernelFrames::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_TargetPid =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      PerfEventConfig>;
+
+  static constexpr FieldMetadata_TargetPid kTargetPid{};
+  void add_target_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TargetPid::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_TargetCmdline =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PerfEventConfig>;
+
+  static constexpr FieldMetadata_TargetCmdline kTargetCmdline{};
+  void add_target_cmdline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TargetCmdline::kFieldId, data, size);
+  }
+  void add_target_cmdline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_TargetCmdline::kFieldId, chars.data, chars.size);
+  }
+  void add_target_cmdline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_TargetCmdline::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_ExcludePid =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      PerfEventConfig>;
+
+  static constexpr FieldMetadata_ExcludePid kExcludePid{};
+  void add_exclude_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ExcludePid::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_ExcludeCmdline =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PerfEventConfig>;
+
+  static constexpr FieldMetadata_ExcludeCmdline kExcludeCmdline{};
+  void add_exclude_cmdline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ExcludeCmdline::kFieldId, data, size);
+  }
+  void add_exclude_cmdline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ExcludeCmdline::kFieldId, chars.data, chars.size);
+  }
+  void add_exclude_cmdline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ExcludeCmdline::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_AdditionalCmdlineCount =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfEventConfig>;
+
+  static constexpr FieldMetadata_AdditionalCmdlineCount kAdditionalCmdlineCount{};
+  void set_additional_cmdline_count(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AdditionalCmdlineCount::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 PerfEventConfig_Scope_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  PerfEventConfig_Scope_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PerfEventConfig_Scope_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PerfEventConfig_Scope_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_target_pid() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> target_pid() const { return GetRepeated<int32_t>(1); }
+  bool has_target_cmdline() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> target_cmdline() const { return GetRepeated<::protozero::ConstChars>(2); }
+  bool has_exclude_pid() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> exclude_pid() const { return GetRepeated<int32_t>(3); }
+  bool has_exclude_cmdline() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> exclude_cmdline() const { return GetRepeated<::protozero::ConstChars>(4); }
+  bool has_additional_cmdline_count() const { return at<5>().valid(); }
+  uint32_t additional_cmdline_count() const { return at<5>().as_uint32(); }
+  bool has_process_shard_count() const { return at<6>().valid(); }
+  uint32_t process_shard_count() const { return at<6>().as_uint32(); }
+};
+
+class PerfEventConfig_Scope : public ::protozero::Message {
+ public:
+  using Decoder = PerfEventConfig_Scope_Decoder;
+  enum : int32_t {
+    kTargetPidFieldNumber = 1,
+    kTargetCmdlineFieldNumber = 2,
+    kExcludePidFieldNumber = 3,
+    kExcludeCmdlineFieldNumber = 4,
+    kAdditionalCmdlineCountFieldNumber = 5,
+    kProcessShardCountFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PerfEventConfig.Scope"; }
+
+
+  using FieldMetadata_TargetPid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      PerfEventConfig_Scope>;
+
+  static constexpr FieldMetadata_TargetPid kTargetPid{};
+  void add_target_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TargetPid::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_TargetCmdline =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PerfEventConfig_Scope>;
+
+  static constexpr FieldMetadata_TargetCmdline kTargetCmdline{};
+  void add_target_cmdline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TargetCmdline::kFieldId, data, size);
+  }
+  void add_target_cmdline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_TargetCmdline::kFieldId, chars.data, chars.size);
+  }
+  void add_target_cmdline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_TargetCmdline::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_ExcludePid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      PerfEventConfig_Scope>;
+
+  static constexpr FieldMetadata_ExcludePid kExcludePid{};
+  void add_exclude_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ExcludePid::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_ExcludeCmdline =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PerfEventConfig_Scope>;
+
+  static constexpr FieldMetadata_ExcludeCmdline kExcludeCmdline{};
+  void add_exclude_cmdline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ExcludeCmdline::kFieldId, data, size);
+  }
+  void add_exclude_cmdline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ExcludeCmdline::kFieldId, chars.data, chars.size);
+  }
+  void add_exclude_cmdline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ExcludeCmdline::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_AdditionalCmdlineCount =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfEventConfig_Scope>;
+
+  static constexpr FieldMetadata_AdditionalCmdlineCount kAdditionalCmdlineCount{};
+  void set_additional_cmdline_count(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AdditionalCmdlineCount::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_ProcessShardCount =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfEventConfig_Scope>;
+
+  static constexpr FieldMetadata_ProcessShardCount kProcessShardCount{};
+  void set_process_shard_count(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProcessShardCount::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 PerfEventConfig_CallstackSampling_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  PerfEventConfig_CallstackSampling_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PerfEventConfig_CallstackSampling_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PerfEventConfig_CallstackSampling_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_scope() const { return at<1>().valid(); }
+  ::protozero::ConstBytes scope() const { return at<1>().as_bytes(); }
+  bool has_kernel_frames() const { return at<2>().valid(); }
+  bool kernel_frames() const { return at<2>().as_bool(); }
+  bool has_user_frames() const { return at<3>().valid(); }
+  int32_t user_frames() const { return at<3>().as_int32(); }
+};
+
+class PerfEventConfig_CallstackSampling : public ::protozero::Message {
+ public:
+  using Decoder = PerfEventConfig_CallstackSampling_Decoder;
+  enum : int32_t {
+    kScopeFieldNumber = 1,
+    kKernelFramesFieldNumber = 2,
+    kUserFramesFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PerfEventConfig.CallstackSampling"; }
+
+
+  using FieldMetadata_Scope =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PerfEventConfig_Scope,
+      PerfEventConfig_CallstackSampling>;
+
+  static constexpr FieldMetadata_Scope kScope{};
+  template <typename T = PerfEventConfig_Scope> T* set_scope() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_KernelFrames =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      PerfEventConfig_CallstackSampling>;
+
+  static constexpr FieldMetadata_KernelFrames kKernelFrames{};
+  void set_kernel_frames(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_KernelFrames::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_UserFrames =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      PerfEventConfig_UnwindMode,
+      PerfEventConfig_CallstackSampling>;
+
+  static constexpr FieldMetadata_UserFrames kUserFrames{};
+  void set_user_frames(PerfEventConfig_UnwindMode value) {
+    static constexpr uint32_t field_id = FieldMetadata_UserFrames::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.
+// gen_amalgamated begin header: gen/protos/perfetto/config/statsd/atom_ids.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STATSD_ATOM_IDS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STATSD_ATOM_IDS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+enum AtomId : int32_t {
+  ATOM_UNSPECIFIED = 0,
+  ATOM_BLE_SCAN_STATE_CHANGED = 2,
+  ATOM_PROCESS_STATE_CHANGED = 3,
+  ATOM_BLE_SCAN_RESULT_RECEIVED = 4,
+  ATOM_SENSOR_STATE_CHANGED = 5,
+  ATOM_GPS_SCAN_STATE_CHANGED = 6,
+  ATOM_SYNC_STATE_CHANGED = 7,
+  ATOM_SCHEDULED_JOB_STATE_CHANGED = 8,
+  ATOM_SCREEN_BRIGHTNESS_CHANGED = 9,
+  ATOM_WAKELOCK_STATE_CHANGED = 10,
+  ATOM_LONG_PARTIAL_WAKELOCK_STATE_CHANGED = 11,
+  ATOM_MOBILE_RADIO_POWER_STATE_CHANGED = 12,
+  ATOM_WIFI_RADIO_POWER_STATE_CHANGED = 13,
+  ATOM_ACTIVITY_MANAGER_SLEEP_STATE_CHANGED = 14,
+  ATOM_MEMORY_FACTOR_STATE_CHANGED = 15,
+  ATOM_EXCESSIVE_CPU_USAGE_REPORTED = 16,
+  ATOM_CACHED_KILL_REPORTED = 17,
+  ATOM_PROCESS_MEMORY_STAT_REPORTED = 18,
+  ATOM_LAUNCHER_EVENT = 19,
+  ATOM_BATTERY_SAVER_MODE_STATE_CHANGED = 20,
+  ATOM_DEVICE_IDLE_MODE_STATE_CHANGED = 21,
+  ATOM_DEVICE_IDLING_MODE_STATE_CHANGED = 22,
+  ATOM_AUDIO_STATE_CHANGED = 23,
+  ATOM_MEDIA_CODEC_STATE_CHANGED = 24,
+  ATOM_CAMERA_STATE_CHANGED = 25,
+  ATOM_FLASHLIGHT_STATE_CHANGED = 26,
+  ATOM_UID_PROCESS_STATE_CHANGED = 27,
+  ATOM_PROCESS_LIFE_CYCLE_STATE_CHANGED = 28,
+  ATOM_SCREEN_STATE_CHANGED = 29,
+  ATOM_BATTERY_LEVEL_CHANGED = 30,
+  ATOM_CHARGING_STATE_CHANGED = 31,
+  ATOM_PLUGGED_STATE_CHANGED = 32,
+  ATOM_INTERACTIVE_STATE_CHANGED = 33,
+  ATOM_TOUCH_EVENT_REPORTED = 34,
+  ATOM_WAKEUP_ALARM_OCCURRED = 35,
+  ATOM_KERNEL_WAKEUP_REPORTED = 36,
+  ATOM_WIFI_LOCK_STATE_CHANGED = 37,
+  ATOM_WIFI_SIGNAL_STRENGTH_CHANGED = 38,
+  ATOM_WIFI_SCAN_STATE_CHANGED = 39,
+  ATOM_PHONE_SIGNAL_STRENGTH_CHANGED = 40,
+  ATOM_SETTING_CHANGED = 41,
+  ATOM_ACTIVITY_FOREGROUND_STATE_CHANGED = 42,
+  ATOM_ISOLATED_UID_CHANGED = 43,
+  ATOM_PACKET_WAKEUP_OCCURRED = 44,
+  ATOM_WALL_CLOCK_TIME_SHIFTED = 45,
+  ATOM_ANOMALY_DETECTED = 46,
+  ATOM_APP_BREADCRUMB_REPORTED = 47,
+  ATOM_APP_START_OCCURRED = 48,
+  ATOM_APP_START_CANCELED = 49,
+  ATOM_APP_START_FULLY_DRAWN = 50,
+  ATOM_LMK_KILL_OCCURRED = 51,
+  ATOM_PICTURE_IN_PICTURE_STATE_CHANGED = 52,
+  ATOM_WIFI_MULTICAST_LOCK_STATE_CHANGED = 53,
+  ATOM_LMK_STATE_CHANGED = 54,
+  ATOM_APP_START_MEMORY_STATE_CAPTURED = 55,
+  ATOM_SHUTDOWN_SEQUENCE_REPORTED = 56,
+  ATOM_BOOT_SEQUENCE_REPORTED = 57,
+  ATOM_DAVEY_OCCURRED = 58,
+  ATOM_OVERLAY_STATE_CHANGED = 59,
+  ATOM_FOREGROUND_SERVICE_STATE_CHANGED = 60,
+  ATOM_CALL_STATE_CHANGED = 61,
+  ATOM_KEYGUARD_STATE_CHANGED = 62,
+  ATOM_KEYGUARD_BOUNCER_STATE_CHANGED = 63,
+  ATOM_KEYGUARD_BOUNCER_PASSWORD_ENTERED = 64,
+  ATOM_APP_DIED = 65,
+  ATOM_RESOURCE_CONFIGURATION_CHANGED = 66,
+  ATOM_BLUETOOTH_ENABLED_STATE_CHANGED = 67,
+  ATOM_BLUETOOTH_CONNECTION_STATE_CHANGED = 68,
+  ATOM_GPS_SIGNAL_QUALITY_CHANGED = 69,
+  ATOM_USB_CONNECTOR_STATE_CHANGED = 70,
+  ATOM_SPEAKER_IMPEDANCE_REPORTED = 71,
+  ATOM_HARDWARE_FAILED = 72,
+  ATOM_PHYSICAL_DROP_DETECTED = 73,
+  ATOM_CHARGE_CYCLES_REPORTED = 74,
+  ATOM_MOBILE_CONNECTION_STATE_CHANGED = 75,
+  ATOM_MOBILE_RADIO_TECHNOLOGY_CHANGED = 76,
+  ATOM_USB_DEVICE_ATTACHED = 77,
+  ATOM_APP_CRASH_OCCURRED = 78,
+  ATOM_ANR_OCCURRED = 79,
+  ATOM_WTF_OCCURRED = 80,
+  ATOM_LOW_MEM_REPORTED = 81,
+  ATOM_GENERIC_ATOM = 82,
+  ATOM_VIBRATOR_STATE_CHANGED = 84,
+  ATOM_DEFERRED_JOB_STATS_REPORTED = 85,
+  ATOM_THERMAL_THROTTLING = 86,
+  ATOM_BIOMETRIC_ACQUIRED = 87,
+  ATOM_BIOMETRIC_AUTHENTICATED = 88,
+  ATOM_BIOMETRIC_ERROR_OCCURRED = 89,
+  ATOM_UI_EVENT_REPORTED = 90,
+  ATOM_BATTERY_HEALTH_SNAPSHOT = 91,
+  ATOM_SLOW_IO = 92,
+  ATOM_BATTERY_CAUSED_SHUTDOWN = 93,
+  ATOM_PHONE_SERVICE_STATE_CHANGED = 94,
+  ATOM_PHONE_STATE_CHANGED = 95,
+  ATOM_USER_RESTRICTION_CHANGED = 96,
+  ATOM_SETTINGS_UI_CHANGED = 97,
+  ATOM_CONNECTIVITY_STATE_CHANGED = 98,
+  ATOM_SERVICE_STATE_CHANGED = 99,
+  ATOM_SERVICE_LAUNCH_REPORTED = 100,
+  ATOM_FLAG_FLIP_UPDATE_OCCURRED = 101,
+  ATOM_BINARY_PUSH_STATE_CHANGED = 102,
+  ATOM_DEVICE_POLICY_EVENT = 103,
+  ATOM_DOCS_UI_FILE_OP_CANCELED = 104,
+  ATOM_DOCS_UI_FILE_OP_COPY_MOVE_MODE_REPORTED = 105,
+  ATOM_DOCS_UI_FILE_OP_FAILURE = 106,
+  ATOM_DOCS_UI_PROVIDER_FILE_OP = 107,
+  ATOM_DOCS_UI_INVALID_SCOPED_ACCESS_REQUEST = 108,
+  ATOM_DOCS_UI_LAUNCH_REPORTED = 109,
+  ATOM_DOCS_UI_ROOT_VISITED = 110,
+  ATOM_DOCS_UI_STARTUP_MS = 111,
+  ATOM_DOCS_UI_USER_ACTION_REPORTED = 112,
+  ATOM_WIFI_ENABLED_STATE_CHANGED = 113,
+  ATOM_WIFI_RUNNING_STATE_CHANGED = 114,
+  ATOM_APP_COMPACTED = 115,
+  ATOM_NETWORK_DNS_EVENT_REPORTED = 116,
+  ATOM_DOCS_UI_PICKER_LAUNCHED_FROM_REPORTED = 117,
+  ATOM_DOCS_UI_PICK_RESULT_REPORTED = 118,
+  ATOM_DOCS_UI_SEARCH_MODE_REPORTED = 119,
+  ATOM_DOCS_UI_SEARCH_TYPE_REPORTED = 120,
+  ATOM_DATA_STALL_EVENT = 121,
+  ATOM_RESCUE_PARTY_RESET_REPORTED = 122,
+  ATOM_SIGNED_CONFIG_REPORTED = 123,
+  ATOM_GNSS_NI_EVENT_REPORTED = 124,
+  ATOM_BLUETOOTH_LINK_LAYER_CONNECTION_EVENT = 125,
+  ATOM_BLUETOOTH_ACL_CONNECTION_STATE_CHANGED = 126,
+  ATOM_BLUETOOTH_SCO_CONNECTION_STATE_CHANGED = 127,
+  ATOM_APP_DOWNGRADED = 128,
+  ATOM_APP_OPTIMIZED_AFTER_DOWNGRADED = 129,
+  ATOM_LOW_STORAGE_STATE_CHANGED = 130,
+  ATOM_GNSS_NFW_NOTIFICATION_REPORTED = 131,
+  ATOM_GNSS_CONFIGURATION_REPORTED = 132,
+  ATOM_USB_PORT_OVERHEAT_EVENT_REPORTED = 133,
+  ATOM_NFC_ERROR_OCCURRED = 134,
+  ATOM_NFC_STATE_CHANGED = 135,
+  ATOM_NFC_BEAM_OCCURRED = 136,
+  ATOM_NFC_CARDEMULATION_OCCURRED = 137,
+  ATOM_NFC_TAG_OCCURRED = 138,
+  ATOM_NFC_HCE_TRANSACTION_OCCURRED = 139,
+  ATOM_SE_STATE_CHANGED = 140,
+  ATOM_SE_OMAPI_REPORTED = 141,
+  ATOM_BROADCAST_DISPATCH_LATENCY_REPORTED = 142,
+  ATOM_ATTENTION_MANAGER_SERVICE_RESULT_REPORTED = 143,
+  ATOM_ADB_CONNECTION_CHANGED = 144,
+  ATOM_SPEECH_DSP_STAT_REPORTED = 145,
+  ATOM_USB_CONTAMINANT_REPORTED = 146,
+  ATOM_WATCHDOG_ROLLBACK_OCCURRED = 147,
+  ATOM_BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED = 148,
+  ATOM_BUBBLE_UI_CHANGED = 149,
+  ATOM_SCHEDULED_JOB_CONSTRAINT_CHANGED = 150,
+  ATOM_BLUETOOTH_ACTIVE_DEVICE_CHANGED = 151,
+  ATOM_BLUETOOTH_A2DP_PLAYBACK_STATE_CHANGED = 152,
+  ATOM_BLUETOOTH_A2DP_CODEC_CONFIG_CHANGED = 153,
+  ATOM_BLUETOOTH_A2DP_CODEC_CAPABILITY_CHANGED = 154,
+  ATOM_BLUETOOTH_A2DP_AUDIO_UNDERRUN_REPORTED = 155,
+  ATOM_BLUETOOTH_A2DP_AUDIO_OVERRUN_REPORTED = 156,
+  ATOM_BLUETOOTH_DEVICE_RSSI_REPORTED = 157,
+  ATOM_BLUETOOTH_DEVICE_FAILED_CONTACT_COUNTER_REPORTED = 158,
+  ATOM_BLUETOOTH_DEVICE_TX_POWER_LEVEL_REPORTED = 159,
+  ATOM_BLUETOOTH_HCI_TIMEOUT_REPORTED = 160,
+  ATOM_BLUETOOTH_QUALITY_REPORT_REPORTED = 161,
+  ATOM_BLUETOOTH_DEVICE_INFO_REPORTED = 162,
+  ATOM_BLUETOOTH_REMOTE_VERSION_INFO_REPORTED = 163,
+  ATOM_BLUETOOTH_SDP_ATTRIBUTE_REPORTED = 164,
+  ATOM_BLUETOOTH_BOND_STATE_CHANGED = 165,
+  ATOM_BLUETOOTH_CLASSIC_PAIRING_EVENT_REPORTED = 166,
+  ATOM_BLUETOOTH_SMP_PAIRING_EVENT_REPORTED = 167,
+  ATOM_SCREEN_TIMEOUT_EXTENSION_REPORTED = 168,
+  ATOM_PROCESS_START_TIME = 169,
+  ATOM_PERMISSION_GRANT_REQUEST_RESULT_REPORTED = 170,
+  ATOM_BLUETOOTH_SOCKET_CONNECTION_STATE_CHANGED = 171,
+  ATOM_DEVICE_IDENTIFIER_ACCESS_DENIED = 172,
+  ATOM_BUBBLE_DEVELOPER_ERROR_REPORTED = 173,
+  ATOM_ASSIST_GESTURE_STAGE_REPORTED = 174,
+  ATOM_ASSIST_GESTURE_FEEDBACK_REPORTED = 175,
+  ATOM_ASSIST_GESTURE_PROGRESS_REPORTED = 176,
+  ATOM_TOUCH_GESTURE_CLASSIFIED = 177,
+  ATOM_HIDDEN_API_USED = 178,
+  ATOM_STYLE_UI_CHANGED = 179,
+  ATOM_PRIVACY_INDICATORS_INTERACTED = 180,
+  ATOM_APP_INSTALL_ON_EXTERNAL_STORAGE_REPORTED = 181,
+  ATOM_NETWORK_STACK_REPORTED = 182,
+  ATOM_APP_MOVED_STORAGE_REPORTED = 183,
+  ATOM_BIOMETRIC_ENROLLED = 184,
+  ATOM_SYSTEM_SERVER_WATCHDOG_OCCURRED = 185,
+  ATOM_TOMB_STONE_OCCURRED = 186,
+  ATOM_BLUETOOTH_CLASS_OF_DEVICE_REPORTED = 187,
+  ATOM_INTELLIGENCE_EVENT_REPORTED = 188,
+  ATOM_THERMAL_THROTTLING_SEVERITY_STATE_CHANGED = 189,
+  ATOM_ROLE_REQUEST_RESULT_REPORTED = 190,
+  ATOM_MEDIAMETRICS_AUDIOPOLICY_REPORTED = 191,
+  ATOM_MEDIAMETRICS_AUDIORECORD_REPORTED = 192,
+  ATOM_MEDIAMETRICS_AUDIOTHREAD_REPORTED = 193,
+  ATOM_MEDIAMETRICS_AUDIOTRACK_REPORTED = 194,
+  ATOM_MEDIAMETRICS_CODEC_REPORTED = 195,
+  ATOM_MEDIAMETRICS_DRM_WIDEVINE_REPORTED = 196,
+  ATOM_MEDIAMETRICS_EXTRACTOR_REPORTED = 197,
+  ATOM_MEDIAMETRICS_MEDIADRM_REPORTED = 198,
+  ATOM_MEDIAMETRICS_NUPLAYER_REPORTED = 199,
+  ATOM_MEDIAMETRICS_RECORDER_REPORTED = 200,
+  ATOM_MEDIAMETRICS_DRMMANAGER_REPORTED = 201,
+  ATOM_CAR_POWER_STATE_CHANGED = 203,
+  ATOM_GARAGE_MODE_INFO = 204,
+  ATOM_TEST_ATOM_REPORTED = 205,
+  ATOM_CONTENT_CAPTURE_CALLER_MISMATCH_REPORTED = 206,
+  ATOM_CONTENT_CAPTURE_SERVICE_EVENTS = 207,
+  ATOM_CONTENT_CAPTURE_SESSION_EVENTS = 208,
+  ATOM_CONTENT_CAPTURE_FLUSHED = 209,
+  ATOM_LOCATION_MANAGER_API_USAGE_REPORTED = 210,
+  ATOM_REVIEW_PERMISSIONS_FRAGMENT_RESULT_REPORTED = 211,
+  ATOM_RUNTIME_PERMISSIONS_UPGRADE_RESULT = 212,
+  ATOM_GRANT_PERMISSIONS_ACTIVITY_BUTTON_ACTIONS = 213,
+  ATOM_LOCATION_ACCESS_CHECK_NOTIFICATION_ACTION = 214,
+  ATOM_APP_PERMISSION_FRAGMENT_ACTION_REPORTED = 215,
+  ATOM_APP_PERMISSION_FRAGMENT_VIEWED = 216,
+  ATOM_APP_PERMISSIONS_FRAGMENT_VIEWED = 217,
+  ATOM_PERMISSION_APPS_FRAGMENT_VIEWED = 218,
+  ATOM_TEXT_SELECTION_EVENT = 219,
+  ATOM_TEXT_LINKIFY_EVENT = 220,
+  ATOM_CONVERSATION_ACTIONS_EVENT = 221,
+  ATOM_LANGUAGE_DETECTION_EVENT = 222,
+  ATOM_EXCLUSION_RECT_STATE_CHANGED = 223,
+  ATOM_BACK_GESTURE_REPORTED_REPORTED = 224,
+  ATOM_UPDATE_ENGINE_UPDATE_ATTEMPT_REPORTED = 225,
+  ATOM_UPDATE_ENGINE_SUCCESSFUL_UPDATE_REPORTED = 226,
+  ATOM_CAMERA_ACTION_EVENT = 227,
+  ATOM_APP_COMPATIBILITY_CHANGE_REPORTED = 228,
+  ATOM_PERFETTO_UPLOADED = 229,
+  ATOM_VMS_CLIENT_CONNECTION_STATE_CHANGED = 230,
+  ATOM_MEDIA_PROVIDER_SCAN_OCCURRED = 233,
+  ATOM_MEDIA_CONTENT_DELETED = 234,
+  ATOM_MEDIA_PROVIDER_PERMISSION_REQUESTED = 235,
+  ATOM_MEDIA_PROVIDER_SCHEMA_CHANGED = 236,
+  ATOM_MEDIA_PROVIDER_IDLE_MAINTENANCE_FINISHED = 237,
+  ATOM_REBOOT_ESCROW_RECOVERY_REPORTED = 238,
+  ATOM_BOOT_TIME_EVENT_DURATION_REPORTED = 239,
+  ATOM_BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED = 240,
+  ATOM_BOOT_TIME_EVENT_UTC_TIME_REPORTED = 241,
+  ATOM_BOOT_TIME_EVENT_ERROR_CODE_REPORTED = 242,
+  ATOM_USERSPACE_REBOOT_REPORTED = 243,
+  ATOM_NOTIFICATION_REPORTED = 244,
+  ATOM_NOTIFICATION_PANEL_REPORTED = 245,
+  ATOM_NOTIFICATION_CHANNEL_MODIFIED = 246,
+  ATOM_INTEGRITY_CHECK_RESULT_REPORTED = 247,
+  ATOM_INTEGRITY_RULES_PUSHED = 248,
+  ATOM_CB_MESSAGE_REPORTED = 249,
+  ATOM_CB_MESSAGE_ERROR = 250,
+  ATOM_WIFI_HEALTH_STAT_REPORTED = 251,
+  ATOM_WIFI_FAILURE_STAT_REPORTED = 252,
+  ATOM_WIFI_CONNECTION_RESULT_REPORTED = 253,
+  ATOM_APP_FREEZE_CHANGED = 254,
+  ATOM_SNAPSHOT_MERGE_REPORTED = 255,
+  ATOM_FOREGROUND_SERVICE_APP_OP_SESSION_ENDED = 256,
+  ATOM_DISPLAY_JANK_REPORTED = 257,
+  ATOM_APP_STANDBY_BUCKET_CHANGED = 258,
+  ATOM_SHARESHEET_STARTED = 259,
+  ATOM_RANKING_SELECTED = 260,
+  ATOM_TVSETTINGS_UI_INTERACTED = 261,
+  ATOM_LAUNCHER_SNAPSHOT = 262,
+  ATOM_PACKAGE_INSTALLER_V2_REPORTED = 263,
+  ATOM_USER_LIFECYCLE_JOURNEY_REPORTED = 264,
+  ATOM_USER_LIFECYCLE_EVENT_OCCURRED = 265,
+  ATOM_ACCESSIBILITY_SHORTCUT_REPORTED = 266,
+  ATOM_ACCESSIBILITY_SERVICE_REPORTED = 267,
+  ATOM_DOCS_UI_DRAG_AND_DROP_REPORTED = 268,
+  ATOM_APP_USAGE_EVENT_OCCURRED = 269,
+  ATOM_AUTO_REVOKE_NOTIFICATION_CLICKED = 270,
+  ATOM_AUTO_REVOKE_FRAGMENT_APP_VIEWED = 271,
+  ATOM_AUTO_REVOKED_APP_INTERACTION = 272,
+  ATOM_APP_PERMISSION_GROUPS_FRAGMENT_AUTO_REVOKE_ACTION = 273,
+  ATOM_EVS_USAGE_STATS_REPORTED = 274,
+  ATOM_AUDIO_POWER_USAGE_DATA_REPORTED = 275,
+  ATOM_TV_TUNER_STATE_CHANGED = 276,
+  ATOM_MEDIAOUTPUT_OP_SWITCH_REPORTED = 277,
+  ATOM_CB_MESSAGE_FILTERED = 278,
+  ATOM_TV_TUNER_DVR_STATUS = 279,
+  ATOM_TV_CAS_SESSION_OPEN_STATUS = 280,
+  ATOM_ASSISTANT_INVOCATION_REPORTED = 281,
+  ATOM_DISPLAY_WAKE_REPORTED = 282,
+  ATOM_CAR_USER_HAL_MODIFY_USER_REQUEST_REPORTED = 283,
+  ATOM_CAR_USER_HAL_MODIFY_USER_RESPONSE_REPORTED = 284,
+  ATOM_CAR_USER_HAL_POST_SWITCH_RESPONSE_REPORTED = 285,
+  ATOM_CAR_USER_HAL_INITIAL_USER_INFO_REQUEST_REPORTED = 286,
+  ATOM_CAR_USER_HAL_INITIAL_USER_INFO_RESPONSE_REPORTED = 287,
+  ATOM_CAR_USER_HAL_USER_ASSOCIATION_REQUEST_REPORTED = 288,
+  ATOM_CAR_USER_HAL_SET_USER_ASSOCIATION_RESPONSE_REPORTED = 289,
+  ATOM_NETWORK_IP_PROVISIONING_REPORTED = 290,
+  ATOM_NETWORK_DHCP_RENEW_REPORTED = 291,
+  ATOM_NETWORK_VALIDATION_REPORTED = 292,
+  ATOM_NETWORK_STACK_QUIRK_REPORTED = 293,
+  ATOM_MEDIAMETRICS_AUDIORECORDDEVICEUSAGE_REPORTED = 294,
+  ATOM_MEDIAMETRICS_AUDIOTHREADDEVICEUSAGE_REPORTED = 295,
+  ATOM_MEDIAMETRICS_AUDIOTRACKDEVICEUSAGE_REPORTED = 296,
+  ATOM_MEDIAMETRICS_AUDIODEVICECONNECTION_REPORTED = 297,
+  ATOM_BLOB_COMMITTED = 298,
+  ATOM_BLOB_LEASED = 299,
+  ATOM_BLOB_OPENED = 300,
+  ATOM_CONTACTS_PROVIDER_STATUS_REPORTED = 301,
+  ATOM_KEYSTORE_KEY_EVENT_REPORTED = 302,
+  ATOM_NETWORK_TETHERING_REPORTED = 303,
+  ATOM_IME_TOUCH_REPORTED = 304,
+  ATOM_UI_INTERACTION_FRAME_INFO_REPORTED = 305,
+  ATOM_UI_ACTION_LATENCY_REPORTED = 306,
+  ATOM_WIFI_DISCONNECT_REPORTED = 307,
+  ATOM_WIFI_CONNECTION_STATE_CHANGED = 308,
+  ATOM_HDMI_CEC_ACTIVE_SOURCE_CHANGED = 309,
+  ATOM_HDMI_CEC_MESSAGE_REPORTED = 310,
+  ATOM_AIRPLANE_MODE = 311,
+  ATOM_MODEM_RESTART = 312,
+  ATOM_CARRIER_ID_MISMATCH_REPORTED = 313,
+  ATOM_CARRIER_ID_TABLE_UPDATED = 314,
+  ATOM_DATA_STALL_RECOVERY_REPORTED = 315,
+  ATOM_MEDIAMETRICS_MEDIAPARSER_REPORTED = 316,
+  ATOM_TLS_HANDSHAKE_REPORTED = 317,
+  ATOM_TEXT_CLASSIFIER_API_USAGE_REPORTED = 318,
+  ATOM_CAR_WATCHDOG_KILL_STATS_REPORTED = 319,
+  ATOM_MEDIAMETRICS_PLAYBACK_REPORTED = 320,
+  ATOM_MEDIA_NETWORK_INFO_CHANGED = 321,
+  ATOM_MEDIA_PLAYBACK_STATE_CHANGED = 322,
+  ATOM_MEDIA_PLAYBACK_ERROR_REPORTED = 323,
+  ATOM_MEDIA_PLAYBACK_TRACK_CHANGED = 324,
+  ATOM_WIFI_SCAN_REPORTED = 325,
+  ATOM_WIFI_PNO_SCAN_REPORTED = 326,
+  ATOM_TIF_TUNE_CHANGED = 327,
+  ATOM_AUTO_ROTATE_REPORTED = 328,
+  ATOM_PERFETTO_TRIGGER = 329,
+  ATOM_TRANSCODING_DATA = 330,
+  ATOM_IMS_SERVICE_ENTITLEMENT_UPDATED = 331,
+  ATOM_DEVICE_ROTATED = 333,
+  ATOM_SIM_SPECIFIC_SETTINGS_RESTORED = 334,
+  ATOM_TEXT_CLASSIFIER_DOWNLOAD_REPORTED = 335,
+  ATOM_PIN_STORAGE_EVENT = 336,
+  ATOM_FACE_DOWN_REPORTED = 337,
+  ATOM_BLUETOOTH_HAL_CRASH_REASON_REPORTED = 338,
+  ATOM_REBOOT_ESCROW_PREPARATION_REPORTED = 339,
+  ATOM_REBOOT_ESCROW_LSKF_CAPTURE_REPORTED = 340,
+  ATOM_REBOOT_ESCROW_REBOOT_REPORTED = 341,
+  ATOM_BINDER_LATENCY_REPORTED = 342,
+  ATOM_MEDIAMETRICS_AAUDIOSTREAM_REPORTED = 343,
+  ATOM_MEDIA_TRANSCODING_SESSION_ENDED = 344,
+  ATOM_MAGNIFICATION_USAGE_REPORTED = 345,
+  ATOM_MAGNIFICATION_MODE_WITH_IME_ON_REPORTED = 346,
+  ATOM_APP_SEARCH_CALL_STATS_REPORTED = 347,
+  ATOM_APP_SEARCH_PUT_DOCUMENT_STATS_REPORTED = 348,
+  ATOM_DEVICE_CONTROL_CHANGED = 349,
+  ATOM_DEVICE_STATE_CHANGED = 350,
+  ATOM_INPUTDEVICE_REGISTERED = 351,
+  ATOM_SMARTSPACE_CARD_REPORTED = 352,
+  ATOM_AUTH_PROMPT_AUTHENTICATE_INVOKED = 353,
+  ATOM_AUTH_MANAGER_CAN_AUTHENTICATE_INVOKED = 354,
+  ATOM_AUTH_ENROLL_ACTION_INVOKED = 355,
+  ATOM_AUTH_DEPRECATED_API_USED = 356,
+  ATOM_UNATTENDED_REBOOT_OCCURRED = 357,
+  ATOM_LONG_REBOOT_BLOCKING_REPORTED = 358,
+  ATOM_LOCATION_TIME_ZONE_PROVIDER_STATE_CHANGED = 359,
+  ATOM_FDTRACK_EVENT_OCCURRED = 364,
+  ATOM_TIMEOUT_AUTO_EXTENDED_REPORTED = 365,
+  ATOM_ALARM_BATCH_DELIVERED = 367,
+  ATOM_ALARM_SCHEDULED = 368,
+  ATOM_CAR_WATCHDOG_IO_OVERUSE_STATS_REPORTED = 369,
+  ATOM_USER_LEVEL_HIBERNATION_STATE_CHANGED = 370,
+  ATOM_APP_SEARCH_INITIALIZE_STATS_REPORTED = 371,
+  ATOM_APP_SEARCH_QUERY_STATS_REPORTED = 372,
+  ATOM_APP_PROCESS_DIED = 373,
+  ATOM_NETWORK_IP_REACHABILITY_MONITOR_REPORTED = 374,
+  ATOM_SLOW_INPUT_EVENT_REPORTED = 375,
+  ATOM_ANR_OCCURRED_PROCESSING_STARTED = 376,
+  ATOM_APP_SEARCH_REMOVE_STATS_REPORTED = 377,
+  ATOM_MEDIA_CODEC_REPORTED = 378,
+  ATOM_PERMISSION_USAGE_FRAGMENT_INTERACTION = 379,
+  ATOM_PERMISSION_DETAILS_INTERACTION = 380,
+  ATOM_PRIVACY_SENSOR_TOGGLE_INTERACTION = 381,
+  ATOM_PRIVACY_TOGGLE_DIALOG_INTERACTION = 382,
+  ATOM_APP_SEARCH_OPTIMIZE_STATS_REPORTED = 383,
+  ATOM_NON_A11Y_TOOL_SERVICE_WARNING_REPORT = 384,
+  ATOM_APP_SEARCH_SET_SCHEMA_STATS_REPORTED = 385,
+  ATOM_APP_COMPAT_STATE_CHANGED = 386,
+  ATOM_SIZE_COMPAT_RESTART_BUTTON_EVENT_REPORTED = 387,
+  ATOM_SPLITSCREEN_UI_CHANGED = 388,
+  ATOM_NETWORK_DNS_HANDSHAKE_REPORTED = 389,
+  ATOM_BLUETOOTH_CODE_PATH_COUNTER = 390,
+  ATOM_BLUETOOTH_LE_BATCH_SCAN_REPORT_DELAY = 392,
+  ATOM_ACCESSIBILITY_FLOATING_MENU_UI_CHANGED = 393,
+  ATOM_NEURALNETWORKS_COMPILATION_COMPLETED = 394,
+  ATOM_NEURALNETWORKS_EXECUTION_COMPLETED = 395,
+  ATOM_NEURALNETWORKS_COMPILATION_FAILED = 396,
+  ATOM_NEURALNETWORKS_EXECUTION_FAILED = 397,
+  ATOM_CONTEXT_HUB_BOOTED = 398,
+  ATOM_CONTEXT_HUB_RESTARTED = 399,
+  ATOM_CONTEXT_HUB_LOADED_NANOAPP_SNAPSHOT_REPORTED = 400,
+  ATOM_CHRE_CODE_DOWNLOAD_TRANSACTED = 401,
+  ATOM_UWB_SESSION_INITED = 402,
+  ATOM_UWB_SESSION_CLOSED = 403,
+  ATOM_UWB_FIRST_RANGING_RECEIVED = 404,
+  ATOM_UWB_RANGING_MEASUREMENT_RECEIVED = 405,
+  ATOM_TEXT_CLASSIFIER_DOWNLOAD_WORK_SCHEDULED = 406,
+  ATOM_TEXT_CLASSIFIER_DOWNLOAD_WORK_COMPLETED = 407,
+  ATOM_CLIPBOARD_CLEARED = 408,
+  ATOM_VM_CREATION_REQUESTED = 409,
+  ATOM_NEARBY_DEVICE_SCAN_STATE_CHANGED = 410,
+  ATOM_CAMERA_COMPAT_CONTROL_EVENT_REPORTED = 411,
+  ATOM_APPLICATION_LOCALES_CHANGED = 412,
+  ATOM_MEDIAMETRICS_AUDIOTRACKSTATUS_REPORTED = 413,
+  ATOM_FOLD_STATE_DURATION_REPORTED = 414,
+  ATOM_LOCATION_TIME_ZONE_PROVIDER_CONTROLLER_STATE_CHANGED = 415,
+  ATOM_DISPLAY_HBM_STATE_CHANGED = 416,
+  ATOM_DISPLAY_HBM_BRIGHTNESS_CHANGED = 417,
+  ATOM_PERSISTENT_URI_PERMISSIONS_FLUSHED = 418,
+  ATOM_EARLY_BOOT_COMP_OS_ARTIFACTS_CHECK_REPORTED = 419,
+  ATOM_VBMETA_DIGEST_REPORTED = 420,
+  ATOM_APEX_INFO_GATHERED = 421,
+  ATOM_PVM_INFO_GATHERED = 422,
+  ATOM_WEAR_SETTINGS_UI_INTERACTED = 423,
+  ATOM_TRACING_SERVICE_REPORT_EVENT = 424,
+  ATOM_MEDIAMETRICS_AUDIORECORDSTATUS_REPORTED = 425,
+  ATOM_LAUNCHER_LATENCY = 426,
+  ATOM_DROPBOX_ENTRY_DROPPED = 427,
+  ATOM_WIFI_P2P_CONNECTION_REPORTED = 428,
+  ATOM_GAME_STATE_CHANGED = 429,
+  ATOM_HOTWORD_DETECTOR_CREATE_REQUESTED = 430,
+  ATOM_HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED = 431,
+  ATOM_HOTWORD_DETECTION_SERVICE_RESTARTED = 432,
+  ATOM_HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED = 433,
+  ATOM_HOTWORD_DETECTOR_EVENTS = 434,
+  ATOM_AD_SERVICES_API_CALLED = 435,
+  ATOM_AD_SERVICES_MESUREMENT_REPORTS_UPLOADED = 436,
+  ATOM_BOOT_COMPLETED_BROADCAST_COMPLETION_LATENCY_REPORTED = 437,
+  ATOM_CONTACTS_INDEXER_UPDATE_STATS_REPORTED = 440,
+  ATOM_APP_BACKGROUND_RESTRICTIONS_INFO = 441,
+  ATOM_MMS_SMS_PROVIDER_GET_THREAD_ID_FAILED = 442,
+  ATOM_MMS_SMS_DATABASE_HELPER_ON_UPGRADE_FAILED = 443,
+  ATOM_PERMISSION_REMINDER_NOTIFICATION_INTERACTED = 444,
+  ATOM_RECENT_PERMISSION_DECISIONS_INTERACTED = 445,
+  ATOM_GNSS_PSDS_DOWNLOAD_REPORTED = 446,
+  ATOM_LE_AUDIO_CONNECTION_SESSION_REPORTED = 447,
+  ATOM_LE_AUDIO_BROADCAST_SESSION_REPORTED = 448,
+  ATOM_DREAM_UI_EVENT_REPORTED = 449,
+  ATOM_TASK_MANAGER_EVENT_REPORTED = 450,
+  ATOM_CDM_ASSOCIATION_ACTION = 451,
+  ATOM_MAGNIFICATION_TRIPLE_TAP_AND_HOLD_ACTIVATED_SESSION_REPORTED = 452,
+  ATOM_MAGNIFICATION_FOLLOW_TYPING_FOCUS_ACTIVATED_SESSION_REPORTED = 453,
+  ATOM_ACCESSIBILITY_TEXT_READING_OPTIONS_CHANGED = 454,
+  ATOM_WIFI_SETUP_FAILURE_CRASH_REPORTED = 455,
+  ATOM_UWB_DEVICE_ERROR_REPORTED = 456,
+  ATOM_ISOLATED_COMPILATION_SCHEDULED = 457,
+  ATOM_ISOLATED_COMPILATION_ENDED = 458,
+  ATOM_ONS_OPPORTUNISTIC_ESIM_PROVISIONING_COMPLETE = 459,
+  ATOM_SYSTEM_SERVER_PRE_WATCHDOG_OCCURRED = 460,
+  ATOM_TELEPHONY_ANOMALY_DETECTED = 461,
+  ATOM_LETTERBOX_POSITION_CHANGED = 462,
+  ATOM_REMOTE_KEY_PROVISIONING_ATTEMPT = 463,
+  ATOM_REMOTE_KEY_PROVISIONING_NETWORK_INFO = 464,
+  ATOM_REMOTE_KEY_PROVISIONING_TIMING = 465,
+  ATOM_MEDIAOUTPUT_OP_INTERACTION_REPORT = 466,
+  ATOM_SYNC_EXEMPTION_OCCURRED = 468,
+  ATOM_AUTOFILL_PRESENTATION_EVENT_REPORTED = 469,
+  ATOM_DOCK_STATE_CHANGED = 470,
+  ATOM_SAFETY_SOURCE_STATE_COLLECTED = 471,
+  ATOM_SAFETY_CENTER_SYSTEM_EVENT_REPORTED = 472,
+  ATOM_SAFETY_CENTER_INTERACTION_REPORTED = 473,
+  ATOM_SETTINGS_PROVIDER_SETTING_CHANGED = 474,
+  ATOM_BROADCAST_DELIVERY_EVENT_REPORTED = 475,
+  ATOM_SERVICE_REQUEST_EVENT_REPORTED = 476,
+  ATOM_PROVIDER_ACQUISITION_EVENT_REPORTED = 477,
+  ATOM_BLUETOOTH_DEVICE_NAME_REPORTED = 478,
+  ATOM_CB_CONFIG_UPDATED = 479,
+  ATOM_CB_MODULE_ERROR_REPORTED = 480,
+  ATOM_CB_SERVICE_FEATURE_CHANGED = 481,
+  ATOM_CB_RECEIVER_FEATURE_CHANGED = 482,
+  ATOM_JSSCRIPTENGINE_LATENCY_REPORTED = 483,
+  ATOM_PRIVACY_SIGNAL_NOTIFICATION_INTERACTION = 484,
+  ATOM_PRIVACY_SIGNAL_ISSUE_CARD_INTERACTION = 485,
+  ATOM_PRIVACY_SIGNALS_JOB_FAILURE = 486,
+  ATOM_VIBRATION_REPORTED = 487,
+  ATOM_UWB_RANGING_START = 489,
+  ATOM_MOBILE_DATA_DOWNLOAD_FILE_GROUP_STATUS_REPORTED = 490,
+  ATOM_APP_COMPACTED_V2 = 491,
+  ATOM_AD_SERVICES_SETTINGS_USAGE_REPORTED = 493,
+  ATOM_DISPLAY_BRIGHTNESS_CHANGED = 494,
+  ATOM_ACTIVITY_ACTION_BLOCKED = 495,
+  ATOM_BACKGROUND_FETCH_PROCESS_REPORTED = 496,
+  ATOM_UPDATE_CUSTOM_AUDIENCE_PROCESS_REPORTED = 497,
+  ATOM_RUN_AD_BIDDING_PROCESS_REPORTED = 498,
+  ATOM_RUN_AD_SCORING_PROCESS_REPORTED = 499,
+  ATOM_RUN_AD_SELECTION_PROCESS_REPORTED = 500,
+  ATOM_RUN_AD_BIDDING_PER_CA_PROCESS_REPORTED = 501,
+  ATOM_MOBILE_DATA_DOWNLOAD_DOWNLOAD_RESULT_REPORTED = 502,
+  ATOM_MOBILE_DATA_DOWNLOAD_FILE_GROUP_STORAGE_STATS_REPORTED = 503,
+  ATOM_NETWORK_DNS_SERVER_SUPPORT_REPORTED = 504,
+  ATOM_VM_BOOTED = 505,
+  ATOM_VM_EXITED = 506,
+  ATOM_AMBIENT_BRIGHTNESS_STATS_REPORTED = 507,
+  ATOM_MEDIAMETRICS_SPATIALIZERCAPABILITIES_REPORTED = 508,
+  ATOM_MEDIAMETRICS_SPATIALIZERDEVICEENABLED_REPORTED = 509,
+  ATOM_MEDIAMETRICS_HEADTRACKERDEVICEENABLED_REPORTED = 510,
+  ATOM_MEDIAMETRICS_HEADTRACKERDEVICESUPPORTED_REPORTED = 511,
+  ATOM_AD_SERVICES_MEASUREMENT_REGISTRATIONS = 512,
+  ATOM_HEARING_AID_INFO_REPORTED = 513,
+  ATOM_DEVICE_WIDE_JOB_CONSTRAINT_CHANGED = 514,
+  ATOM_AMBIENT_MODE_CHANGED = 515,
+  ATOM_ANR_LATENCY_REPORTED = 516,
+  ATOM_RESOURCE_API_INFO = 517,
+  ATOM_SYSTEM_DEFAULT_NETWORK_CHANGED = 518,
+  ATOM_IWLAN_SETUP_DATA_CALL_RESULT_REPORTED = 519,
+  ATOM_IWLAN_PDN_DISCONNECTED_REASON_REPORTED = 520,
+  ATOM_AIRPLANE_MODE_SESSION_REPORTED = 521,
+  ATOM_VM_CPU_STATUS_REPORTED = 522,
+  ATOM_VM_MEM_STATUS_REPORTED = 523,
+  ATOM_PACKAGE_INSTALLATION_SESSION_REPORTED = 524,
+  ATOM_DEFAULT_NETWORK_REMATCH_INFO = 525,
+  ATOM_NETWORK_SELECTION_PERFORMANCE = 526,
+  ATOM_NETWORK_NSD_REPORTED = 527,
+  ATOM_BLUETOOTH_DISCONNECTION_REASON_REPORTED = 529,
+  ATOM_BLUETOOTH_LOCAL_VERSIONS_REPORTED = 530,
+  ATOM_BLUETOOTH_REMOTE_SUPPORTED_FEATURES_REPORTED = 531,
+  ATOM_BLUETOOTH_LOCAL_SUPPORTED_FEATURES_REPORTED = 532,
+  ATOM_BLUETOOTH_GATT_APP_INFO = 533,
+  ATOM_BRIGHTNESS_CONFIGURATION_UPDATED = 534,
+  ATOM_AD_SERVICES_GET_TOPICS_REPORTED = 535,
+  ATOM_AD_SERVICES_EPOCH_COMPUTATION_GET_TOP_TOPICS_REPORTED = 536,
+  ATOM_AD_SERVICES_EPOCH_COMPUTATION_CLASSIFIER_REPORTED = 537,
+  ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_LAUNCHED = 538,
+  ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_FINISHED = 539,
+  ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_CONNECTION_REPORTED = 540,
+  ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_DEVICE_SCAN_TRIGGERED = 541,
+  ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_FIRST_DEVICE_SCAN_LATENCY = 542,
+  ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_CONNECT_DEVICE_LATENCY = 543,
+  ATOM_PACKAGE_MANAGER_SNAPSHOT_REPORTED = 544,
+  ATOM_PACKAGE_MANAGER_APPS_FILTER_CACHE_BUILD_REPORTED = 545,
+  ATOM_PACKAGE_MANAGER_APPS_FILTER_CACHE_UPDATE_REPORTED = 546,
+  ATOM_LAUNCHER_IMPRESSION_EVENT = 547,
+  ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_ALL_DEVICES_SCAN_LATENCY = 549,
+  ATOM_WS_WATCH_FACE_EDITED = 551,
+  ATOM_WS_WATCH_FACE_FAVORITE_ACTION_REPORTED = 552,
+  ATOM_WS_WATCH_FACE_SET_ACTION_REPORTED = 553,
+  ATOM_PACKAGE_UNINSTALLATION_REPORTED = 554,
+  ATOM_GAME_MODE_CHANGED = 555,
+  ATOM_GAME_MODE_CONFIGURATION_CHANGED = 556,
+  ATOM_BEDTIME_MODE_STATE_CHANGED = 557,
+  ATOM_NETWORK_SLICE_SESSION_ENDED = 558,
+  ATOM_NETWORK_SLICE_DAILY_DATA_USAGE_REPORTED = 559,
+  ATOM_NFC_TAG_TYPE_OCCURRED = 560,
+  ATOM_NFC_AID_CONFLICT_OCCURRED = 561,
+  ATOM_NFC_READER_CONFLICT_OCCURRED = 562,
+  ATOM_WS_TILE_LIST_CHANGED = 563,
+  ATOM_GET_TYPE_ACCESSED_WITHOUT_PERMISSION = 564,
+  ATOM_MOBILE_BUNDLED_APP_INFO_GATHERED = 566,
+  ATOM_WS_WATCH_FACE_COMPLICATION_SET_CHANGED = 567,
+  ATOM_MEDIA_DRM_CREATED = 568,
+  ATOM_MEDIA_DRM_ERRORED = 569,
+  ATOM_MEDIA_DRM_SESSION_OPENED = 570,
+  ATOM_MEDIA_DRM_SESSION_CLOSED = 571,
+  ATOM_USER_SELECTED_RESOLUTION = 572,
+  ATOM_UNSAFE_INTENT_EVENT_REPORTED = 573,
+  ATOM_PERFORMANCE_HINT_SESSION_REPORTED = 574,
+  ATOM_MEDIAMETRICS_MIDI_DEVICE_CLOSE_REPORTED = 576,
+  ATOM_BIOMETRIC_TOUCH_REPORTED = 577,
+  ATOM_HOTWORD_AUDIO_EGRESS_EVENT_REPORTED = 578,
+  ATOM_APP_SEARCH_SCHEMA_MIGRATION_STATS_REPORTED = 579,
+  ATOM_LOCATION_ENABLED_STATE_CHANGED = 580,
+  ATOM_IME_REQUEST_FINISHED = 581,
+  ATOM_USB_COMPLIANCE_WARNINGS_REPORTED = 582,
+  ATOM_APP_SUPPORTED_LOCALES_CHANGED = 583,
+  ATOM_GRAMMATICAL_INFLECTION_CHANGED = 584,
+  ATOM_MEDIA_PROVIDER_VOLUME_RECOVERY_REPORTED = 586,
+  ATOM_BIOMETRIC_PROPERTIES_COLLECTED = 587,
+  ATOM_KERNEL_WAKEUP_ATTRIBUTED = 588,
+  ATOM_SCREEN_STATE_CHANGED_V2 = 589,
+  ATOM_WS_BACKUP_ACTION_REPORTED = 590,
+  ATOM_WS_RESTORE_ACTION_REPORTED = 591,
+  ATOM_DEVICE_LOG_ACCESS_EVENT_REPORTED = 592,
+  ATOM_MEDIA_SESSION_UPDATED = 594,
+  ATOM_WEAR_OOBE_STATE_CHANGED = 595,
+  ATOM_WS_NOTIFICATION_UPDATED = 596,
+  ATOM_NETWORK_VALIDATION_FAILURE_STATS_DAILY_REPORTED = 601,
+  ATOM_WS_COMPLICATION_TAPPED = 602,
+  ATOM_WS_WEAR_TIME_SESSION = 610,
+  ATOM_WIFI_BYTES_TRANSFER = 10000,
+  ATOM_WIFI_BYTES_TRANSFER_BY_FG_BG = 10001,
+  ATOM_MOBILE_BYTES_TRANSFER = 10002,
+  ATOM_MOBILE_BYTES_TRANSFER_BY_FG_BG = 10003,
+  ATOM_BLUETOOTH_BYTES_TRANSFER = 10006,
+  ATOM_KERNEL_WAKELOCK = 10004,
+  ATOM_SUBSYSTEM_SLEEP_STATE = 10005,
+  ATOM_CPU_TIME_PER_UID = 10009,
+  ATOM_CPU_TIME_PER_UID_FREQ = 10010,
+  ATOM_WIFI_ACTIVITY_INFO = 10011,
+  ATOM_MODEM_ACTIVITY_INFO = 10012,
+  ATOM_BLUETOOTH_ACTIVITY_INFO = 10007,
+  ATOM_PROCESS_MEMORY_STATE = 10013,
+  ATOM_SYSTEM_ELAPSED_REALTIME = 10014,
+  ATOM_SYSTEM_UPTIME = 10015,
+  ATOM_CPU_ACTIVE_TIME = 10016,
+  ATOM_CPU_CLUSTER_TIME = 10017,
+  ATOM_DISK_SPACE = 10018,
+  ATOM_REMAINING_BATTERY_CAPACITY = 10019,
+  ATOM_FULL_BATTERY_CAPACITY = 10020,
+  ATOM_TEMPERATURE = 10021,
+  ATOM_BINDER_CALLS = 10022,
+  ATOM_BINDER_CALLS_EXCEPTIONS = 10023,
+  ATOM_LOOPER_STATS = 10024,
+  ATOM_DISK_STATS = 10025,
+  ATOM_DIRECTORY_USAGE = 10026,
+  ATOM_APP_SIZE = 10027,
+  ATOM_CATEGORY_SIZE = 10028,
+  ATOM_PROC_STATS = 10029,
+  ATOM_BATTERY_VOLTAGE = 10030,
+  ATOM_NUM_FINGERPRINTS_ENROLLED = 10031,
+  ATOM_DISK_IO = 10032,
+  ATOM_POWER_PROFILE = 10033,
+  ATOM_PROC_STATS_PKG_PROC = 10034,
+  ATOM_PROCESS_CPU_TIME = 10035,
+  ATOM_CPU_TIME_PER_THREAD_FREQ = 10037,
+  ATOM_ON_DEVICE_POWER_MEASUREMENT = 10038,
+  ATOM_DEVICE_CALCULATED_POWER_USE = 10039,
+  ATOM_PROCESS_MEMORY_HIGH_WATER_MARK = 10042,
+  ATOM_BATTERY_LEVEL = 10043,
+  ATOM_BUILD_INFORMATION = 10044,
+  ATOM_BATTERY_CYCLE_COUNT = 10045,
+  ATOM_DEBUG_ELAPSED_CLOCK = 10046,
+  ATOM_DEBUG_FAILING_ELAPSED_CLOCK = 10047,
+  ATOM_NUM_FACES_ENROLLED = 10048,
+  ATOM_ROLE_HOLDER = 10049,
+  ATOM_DANGEROUS_PERMISSION_STATE = 10050,
+  ATOM_TRAIN_INFO = 10051,
+  ATOM_TIME_ZONE_DATA_INFO = 10052,
+  ATOM_EXTERNAL_STORAGE_INFO = 10053,
+  ATOM_GPU_STATS_GLOBAL_INFO = 10054,
+  ATOM_GPU_STATS_APP_INFO = 10055,
+  ATOM_SYSTEM_ION_HEAP_SIZE = 10056,
+  ATOM_APPS_ON_EXTERNAL_STORAGE_INFO = 10057,
+  ATOM_FACE_SETTINGS = 10058,
+  ATOM_COOLING_DEVICE = 10059,
+  ATOM_APP_OPS = 10060,
+  ATOM_PROCESS_SYSTEM_ION_HEAP_SIZE = 10061,
+  ATOM_SURFACEFLINGER_STATS_GLOBAL_INFO = 10062,
+  ATOM_SURFACEFLINGER_STATS_LAYER_INFO = 10063,
+  ATOM_PROCESS_MEMORY_SNAPSHOT = 10064,
+  ATOM_VMS_CLIENT_STATS = 10065,
+  ATOM_NOTIFICATION_REMOTE_VIEWS = 10066,
+  ATOM_DANGEROUS_PERMISSION_STATE_SAMPLED = 10067,
+  ATOM_GRAPHICS_STATS = 10068,
+  ATOM_RUNTIME_APP_OP_ACCESS = 10069,
+  ATOM_ION_HEAP_SIZE = 10070,
+  ATOM_PACKAGE_NOTIFICATION_PREFERENCES = 10071,
+  ATOM_PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES = 10072,
+  ATOM_PACKAGE_NOTIFICATION_CHANNEL_GROUP_PREFERENCES = 10073,
+  ATOM_GNSS_STATS = 10074,
+  ATOM_ATTRIBUTED_APP_OPS = 10075,
+  ATOM_VOICE_CALL_SESSION = 10076,
+  ATOM_VOICE_CALL_RAT_USAGE = 10077,
+  ATOM_SIM_SLOT_STATE = 10078,
+  ATOM_SUPPORTED_RADIO_ACCESS_FAMILY = 10079,
+  ATOM_SETTING_SNAPSHOT = 10080,
+  ATOM_BLOB_INFO = 10081,
+  ATOM_DATA_USAGE_BYTES_TRANSFER = 10082,
+  ATOM_BYTES_TRANSFER_BY_TAG_AND_METERED = 10083,
+  ATOM_DND_MODE_RULE = 10084,
+  ATOM_GENERAL_EXTERNAL_STORAGE_ACCESS_STATS = 10085,
+  ATOM_INCOMING_SMS = 10086,
+  ATOM_OUTGOING_SMS = 10087,
+  ATOM_CARRIER_ID_TABLE_VERSION = 10088,
+  ATOM_DATA_CALL_SESSION = 10089,
+  ATOM_CELLULAR_SERVICE_STATE = 10090,
+  ATOM_CELLULAR_DATA_SERVICE_SWITCH = 10091,
+  ATOM_SYSTEM_MEMORY = 10092,
+  ATOM_IMS_REGISTRATION_TERMINATION = 10093,
+  ATOM_IMS_REGISTRATION_STATS = 10094,
+  ATOM_CPU_TIME_PER_CLUSTER_FREQ = 10095,
+  ATOM_CPU_CYCLES_PER_UID_CLUSTER = 10096,
+  ATOM_DEVICE_ROTATED_DATA = 10097,
+  ATOM_CPU_CYCLES_PER_THREAD_GROUP_CLUSTER = 10098,
+  ATOM_MEDIA_DRM_ACTIVITY_INFO = 10099,
+  ATOM_OEM_MANAGED_BYTES_TRANSFER = 10100,
+  ATOM_GNSS_POWER_STATS = 10101,
+  ATOM_TIME_ZONE_DETECTOR_STATE = 10102,
+  ATOM_KEYSTORE2_STORAGE_STATS = 10103,
+  ATOM_RKP_POOL_STATS = 10104,
+  ATOM_PROCESS_DMABUF_MEMORY = 10105,
+  ATOM_PENDING_ALARM_INFO = 10106,
+  ATOM_USER_LEVEL_HIBERNATED_APPS = 10107,
+  ATOM_LAUNCHER_LAYOUT_SNAPSHOT = 10108,
+  ATOM_GLOBAL_HIBERNATED_APPS = 10109,
+  ATOM_INPUT_EVENT_LATENCY_SKETCH = 10110,
+  ATOM_BATTERY_USAGE_STATS_BEFORE_RESET = 10111,
+  ATOM_BATTERY_USAGE_STATS_SINCE_RESET = 10112,
+  ATOM_BATTERY_USAGE_STATS_SINCE_RESET_USING_POWER_PROFILE_MODEL = 10113,
+  ATOM_INSTALLED_INCREMENTAL_PACKAGE = 10114,
+  ATOM_TELEPHONY_NETWORK_REQUESTS = 10115,
+  ATOM_APP_SEARCH_STORAGE_INFO = 10116,
+  ATOM_VMSTAT = 10117,
+  ATOM_KEYSTORE2_KEY_CREATION_WITH_GENERAL_INFO = 10118,
+  ATOM_KEYSTORE2_KEY_CREATION_WITH_AUTH_INFO = 10119,
+  ATOM_KEYSTORE2_KEY_CREATION_WITH_PURPOSE_AND_MODES_INFO = 10120,
+  ATOM_KEYSTORE2_ATOM_WITH_OVERFLOW = 10121,
+  ATOM_KEYSTORE2_KEY_OPERATION_WITH_PURPOSE_AND_MODES_INFO = 10122,
+  ATOM_KEYSTORE2_KEY_OPERATION_WITH_GENERAL_INFO = 10123,
+  ATOM_RKP_ERROR_STATS = 10124,
+  ATOM_KEYSTORE2_CRASH_STATS = 10125,
+  ATOM_VENDOR_APEX_INFO = 10126,
+  ATOM_ACCESSIBILITY_SHORTCUT_STATS = 10127,
+  ATOM_ACCESSIBILITY_FLOATING_MENU_STATS = 10128,
+  ATOM_DATA_USAGE_BYTES_TRANSFER_V2 = 10129,
+  ATOM_MEDIA_CAPABILITIES = 10130,
+  ATOM_CAR_WATCHDOG_SYSTEM_IO_USAGE_SUMMARY = 10131,
+  ATOM_CAR_WATCHDOG_UID_IO_USAGE_SUMMARY = 10132,
+  ATOM_IMS_REGISTRATION_FEATURE_TAG_STATS = 10133,
+  ATOM_RCS_CLIENT_PROVISIONING_STATS = 10134,
+  ATOM_RCS_ACS_PROVISIONING_STATS = 10135,
+  ATOM_SIP_DELEGATE_STATS = 10136,
+  ATOM_SIP_TRANSPORT_FEATURE_TAG_STATS = 10137,
+  ATOM_SIP_MESSAGE_RESPONSE = 10138,
+  ATOM_SIP_TRANSPORT_SESSION = 10139,
+  ATOM_IMS_DEDICATED_BEARER_LISTENER_EVENT = 10140,
+  ATOM_IMS_DEDICATED_BEARER_EVENT = 10141,
+  ATOM_IMS_REGISTRATION_SERVICE_DESC_STATS = 10142,
+  ATOM_UCE_EVENT_STATS = 10143,
+  ATOM_PRESENCE_NOTIFY_EVENT = 10144,
+  ATOM_GBA_EVENT = 10145,
+  ATOM_PER_SIM_STATUS = 10146,
+  ATOM_GPU_WORK_PER_UID = 10147,
+  ATOM_PERSISTENT_URI_PERMISSIONS_AMOUNT_PER_PACKAGE = 10148,
+  ATOM_SIGNED_PARTITION_INFO = 10149,
+  ATOM_PINNED_FILE_SIZES_PER_PACKAGE = 10150,
+  ATOM_PENDING_INTENTS_PER_PACKAGE = 10151,
+  ATOM_USER_INFO = 10152,
+  ATOM_TELEPHONY_NETWORK_REQUESTS_V2 = 10153,
+  ATOM_DEVICE_TELEPHONY_PROPERTIES = 10154,
+  ATOM_REMOTE_KEY_PROVISIONING_ERROR_COUNTS = 10155,
+  ATOM_SAFETY_STATE = 10156,
+  ATOM_INCOMING_MMS = 10157,
+  ATOM_OUTGOING_MMS = 10158,
+  ATOM_MULTI_USER_INFO = 10160,
+  ATOM_NETWORK_BPF_MAP_INFO = 10161,
+  ATOM_OUTGOING_SHORT_CODE_SMS = 10162,
+  ATOM_CONNECTIVITY_STATE_SAMPLE = 10163,
+  ATOM_NETWORK_SELECTION_REMATCH_REASONS_INFO = 10164,
+  ATOM_GAME_MODE_INFO = 10165,
+  ATOM_GAME_MODE_CONFIGURATION = 10166,
+  ATOM_GAME_MODE_LISTENER = 10167,
+  ATOM_NETWORK_SLICE_REQUEST_COUNT = 10168,
+  ATOM_WS_TILE_SNAPSHOT = 10169,
+  ATOM_WS_ACTIVE_WATCH_FACE_COMPLICATION_SET_SNAPSHOT = 10170,
+  ATOM_PROCESS_STATE = 10171,
+  ATOM_PROCESS_ASSOCIATION = 10172,
+  ATOM_ADPF_SYSTEM_COMPONENT_INFO = 10173,
+  ATOM_NOTIFICATION_MEMORY_USE = 10174,
+  ATOM_HDR_CAPABILITIES = 10175,
+  ATOM_WS_FAVOURITE_WATCH_FACE_LIST_SNAPSHOT = 10176,
+  ATOM_WIFI_AWARE_NDP_REPORTED = 638,
+  ATOM_WIFI_AWARE_ATTACH_REPORTED = 639,
+  ATOM_WIFI_SELF_RECOVERY_TRIGGERED = 661,
+  ATOM_SOFT_AP_STARTED = 680,
+  ATOM_SOFT_AP_STOPPED = 681,
+  ATOM_WIFI_LOCK_RELEASED = 687,
+  ATOM_WIFI_LOCK_DEACTIVATED = 688,
+  ATOM_WIFI_CONFIG_SAVED = 689,
+  ATOM_WIFI_AWARE_RESOURCE_USING_CHANGED = 690,
+  ATOM_WIFI_AWARE_HAL_API_CALLED = 691,
+  ATOM_WIFI_LOCAL_ONLY_REQUEST_RECEIVED = 692,
+  ATOM_WIFI_LOCAL_ONLY_REQUEST_SCAN_TRIGGERED = 693,
+  ATOM_WIFI_THREAD_TASK_EXECUTED = 694,
+  ATOM_WIFI_STATE_CHANGED = 700,
+  ATOM_WIFI_AWARE_CAPABILITIES = 10190,
+  ATOM_WIFI_MODULE_INFO = 10193,
+  ATOM_SETTINGS_SPA_REPORTED = 622,
+  ATOM_EXPRESS_EVENT_REPORTED = 528,
+  ATOM_EXPRESS_HISTOGRAM_SAMPLE_REPORTED = 593,
+  ATOM_EXPRESS_UID_EVENT_REPORTED = 644,
+  ATOM_EXPRESS_UID_HISTOGRAM_SAMPLE_REPORTED = 658,
+  ATOM_PERMISSION_RATIONALE_DIALOG_VIEWED = 645,
+  ATOM_PERMISSION_RATIONALE_DIALOG_ACTION_REPORTED = 646,
+  ATOM_APP_DATA_SHARING_UPDATES_NOTIFICATION_INTERACTION = 647,
+  ATOM_APP_DATA_SHARING_UPDATES_FRAGMENT_VIEWED = 648,
+  ATOM_APP_DATA_SHARING_UPDATES_FRAGMENT_ACTION_REPORTED = 649,
+  ATOM_WS_INCOMING_CALL_ACTION_REPORTED = 626,
+  ATOM_WS_CALL_DISCONNECTION_REPORTED = 627,
+  ATOM_WS_CALL_DURATION_REPORTED = 628,
+  ATOM_WS_CALL_USER_EXPERIENCE_LATENCY_REPORTED = 629,
+  ATOM_WS_CALL_INTERACTION_REPORTED = 630,
+  ATOM_FULL_SCREEN_INTENT_LAUNCHED = 631,
+  ATOM_BAL_ALLOWED = 632,
+  ATOM_IN_TASK_ACTIVITY_STARTED = 685,
+  ATOM_CACHED_APPS_HIGH_WATERMARK = 10189,
+  ATOM_ODREFRESH_REPORTED = 366,
+  ATOM_ODSIGN_REPORTED = 548,
+  ATOM_ART_DATUM_REPORTED = 332,
+  ATOM_ART_DEVICE_DATUM_REPORTED = 550,
+  ATOM_ART_DATUM_DELTA_REPORTED = 565,
+  ATOM_BACKGROUND_DEXOPT_JOB_ENDED = 467,
+  ATOM_WEAR_ADAPTIVE_SUSPEND_STATS_REPORTED = 619,
+  ATOM_WEAR_POWER_ANOMALY_SERVICE_OPERATIONAL_STATS_REPORTED = 620,
+  ATOM_WEAR_POWER_ANOMALY_SERVICE_EVENT_STATS_REPORTED = 621,
+  ATOM_EMERGENCY_STATE_CHANGED = 633,
+  ATOM_DND_STATE_CHANGED = 657,
+  ATOM_MTE_STATE = 10181,
+  ATOM_AD_SERVICES_BACK_COMPAT_GET_TOPICS_REPORTED = 598,
+  ATOM_AD_SERVICES_BACK_COMPAT_EPOCH_COMPUTATION_CLASSIFIER_REPORTED = 599,
+  ATOM_AD_SERVICES_MEASUREMENT_DEBUG_KEYS = 640,
+  ATOM_AD_SERVICES_ERROR_REPORTED = 662,
+  ATOM_AD_SERVICES_BACKGROUND_JOBS_EXECUTION_REPORTED = 663,
+  ATOM_AD_SERVICES_MEASUREMENT_DELAYED_SOURCE_REGISTRATION = 673,
+  ATOM_AD_SERVICES_MEASUREMENT_ATTRIBUTION = 674,
+  ATOM_AD_SERVICES_MEASUREMENT_JOBS = 675,
+  ATOM_AD_SERVICES_MEASUREMENT_WIPEOUT = 676,
+  ATOM_AD_SERVICES_CONSENT_MIGRATED = 702,
+  ATOM_RKPD_POOL_STATS = 664,
+  ATOM_RKPD_CLIENT_OPERATION = 665,
+  ATOM_AUTOFILL_UI_EVENT_REPORTED = 603,
+  ATOM_AUTOFILL_FILL_REQUEST_REPORTED = 604,
+  ATOM_AUTOFILL_FILL_RESPONSE_REPORTED = 605,
+  ATOM_AUTOFILL_SAVE_EVENT_REPORTED = 606,
+  ATOM_AUTOFILL_SESSION_COMMITTED = 607,
+  ATOM_AUTOFILL_FIELD_CLASSIFICATION_EVENT_REPORTED = 659,
+  ATOM_TEST_EXTENSION_ATOM_REPORTED = 660,
+  ATOM_TEST_RESTRICTED_ATOM_REPORTED = 672,
+  ATOM_STATS_SOCKET_LOSS_REPORTED = 752,
+  ATOM_PLUGIN_INITIALIZED = 655,
+  ATOM_TV_LOW_POWER_STANDBY_POLICY = 679,
+  ATOM_LOCKSCREEN_SHORTCUT_SELECTED = 611,
+  ATOM_LOCKSCREEN_SHORTCUT_TRIGGERED = 612,
+  ATOM_EMERGENCY_NUMBERS_INFO = 10180,
+  ATOM_QUALIFIED_RAT_LIST_CHANGED = 634,
+  ATOM_QNS_IMS_CALL_DROP_STATS = 635,
+  ATOM_QNS_FALLBACK_RESTRICTION_CHANGED = 636,
+  ATOM_QNS_RAT_PREFERENCE_MISMATCH_INFO = 10177,
+  ATOM_QNS_HANDOVER_TIME_MILLIS = 10178,
+  ATOM_QNS_HANDOVER_PINGPONG = 10179,
+  ATOM_SATELLITE_CONTROLLER = 10182,
+  ATOM_SATELLITE_SESSION = 10183,
+  ATOM_SATELLITE_INCOMING_DATAGRAM = 10184,
+  ATOM_SATELLITE_OUTGOING_DATAGRAM = 10185,
+  ATOM_SATELLITE_PROVISION = 10186,
+  ATOM_SATELLITE_SOS_MESSAGE_RECOMMENDER = 10187,
+  ATOM_IKE_SESSION_TERMINATED = 678,
+  ATOM_IKE_LIVENESS_CHECK_SESSION_VALIDATED = 760,
+  ATOM_BLUETOOTH_HASHED_DEVICE_NAME_REPORTED = 613,
+  ATOM_BLUETOOTH_L2CAP_COC_CLIENT_CONNECTION = 614,
+  ATOM_BLUETOOTH_L2CAP_COC_SERVER_CONNECTION = 615,
+  ATOM_BLUETOOTH_LE_SESSION_CONNECTED = 656,
+  ATOM_RESTRICTED_BLUETOOTH_DEVICE_NAME_REPORTED = 666,
+  ATOM_BLUETOOTH_PROFILE_CONNECTION_ATTEMPTED = 696,
+  ATOM_HEALTH_CONNECT_UI_IMPRESSION = 623,
+  ATOM_HEALTH_CONNECT_UI_INTERACTION = 624,
+  ATOM_HEALTH_CONNECT_APP_OPENED_REPORTED = 625,
+  ATOM_HEALTH_CONNECT_API_CALLED = 616,
+  ATOM_HEALTH_CONNECT_USAGE_STATS = 617,
+  ATOM_HEALTH_CONNECT_STORAGE_STATS = 618,
+  ATOM_HEALTH_CONNECT_API_INVOKED = 643,
+  ATOM_EXERCISE_ROUTE_API_CALLED = 654,
+  ATOM_ATOM_9999 = 9999,
+  ATOM_ATOM_99999 = 99999,
+  ATOM_THREADNETWORK_TELEMETRY_DATA_REPORTED = 738,
+  ATOM_THREADNETWORK_TOPO_ENTRY_REPEATED = 739,
+  ATOM_THREADNETWORK_DEVICE_INFO_REPORTED = 740,
+  ATOM_EMERGENCY_NUMBER_DIALED = 637,
+  ATOM_SANDBOX_API_CALLED = 488,
+  ATOM_SANDBOX_ACTIVITY_EVENT_OCCURRED = 735,
+  ATOM_SANDBOX_SDK_STORAGE = 10159,
+  ATOM_CRONET_ENGINE_CREATED = 703,
+  ATOM_CRONET_TRAFFIC_REPORTED = 704,
+  ATOM_CRONET_ENGINE_BUILDER_INITIALIZED = 762,
+  ATOM_CRONET_HTTP_FLAGS_INITIALIZED = 763,
+  ATOM_CRONET_INITIALIZED = 764,
+  ATOM_DAILY_KEEPALIVE_INFO_REPORTED = 650,
+  ATOM_IP_CLIENT_RA_INFO_REPORTED = 778,
+  ATOM_APF_SESSION_INFO_REPORTED = 777,
+  ATOM_CREDENTIAL_MANAGER_API_CALLED = 585,
+  ATOM_CREDENTIAL_MANAGER_INIT_PHASE_REPORTED = 651,
+  ATOM_CREDENTIAL_MANAGER_CANDIDATE_PHASE_REPORTED = 652,
+  ATOM_CREDENTIAL_MANAGER_FINAL_PHASE_REPORTED = 653,
+  ATOM_CREDENTIAL_MANAGER_TOTAL_REPORTED = 667,
+  ATOM_CREDENTIAL_MANAGER_FINALNOUID_REPORTED = 668,
+  ATOM_CREDENTIAL_MANAGER_GET_REPORTED = 669,
+  ATOM_CREDENTIAL_MANAGER_AUTH_CLICK_REPORTED = 670,
+  ATOM_CREDENTIAL_MANAGER_APIV2_CALLED = 671,
+  ATOM_UWB_ACTIVITY_INFO = 10188,
+  ATOM_MEDIA_ACTION_REPORTED = 608,
+  ATOM_MEDIA_CONTROLS_LAUNCHED = 609,
+  ATOM_MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED = 600,
+  ATOM_MEDIA_CODEC_STARTED = 641,
+  ATOM_MEDIA_CODEC_STOPPED = 642,
+  ATOM_MEDIA_CODEC_RENDERED = 684,
+};
+
+constexpr AtomId AtomId_MIN = AtomId::ATOM_UNSPECIFIED;
+constexpr AtomId AtomId_MAX = AtomId::ATOM_ATOM_99999;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* AtomId_Name(::perfetto::protos::pbzero::AtomId value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::AtomId::ATOM_UNSPECIFIED:
+    return "ATOM_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLE_SCAN_STATE_CHANGED:
+    return "ATOM_BLE_SCAN_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PROCESS_STATE_CHANGED:
+    return "ATOM_PROCESS_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLE_SCAN_RESULT_RECEIVED:
+    return "ATOM_BLE_SCAN_RESULT_RECEIVED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SENSOR_STATE_CHANGED:
+    return "ATOM_SENSOR_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GPS_SCAN_STATE_CHANGED:
+    return "ATOM_GPS_SCAN_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SYNC_STATE_CHANGED:
+    return "ATOM_SYNC_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SCHEDULED_JOB_STATE_CHANGED:
+    return "ATOM_SCHEDULED_JOB_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SCREEN_BRIGHTNESS_CHANGED:
+    return "ATOM_SCREEN_BRIGHTNESS_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WAKELOCK_STATE_CHANGED:
+    return "ATOM_WAKELOCK_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LONG_PARTIAL_WAKELOCK_STATE_CHANGED:
+    return "ATOM_LONG_PARTIAL_WAKELOCK_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MOBILE_RADIO_POWER_STATE_CHANGED:
+    return "ATOM_MOBILE_RADIO_POWER_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_RADIO_POWER_STATE_CHANGED:
+    return "ATOM_WIFI_RADIO_POWER_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ACTIVITY_MANAGER_SLEEP_STATE_CHANGED:
+    return "ATOM_ACTIVITY_MANAGER_SLEEP_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEMORY_FACTOR_STATE_CHANGED:
+    return "ATOM_MEMORY_FACTOR_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_EXCESSIVE_CPU_USAGE_REPORTED:
+    return "ATOM_EXCESSIVE_CPU_USAGE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CACHED_KILL_REPORTED:
+    return "ATOM_CACHED_KILL_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PROCESS_MEMORY_STAT_REPORTED:
+    return "ATOM_PROCESS_MEMORY_STAT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LAUNCHER_EVENT:
+    return "ATOM_LAUNCHER_EVENT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BATTERY_SAVER_MODE_STATE_CHANGED:
+    return "ATOM_BATTERY_SAVER_MODE_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DEVICE_IDLE_MODE_STATE_CHANGED:
+    return "ATOM_DEVICE_IDLE_MODE_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DEVICE_IDLING_MODE_STATE_CHANGED:
+    return "ATOM_DEVICE_IDLING_MODE_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AUDIO_STATE_CHANGED:
+    return "ATOM_AUDIO_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_CODEC_STATE_CHANGED:
+    return "ATOM_MEDIA_CODEC_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CAMERA_STATE_CHANGED:
+    return "ATOM_CAMERA_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_FLASHLIGHT_STATE_CHANGED:
+    return "ATOM_FLASHLIGHT_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_UID_PROCESS_STATE_CHANGED:
+    return "ATOM_UID_PROCESS_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PROCESS_LIFE_CYCLE_STATE_CHANGED:
+    return "ATOM_PROCESS_LIFE_CYCLE_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SCREEN_STATE_CHANGED:
+    return "ATOM_SCREEN_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BATTERY_LEVEL_CHANGED:
+    return "ATOM_BATTERY_LEVEL_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CHARGING_STATE_CHANGED:
+    return "ATOM_CHARGING_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PLUGGED_STATE_CHANGED:
+    return "ATOM_PLUGGED_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_INTERACTIVE_STATE_CHANGED:
+    return "ATOM_INTERACTIVE_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TOUCH_EVENT_REPORTED:
+    return "ATOM_TOUCH_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WAKEUP_ALARM_OCCURRED:
+    return "ATOM_WAKEUP_ALARM_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_KERNEL_WAKEUP_REPORTED:
+    return "ATOM_KERNEL_WAKEUP_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_LOCK_STATE_CHANGED:
+    return "ATOM_WIFI_LOCK_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_SIGNAL_STRENGTH_CHANGED:
+    return "ATOM_WIFI_SIGNAL_STRENGTH_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_SCAN_STATE_CHANGED:
+    return "ATOM_WIFI_SCAN_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PHONE_SIGNAL_STRENGTH_CHANGED:
+    return "ATOM_PHONE_SIGNAL_STRENGTH_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SETTING_CHANGED:
+    return "ATOM_SETTING_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ACTIVITY_FOREGROUND_STATE_CHANGED:
+    return "ATOM_ACTIVITY_FOREGROUND_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ISOLATED_UID_CHANGED:
+    return "ATOM_ISOLATED_UID_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PACKET_WAKEUP_OCCURRED:
+    return "ATOM_PACKET_WAKEUP_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WALL_CLOCK_TIME_SHIFTED:
+    return "ATOM_WALL_CLOCK_TIME_SHIFTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ANOMALY_DETECTED:
+    return "ATOM_ANOMALY_DETECTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_BREADCRUMB_REPORTED:
+    return "ATOM_APP_BREADCRUMB_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_START_OCCURRED:
+    return "ATOM_APP_START_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_START_CANCELED:
+    return "ATOM_APP_START_CANCELED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_START_FULLY_DRAWN:
+    return "ATOM_APP_START_FULLY_DRAWN";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LMK_KILL_OCCURRED:
+    return "ATOM_LMK_KILL_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PICTURE_IN_PICTURE_STATE_CHANGED:
+    return "ATOM_PICTURE_IN_PICTURE_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_MULTICAST_LOCK_STATE_CHANGED:
+    return "ATOM_WIFI_MULTICAST_LOCK_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LMK_STATE_CHANGED:
+    return "ATOM_LMK_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_START_MEMORY_STATE_CAPTURED:
+    return "ATOM_APP_START_MEMORY_STATE_CAPTURED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SHUTDOWN_SEQUENCE_REPORTED:
+    return "ATOM_SHUTDOWN_SEQUENCE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BOOT_SEQUENCE_REPORTED:
+    return "ATOM_BOOT_SEQUENCE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DAVEY_OCCURRED:
+    return "ATOM_DAVEY_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_OVERLAY_STATE_CHANGED:
+    return "ATOM_OVERLAY_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_FOREGROUND_SERVICE_STATE_CHANGED:
+    return "ATOM_FOREGROUND_SERVICE_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CALL_STATE_CHANGED:
+    return "ATOM_CALL_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_KEYGUARD_STATE_CHANGED:
+    return "ATOM_KEYGUARD_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_KEYGUARD_BOUNCER_STATE_CHANGED:
+    return "ATOM_KEYGUARD_BOUNCER_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_KEYGUARD_BOUNCER_PASSWORD_ENTERED:
+    return "ATOM_KEYGUARD_BOUNCER_PASSWORD_ENTERED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_DIED:
+    return "ATOM_APP_DIED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_RESOURCE_CONFIGURATION_CHANGED:
+    return "ATOM_RESOURCE_CONFIGURATION_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_ENABLED_STATE_CHANGED:
+    return "ATOM_BLUETOOTH_ENABLED_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_CONNECTION_STATE_CHANGED:
+    return "ATOM_BLUETOOTH_CONNECTION_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GPS_SIGNAL_QUALITY_CHANGED:
+    return "ATOM_GPS_SIGNAL_QUALITY_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_USB_CONNECTOR_STATE_CHANGED:
+    return "ATOM_USB_CONNECTOR_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SPEAKER_IMPEDANCE_REPORTED:
+    return "ATOM_SPEAKER_IMPEDANCE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HARDWARE_FAILED:
+    return "ATOM_HARDWARE_FAILED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PHYSICAL_DROP_DETECTED:
+    return "ATOM_PHYSICAL_DROP_DETECTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CHARGE_CYCLES_REPORTED:
+    return "ATOM_CHARGE_CYCLES_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MOBILE_CONNECTION_STATE_CHANGED:
+    return "ATOM_MOBILE_CONNECTION_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MOBILE_RADIO_TECHNOLOGY_CHANGED:
+    return "ATOM_MOBILE_RADIO_TECHNOLOGY_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_USB_DEVICE_ATTACHED:
+    return "ATOM_USB_DEVICE_ATTACHED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_CRASH_OCCURRED:
+    return "ATOM_APP_CRASH_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ANR_OCCURRED:
+    return "ATOM_ANR_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WTF_OCCURRED:
+    return "ATOM_WTF_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LOW_MEM_REPORTED:
+    return "ATOM_LOW_MEM_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GENERIC_ATOM:
+    return "ATOM_GENERIC_ATOM";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_VIBRATOR_STATE_CHANGED:
+    return "ATOM_VIBRATOR_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DEFERRED_JOB_STATS_REPORTED:
+    return "ATOM_DEFERRED_JOB_STATS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_THERMAL_THROTTLING:
+    return "ATOM_THERMAL_THROTTLING";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BIOMETRIC_ACQUIRED:
+    return "ATOM_BIOMETRIC_ACQUIRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BIOMETRIC_AUTHENTICATED:
+    return "ATOM_BIOMETRIC_AUTHENTICATED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BIOMETRIC_ERROR_OCCURRED:
+    return "ATOM_BIOMETRIC_ERROR_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_UI_EVENT_REPORTED:
+    return "ATOM_UI_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BATTERY_HEALTH_SNAPSHOT:
+    return "ATOM_BATTERY_HEALTH_SNAPSHOT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SLOW_IO:
+    return "ATOM_SLOW_IO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BATTERY_CAUSED_SHUTDOWN:
+    return "ATOM_BATTERY_CAUSED_SHUTDOWN";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PHONE_SERVICE_STATE_CHANGED:
+    return "ATOM_PHONE_SERVICE_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PHONE_STATE_CHANGED:
+    return "ATOM_PHONE_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_USER_RESTRICTION_CHANGED:
+    return "ATOM_USER_RESTRICTION_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SETTINGS_UI_CHANGED:
+    return "ATOM_SETTINGS_UI_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CONNECTIVITY_STATE_CHANGED:
+    return "ATOM_CONNECTIVITY_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SERVICE_STATE_CHANGED:
+    return "ATOM_SERVICE_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SERVICE_LAUNCH_REPORTED:
+    return "ATOM_SERVICE_LAUNCH_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_FLAG_FLIP_UPDATE_OCCURRED:
+    return "ATOM_FLAG_FLIP_UPDATE_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BINARY_PUSH_STATE_CHANGED:
+    return "ATOM_BINARY_PUSH_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DEVICE_POLICY_EVENT:
+    return "ATOM_DEVICE_POLICY_EVENT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DOCS_UI_FILE_OP_CANCELED:
+    return "ATOM_DOCS_UI_FILE_OP_CANCELED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DOCS_UI_FILE_OP_COPY_MOVE_MODE_REPORTED:
+    return "ATOM_DOCS_UI_FILE_OP_COPY_MOVE_MODE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DOCS_UI_FILE_OP_FAILURE:
+    return "ATOM_DOCS_UI_FILE_OP_FAILURE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DOCS_UI_PROVIDER_FILE_OP:
+    return "ATOM_DOCS_UI_PROVIDER_FILE_OP";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DOCS_UI_INVALID_SCOPED_ACCESS_REQUEST:
+    return "ATOM_DOCS_UI_INVALID_SCOPED_ACCESS_REQUEST";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DOCS_UI_LAUNCH_REPORTED:
+    return "ATOM_DOCS_UI_LAUNCH_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DOCS_UI_ROOT_VISITED:
+    return "ATOM_DOCS_UI_ROOT_VISITED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DOCS_UI_STARTUP_MS:
+    return "ATOM_DOCS_UI_STARTUP_MS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DOCS_UI_USER_ACTION_REPORTED:
+    return "ATOM_DOCS_UI_USER_ACTION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_ENABLED_STATE_CHANGED:
+    return "ATOM_WIFI_ENABLED_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_RUNNING_STATE_CHANGED:
+    return "ATOM_WIFI_RUNNING_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_COMPACTED:
+    return "ATOM_APP_COMPACTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NETWORK_DNS_EVENT_REPORTED:
+    return "ATOM_NETWORK_DNS_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DOCS_UI_PICKER_LAUNCHED_FROM_REPORTED:
+    return "ATOM_DOCS_UI_PICKER_LAUNCHED_FROM_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DOCS_UI_PICK_RESULT_REPORTED:
+    return "ATOM_DOCS_UI_PICK_RESULT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DOCS_UI_SEARCH_MODE_REPORTED:
+    return "ATOM_DOCS_UI_SEARCH_MODE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DOCS_UI_SEARCH_TYPE_REPORTED:
+    return "ATOM_DOCS_UI_SEARCH_TYPE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DATA_STALL_EVENT:
+    return "ATOM_DATA_STALL_EVENT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_RESCUE_PARTY_RESET_REPORTED:
+    return "ATOM_RESCUE_PARTY_RESET_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SIGNED_CONFIG_REPORTED:
+    return "ATOM_SIGNED_CONFIG_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GNSS_NI_EVENT_REPORTED:
+    return "ATOM_GNSS_NI_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_LINK_LAYER_CONNECTION_EVENT:
+    return "ATOM_BLUETOOTH_LINK_LAYER_CONNECTION_EVENT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_ACL_CONNECTION_STATE_CHANGED:
+    return "ATOM_BLUETOOTH_ACL_CONNECTION_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_SCO_CONNECTION_STATE_CHANGED:
+    return "ATOM_BLUETOOTH_SCO_CONNECTION_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_DOWNGRADED:
+    return "ATOM_APP_DOWNGRADED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_OPTIMIZED_AFTER_DOWNGRADED:
+    return "ATOM_APP_OPTIMIZED_AFTER_DOWNGRADED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LOW_STORAGE_STATE_CHANGED:
+    return "ATOM_LOW_STORAGE_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GNSS_NFW_NOTIFICATION_REPORTED:
+    return "ATOM_GNSS_NFW_NOTIFICATION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GNSS_CONFIGURATION_REPORTED:
+    return "ATOM_GNSS_CONFIGURATION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_USB_PORT_OVERHEAT_EVENT_REPORTED:
+    return "ATOM_USB_PORT_OVERHEAT_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NFC_ERROR_OCCURRED:
+    return "ATOM_NFC_ERROR_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NFC_STATE_CHANGED:
+    return "ATOM_NFC_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NFC_BEAM_OCCURRED:
+    return "ATOM_NFC_BEAM_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NFC_CARDEMULATION_OCCURRED:
+    return "ATOM_NFC_CARDEMULATION_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NFC_TAG_OCCURRED:
+    return "ATOM_NFC_TAG_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NFC_HCE_TRANSACTION_OCCURRED:
+    return "ATOM_NFC_HCE_TRANSACTION_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SE_STATE_CHANGED:
+    return "ATOM_SE_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SE_OMAPI_REPORTED:
+    return "ATOM_SE_OMAPI_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BROADCAST_DISPATCH_LATENCY_REPORTED:
+    return "ATOM_BROADCAST_DISPATCH_LATENCY_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ATTENTION_MANAGER_SERVICE_RESULT_REPORTED:
+    return "ATOM_ATTENTION_MANAGER_SERVICE_RESULT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ADB_CONNECTION_CHANGED:
+    return "ATOM_ADB_CONNECTION_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SPEECH_DSP_STAT_REPORTED:
+    return "ATOM_SPEECH_DSP_STAT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_USB_CONTAMINANT_REPORTED:
+    return "ATOM_USB_CONTAMINANT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WATCHDOG_ROLLBACK_OCCURRED:
+    return "ATOM_WATCHDOG_ROLLBACK_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED:
+    return "ATOM_BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BUBBLE_UI_CHANGED:
+    return "ATOM_BUBBLE_UI_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SCHEDULED_JOB_CONSTRAINT_CHANGED:
+    return "ATOM_SCHEDULED_JOB_CONSTRAINT_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_ACTIVE_DEVICE_CHANGED:
+    return "ATOM_BLUETOOTH_ACTIVE_DEVICE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_A2DP_PLAYBACK_STATE_CHANGED:
+    return "ATOM_BLUETOOTH_A2DP_PLAYBACK_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_A2DP_CODEC_CONFIG_CHANGED:
+    return "ATOM_BLUETOOTH_A2DP_CODEC_CONFIG_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_A2DP_CODEC_CAPABILITY_CHANGED:
+    return "ATOM_BLUETOOTH_A2DP_CODEC_CAPABILITY_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_A2DP_AUDIO_UNDERRUN_REPORTED:
+    return "ATOM_BLUETOOTH_A2DP_AUDIO_UNDERRUN_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_A2DP_AUDIO_OVERRUN_REPORTED:
+    return "ATOM_BLUETOOTH_A2DP_AUDIO_OVERRUN_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_DEVICE_RSSI_REPORTED:
+    return "ATOM_BLUETOOTH_DEVICE_RSSI_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_DEVICE_FAILED_CONTACT_COUNTER_REPORTED:
+    return "ATOM_BLUETOOTH_DEVICE_FAILED_CONTACT_COUNTER_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_DEVICE_TX_POWER_LEVEL_REPORTED:
+    return "ATOM_BLUETOOTH_DEVICE_TX_POWER_LEVEL_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_HCI_TIMEOUT_REPORTED:
+    return "ATOM_BLUETOOTH_HCI_TIMEOUT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_QUALITY_REPORT_REPORTED:
+    return "ATOM_BLUETOOTH_QUALITY_REPORT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_DEVICE_INFO_REPORTED:
+    return "ATOM_BLUETOOTH_DEVICE_INFO_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_REMOTE_VERSION_INFO_REPORTED:
+    return "ATOM_BLUETOOTH_REMOTE_VERSION_INFO_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_SDP_ATTRIBUTE_REPORTED:
+    return "ATOM_BLUETOOTH_SDP_ATTRIBUTE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_BOND_STATE_CHANGED:
+    return "ATOM_BLUETOOTH_BOND_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_CLASSIC_PAIRING_EVENT_REPORTED:
+    return "ATOM_BLUETOOTH_CLASSIC_PAIRING_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_SMP_PAIRING_EVENT_REPORTED:
+    return "ATOM_BLUETOOTH_SMP_PAIRING_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SCREEN_TIMEOUT_EXTENSION_REPORTED:
+    return "ATOM_SCREEN_TIMEOUT_EXTENSION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PROCESS_START_TIME:
+    return "ATOM_PROCESS_START_TIME";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PERMISSION_GRANT_REQUEST_RESULT_REPORTED:
+    return "ATOM_PERMISSION_GRANT_REQUEST_RESULT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_SOCKET_CONNECTION_STATE_CHANGED:
+    return "ATOM_BLUETOOTH_SOCKET_CONNECTION_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DEVICE_IDENTIFIER_ACCESS_DENIED:
+    return "ATOM_DEVICE_IDENTIFIER_ACCESS_DENIED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BUBBLE_DEVELOPER_ERROR_REPORTED:
+    return "ATOM_BUBBLE_DEVELOPER_ERROR_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ASSIST_GESTURE_STAGE_REPORTED:
+    return "ATOM_ASSIST_GESTURE_STAGE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ASSIST_GESTURE_FEEDBACK_REPORTED:
+    return "ATOM_ASSIST_GESTURE_FEEDBACK_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ASSIST_GESTURE_PROGRESS_REPORTED:
+    return "ATOM_ASSIST_GESTURE_PROGRESS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TOUCH_GESTURE_CLASSIFIED:
+    return "ATOM_TOUCH_GESTURE_CLASSIFIED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HIDDEN_API_USED:
+    return "ATOM_HIDDEN_API_USED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_STYLE_UI_CHANGED:
+    return "ATOM_STYLE_UI_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PRIVACY_INDICATORS_INTERACTED:
+    return "ATOM_PRIVACY_INDICATORS_INTERACTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_INSTALL_ON_EXTERNAL_STORAGE_REPORTED:
+    return "ATOM_APP_INSTALL_ON_EXTERNAL_STORAGE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NETWORK_STACK_REPORTED:
+    return "ATOM_NETWORK_STACK_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_MOVED_STORAGE_REPORTED:
+    return "ATOM_APP_MOVED_STORAGE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BIOMETRIC_ENROLLED:
+    return "ATOM_BIOMETRIC_ENROLLED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SYSTEM_SERVER_WATCHDOG_OCCURRED:
+    return "ATOM_SYSTEM_SERVER_WATCHDOG_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TOMB_STONE_OCCURRED:
+    return "ATOM_TOMB_STONE_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_CLASS_OF_DEVICE_REPORTED:
+    return "ATOM_BLUETOOTH_CLASS_OF_DEVICE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_INTELLIGENCE_EVENT_REPORTED:
+    return "ATOM_INTELLIGENCE_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_THERMAL_THROTTLING_SEVERITY_STATE_CHANGED:
+    return "ATOM_THERMAL_THROTTLING_SEVERITY_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ROLE_REQUEST_RESULT_REPORTED:
+    return "ATOM_ROLE_REQUEST_RESULT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_AUDIOPOLICY_REPORTED:
+    return "ATOM_MEDIAMETRICS_AUDIOPOLICY_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_AUDIORECORD_REPORTED:
+    return "ATOM_MEDIAMETRICS_AUDIORECORD_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_AUDIOTHREAD_REPORTED:
+    return "ATOM_MEDIAMETRICS_AUDIOTHREAD_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_AUDIOTRACK_REPORTED:
+    return "ATOM_MEDIAMETRICS_AUDIOTRACK_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_CODEC_REPORTED:
+    return "ATOM_MEDIAMETRICS_CODEC_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_DRM_WIDEVINE_REPORTED:
+    return "ATOM_MEDIAMETRICS_DRM_WIDEVINE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_EXTRACTOR_REPORTED:
+    return "ATOM_MEDIAMETRICS_EXTRACTOR_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_MEDIADRM_REPORTED:
+    return "ATOM_MEDIAMETRICS_MEDIADRM_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_NUPLAYER_REPORTED:
+    return "ATOM_MEDIAMETRICS_NUPLAYER_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_RECORDER_REPORTED:
+    return "ATOM_MEDIAMETRICS_RECORDER_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_DRMMANAGER_REPORTED:
+    return "ATOM_MEDIAMETRICS_DRMMANAGER_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CAR_POWER_STATE_CHANGED:
+    return "ATOM_CAR_POWER_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GARAGE_MODE_INFO:
+    return "ATOM_GARAGE_MODE_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TEST_ATOM_REPORTED:
+    return "ATOM_TEST_ATOM_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CONTENT_CAPTURE_CALLER_MISMATCH_REPORTED:
+    return "ATOM_CONTENT_CAPTURE_CALLER_MISMATCH_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CONTENT_CAPTURE_SERVICE_EVENTS:
+    return "ATOM_CONTENT_CAPTURE_SERVICE_EVENTS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CONTENT_CAPTURE_SESSION_EVENTS:
+    return "ATOM_CONTENT_CAPTURE_SESSION_EVENTS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CONTENT_CAPTURE_FLUSHED:
+    return "ATOM_CONTENT_CAPTURE_FLUSHED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LOCATION_MANAGER_API_USAGE_REPORTED:
+    return "ATOM_LOCATION_MANAGER_API_USAGE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_REVIEW_PERMISSIONS_FRAGMENT_RESULT_REPORTED:
+    return "ATOM_REVIEW_PERMISSIONS_FRAGMENT_RESULT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_RUNTIME_PERMISSIONS_UPGRADE_RESULT:
+    return "ATOM_RUNTIME_PERMISSIONS_UPGRADE_RESULT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GRANT_PERMISSIONS_ACTIVITY_BUTTON_ACTIONS:
+    return "ATOM_GRANT_PERMISSIONS_ACTIVITY_BUTTON_ACTIONS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LOCATION_ACCESS_CHECK_NOTIFICATION_ACTION:
+    return "ATOM_LOCATION_ACCESS_CHECK_NOTIFICATION_ACTION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_PERMISSION_FRAGMENT_ACTION_REPORTED:
+    return "ATOM_APP_PERMISSION_FRAGMENT_ACTION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_PERMISSION_FRAGMENT_VIEWED:
+    return "ATOM_APP_PERMISSION_FRAGMENT_VIEWED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_PERMISSIONS_FRAGMENT_VIEWED:
+    return "ATOM_APP_PERMISSIONS_FRAGMENT_VIEWED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PERMISSION_APPS_FRAGMENT_VIEWED:
+    return "ATOM_PERMISSION_APPS_FRAGMENT_VIEWED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TEXT_SELECTION_EVENT:
+    return "ATOM_TEXT_SELECTION_EVENT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TEXT_LINKIFY_EVENT:
+    return "ATOM_TEXT_LINKIFY_EVENT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CONVERSATION_ACTIONS_EVENT:
+    return "ATOM_CONVERSATION_ACTIONS_EVENT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LANGUAGE_DETECTION_EVENT:
+    return "ATOM_LANGUAGE_DETECTION_EVENT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_EXCLUSION_RECT_STATE_CHANGED:
+    return "ATOM_EXCLUSION_RECT_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BACK_GESTURE_REPORTED_REPORTED:
+    return "ATOM_BACK_GESTURE_REPORTED_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_UPDATE_ENGINE_UPDATE_ATTEMPT_REPORTED:
+    return "ATOM_UPDATE_ENGINE_UPDATE_ATTEMPT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_UPDATE_ENGINE_SUCCESSFUL_UPDATE_REPORTED:
+    return "ATOM_UPDATE_ENGINE_SUCCESSFUL_UPDATE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CAMERA_ACTION_EVENT:
+    return "ATOM_CAMERA_ACTION_EVENT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_COMPATIBILITY_CHANGE_REPORTED:
+    return "ATOM_APP_COMPATIBILITY_CHANGE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PERFETTO_UPLOADED:
+    return "ATOM_PERFETTO_UPLOADED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_VMS_CLIENT_CONNECTION_STATE_CHANGED:
+    return "ATOM_VMS_CLIENT_CONNECTION_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_PROVIDER_SCAN_OCCURRED:
+    return "ATOM_MEDIA_PROVIDER_SCAN_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_CONTENT_DELETED:
+    return "ATOM_MEDIA_CONTENT_DELETED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_PROVIDER_PERMISSION_REQUESTED:
+    return "ATOM_MEDIA_PROVIDER_PERMISSION_REQUESTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_PROVIDER_SCHEMA_CHANGED:
+    return "ATOM_MEDIA_PROVIDER_SCHEMA_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_PROVIDER_IDLE_MAINTENANCE_FINISHED:
+    return "ATOM_MEDIA_PROVIDER_IDLE_MAINTENANCE_FINISHED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_REBOOT_ESCROW_RECOVERY_REPORTED:
+    return "ATOM_REBOOT_ESCROW_RECOVERY_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BOOT_TIME_EVENT_DURATION_REPORTED:
+    return "ATOM_BOOT_TIME_EVENT_DURATION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED:
+    return "ATOM_BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BOOT_TIME_EVENT_UTC_TIME_REPORTED:
+    return "ATOM_BOOT_TIME_EVENT_UTC_TIME_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BOOT_TIME_EVENT_ERROR_CODE_REPORTED:
+    return "ATOM_BOOT_TIME_EVENT_ERROR_CODE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_USERSPACE_REBOOT_REPORTED:
+    return "ATOM_USERSPACE_REBOOT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NOTIFICATION_REPORTED:
+    return "ATOM_NOTIFICATION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NOTIFICATION_PANEL_REPORTED:
+    return "ATOM_NOTIFICATION_PANEL_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NOTIFICATION_CHANNEL_MODIFIED:
+    return "ATOM_NOTIFICATION_CHANNEL_MODIFIED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_INTEGRITY_CHECK_RESULT_REPORTED:
+    return "ATOM_INTEGRITY_CHECK_RESULT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_INTEGRITY_RULES_PUSHED:
+    return "ATOM_INTEGRITY_RULES_PUSHED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CB_MESSAGE_REPORTED:
+    return "ATOM_CB_MESSAGE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CB_MESSAGE_ERROR:
+    return "ATOM_CB_MESSAGE_ERROR";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_HEALTH_STAT_REPORTED:
+    return "ATOM_WIFI_HEALTH_STAT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_FAILURE_STAT_REPORTED:
+    return "ATOM_WIFI_FAILURE_STAT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_CONNECTION_RESULT_REPORTED:
+    return "ATOM_WIFI_CONNECTION_RESULT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_FREEZE_CHANGED:
+    return "ATOM_APP_FREEZE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SNAPSHOT_MERGE_REPORTED:
+    return "ATOM_SNAPSHOT_MERGE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_FOREGROUND_SERVICE_APP_OP_SESSION_ENDED:
+    return "ATOM_FOREGROUND_SERVICE_APP_OP_SESSION_ENDED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DISPLAY_JANK_REPORTED:
+    return "ATOM_DISPLAY_JANK_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_STANDBY_BUCKET_CHANGED:
+    return "ATOM_APP_STANDBY_BUCKET_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SHARESHEET_STARTED:
+    return "ATOM_SHARESHEET_STARTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_RANKING_SELECTED:
+    return "ATOM_RANKING_SELECTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TVSETTINGS_UI_INTERACTED:
+    return "ATOM_TVSETTINGS_UI_INTERACTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LAUNCHER_SNAPSHOT:
+    return "ATOM_LAUNCHER_SNAPSHOT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PACKAGE_INSTALLER_V2_REPORTED:
+    return "ATOM_PACKAGE_INSTALLER_V2_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_USER_LIFECYCLE_JOURNEY_REPORTED:
+    return "ATOM_USER_LIFECYCLE_JOURNEY_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_USER_LIFECYCLE_EVENT_OCCURRED:
+    return "ATOM_USER_LIFECYCLE_EVENT_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ACCESSIBILITY_SHORTCUT_REPORTED:
+    return "ATOM_ACCESSIBILITY_SHORTCUT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ACCESSIBILITY_SERVICE_REPORTED:
+    return "ATOM_ACCESSIBILITY_SERVICE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DOCS_UI_DRAG_AND_DROP_REPORTED:
+    return "ATOM_DOCS_UI_DRAG_AND_DROP_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_USAGE_EVENT_OCCURRED:
+    return "ATOM_APP_USAGE_EVENT_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AUTO_REVOKE_NOTIFICATION_CLICKED:
+    return "ATOM_AUTO_REVOKE_NOTIFICATION_CLICKED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AUTO_REVOKE_FRAGMENT_APP_VIEWED:
+    return "ATOM_AUTO_REVOKE_FRAGMENT_APP_VIEWED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AUTO_REVOKED_APP_INTERACTION:
+    return "ATOM_AUTO_REVOKED_APP_INTERACTION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_PERMISSION_GROUPS_FRAGMENT_AUTO_REVOKE_ACTION:
+    return "ATOM_APP_PERMISSION_GROUPS_FRAGMENT_AUTO_REVOKE_ACTION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_EVS_USAGE_STATS_REPORTED:
+    return "ATOM_EVS_USAGE_STATS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AUDIO_POWER_USAGE_DATA_REPORTED:
+    return "ATOM_AUDIO_POWER_USAGE_DATA_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TV_TUNER_STATE_CHANGED:
+    return "ATOM_TV_TUNER_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAOUTPUT_OP_SWITCH_REPORTED:
+    return "ATOM_MEDIAOUTPUT_OP_SWITCH_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CB_MESSAGE_FILTERED:
+    return "ATOM_CB_MESSAGE_FILTERED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TV_TUNER_DVR_STATUS:
+    return "ATOM_TV_TUNER_DVR_STATUS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TV_CAS_SESSION_OPEN_STATUS:
+    return "ATOM_TV_CAS_SESSION_OPEN_STATUS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ASSISTANT_INVOCATION_REPORTED:
+    return "ATOM_ASSISTANT_INVOCATION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DISPLAY_WAKE_REPORTED:
+    return "ATOM_DISPLAY_WAKE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CAR_USER_HAL_MODIFY_USER_REQUEST_REPORTED:
+    return "ATOM_CAR_USER_HAL_MODIFY_USER_REQUEST_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CAR_USER_HAL_MODIFY_USER_RESPONSE_REPORTED:
+    return "ATOM_CAR_USER_HAL_MODIFY_USER_RESPONSE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CAR_USER_HAL_POST_SWITCH_RESPONSE_REPORTED:
+    return "ATOM_CAR_USER_HAL_POST_SWITCH_RESPONSE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CAR_USER_HAL_INITIAL_USER_INFO_REQUEST_REPORTED:
+    return "ATOM_CAR_USER_HAL_INITIAL_USER_INFO_REQUEST_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CAR_USER_HAL_INITIAL_USER_INFO_RESPONSE_REPORTED:
+    return "ATOM_CAR_USER_HAL_INITIAL_USER_INFO_RESPONSE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CAR_USER_HAL_USER_ASSOCIATION_REQUEST_REPORTED:
+    return "ATOM_CAR_USER_HAL_USER_ASSOCIATION_REQUEST_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CAR_USER_HAL_SET_USER_ASSOCIATION_RESPONSE_REPORTED:
+    return "ATOM_CAR_USER_HAL_SET_USER_ASSOCIATION_RESPONSE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NETWORK_IP_PROVISIONING_REPORTED:
+    return "ATOM_NETWORK_IP_PROVISIONING_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NETWORK_DHCP_RENEW_REPORTED:
+    return "ATOM_NETWORK_DHCP_RENEW_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NETWORK_VALIDATION_REPORTED:
+    return "ATOM_NETWORK_VALIDATION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NETWORK_STACK_QUIRK_REPORTED:
+    return "ATOM_NETWORK_STACK_QUIRK_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_AUDIORECORDDEVICEUSAGE_REPORTED:
+    return "ATOM_MEDIAMETRICS_AUDIORECORDDEVICEUSAGE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_AUDIOTHREADDEVICEUSAGE_REPORTED:
+    return "ATOM_MEDIAMETRICS_AUDIOTHREADDEVICEUSAGE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_AUDIOTRACKDEVICEUSAGE_REPORTED:
+    return "ATOM_MEDIAMETRICS_AUDIOTRACKDEVICEUSAGE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_AUDIODEVICECONNECTION_REPORTED:
+    return "ATOM_MEDIAMETRICS_AUDIODEVICECONNECTION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLOB_COMMITTED:
+    return "ATOM_BLOB_COMMITTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLOB_LEASED:
+    return "ATOM_BLOB_LEASED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLOB_OPENED:
+    return "ATOM_BLOB_OPENED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CONTACTS_PROVIDER_STATUS_REPORTED:
+    return "ATOM_CONTACTS_PROVIDER_STATUS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_KEYSTORE_KEY_EVENT_REPORTED:
+    return "ATOM_KEYSTORE_KEY_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NETWORK_TETHERING_REPORTED:
+    return "ATOM_NETWORK_TETHERING_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_IME_TOUCH_REPORTED:
+    return "ATOM_IME_TOUCH_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_UI_INTERACTION_FRAME_INFO_REPORTED:
+    return "ATOM_UI_INTERACTION_FRAME_INFO_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_UI_ACTION_LATENCY_REPORTED:
+    return "ATOM_UI_ACTION_LATENCY_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_DISCONNECT_REPORTED:
+    return "ATOM_WIFI_DISCONNECT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_CONNECTION_STATE_CHANGED:
+    return "ATOM_WIFI_CONNECTION_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HDMI_CEC_ACTIVE_SOURCE_CHANGED:
+    return "ATOM_HDMI_CEC_ACTIVE_SOURCE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HDMI_CEC_MESSAGE_REPORTED:
+    return "ATOM_HDMI_CEC_MESSAGE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AIRPLANE_MODE:
+    return "ATOM_AIRPLANE_MODE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MODEM_RESTART:
+    return "ATOM_MODEM_RESTART";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CARRIER_ID_MISMATCH_REPORTED:
+    return "ATOM_CARRIER_ID_MISMATCH_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CARRIER_ID_TABLE_UPDATED:
+    return "ATOM_CARRIER_ID_TABLE_UPDATED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DATA_STALL_RECOVERY_REPORTED:
+    return "ATOM_DATA_STALL_RECOVERY_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_MEDIAPARSER_REPORTED:
+    return "ATOM_MEDIAMETRICS_MEDIAPARSER_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TLS_HANDSHAKE_REPORTED:
+    return "ATOM_TLS_HANDSHAKE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TEXT_CLASSIFIER_API_USAGE_REPORTED:
+    return "ATOM_TEXT_CLASSIFIER_API_USAGE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CAR_WATCHDOG_KILL_STATS_REPORTED:
+    return "ATOM_CAR_WATCHDOG_KILL_STATS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_PLAYBACK_REPORTED:
+    return "ATOM_MEDIAMETRICS_PLAYBACK_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_NETWORK_INFO_CHANGED:
+    return "ATOM_MEDIA_NETWORK_INFO_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_PLAYBACK_STATE_CHANGED:
+    return "ATOM_MEDIA_PLAYBACK_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_PLAYBACK_ERROR_REPORTED:
+    return "ATOM_MEDIA_PLAYBACK_ERROR_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_PLAYBACK_TRACK_CHANGED:
+    return "ATOM_MEDIA_PLAYBACK_TRACK_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_SCAN_REPORTED:
+    return "ATOM_WIFI_SCAN_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_PNO_SCAN_REPORTED:
+    return "ATOM_WIFI_PNO_SCAN_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TIF_TUNE_CHANGED:
+    return "ATOM_TIF_TUNE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AUTO_ROTATE_REPORTED:
+    return "ATOM_AUTO_ROTATE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PERFETTO_TRIGGER:
+    return "ATOM_PERFETTO_TRIGGER";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TRANSCODING_DATA:
+    return "ATOM_TRANSCODING_DATA";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_IMS_SERVICE_ENTITLEMENT_UPDATED:
+    return "ATOM_IMS_SERVICE_ENTITLEMENT_UPDATED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DEVICE_ROTATED:
+    return "ATOM_DEVICE_ROTATED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SIM_SPECIFIC_SETTINGS_RESTORED:
+    return "ATOM_SIM_SPECIFIC_SETTINGS_RESTORED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TEXT_CLASSIFIER_DOWNLOAD_REPORTED:
+    return "ATOM_TEXT_CLASSIFIER_DOWNLOAD_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PIN_STORAGE_EVENT:
+    return "ATOM_PIN_STORAGE_EVENT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_FACE_DOWN_REPORTED:
+    return "ATOM_FACE_DOWN_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_HAL_CRASH_REASON_REPORTED:
+    return "ATOM_BLUETOOTH_HAL_CRASH_REASON_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_REBOOT_ESCROW_PREPARATION_REPORTED:
+    return "ATOM_REBOOT_ESCROW_PREPARATION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_REBOOT_ESCROW_LSKF_CAPTURE_REPORTED:
+    return "ATOM_REBOOT_ESCROW_LSKF_CAPTURE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_REBOOT_ESCROW_REBOOT_REPORTED:
+    return "ATOM_REBOOT_ESCROW_REBOOT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BINDER_LATENCY_REPORTED:
+    return "ATOM_BINDER_LATENCY_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_AAUDIOSTREAM_REPORTED:
+    return "ATOM_MEDIAMETRICS_AAUDIOSTREAM_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_TRANSCODING_SESSION_ENDED:
+    return "ATOM_MEDIA_TRANSCODING_SESSION_ENDED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MAGNIFICATION_USAGE_REPORTED:
+    return "ATOM_MAGNIFICATION_USAGE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MAGNIFICATION_MODE_WITH_IME_ON_REPORTED:
+    return "ATOM_MAGNIFICATION_MODE_WITH_IME_ON_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_SEARCH_CALL_STATS_REPORTED:
+    return "ATOM_APP_SEARCH_CALL_STATS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_SEARCH_PUT_DOCUMENT_STATS_REPORTED:
+    return "ATOM_APP_SEARCH_PUT_DOCUMENT_STATS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DEVICE_CONTROL_CHANGED:
+    return "ATOM_DEVICE_CONTROL_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DEVICE_STATE_CHANGED:
+    return "ATOM_DEVICE_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_INPUTDEVICE_REGISTERED:
+    return "ATOM_INPUTDEVICE_REGISTERED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SMARTSPACE_CARD_REPORTED:
+    return "ATOM_SMARTSPACE_CARD_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AUTH_PROMPT_AUTHENTICATE_INVOKED:
+    return "ATOM_AUTH_PROMPT_AUTHENTICATE_INVOKED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AUTH_MANAGER_CAN_AUTHENTICATE_INVOKED:
+    return "ATOM_AUTH_MANAGER_CAN_AUTHENTICATE_INVOKED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AUTH_ENROLL_ACTION_INVOKED:
+    return "ATOM_AUTH_ENROLL_ACTION_INVOKED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AUTH_DEPRECATED_API_USED:
+    return "ATOM_AUTH_DEPRECATED_API_USED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_UNATTENDED_REBOOT_OCCURRED:
+    return "ATOM_UNATTENDED_REBOOT_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LONG_REBOOT_BLOCKING_REPORTED:
+    return "ATOM_LONG_REBOOT_BLOCKING_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LOCATION_TIME_ZONE_PROVIDER_STATE_CHANGED:
+    return "ATOM_LOCATION_TIME_ZONE_PROVIDER_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_FDTRACK_EVENT_OCCURRED:
+    return "ATOM_FDTRACK_EVENT_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TIMEOUT_AUTO_EXTENDED_REPORTED:
+    return "ATOM_TIMEOUT_AUTO_EXTENDED_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ALARM_BATCH_DELIVERED:
+    return "ATOM_ALARM_BATCH_DELIVERED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ALARM_SCHEDULED:
+    return "ATOM_ALARM_SCHEDULED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CAR_WATCHDOG_IO_OVERUSE_STATS_REPORTED:
+    return "ATOM_CAR_WATCHDOG_IO_OVERUSE_STATS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_USER_LEVEL_HIBERNATION_STATE_CHANGED:
+    return "ATOM_USER_LEVEL_HIBERNATION_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_SEARCH_INITIALIZE_STATS_REPORTED:
+    return "ATOM_APP_SEARCH_INITIALIZE_STATS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_SEARCH_QUERY_STATS_REPORTED:
+    return "ATOM_APP_SEARCH_QUERY_STATS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_PROCESS_DIED:
+    return "ATOM_APP_PROCESS_DIED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NETWORK_IP_REACHABILITY_MONITOR_REPORTED:
+    return "ATOM_NETWORK_IP_REACHABILITY_MONITOR_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SLOW_INPUT_EVENT_REPORTED:
+    return "ATOM_SLOW_INPUT_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ANR_OCCURRED_PROCESSING_STARTED:
+    return "ATOM_ANR_OCCURRED_PROCESSING_STARTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_SEARCH_REMOVE_STATS_REPORTED:
+    return "ATOM_APP_SEARCH_REMOVE_STATS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_CODEC_REPORTED:
+    return "ATOM_MEDIA_CODEC_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PERMISSION_USAGE_FRAGMENT_INTERACTION:
+    return "ATOM_PERMISSION_USAGE_FRAGMENT_INTERACTION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PERMISSION_DETAILS_INTERACTION:
+    return "ATOM_PERMISSION_DETAILS_INTERACTION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PRIVACY_SENSOR_TOGGLE_INTERACTION:
+    return "ATOM_PRIVACY_SENSOR_TOGGLE_INTERACTION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PRIVACY_TOGGLE_DIALOG_INTERACTION:
+    return "ATOM_PRIVACY_TOGGLE_DIALOG_INTERACTION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_SEARCH_OPTIMIZE_STATS_REPORTED:
+    return "ATOM_APP_SEARCH_OPTIMIZE_STATS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NON_A11Y_TOOL_SERVICE_WARNING_REPORT:
+    return "ATOM_NON_A11Y_TOOL_SERVICE_WARNING_REPORT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_SEARCH_SET_SCHEMA_STATS_REPORTED:
+    return "ATOM_APP_SEARCH_SET_SCHEMA_STATS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_COMPAT_STATE_CHANGED:
+    return "ATOM_APP_COMPAT_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SIZE_COMPAT_RESTART_BUTTON_EVENT_REPORTED:
+    return "ATOM_SIZE_COMPAT_RESTART_BUTTON_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SPLITSCREEN_UI_CHANGED:
+    return "ATOM_SPLITSCREEN_UI_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NETWORK_DNS_HANDSHAKE_REPORTED:
+    return "ATOM_NETWORK_DNS_HANDSHAKE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_CODE_PATH_COUNTER:
+    return "ATOM_BLUETOOTH_CODE_PATH_COUNTER";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_LE_BATCH_SCAN_REPORT_DELAY:
+    return "ATOM_BLUETOOTH_LE_BATCH_SCAN_REPORT_DELAY";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ACCESSIBILITY_FLOATING_MENU_UI_CHANGED:
+    return "ATOM_ACCESSIBILITY_FLOATING_MENU_UI_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NEURALNETWORKS_COMPILATION_COMPLETED:
+    return "ATOM_NEURALNETWORKS_COMPILATION_COMPLETED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NEURALNETWORKS_EXECUTION_COMPLETED:
+    return "ATOM_NEURALNETWORKS_EXECUTION_COMPLETED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NEURALNETWORKS_COMPILATION_FAILED:
+    return "ATOM_NEURALNETWORKS_COMPILATION_FAILED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NEURALNETWORKS_EXECUTION_FAILED:
+    return "ATOM_NEURALNETWORKS_EXECUTION_FAILED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CONTEXT_HUB_BOOTED:
+    return "ATOM_CONTEXT_HUB_BOOTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CONTEXT_HUB_RESTARTED:
+    return "ATOM_CONTEXT_HUB_RESTARTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CONTEXT_HUB_LOADED_NANOAPP_SNAPSHOT_REPORTED:
+    return "ATOM_CONTEXT_HUB_LOADED_NANOAPP_SNAPSHOT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CHRE_CODE_DOWNLOAD_TRANSACTED:
+    return "ATOM_CHRE_CODE_DOWNLOAD_TRANSACTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_UWB_SESSION_INITED:
+    return "ATOM_UWB_SESSION_INITED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_UWB_SESSION_CLOSED:
+    return "ATOM_UWB_SESSION_CLOSED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_UWB_FIRST_RANGING_RECEIVED:
+    return "ATOM_UWB_FIRST_RANGING_RECEIVED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_UWB_RANGING_MEASUREMENT_RECEIVED:
+    return "ATOM_UWB_RANGING_MEASUREMENT_RECEIVED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TEXT_CLASSIFIER_DOWNLOAD_WORK_SCHEDULED:
+    return "ATOM_TEXT_CLASSIFIER_DOWNLOAD_WORK_SCHEDULED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TEXT_CLASSIFIER_DOWNLOAD_WORK_COMPLETED:
+    return "ATOM_TEXT_CLASSIFIER_DOWNLOAD_WORK_COMPLETED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CLIPBOARD_CLEARED:
+    return "ATOM_CLIPBOARD_CLEARED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_VM_CREATION_REQUESTED:
+    return "ATOM_VM_CREATION_REQUESTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NEARBY_DEVICE_SCAN_STATE_CHANGED:
+    return "ATOM_NEARBY_DEVICE_SCAN_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CAMERA_COMPAT_CONTROL_EVENT_REPORTED:
+    return "ATOM_CAMERA_COMPAT_CONTROL_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APPLICATION_LOCALES_CHANGED:
+    return "ATOM_APPLICATION_LOCALES_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_AUDIOTRACKSTATUS_REPORTED:
+    return "ATOM_MEDIAMETRICS_AUDIOTRACKSTATUS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_FOLD_STATE_DURATION_REPORTED:
+    return "ATOM_FOLD_STATE_DURATION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LOCATION_TIME_ZONE_PROVIDER_CONTROLLER_STATE_CHANGED:
+    return "ATOM_LOCATION_TIME_ZONE_PROVIDER_CONTROLLER_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DISPLAY_HBM_STATE_CHANGED:
+    return "ATOM_DISPLAY_HBM_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DISPLAY_HBM_BRIGHTNESS_CHANGED:
+    return "ATOM_DISPLAY_HBM_BRIGHTNESS_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PERSISTENT_URI_PERMISSIONS_FLUSHED:
+    return "ATOM_PERSISTENT_URI_PERMISSIONS_FLUSHED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_EARLY_BOOT_COMP_OS_ARTIFACTS_CHECK_REPORTED:
+    return "ATOM_EARLY_BOOT_COMP_OS_ARTIFACTS_CHECK_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_VBMETA_DIGEST_REPORTED:
+    return "ATOM_VBMETA_DIGEST_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APEX_INFO_GATHERED:
+    return "ATOM_APEX_INFO_GATHERED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PVM_INFO_GATHERED:
+    return "ATOM_PVM_INFO_GATHERED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WEAR_SETTINGS_UI_INTERACTED:
+    return "ATOM_WEAR_SETTINGS_UI_INTERACTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TRACING_SERVICE_REPORT_EVENT:
+    return "ATOM_TRACING_SERVICE_REPORT_EVENT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_AUDIORECORDSTATUS_REPORTED:
+    return "ATOM_MEDIAMETRICS_AUDIORECORDSTATUS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LAUNCHER_LATENCY:
+    return "ATOM_LAUNCHER_LATENCY";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DROPBOX_ENTRY_DROPPED:
+    return "ATOM_DROPBOX_ENTRY_DROPPED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_P2P_CONNECTION_REPORTED:
+    return "ATOM_WIFI_P2P_CONNECTION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GAME_STATE_CHANGED:
+    return "ATOM_GAME_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HOTWORD_DETECTOR_CREATE_REQUESTED:
+    return "ATOM_HOTWORD_DETECTOR_CREATE_REQUESTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED:
+    return "ATOM_HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HOTWORD_DETECTION_SERVICE_RESTARTED:
+    return "ATOM_HOTWORD_DETECTION_SERVICE_RESTARTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED:
+    return "ATOM_HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HOTWORD_DETECTOR_EVENTS:
+    return "ATOM_HOTWORD_DETECTOR_EVENTS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AD_SERVICES_API_CALLED:
+    return "ATOM_AD_SERVICES_API_CALLED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AD_SERVICES_MESUREMENT_REPORTS_UPLOADED:
+    return "ATOM_AD_SERVICES_MESUREMENT_REPORTS_UPLOADED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BOOT_COMPLETED_BROADCAST_COMPLETION_LATENCY_REPORTED:
+    return "ATOM_BOOT_COMPLETED_BROADCAST_COMPLETION_LATENCY_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CONTACTS_INDEXER_UPDATE_STATS_REPORTED:
+    return "ATOM_CONTACTS_INDEXER_UPDATE_STATS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_BACKGROUND_RESTRICTIONS_INFO:
+    return "ATOM_APP_BACKGROUND_RESTRICTIONS_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MMS_SMS_PROVIDER_GET_THREAD_ID_FAILED:
+    return "ATOM_MMS_SMS_PROVIDER_GET_THREAD_ID_FAILED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MMS_SMS_DATABASE_HELPER_ON_UPGRADE_FAILED:
+    return "ATOM_MMS_SMS_DATABASE_HELPER_ON_UPGRADE_FAILED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PERMISSION_REMINDER_NOTIFICATION_INTERACTED:
+    return "ATOM_PERMISSION_REMINDER_NOTIFICATION_INTERACTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_RECENT_PERMISSION_DECISIONS_INTERACTED:
+    return "ATOM_RECENT_PERMISSION_DECISIONS_INTERACTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GNSS_PSDS_DOWNLOAD_REPORTED:
+    return "ATOM_GNSS_PSDS_DOWNLOAD_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LE_AUDIO_CONNECTION_SESSION_REPORTED:
+    return "ATOM_LE_AUDIO_CONNECTION_SESSION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LE_AUDIO_BROADCAST_SESSION_REPORTED:
+    return "ATOM_LE_AUDIO_BROADCAST_SESSION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DREAM_UI_EVENT_REPORTED:
+    return "ATOM_DREAM_UI_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TASK_MANAGER_EVENT_REPORTED:
+    return "ATOM_TASK_MANAGER_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CDM_ASSOCIATION_ACTION:
+    return "ATOM_CDM_ASSOCIATION_ACTION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MAGNIFICATION_TRIPLE_TAP_AND_HOLD_ACTIVATED_SESSION_REPORTED:
+    return "ATOM_MAGNIFICATION_TRIPLE_TAP_AND_HOLD_ACTIVATED_SESSION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MAGNIFICATION_FOLLOW_TYPING_FOCUS_ACTIVATED_SESSION_REPORTED:
+    return "ATOM_MAGNIFICATION_FOLLOW_TYPING_FOCUS_ACTIVATED_SESSION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ACCESSIBILITY_TEXT_READING_OPTIONS_CHANGED:
+    return "ATOM_ACCESSIBILITY_TEXT_READING_OPTIONS_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_SETUP_FAILURE_CRASH_REPORTED:
+    return "ATOM_WIFI_SETUP_FAILURE_CRASH_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_UWB_DEVICE_ERROR_REPORTED:
+    return "ATOM_UWB_DEVICE_ERROR_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ISOLATED_COMPILATION_SCHEDULED:
+    return "ATOM_ISOLATED_COMPILATION_SCHEDULED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ISOLATED_COMPILATION_ENDED:
+    return "ATOM_ISOLATED_COMPILATION_ENDED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ONS_OPPORTUNISTIC_ESIM_PROVISIONING_COMPLETE:
+    return "ATOM_ONS_OPPORTUNISTIC_ESIM_PROVISIONING_COMPLETE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SYSTEM_SERVER_PRE_WATCHDOG_OCCURRED:
+    return "ATOM_SYSTEM_SERVER_PRE_WATCHDOG_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TELEPHONY_ANOMALY_DETECTED:
+    return "ATOM_TELEPHONY_ANOMALY_DETECTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LETTERBOX_POSITION_CHANGED:
+    return "ATOM_LETTERBOX_POSITION_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_REMOTE_KEY_PROVISIONING_ATTEMPT:
+    return "ATOM_REMOTE_KEY_PROVISIONING_ATTEMPT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_REMOTE_KEY_PROVISIONING_NETWORK_INFO:
+    return "ATOM_REMOTE_KEY_PROVISIONING_NETWORK_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_REMOTE_KEY_PROVISIONING_TIMING:
+    return "ATOM_REMOTE_KEY_PROVISIONING_TIMING";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAOUTPUT_OP_INTERACTION_REPORT:
+    return "ATOM_MEDIAOUTPUT_OP_INTERACTION_REPORT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SYNC_EXEMPTION_OCCURRED:
+    return "ATOM_SYNC_EXEMPTION_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AUTOFILL_PRESENTATION_EVENT_REPORTED:
+    return "ATOM_AUTOFILL_PRESENTATION_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DOCK_STATE_CHANGED:
+    return "ATOM_DOCK_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SAFETY_SOURCE_STATE_COLLECTED:
+    return "ATOM_SAFETY_SOURCE_STATE_COLLECTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SAFETY_CENTER_SYSTEM_EVENT_REPORTED:
+    return "ATOM_SAFETY_CENTER_SYSTEM_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SAFETY_CENTER_INTERACTION_REPORTED:
+    return "ATOM_SAFETY_CENTER_INTERACTION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SETTINGS_PROVIDER_SETTING_CHANGED:
+    return "ATOM_SETTINGS_PROVIDER_SETTING_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BROADCAST_DELIVERY_EVENT_REPORTED:
+    return "ATOM_BROADCAST_DELIVERY_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SERVICE_REQUEST_EVENT_REPORTED:
+    return "ATOM_SERVICE_REQUEST_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PROVIDER_ACQUISITION_EVENT_REPORTED:
+    return "ATOM_PROVIDER_ACQUISITION_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_DEVICE_NAME_REPORTED:
+    return "ATOM_BLUETOOTH_DEVICE_NAME_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CB_CONFIG_UPDATED:
+    return "ATOM_CB_CONFIG_UPDATED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CB_MODULE_ERROR_REPORTED:
+    return "ATOM_CB_MODULE_ERROR_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CB_SERVICE_FEATURE_CHANGED:
+    return "ATOM_CB_SERVICE_FEATURE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CB_RECEIVER_FEATURE_CHANGED:
+    return "ATOM_CB_RECEIVER_FEATURE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_JSSCRIPTENGINE_LATENCY_REPORTED:
+    return "ATOM_JSSCRIPTENGINE_LATENCY_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PRIVACY_SIGNAL_NOTIFICATION_INTERACTION:
+    return "ATOM_PRIVACY_SIGNAL_NOTIFICATION_INTERACTION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PRIVACY_SIGNAL_ISSUE_CARD_INTERACTION:
+    return "ATOM_PRIVACY_SIGNAL_ISSUE_CARD_INTERACTION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PRIVACY_SIGNALS_JOB_FAILURE:
+    return "ATOM_PRIVACY_SIGNALS_JOB_FAILURE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_VIBRATION_REPORTED:
+    return "ATOM_VIBRATION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_UWB_RANGING_START:
+    return "ATOM_UWB_RANGING_START";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MOBILE_DATA_DOWNLOAD_FILE_GROUP_STATUS_REPORTED:
+    return "ATOM_MOBILE_DATA_DOWNLOAD_FILE_GROUP_STATUS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_COMPACTED_V2:
+    return "ATOM_APP_COMPACTED_V2";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AD_SERVICES_SETTINGS_USAGE_REPORTED:
+    return "ATOM_AD_SERVICES_SETTINGS_USAGE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DISPLAY_BRIGHTNESS_CHANGED:
+    return "ATOM_DISPLAY_BRIGHTNESS_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ACTIVITY_ACTION_BLOCKED:
+    return "ATOM_ACTIVITY_ACTION_BLOCKED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BACKGROUND_FETCH_PROCESS_REPORTED:
+    return "ATOM_BACKGROUND_FETCH_PROCESS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_UPDATE_CUSTOM_AUDIENCE_PROCESS_REPORTED:
+    return "ATOM_UPDATE_CUSTOM_AUDIENCE_PROCESS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_RUN_AD_BIDDING_PROCESS_REPORTED:
+    return "ATOM_RUN_AD_BIDDING_PROCESS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_RUN_AD_SCORING_PROCESS_REPORTED:
+    return "ATOM_RUN_AD_SCORING_PROCESS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_RUN_AD_SELECTION_PROCESS_REPORTED:
+    return "ATOM_RUN_AD_SELECTION_PROCESS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_RUN_AD_BIDDING_PER_CA_PROCESS_REPORTED:
+    return "ATOM_RUN_AD_BIDDING_PER_CA_PROCESS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MOBILE_DATA_DOWNLOAD_DOWNLOAD_RESULT_REPORTED:
+    return "ATOM_MOBILE_DATA_DOWNLOAD_DOWNLOAD_RESULT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MOBILE_DATA_DOWNLOAD_FILE_GROUP_STORAGE_STATS_REPORTED:
+    return "ATOM_MOBILE_DATA_DOWNLOAD_FILE_GROUP_STORAGE_STATS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NETWORK_DNS_SERVER_SUPPORT_REPORTED:
+    return "ATOM_NETWORK_DNS_SERVER_SUPPORT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_VM_BOOTED:
+    return "ATOM_VM_BOOTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_VM_EXITED:
+    return "ATOM_VM_EXITED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AMBIENT_BRIGHTNESS_STATS_REPORTED:
+    return "ATOM_AMBIENT_BRIGHTNESS_STATS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_SPATIALIZERCAPABILITIES_REPORTED:
+    return "ATOM_MEDIAMETRICS_SPATIALIZERCAPABILITIES_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_SPATIALIZERDEVICEENABLED_REPORTED:
+    return "ATOM_MEDIAMETRICS_SPATIALIZERDEVICEENABLED_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_HEADTRACKERDEVICEENABLED_REPORTED:
+    return "ATOM_MEDIAMETRICS_HEADTRACKERDEVICEENABLED_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_HEADTRACKERDEVICESUPPORTED_REPORTED:
+    return "ATOM_MEDIAMETRICS_HEADTRACKERDEVICESUPPORTED_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AD_SERVICES_MEASUREMENT_REGISTRATIONS:
+    return "ATOM_AD_SERVICES_MEASUREMENT_REGISTRATIONS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HEARING_AID_INFO_REPORTED:
+    return "ATOM_HEARING_AID_INFO_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DEVICE_WIDE_JOB_CONSTRAINT_CHANGED:
+    return "ATOM_DEVICE_WIDE_JOB_CONSTRAINT_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AMBIENT_MODE_CHANGED:
+    return "ATOM_AMBIENT_MODE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ANR_LATENCY_REPORTED:
+    return "ATOM_ANR_LATENCY_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_RESOURCE_API_INFO:
+    return "ATOM_RESOURCE_API_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SYSTEM_DEFAULT_NETWORK_CHANGED:
+    return "ATOM_SYSTEM_DEFAULT_NETWORK_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_IWLAN_SETUP_DATA_CALL_RESULT_REPORTED:
+    return "ATOM_IWLAN_SETUP_DATA_CALL_RESULT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_IWLAN_PDN_DISCONNECTED_REASON_REPORTED:
+    return "ATOM_IWLAN_PDN_DISCONNECTED_REASON_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AIRPLANE_MODE_SESSION_REPORTED:
+    return "ATOM_AIRPLANE_MODE_SESSION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_VM_CPU_STATUS_REPORTED:
+    return "ATOM_VM_CPU_STATUS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_VM_MEM_STATUS_REPORTED:
+    return "ATOM_VM_MEM_STATUS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PACKAGE_INSTALLATION_SESSION_REPORTED:
+    return "ATOM_PACKAGE_INSTALLATION_SESSION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DEFAULT_NETWORK_REMATCH_INFO:
+    return "ATOM_DEFAULT_NETWORK_REMATCH_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NETWORK_SELECTION_PERFORMANCE:
+    return "ATOM_NETWORK_SELECTION_PERFORMANCE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NETWORK_NSD_REPORTED:
+    return "ATOM_NETWORK_NSD_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_DISCONNECTION_REASON_REPORTED:
+    return "ATOM_BLUETOOTH_DISCONNECTION_REASON_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_LOCAL_VERSIONS_REPORTED:
+    return "ATOM_BLUETOOTH_LOCAL_VERSIONS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_REMOTE_SUPPORTED_FEATURES_REPORTED:
+    return "ATOM_BLUETOOTH_REMOTE_SUPPORTED_FEATURES_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_LOCAL_SUPPORTED_FEATURES_REPORTED:
+    return "ATOM_BLUETOOTH_LOCAL_SUPPORTED_FEATURES_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_GATT_APP_INFO:
+    return "ATOM_BLUETOOTH_GATT_APP_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BRIGHTNESS_CONFIGURATION_UPDATED:
+    return "ATOM_BRIGHTNESS_CONFIGURATION_UPDATED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AD_SERVICES_GET_TOPICS_REPORTED:
+    return "ATOM_AD_SERVICES_GET_TOPICS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AD_SERVICES_EPOCH_COMPUTATION_GET_TOP_TOPICS_REPORTED:
+    return "ATOM_AD_SERVICES_EPOCH_COMPUTATION_GET_TOP_TOPICS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AD_SERVICES_EPOCH_COMPUTATION_CLASSIFIER_REPORTED:
+    return "ATOM_AD_SERVICES_EPOCH_COMPUTATION_CLASSIFIER_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_LAUNCHED:
+    return "ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_LAUNCHED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_FINISHED:
+    return "ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_FINISHED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_CONNECTION_REPORTED:
+    return "ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_CONNECTION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_DEVICE_SCAN_TRIGGERED:
+    return "ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_DEVICE_SCAN_TRIGGERED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_FIRST_DEVICE_SCAN_LATENCY:
+    return "ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_FIRST_DEVICE_SCAN_LATENCY";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_CONNECT_DEVICE_LATENCY:
+    return "ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_CONNECT_DEVICE_LATENCY";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PACKAGE_MANAGER_SNAPSHOT_REPORTED:
+    return "ATOM_PACKAGE_MANAGER_SNAPSHOT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PACKAGE_MANAGER_APPS_FILTER_CACHE_BUILD_REPORTED:
+    return "ATOM_PACKAGE_MANAGER_APPS_FILTER_CACHE_BUILD_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PACKAGE_MANAGER_APPS_FILTER_CACHE_UPDATE_REPORTED:
+    return "ATOM_PACKAGE_MANAGER_APPS_FILTER_CACHE_UPDATE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LAUNCHER_IMPRESSION_EVENT:
+    return "ATOM_LAUNCHER_IMPRESSION_EVENT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_ALL_DEVICES_SCAN_LATENCY:
+    return "ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_ALL_DEVICES_SCAN_LATENCY";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WS_WATCH_FACE_EDITED:
+    return "ATOM_WS_WATCH_FACE_EDITED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WS_WATCH_FACE_FAVORITE_ACTION_REPORTED:
+    return "ATOM_WS_WATCH_FACE_FAVORITE_ACTION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WS_WATCH_FACE_SET_ACTION_REPORTED:
+    return "ATOM_WS_WATCH_FACE_SET_ACTION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PACKAGE_UNINSTALLATION_REPORTED:
+    return "ATOM_PACKAGE_UNINSTALLATION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GAME_MODE_CHANGED:
+    return "ATOM_GAME_MODE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GAME_MODE_CONFIGURATION_CHANGED:
+    return "ATOM_GAME_MODE_CONFIGURATION_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BEDTIME_MODE_STATE_CHANGED:
+    return "ATOM_BEDTIME_MODE_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NETWORK_SLICE_SESSION_ENDED:
+    return "ATOM_NETWORK_SLICE_SESSION_ENDED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NETWORK_SLICE_DAILY_DATA_USAGE_REPORTED:
+    return "ATOM_NETWORK_SLICE_DAILY_DATA_USAGE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NFC_TAG_TYPE_OCCURRED:
+    return "ATOM_NFC_TAG_TYPE_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NFC_AID_CONFLICT_OCCURRED:
+    return "ATOM_NFC_AID_CONFLICT_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NFC_READER_CONFLICT_OCCURRED:
+    return "ATOM_NFC_READER_CONFLICT_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WS_TILE_LIST_CHANGED:
+    return "ATOM_WS_TILE_LIST_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GET_TYPE_ACCESSED_WITHOUT_PERMISSION:
+    return "ATOM_GET_TYPE_ACCESSED_WITHOUT_PERMISSION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MOBILE_BUNDLED_APP_INFO_GATHERED:
+    return "ATOM_MOBILE_BUNDLED_APP_INFO_GATHERED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WS_WATCH_FACE_COMPLICATION_SET_CHANGED:
+    return "ATOM_WS_WATCH_FACE_COMPLICATION_SET_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_DRM_CREATED:
+    return "ATOM_MEDIA_DRM_CREATED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_DRM_ERRORED:
+    return "ATOM_MEDIA_DRM_ERRORED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_DRM_SESSION_OPENED:
+    return "ATOM_MEDIA_DRM_SESSION_OPENED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_DRM_SESSION_CLOSED:
+    return "ATOM_MEDIA_DRM_SESSION_CLOSED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_USER_SELECTED_RESOLUTION:
+    return "ATOM_USER_SELECTED_RESOLUTION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_UNSAFE_INTENT_EVENT_REPORTED:
+    return "ATOM_UNSAFE_INTENT_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PERFORMANCE_HINT_SESSION_REPORTED:
+    return "ATOM_PERFORMANCE_HINT_SESSION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_MIDI_DEVICE_CLOSE_REPORTED:
+    return "ATOM_MEDIAMETRICS_MIDI_DEVICE_CLOSE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BIOMETRIC_TOUCH_REPORTED:
+    return "ATOM_BIOMETRIC_TOUCH_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HOTWORD_AUDIO_EGRESS_EVENT_REPORTED:
+    return "ATOM_HOTWORD_AUDIO_EGRESS_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_SEARCH_SCHEMA_MIGRATION_STATS_REPORTED:
+    return "ATOM_APP_SEARCH_SCHEMA_MIGRATION_STATS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LOCATION_ENABLED_STATE_CHANGED:
+    return "ATOM_LOCATION_ENABLED_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_IME_REQUEST_FINISHED:
+    return "ATOM_IME_REQUEST_FINISHED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_USB_COMPLIANCE_WARNINGS_REPORTED:
+    return "ATOM_USB_COMPLIANCE_WARNINGS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_SUPPORTED_LOCALES_CHANGED:
+    return "ATOM_APP_SUPPORTED_LOCALES_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GRAMMATICAL_INFLECTION_CHANGED:
+    return "ATOM_GRAMMATICAL_INFLECTION_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_PROVIDER_VOLUME_RECOVERY_REPORTED:
+    return "ATOM_MEDIA_PROVIDER_VOLUME_RECOVERY_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BIOMETRIC_PROPERTIES_COLLECTED:
+    return "ATOM_BIOMETRIC_PROPERTIES_COLLECTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_KERNEL_WAKEUP_ATTRIBUTED:
+    return "ATOM_KERNEL_WAKEUP_ATTRIBUTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SCREEN_STATE_CHANGED_V2:
+    return "ATOM_SCREEN_STATE_CHANGED_V2";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WS_BACKUP_ACTION_REPORTED:
+    return "ATOM_WS_BACKUP_ACTION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WS_RESTORE_ACTION_REPORTED:
+    return "ATOM_WS_RESTORE_ACTION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DEVICE_LOG_ACCESS_EVENT_REPORTED:
+    return "ATOM_DEVICE_LOG_ACCESS_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_SESSION_UPDATED:
+    return "ATOM_MEDIA_SESSION_UPDATED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WEAR_OOBE_STATE_CHANGED:
+    return "ATOM_WEAR_OOBE_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WS_NOTIFICATION_UPDATED:
+    return "ATOM_WS_NOTIFICATION_UPDATED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NETWORK_VALIDATION_FAILURE_STATS_DAILY_REPORTED:
+    return "ATOM_NETWORK_VALIDATION_FAILURE_STATS_DAILY_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WS_COMPLICATION_TAPPED:
+    return "ATOM_WS_COMPLICATION_TAPPED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WS_WEAR_TIME_SESSION:
+    return "ATOM_WS_WEAR_TIME_SESSION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_BYTES_TRANSFER:
+    return "ATOM_WIFI_BYTES_TRANSFER";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_BYTES_TRANSFER_BY_FG_BG:
+    return "ATOM_WIFI_BYTES_TRANSFER_BY_FG_BG";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MOBILE_BYTES_TRANSFER:
+    return "ATOM_MOBILE_BYTES_TRANSFER";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MOBILE_BYTES_TRANSFER_BY_FG_BG:
+    return "ATOM_MOBILE_BYTES_TRANSFER_BY_FG_BG";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_BYTES_TRANSFER:
+    return "ATOM_BLUETOOTH_BYTES_TRANSFER";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_KERNEL_WAKELOCK:
+    return "ATOM_KERNEL_WAKELOCK";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SUBSYSTEM_SLEEP_STATE:
+    return "ATOM_SUBSYSTEM_SLEEP_STATE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CPU_TIME_PER_UID:
+    return "ATOM_CPU_TIME_PER_UID";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CPU_TIME_PER_UID_FREQ:
+    return "ATOM_CPU_TIME_PER_UID_FREQ";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_ACTIVITY_INFO:
+    return "ATOM_WIFI_ACTIVITY_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MODEM_ACTIVITY_INFO:
+    return "ATOM_MODEM_ACTIVITY_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_ACTIVITY_INFO:
+    return "ATOM_BLUETOOTH_ACTIVITY_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PROCESS_MEMORY_STATE:
+    return "ATOM_PROCESS_MEMORY_STATE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SYSTEM_ELAPSED_REALTIME:
+    return "ATOM_SYSTEM_ELAPSED_REALTIME";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SYSTEM_UPTIME:
+    return "ATOM_SYSTEM_UPTIME";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CPU_ACTIVE_TIME:
+    return "ATOM_CPU_ACTIVE_TIME";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CPU_CLUSTER_TIME:
+    return "ATOM_CPU_CLUSTER_TIME";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DISK_SPACE:
+    return "ATOM_DISK_SPACE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_REMAINING_BATTERY_CAPACITY:
+    return "ATOM_REMAINING_BATTERY_CAPACITY";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_FULL_BATTERY_CAPACITY:
+    return "ATOM_FULL_BATTERY_CAPACITY";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TEMPERATURE:
+    return "ATOM_TEMPERATURE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BINDER_CALLS:
+    return "ATOM_BINDER_CALLS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BINDER_CALLS_EXCEPTIONS:
+    return "ATOM_BINDER_CALLS_EXCEPTIONS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LOOPER_STATS:
+    return "ATOM_LOOPER_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DISK_STATS:
+    return "ATOM_DISK_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DIRECTORY_USAGE:
+    return "ATOM_DIRECTORY_USAGE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_SIZE:
+    return "ATOM_APP_SIZE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CATEGORY_SIZE:
+    return "ATOM_CATEGORY_SIZE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PROC_STATS:
+    return "ATOM_PROC_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BATTERY_VOLTAGE:
+    return "ATOM_BATTERY_VOLTAGE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NUM_FINGERPRINTS_ENROLLED:
+    return "ATOM_NUM_FINGERPRINTS_ENROLLED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DISK_IO:
+    return "ATOM_DISK_IO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_POWER_PROFILE:
+    return "ATOM_POWER_PROFILE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PROC_STATS_PKG_PROC:
+    return "ATOM_PROC_STATS_PKG_PROC";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PROCESS_CPU_TIME:
+    return "ATOM_PROCESS_CPU_TIME";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CPU_TIME_PER_THREAD_FREQ:
+    return "ATOM_CPU_TIME_PER_THREAD_FREQ";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ON_DEVICE_POWER_MEASUREMENT:
+    return "ATOM_ON_DEVICE_POWER_MEASUREMENT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DEVICE_CALCULATED_POWER_USE:
+    return "ATOM_DEVICE_CALCULATED_POWER_USE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PROCESS_MEMORY_HIGH_WATER_MARK:
+    return "ATOM_PROCESS_MEMORY_HIGH_WATER_MARK";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BATTERY_LEVEL:
+    return "ATOM_BATTERY_LEVEL";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BUILD_INFORMATION:
+    return "ATOM_BUILD_INFORMATION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BATTERY_CYCLE_COUNT:
+    return "ATOM_BATTERY_CYCLE_COUNT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DEBUG_ELAPSED_CLOCK:
+    return "ATOM_DEBUG_ELAPSED_CLOCK";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DEBUG_FAILING_ELAPSED_CLOCK:
+    return "ATOM_DEBUG_FAILING_ELAPSED_CLOCK";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NUM_FACES_ENROLLED:
+    return "ATOM_NUM_FACES_ENROLLED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ROLE_HOLDER:
+    return "ATOM_ROLE_HOLDER";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DANGEROUS_PERMISSION_STATE:
+    return "ATOM_DANGEROUS_PERMISSION_STATE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TRAIN_INFO:
+    return "ATOM_TRAIN_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TIME_ZONE_DATA_INFO:
+    return "ATOM_TIME_ZONE_DATA_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_EXTERNAL_STORAGE_INFO:
+    return "ATOM_EXTERNAL_STORAGE_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GPU_STATS_GLOBAL_INFO:
+    return "ATOM_GPU_STATS_GLOBAL_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GPU_STATS_APP_INFO:
+    return "ATOM_GPU_STATS_APP_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SYSTEM_ION_HEAP_SIZE:
+    return "ATOM_SYSTEM_ION_HEAP_SIZE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APPS_ON_EXTERNAL_STORAGE_INFO:
+    return "ATOM_APPS_ON_EXTERNAL_STORAGE_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_FACE_SETTINGS:
+    return "ATOM_FACE_SETTINGS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_COOLING_DEVICE:
+    return "ATOM_COOLING_DEVICE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_OPS:
+    return "ATOM_APP_OPS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PROCESS_SYSTEM_ION_HEAP_SIZE:
+    return "ATOM_PROCESS_SYSTEM_ION_HEAP_SIZE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SURFACEFLINGER_STATS_GLOBAL_INFO:
+    return "ATOM_SURFACEFLINGER_STATS_GLOBAL_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SURFACEFLINGER_STATS_LAYER_INFO:
+    return "ATOM_SURFACEFLINGER_STATS_LAYER_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PROCESS_MEMORY_SNAPSHOT:
+    return "ATOM_PROCESS_MEMORY_SNAPSHOT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_VMS_CLIENT_STATS:
+    return "ATOM_VMS_CLIENT_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NOTIFICATION_REMOTE_VIEWS:
+    return "ATOM_NOTIFICATION_REMOTE_VIEWS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DANGEROUS_PERMISSION_STATE_SAMPLED:
+    return "ATOM_DANGEROUS_PERMISSION_STATE_SAMPLED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GRAPHICS_STATS:
+    return "ATOM_GRAPHICS_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_RUNTIME_APP_OP_ACCESS:
+    return "ATOM_RUNTIME_APP_OP_ACCESS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ION_HEAP_SIZE:
+    return "ATOM_ION_HEAP_SIZE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PACKAGE_NOTIFICATION_PREFERENCES:
+    return "ATOM_PACKAGE_NOTIFICATION_PREFERENCES";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES:
+    return "ATOM_PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PACKAGE_NOTIFICATION_CHANNEL_GROUP_PREFERENCES:
+    return "ATOM_PACKAGE_NOTIFICATION_CHANNEL_GROUP_PREFERENCES";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GNSS_STATS:
+    return "ATOM_GNSS_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ATTRIBUTED_APP_OPS:
+    return "ATOM_ATTRIBUTED_APP_OPS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_VOICE_CALL_SESSION:
+    return "ATOM_VOICE_CALL_SESSION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_VOICE_CALL_RAT_USAGE:
+    return "ATOM_VOICE_CALL_RAT_USAGE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SIM_SLOT_STATE:
+    return "ATOM_SIM_SLOT_STATE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SUPPORTED_RADIO_ACCESS_FAMILY:
+    return "ATOM_SUPPORTED_RADIO_ACCESS_FAMILY";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SETTING_SNAPSHOT:
+    return "ATOM_SETTING_SNAPSHOT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLOB_INFO:
+    return "ATOM_BLOB_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DATA_USAGE_BYTES_TRANSFER:
+    return "ATOM_DATA_USAGE_BYTES_TRANSFER";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BYTES_TRANSFER_BY_TAG_AND_METERED:
+    return "ATOM_BYTES_TRANSFER_BY_TAG_AND_METERED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DND_MODE_RULE:
+    return "ATOM_DND_MODE_RULE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GENERAL_EXTERNAL_STORAGE_ACCESS_STATS:
+    return "ATOM_GENERAL_EXTERNAL_STORAGE_ACCESS_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_INCOMING_SMS:
+    return "ATOM_INCOMING_SMS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_OUTGOING_SMS:
+    return "ATOM_OUTGOING_SMS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CARRIER_ID_TABLE_VERSION:
+    return "ATOM_CARRIER_ID_TABLE_VERSION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DATA_CALL_SESSION:
+    return "ATOM_DATA_CALL_SESSION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CELLULAR_SERVICE_STATE:
+    return "ATOM_CELLULAR_SERVICE_STATE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CELLULAR_DATA_SERVICE_SWITCH:
+    return "ATOM_CELLULAR_DATA_SERVICE_SWITCH";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SYSTEM_MEMORY:
+    return "ATOM_SYSTEM_MEMORY";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_IMS_REGISTRATION_TERMINATION:
+    return "ATOM_IMS_REGISTRATION_TERMINATION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_IMS_REGISTRATION_STATS:
+    return "ATOM_IMS_REGISTRATION_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CPU_TIME_PER_CLUSTER_FREQ:
+    return "ATOM_CPU_TIME_PER_CLUSTER_FREQ";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CPU_CYCLES_PER_UID_CLUSTER:
+    return "ATOM_CPU_CYCLES_PER_UID_CLUSTER";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DEVICE_ROTATED_DATA:
+    return "ATOM_DEVICE_ROTATED_DATA";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CPU_CYCLES_PER_THREAD_GROUP_CLUSTER:
+    return "ATOM_CPU_CYCLES_PER_THREAD_GROUP_CLUSTER";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_DRM_ACTIVITY_INFO:
+    return "ATOM_MEDIA_DRM_ACTIVITY_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_OEM_MANAGED_BYTES_TRANSFER:
+    return "ATOM_OEM_MANAGED_BYTES_TRANSFER";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GNSS_POWER_STATS:
+    return "ATOM_GNSS_POWER_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TIME_ZONE_DETECTOR_STATE:
+    return "ATOM_TIME_ZONE_DETECTOR_STATE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_KEYSTORE2_STORAGE_STATS:
+    return "ATOM_KEYSTORE2_STORAGE_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_RKP_POOL_STATS:
+    return "ATOM_RKP_POOL_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PROCESS_DMABUF_MEMORY:
+    return "ATOM_PROCESS_DMABUF_MEMORY";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PENDING_ALARM_INFO:
+    return "ATOM_PENDING_ALARM_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_USER_LEVEL_HIBERNATED_APPS:
+    return "ATOM_USER_LEVEL_HIBERNATED_APPS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LAUNCHER_LAYOUT_SNAPSHOT:
+    return "ATOM_LAUNCHER_LAYOUT_SNAPSHOT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GLOBAL_HIBERNATED_APPS:
+    return "ATOM_GLOBAL_HIBERNATED_APPS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_INPUT_EVENT_LATENCY_SKETCH:
+    return "ATOM_INPUT_EVENT_LATENCY_SKETCH";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BATTERY_USAGE_STATS_BEFORE_RESET:
+    return "ATOM_BATTERY_USAGE_STATS_BEFORE_RESET";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BATTERY_USAGE_STATS_SINCE_RESET:
+    return "ATOM_BATTERY_USAGE_STATS_SINCE_RESET";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BATTERY_USAGE_STATS_SINCE_RESET_USING_POWER_PROFILE_MODEL:
+    return "ATOM_BATTERY_USAGE_STATS_SINCE_RESET_USING_POWER_PROFILE_MODEL";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_INSTALLED_INCREMENTAL_PACKAGE:
+    return "ATOM_INSTALLED_INCREMENTAL_PACKAGE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TELEPHONY_NETWORK_REQUESTS:
+    return "ATOM_TELEPHONY_NETWORK_REQUESTS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_SEARCH_STORAGE_INFO:
+    return "ATOM_APP_SEARCH_STORAGE_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_VMSTAT:
+    return "ATOM_VMSTAT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_KEYSTORE2_KEY_CREATION_WITH_GENERAL_INFO:
+    return "ATOM_KEYSTORE2_KEY_CREATION_WITH_GENERAL_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_KEYSTORE2_KEY_CREATION_WITH_AUTH_INFO:
+    return "ATOM_KEYSTORE2_KEY_CREATION_WITH_AUTH_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_KEYSTORE2_KEY_CREATION_WITH_PURPOSE_AND_MODES_INFO:
+    return "ATOM_KEYSTORE2_KEY_CREATION_WITH_PURPOSE_AND_MODES_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_KEYSTORE2_ATOM_WITH_OVERFLOW:
+    return "ATOM_KEYSTORE2_ATOM_WITH_OVERFLOW";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_KEYSTORE2_KEY_OPERATION_WITH_PURPOSE_AND_MODES_INFO:
+    return "ATOM_KEYSTORE2_KEY_OPERATION_WITH_PURPOSE_AND_MODES_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_KEYSTORE2_KEY_OPERATION_WITH_GENERAL_INFO:
+    return "ATOM_KEYSTORE2_KEY_OPERATION_WITH_GENERAL_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_RKP_ERROR_STATS:
+    return "ATOM_RKP_ERROR_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_KEYSTORE2_CRASH_STATS:
+    return "ATOM_KEYSTORE2_CRASH_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_VENDOR_APEX_INFO:
+    return "ATOM_VENDOR_APEX_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ACCESSIBILITY_SHORTCUT_STATS:
+    return "ATOM_ACCESSIBILITY_SHORTCUT_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ACCESSIBILITY_FLOATING_MENU_STATS:
+    return "ATOM_ACCESSIBILITY_FLOATING_MENU_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DATA_USAGE_BYTES_TRANSFER_V2:
+    return "ATOM_DATA_USAGE_BYTES_TRANSFER_V2";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_CAPABILITIES:
+    return "ATOM_MEDIA_CAPABILITIES";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CAR_WATCHDOG_SYSTEM_IO_USAGE_SUMMARY:
+    return "ATOM_CAR_WATCHDOG_SYSTEM_IO_USAGE_SUMMARY";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CAR_WATCHDOG_UID_IO_USAGE_SUMMARY:
+    return "ATOM_CAR_WATCHDOG_UID_IO_USAGE_SUMMARY";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_IMS_REGISTRATION_FEATURE_TAG_STATS:
+    return "ATOM_IMS_REGISTRATION_FEATURE_TAG_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_RCS_CLIENT_PROVISIONING_STATS:
+    return "ATOM_RCS_CLIENT_PROVISIONING_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_RCS_ACS_PROVISIONING_STATS:
+    return "ATOM_RCS_ACS_PROVISIONING_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SIP_DELEGATE_STATS:
+    return "ATOM_SIP_DELEGATE_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SIP_TRANSPORT_FEATURE_TAG_STATS:
+    return "ATOM_SIP_TRANSPORT_FEATURE_TAG_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SIP_MESSAGE_RESPONSE:
+    return "ATOM_SIP_MESSAGE_RESPONSE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SIP_TRANSPORT_SESSION:
+    return "ATOM_SIP_TRANSPORT_SESSION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_IMS_DEDICATED_BEARER_LISTENER_EVENT:
+    return "ATOM_IMS_DEDICATED_BEARER_LISTENER_EVENT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_IMS_DEDICATED_BEARER_EVENT:
+    return "ATOM_IMS_DEDICATED_BEARER_EVENT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_IMS_REGISTRATION_SERVICE_DESC_STATS:
+    return "ATOM_IMS_REGISTRATION_SERVICE_DESC_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_UCE_EVENT_STATS:
+    return "ATOM_UCE_EVENT_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PRESENCE_NOTIFY_EVENT:
+    return "ATOM_PRESENCE_NOTIFY_EVENT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GBA_EVENT:
+    return "ATOM_GBA_EVENT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PER_SIM_STATUS:
+    return "ATOM_PER_SIM_STATUS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GPU_WORK_PER_UID:
+    return "ATOM_GPU_WORK_PER_UID";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PERSISTENT_URI_PERMISSIONS_AMOUNT_PER_PACKAGE:
+    return "ATOM_PERSISTENT_URI_PERMISSIONS_AMOUNT_PER_PACKAGE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SIGNED_PARTITION_INFO:
+    return "ATOM_SIGNED_PARTITION_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PINNED_FILE_SIZES_PER_PACKAGE:
+    return "ATOM_PINNED_FILE_SIZES_PER_PACKAGE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PENDING_INTENTS_PER_PACKAGE:
+    return "ATOM_PENDING_INTENTS_PER_PACKAGE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_USER_INFO:
+    return "ATOM_USER_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TELEPHONY_NETWORK_REQUESTS_V2:
+    return "ATOM_TELEPHONY_NETWORK_REQUESTS_V2";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DEVICE_TELEPHONY_PROPERTIES:
+    return "ATOM_DEVICE_TELEPHONY_PROPERTIES";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_REMOTE_KEY_PROVISIONING_ERROR_COUNTS:
+    return "ATOM_REMOTE_KEY_PROVISIONING_ERROR_COUNTS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SAFETY_STATE:
+    return "ATOM_SAFETY_STATE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_INCOMING_MMS:
+    return "ATOM_INCOMING_MMS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_OUTGOING_MMS:
+    return "ATOM_OUTGOING_MMS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MULTI_USER_INFO:
+    return "ATOM_MULTI_USER_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NETWORK_BPF_MAP_INFO:
+    return "ATOM_NETWORK_BPF_MAP_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_OUTGOING_SHORT_CODE_SMS:
+    return "ATOM_OUTGOING_SHORT_CODE_SMS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CONNECTIVITY_STATE_SAMPLE:
+    return "ATOM_CONNECTIVITY_STATE_SAMPLE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NETWORK_SELECTION_REMATCH_REASONS_INFO:
+    return "ATOM_NETWORK_SELECTION_REMATCH_REASONS_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GAME_MODE_INFO:
+    return "ATOM_GAME_MODE_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GAME_MODE_CONFIGURATION:
+    return "ATOM_GAME_MODE_CONFIGURATION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GAME_MODE_LISTENER:
+    return "ATOM_GAME_MODE_LISTENER";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NETWORK_SLICE_REQUEST_COUNT:
+    return "ATOM_NETWORK_SLICE_REQUEST_COUNT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WS_TILE_SNAPSHOT:
+    return "ATOM_WS_TILE_SNAPSHOT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WS_ACTIVE_WATCH_FACE_COMPLICATION_SET_SNAPSHOT:
+    return "ATOM_WS_ACTIVE_WATCH_FACE_COMPLICATION_SET_SNAPSHOT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PROCESS_STATE:
+    return "ATOM_PROCESS_STATE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PROCESS_ASSOCIATION:
+    return "ATOM_PROCESS_ASSOCIATION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ADPF_SYSTEM_COMPONENT_INFO:
+    return "ATOM_ADPF_SYSTEM_COMPONENT_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NOTIFICATION_MEMORY_USE:
+    return "ATOM_NOTIFICATION_MEMORY_USE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HDR_CAPABILITIES:
+    return "ATOM_HDR_CAPABILITIES";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WS_FAVOURITE_WATCH_FACE_LIST_SNAPSHOT:
+    return "ATOM_WS_FAVOURITE_WATCH_FACE_LIST_SNAPSHOT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_AWARE_NDP_REPORTED:
+    return "ATOM_WIFI_AWARE_NDP_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_AWARE_ATTACH_REPORTED:
+    return "ATOM_WIFI_AWARE_ATTACH_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_SELF_RECOVERY_TRIGGERED:
+    return "ATOM_WIFI_SELF_RECOVERY_TRIGGERED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SOFT_AP_STARTED:
+    return "ATOM_SOFT_AP_STARTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SOFT_AP_STOPPED:
+    return "ATOM_SOFT_AP_STOPPED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_LOCK_RELEASED:
+    return "ATOM_WIFI_LOCK_RELEASED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_LOCK_DEACTIVATED:
+    return "ATOM_WIFI_LOCK_DEACTIVATED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_CONFIG_SAVED:
+    return "ATOM_WIFI_CONFIG_SAVED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_AWARE_RESOURCE_USING_CHANGED:
+    return "ATOM_WIFI_AWARE_RESOURCE_USING_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_AWARE_HAL_API_CALLED:
+    return "ATOM_WIFI_AWARE_HAL_API_CALLED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_LOCAL_ONLY_REQUEST_RECEIVED:
+    return "ATOM_WIFI_LOCAL_ONLY_REQUEST_RECEIVED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_LOCAL_ONLY_REQUEST_SCAN_TRIGGERED:
+    return "ATOM_WIFI_LOCAL_ONLY_REQUEST_SCAN_TRIGGERED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_THREAD_TASK_EXECUTED:
+    return "ATOM_WIFI_THREAD_TASK_EXECUTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_STATE_CHANGED:
+    return "ATOM_WIFI_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_AWARE_CAPABILITIES:
+    return "ATOM_WIFI_AWARE_CAPABILITIES";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_MODULE_INFO:
+    return "ATOM_WIFI_MODULE_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SETTINGS_SPA_REPORTED:
+    return "ATOM_SETTINGS_SPA_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_EXPRESS_EVENT_REPORTED:
+    return "ATOM_EXPRESS_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_EXPRESS_HISTOGRAM_SAMPLE_REPORTED:
+    return "ATOM_EXPRESS_HISTOGRAM_SAMPLE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_EXPRESS_UID_EVENT_REPORTED:
+    return "ATOM_EXPRESS_UID_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_EXPRESS_UID_HISTOGRAM_SAMPLE_REPORTED:
+    return "ATOM_EXPRESS_UID_HISTOGRAM_SAMPLE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PERMISSION_RATIONALE_DIALOG_VIEWED:
+    return "ATOM_PERMISSION_RATIONALE_DIALOG_VIEWED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PERMISSION_RATIONALE_DIALOG_ACTION_REPORTED:
+    return "ATOM_PERMISSION_RATIONALE_DIALOG_ACTION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_DATA_SHARING_UPDATES_NOTIFICATION_INTERACTION:
+    return "ATOM_APP_DATA_SHARING_UPDATES_NOTIFICATION_INTERACTION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_DATA_SHARING_UPDATES_FRAGMENT_VIEWED:
+    return "ATOM_APP_DATA_SHARING_UPDATES_FRAGMENT_VIEWED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_DATA_SHARING_UPDATES_FRAGMENT_ACTION_REPORTED:
+    return "ATOM_APP_DATA_SHARING_UPDATES_FRAGMENT_ACTION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WS_INCOMING_CALL_ACTION_REPORTED:
+    return "ATOM_WS_INCOMING_CALL_ACTION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WS_CALL_DISCONNECTION_REPORTED:
+    return "ATOM_WS_CALL_DISCONNECTION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WS_CALL_DURATION_REPORTED:
+    return "ATOM_WS_CALL_DURATION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WS_CALL_USER_EXPERIENCE_LATENCY_REPORTED:
+    return "ATOM_WS_CALL_USER_EXPERIENCE_LATENCY_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WS_CALL_INTERACTION_REPORTED:
+    return "ATOM_WS_CALL_INTERACTION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_FULL_SCREEN_INTENT_LAUNCHED:
+    return "ATOM_FULL_SCREEN_INTENT_LAUNCHED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BAL_ALLOWED:
+    return "ATOM_BAL_ALLOWED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_IN_TASK_ACTIVITY_STARTED:
+    return "ATOM_IN_TASK_ACTIVITY_STARTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CACHED_APPS_HIGH_WATERMARK:
+    return "ATOM_CACHED_APPS_HIGH_WATERMARK";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ODREFRESH_REPORTED:
+    return "ATOM_ODREFRESH_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ODSIGN_REPORTED:
+    return "ATOM_ODSIGN_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ART_DATUM_REPORTED:
+    return "ATOM_ART_DATUM_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ART_DEVICE_DATUM_REPORTED:
+    return "ATOM_ART_DEVICE_DATUM_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ART_DATUM_DELTA_REPORTED:
+    return "ATOM_ART_DATUM_DELTA_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BACKGROUND_DEXOPT_JOB_ENDED:
+    return "ATOM_BACKGROUND_DEXOPT_JOB_ENDED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WEAR_ADAPTIVE_SUSPEND_STATS_REPORTED:
+    return "ATOM_WEAR_ADAPTIVE_SUSPEND_STATS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WEAR_POWER_ANOMALY_SERVICE_OPERATIONAL_STATS_REPORTED:
+    return "ATOM_WEAR_POWER_ANOMALY_SERVICE_OPERATIONAL_STATS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WEAR_POWER_ANOMALY_SERVICE_EVENT_STATS_REPORTED:
+    return "ATOM_WEAR_POWER_ANOMALY_SERVICE_EVENT_STATS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_EMERGENCY_STATE_CHANGED:
+    return "ATOM_EMERGENCY_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DND_STATE_CHANGED:
+    return "ATOM_DND_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MTE_STATE:
+    return "ATOM_MTE_STATE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AD_SERVICES_BACK_COMPAT_GET_TOPICS_REPORTED:
+    return "ATOM_AD_SERVICES_BACK_COMPAT_GET_TOPICS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AD_SERVICES_BACK_COMPAT_EPOCH_COMPUTATION_CLASSIFIER_REPORTED:
+    return "ATOM_AD_SERVICES_BACK_COMPAT_EPOCH_COMPUTATION_CLASSIFIER_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AD_SERVICES_MEASUREMENT_DEBUG_KEYS:
+    return "ATOM_AD_SERVICES_MEASUREMENT_DEBUG_KEYS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AD_SERVICES_ERROR_REPORTED:
+    return "ATOM_AD_SERVICES_ERROR_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AD_SERVICES_BACKGROUND_JOBS_EXECUTION_REPORTED:
+    return "ATOM_AD_SERVICES_BACKGROUND_JOBS_EXECUTION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AD_SERVICES_MEASUREMENT_DELAYED_SOURCE_REGISTRATION:
+    return "ATOM_AD_SERVICES_MEASUREMENT_DELAYED_SOURCE_REGISTRATION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AD_SERVICES_MEASUREMENT_ATTRIBUTION:
+    return "ATOM_AD_SERVICES_MEASUREMENT_ATTRIBUTION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AD_SERVICES_MEASUREMENT_JOBS:
+    return "ATOM_AD_SERVICES_MEASUREMENT_JOBS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AD_SERVICES_MEASUREMENT_WIPEOUT:
+    return "ATOM_AD_SERVICES_MEASUREMENT_WIPEOUT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AD_SERVICES_CONSENT_MIGRATED:
+    return "ATOM_AD_SERVICES_CONSENT_MIGRATED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_RKPD_POOL_STATS:
+    return "ATOM_RKPD_POOL_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_RKPD_CLIENT_OPERATION:
+    return "ATOM_RKPD_CLIENT_OPERATION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AUTOFILL_UI_EVENT_REPORTED:
+    return "ATOM_AUTOFILL_UI_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AUTOFILL_FILL_REQUEST_REPORTED:
+    return "ATOM_AUTOFILL_FILL_REQUEST_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AUTOFILL_FILL_RESPONSE_REPORTED:
+    return "ATOM_AUTOFILL_FILL_RESPONSE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AUTOFILL_SAVE_EVENT_REPORTED:
+    return "ATOM_AUTOFILL_SAVE_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AUTOFILL_SESSION_COMMITTED:
+    return "ATOM_AUTOFILL_SESSION_COMMITTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AUTOFILL_FIELD_CLASSIFICATION_EVENT_REPORTED:
+    return "ATOM_AUTOFILL_FIELD_CLASSIFICATION_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TEST_EXTENSION_ATOM_REPORTED:
+    return "ATOM_TEST_EXTENSION_ATOM_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TEST_RESTRICTED_ATOM_REPORTED:
+    return "ATOM_TEST_RESTRICTED_ATOM_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_STATS_SOCKET_LOSS_REPORTED:
+    return "ATOM_STATS_SOCKET_LOSS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PLUGIN_INITIALIZED:
+    return "ATOM_PLUGIN_INITIALIZED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TV_LOW_POWER_STANDBY_POLICY:
+    return "ATOM_TV_LOW_POWER_STANDBY_POLICY";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LOCKSCREEN_SHORTCUT_SELECTED:
+    return "ATOM_LOCKSCREEN_SHORTCUT_SELECTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LOCKSCREEN_SHORTCUT_TRIGGERED:
+    return "ATOM_LOCKSCREEN_SHORTCUT_TRIGGERED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_EMERGENCY_NUMBERS_INFO:
+    return "ATOM_EMERGENCY_NUMBERS_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_QUALIFIED_RAT_LIST_CHANGED:
+    return "ATOM_QUALIFIED_RAT_LIST_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_QNS_IMS_CALL_DROP_STATS:
+    return "ATOM_QNS_IMS_CALL_DROP_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_QNS_FALLBACK_RESTRICTION_CHANGED:
+    return "ATOM_QNS_FALLBACK_RESTRICTION_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_QNS_RAT_PREFERENCE_MISMATCH_INFO:
+    return "ATOM_QNS_RAT_PREFERENCE_MISMATCH_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_QNS_HANDOVER_TIME_MILLIS:
+    return "ATOM_QNS_HANDOVER_TIME_MILLIS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_QNS_HANDOVER_PINGPONG:
+    return "ATOM_QNS_HANDOVER_PINGPONG";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SATELLITE_CONTROLLER:
+    return "ATOM_SATELLITE_CONTROLLER";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SATELLITE_SESSION:
+    return "ATOM_SATELLITE_SESSION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SATELLITE_INCOMING_DATAGRAM:
+    return "ATOM_SATELLITE_INCOMING_DATAGRAM";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SATELLITE_OUTGOING_DATAGRAM:
+    return "ATOM_SATELLITE_OUTGOING_DATAGRAM";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SATELLITE_PROVISION:
+    return "ATOM_SATELLITE_PROVISION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SATELLITE_SOS_MESSAGE_RECOMMENDER:
+    return "ATOM_SATELLITE_SOS_MESSAGE_RECOMMENDER";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_IKE_SESSION_TERMINATED:
+    return "ATOM_IKE_SESSION_TERMINATED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_IKE_LIVENESS_CHECK_SESSION_VALIDATED:
+    return "ATOM_IKE_LIVENESS_CHECK_SESSION_VALIDATED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_HASHED_DEVICE_NAME_REPORTED:
+    return "ATOM_BLUETOOTH_HASHED_DEVICE_NAME_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_L2CAP_COC_CLIENT_CONNECTION:
+    return "ATOM_BLUETOOTH_L2CAP_COC_CLIENT_CONNECTION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_L2CAP_COC_SERVER_CONNECTION:
+    return "ATOM_BLUETOOTH_L2CAP_COC_SERVER_CONNECTION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_LE_SESSION_CONNECTED:
+    return "ATOM_BLUETOOTH_LE_SESSION_CONNECTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_RESTRICTED_BLUETOOTH_DEVICE_NAME_REPORTED:
+    return "ATOM_RESTRICTED_BLUETOOTH_DEVICE_NAME_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_PROFILE_CONNECTION_ATTEMPTED:
+    return "ATOM_BLUETOOTH_PROFILE_CONNECTION_ATTEMPTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HEALTH_CONNECT_UI_IMPRESSION:
+    return "ATOM_HEALTH_CONNECT_UI_IMPRESSION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HEALTH_CONNECT_UI_INTERACTION:
+    return "ATOM_HEALTH_CONNECT_UI_INTERACTION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HEALTH_CONNECT_APP_OPENED_REPORTED:
+    return "ATOM_HEALTH_CONNECT_APP_OPENED_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HEALTH_CONNECT_API_CALLED:
+    return "ATOM_HEALTH_CONNECT_API_CALLED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HEALTH_CONNECT_USAGE_STATS:
+    return "ATOM_HEALTH_CONNECT_USAGE_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HEALTH_CONNECT_STORAGE_STATS:
+    return "ATOM_HEALTH_CONNECT_STORAGE_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HEALTH_CONNECT_API_INVOKED:
+    return "ATOM_HEALTH_CONNECT_API_INVOKED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_EXERCISE_ROUTE_API_CALLED:
+    return "ATOM_EXERCISE_ROUTE_API_CALLED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ATOM_9999:
+    return "ATOM_ATOM_9999";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ATOM_99999:
+    return "ATOM_ATOM_99999";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_THREADNETWORK_TELEMETRY_DATA_REPORTED:
+    return "ATOM_THREADNETWORK_TELEMETRY_DATA_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_THREADNETWORK_TOPO_ENTRY_REPEATED:
+    return "ATOM_THREADNETWORK_TOPO_ENTRY_REPEATED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_THREADNETWORK_DEVICE_INFO_REPORTED:
+    return "ATOM_THREADNETWORK_DEVICE_INFO_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_EMERGENCY_NUMBER_DIALED:
+    return "ATOM_EMERGENCY_NUMBER_DIALED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SANDBOX_API_CALLED:
+    return "ATOM_SANDBOX_API_CALLED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SANDBOX_ACTIVITY_EVENT_OCCURRED:
+    return "ATOM_SANDBOX_ACTIVITY_EVENT_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SANDBOX_SDK_STORAGE:
+    return "ATOM_SANDBOX_SDK_STORAGE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CRONET_ENGINE_CREATED:
+    return "ATOM_CRONET_ENGINE_CREATED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CRONET_TRAFFIC_REPORTED:
+    return "ATOM_CRONET_TRAFFIC_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CRONET_ENGINE_BUILDER_INITIALIZED:
+    return "ATOM_CRONET_ENGINE_BUILDER_INITIALIZED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CRONET_HTTP_FLAGS_INITIALIZED:
+    return "ATOM_CRONET_HTTP_FLAGS_INITIALIZED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CRONET_INITIALIZED:
+    return "ATOM_CRONET_INITIALIZED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DAILY_KEEPALIVE_INFO_REPORTED:
+    return "ATOM_DAILY_KEEPALIVE_INFO_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_IP_CLIENT_RA_INFO_REPORTED:
+    return "ATOM_IP_CLIENT_RA_INFO_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APF_SESSION_INFO_REPORTED:
+    return "ATOM_APF_SESSION_INFO_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CREDENTIAL_MANAGER_API_CALLED:
+    return "ATOM_CREDENTIAL_MANAGER_API_CALLED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CREDENTIAL_MANAGER_INIT_PHASE_REPORTED:
+    return "ATOM_CREDENTIAL_MANAGER_INIT_PHASE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CREDENTIAL_MANAGER_CANDIDATE_PHASE_REPORTED:
+    return "ATOM_CREDENTIAL_MANAGER_CANDIDATE_PHASE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CREDENTIAL_MANAGER_FINAL_PHASE_REPORTED:
+    return "ATOM_CREDENTIAL_MANAGER_FINAL_PHASE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CREDENTIAL_MANAGER_TOTAL_REPORTED:
+    return "ATOM_CREDENTIAL_MANAGER_TOTAL_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CREDENTIAL_MANAGER_FINALNOUID_REPORTED:
+    return "ATOM_CREDENTIAL_MANAGER_FINALNOUID_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CREDENTIAL_MANAGER_GET_REPORTED:
+    return "ATOM_CREDENTIAL_MANAGER_GET_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CREDENTIAL_MANAGER_AUTH_CLICK_REPORTED:
+    return "ATOM_CREDENTIAL_MANAGER_AUTH_CLICK_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CREDENTIAL_MANAGER_APIV2_CALLED:
+    return "ATOM_CREDENTIAL_MANAGER_APIV2_CALLED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_UWB_ACTIVITY_INFO:
+    return "ATOM_UWB_ACTIVITY_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_ACTION_REPORTED:
+    return "ATOM_MEDIA_ACTION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_CONTROLS_LAUNCHED:
+    return "ATOM_MEDIA_CONTROLS_LAUNCHED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED:
+    return "ATOM_MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_CODEC_STARTED:
+    return "ATOM_MEDIA_CODEC_STARTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_CODEC_STOPPED:
+    return "ATOM_MEDIA_CODEC_STOPPED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_CODEC_RENDERED:
+    return "ATOM_MEDIA_CODEC_RENDERED";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/statsd/statsd_tracing_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STATSD_STATSD_TRACING_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STATSD_STATSD_TRACING_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class StatsdPullAtomConfig;
+enum AtomId : int32_t;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class StatsdPullAtomConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  StatsdPullAtomConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit StatsdPullAtomConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit StatsdPullAtomConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pull_atom_id() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> pull_atom_id() const { return GetRepeated<int32_t>(1); }
+  bool has_raw_pull_atom_id() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> raw_pull_atom_id() const { return GetRepeated<int32_t>(2); }
+  bool has_pull_frequency_ms() const { return at<3>().valid(); }
+  int32_t pull_frequency_ms() const { return at<3>().as_int32(); }
+  bool has_packages() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> packages() const { return GetRepeated<::protozero::ConstChars>(4); }
+};
+
+class StatsdPullAtomConfig : public ::protozero::Message {
+ public:
+  using Decoder = StatsdPullAtomConfig_Decoder;
+  enum : int32_t {
+    kPullAtomIdFieldNumber = 1,
+    kRawPullAtomIdFieldNumber = 2,
+    kPullFrequencyMsFieldNumber = 3,
+    kPackagesFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.StatsdPullAtomConfig"; }
+
+
+  using FieldMetadata_PullAtomId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      AtomId,
+      StatsdPullAtomConfig>;
+
+  static constexpr FieldMetadata_PullAtomId kPullAtomId{};
+  void add_pull_atom_id(AtomId value) {
+    static constexpr uint32_t field_id = FieldMetadata_PullAtomId::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_RawPullAtomId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      StatsdPullAtomConfig>;
+
+  static constexpr FieldMetadata_RawPullAtomId kRawPullAtomId{};
+  void add_raw_pull_atom_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RawPullAtomId::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_PullFrequencyMs =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      StatsdPullAtomConfig>;
+
+  static constexpr FieldMetadata_PullFrequencyMs kPullFrequencyMs{};
+  void set_pull_frequency_ms(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PullFrequencyMs::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_Packages =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      StatsdPullAtomConfig>;
+
+  static constexpr FieldMetadata_Packages kPackages{};
+  void add_packages(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Packages::kFieldId, data, size);
+  }
+  void add_packages(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Packages::kFieldId, chars.data, chars.size);
+  }
+  void add_packages(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Packages::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 StatsdTracingConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  StatsdTracingConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit StatsdTracingConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit StatsdTracingConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_push_atom_id() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> push_atom_id() const { return GetRepeated<int32_t>(1); }
+  bool has_raw_push_atom_id() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> raw_push_atom_id() const { return GetRepeated<int32_t>(2); }
+  bool has_pull_config() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> pull_config() const { return GetRepeated<::protozero::ConstBytes>(3); }
+};
+
+class StatsdTracingConfig : public ::protozero::Message {
+ public:
+  using Decoder = StatsdTracingConfig_Decoder;
+  enum : int32_t {
+    kPushAtomIdFieldNumber = 1,
+    kRawPushAtomIdFieldNumber = 2,
+    kPullConfigFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.StatsdTracingConfig"; }
+
+
+  using FieldMetadata_PushAtomId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      AtomId,
+      StatsdTracingConfig>;
+
+  static constexpr FieldMetadata_PushAtomId kPushAtomId{};
+  void add_push_atom_id(AtomId value) {
+    static constexpr uint32_t field_id = FieldMetadata_PushAtomId::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_RawPushAtomId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      StatsdTracingConfig>;
+
+  static constexpr FieldMetadata_RawPushAtomId kRawPushAtomId{};
+  void add_raw_push_atom_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RawPushAtomId::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_PullConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      StatsdPullAtomConfig,
+      StatsdTracingConfig>;
+
+  static constexpr FieldMetadata_PullConfig kPullConfig{};
+  template <typename T = StatsdPullAtomConfig> T* add_pull_config() {
+    return BeginNestedMessage<T>(3);
+  }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/sys_stats/sys_stats_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_SYS_STATS_SYS_STATS_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_SYS_STATS_SYS_STATS_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+enum MeminfoCounters : int32_t;
+namespace perfetto_pbzero_enum_SysStatsConfig {
+enum StatCounters : int32_t;
+}  // namespace perfetto_pbzero_enum_SysStatsConfig
+using SysStatsConfig_StatCounters = perfetto_pbzero_enum_SysStatsConfig::StatCounters;
+enum VmstatCounters : int32_t;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_SysStatsConfig {
+enum StatCounters : int32_t {
+  STAT_UNSPECIFIED = 0,
+  STAT_CPU_TIMES = 1,
+  STAT_IRQ_COUNTS = 2,
+  STAT_SOFTIRQ_COUNTS = 3,
+  STAT_FORK_COUNT = 4,
+};
+} // namespace perfetto_pbzero_enum_SysStatsConfig
+using SysStatsConfig_StatCounters = perfetto_pbzero_enum_SysStatsConfig::StatCounters;
+
+
+constexpr SysStatsConfig_StatCounters SysStatsConfig_StatCounters_MIN = SysStatsConfig_StatCounters::STAT_UNSPECIFIED;
+constexpr SysStatsConfig_StatCounters SysStatsConfig_StatCounters_MAX = SysStatsConfig_StatCounters::STAT_FORK_COUNT;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* SysStatsConfig_StatCounters_Name(::perfetto::protos::pbzero::SysStatsConfig_StatCounters value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::SysStatsConfig_StatCounters::STAT_UNSPECIFIED:
+    return "STAT_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::SysStatsConfig_StatCounters::STAT_CPU_TIMES:
+    return "STAT_CPU_TIMES";
+
+  case ::perfetto::protos::pbzero::SysStatsConfig_StatCounters::STAT_IRQ_COUNTS:
+    return "STAT_IRQ_COUNTS";
+
+  case ::perfetto::protos::pbzero::SysStatsConfig_StatCounters::STAT_SOFTIRQ_COUNTS:
+    return "STAT_SOFTIRQ_COUNTS";
+
+  case ::perfetto::protos::pbzero::SysStatsConfig_StatCounters::STAT_FORK_COUNT:
+    return "STAT_FORK_COUNT";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class SysStatsConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/11, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  SysStatsConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SysStatsConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SysStatsConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_meminfo_period_ms() const { return at<1>().valid(); }
+  uint32_t meminfo_period_ms() const { return at<1>().as_uint32(); }
+  bool has_meminfo_counters() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> meminfo_counters() const { return GetRepeated<int32_t>(2); }
+  bool has_vmstat_period_ms() const { return at<3>().valid(); }
+  uint32_t vmstat_period_ms() const { return at<3>().as_uint32(); }
+  bool has_vmstat_counters() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> vmstat_counters() const { return GetRepeated<int32_t>(4); }
+  bool has_stat_period_ms() const { return at<5>().valid(); }
+  uint32_t stat_period_ms() const { return at<5>().as_uint32(); }
+  bool has_stat_counters() const { return at<6>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> stat_counters() const { return GetRepeated<int32_t>(6); }
+  bool has_devfreq_period_ms() const { return at<7>().valid(); }
+  uint32_t devfreq_period_ms() const { return at<7>().as_uint32(); }
+  bool has_cpufreq_period_ms() const { return at<8>().valid(); }
+  uint32_t cpufreq_period_ms() const { return at<8>().as_uint32(); }
+  bool has_buddyinfo_period_ms() const { return at<9>().valid(); }
+  uint32_t buddyinfo_period_ms() const { return at<9>().as_uint32(); }
+  bool has_diskstat_period_ms() const { return at<10>().valid(); }
+  uint32_t diskstat_period_ms() const { return at<10>().as_uint32(); }
+  bool has_psi_period_ms() const { return at<11>().valid(); }
+  uint32_t psi_period_ms() const { return at<11>().as_uint32(); }
+};
+
+class SysStatsConfig : public ::protozero::Message {
+ public:
+  using Decoder = SysStatsConfig_Decoder;
+  enum : int32_t {
+    kMeminfoPeriodMsFieldNumber = 1,
+    kMeminfoCountersFieldNumber = 2,
+    kVmstatPeriodMsFieldNumber = 3,
+    kVmstatCountersFieldNumber = 4,
+    kStatPeriodMsFieldNumber = 5,
+    kStatCountersFieldNumber = 6,
+    kDevfreqPeriodMsFieldNumber = 7,
+    kCpufreqPeriodMsFieldNumber = 8,
+    kBuddyinfoPeriodMsFieldNumber = 9,
+    kDiskstatPeriodMsFieldNumber = 10,
+    kPsiPeriodMsFieldNumber = 11,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SysStatsConfig"; }
+
+
+  using StatCounters = ::perfetto::protos::pbzero::SysStatsConfig_StatCounters;
+  static inline const char* StatCounters_Name(StatCounters value) {
+    return ::perfetto::protos::pbzero::SysStatsConfig_StatCounters_Name(value);
+  }
+  static inline const StatCounters STAT_UNSPECIFIED = StatCounters::STAT_UNSPECIFIED;
+  static inline const StatCounters STAT_CPU_TIMES = StatCounters::STAT_CPU_TIMES;
+  static inline const StatCounters STAT_IRQ_COUNTS = StatCounters::STAT_IRQ_COUNTS;
+  static inline const StatCounters STAT_SOFTIRQ_COUNTS = StatCounters::STAT_SOFTIRQ_COUNTS;
+  static inline const StatCounters STAT_FORK_COUNT = StatCounters::STAT_FORK_COUNT;
+
+  using FieldMetadata_MeminfoPeriodMs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SysStatsConfig>;
+
+  static constexpr FieldMetadata_MeminfoPeriodMs kMeminfoPeriodMs{};
+  void set_meminfo_period_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MeminfoPeriodMs::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_MeminfoCounters =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      MeminfoCounters,
+      SysStatsConfig>;
+
+  static constexpr FieldMetadata_MeminfoCounters kMeminfoCounters{};
+  void add_meminfo_counters(MeminfoCounters value) {
+    static constexpr uint32_t field_id = FieldMetadata_MeminfoCounters::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_VmstatPeriodMs =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SysStatsConfig>;
+
+  static constexpr FieldMetadata_VmstatPeriodMs kVmstatPeriodMs{};
+  void set_vmstat_period_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VmstatPeriodMs::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_VmstatCounters =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      VmstatCounters,
+      SysStatsConfig>;
+
+  static constexpr FieldMetadata_VmstatCounters kVmstatCounters{};
+  void add_vmstat_counters(VmstatCounters value) {
+    static constexpr uint32_t field_id = FieldMetadata_VmstatCounters::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_StatPeriodMs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SysStatsConfig>;
+
+  static constexpr FieldMetadata_StatPeriodMs kStatPeriodMs{};
+  void set_stat_period_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StatPeriodMs::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_StatCounters =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      SysStatsConfig_StatCounters,
+      SysStatsConfig>;
+
+  static constexpr FieldMetadata_StatCounters kStatCounters{};
+  void add_stat_counters(SysStatsConfig_StatCounters value) {
+    static constexpr uint32_t field_id = FieldMetadata_StatCounters::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_DevfreqPeriodMs =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SysStatsConfig>;
+
+  static constexpr FieldMetadata_DevfreqPeriodMs kDevfreqPeriodMs{};
+  void set_devfreq_period_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DevfreqPeriodMs::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_CpufreqPeriodMs =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SysStatsConfig>;
+
+  static constexpr FieldMetadata_CpufreqPeriodMs kCpufreqPeriodMs{};
+  void set_cpufreq_period_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CpufreqPeriodMs::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_BuddyinfoPeriodMs =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SysStatsConfig>;
+
+  static constexpr FieldMetadata_BuddyinfoPeriodMs kBuddyinfoPeriodMs{};
+  void set_buddyinfo_period_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BuddyinfoPeriodMs::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_DiskstatPeriodMs =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SysStatsConfig>;
+
+  static constexpr FieldMetadata_DiskstatPeriodMs kDiskstatPeriodMs{};
+  void set_diskstat_period_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DiskstatPeriodMs::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_PsiPeriodMs =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SysStatsConfig>;
+
+  static constexpr FieldMetadata_PsiPeriodMs kPsiPeriodMs{};
+  void set_psi_period_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PsiPeriodMs::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/system_info/system_info.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_SYSTEM_INFO_SYSTEM_INFO_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_SYSTEM_INFO_SYSTEM_INFO_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class SystemInfoConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/0, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SystemInfoConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SystemInfoConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SystemInfoConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+};
+
+class SystemInfoConfig : public ::protozero::Message {
+ public:
+  using Decoder = SystemInfoConfig_Decoder;
+  static constexpr const char* GetName() { return ".perfetto.protos.SystemInfoConfig"; }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/track_event/track_event_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TRACK_EVENT_TRACK_EVENT_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TRACK_EVENT_TRACK_EVENT_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class TrackEventConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TrackEventConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrackEventConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrackEventConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_disabled_categories() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> disabled_categories() const { return GetRepeated<::protozero::ConstChars>(1); }
+  bool has_enabled_categories() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> enabled_categories() const { return GetRepeated<::protozero::ConstChars>(2); }
+  bool has_disabled_tags() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> disabled_tags() const { return GetRepeated<::protozero::ConstChars>(3); }
+  bool has_enabled_tags() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> enabled_tags() const { return GetRepeated<::protozero::ConstChars>(4); }
+  bool has_disable_incremental_timestamps() const { return at<5>().valid(); }
+  bool disable_incremental_timestamps() const { return at<5>().as_bool(); }
+  bool has_timestamp_unit_multiplier() const { return at<6>().valid(); }
+  uint64_t timestamp_unit_multiplier() const { return at<6>().as_uint64(); }
+  bool has_filter_debug_annotations() const { return at<7>().valid(); }
+  bool filter_debug_annotations() const { return at<7>().as_bool(); }
+  bool has_enable_thread_time_sampling() const { return at<8>().valid(); }
+  bool enable_thread_time_sampling() const { return at<8>().as_bool(); }
+  bool has_filter_dynamic_event_names() const { return at<9>().valid(); }
+  bool filter_dynamic_event_names() const { return at<9>().as_bool(); }
+};
+
+class TrackEventConfig : public ::protozero::Message {
+ public:
+  using Decoder = TrackEventConfig_Decoder;
+  enum : int32_t {
+    kDisabledCategoriesFieldNumber = 1,
+    kEnabledCategoriesFieldNumber = 2,
+    kDisabledTagsFieldNumber = 3,
+    kEnabledTagsFieldNumber = 4,
+    kDisableIncrementalTimestampsFieldNumber = 5,
+    kTimestampUnitMultiplierFieldNumber = 6,
+    kFilterDebugAnnotationsFieldNumber = 7,
+    kEnableThreadTimeSamplingFieldNumber = 8,
+    kFilterDynamicEventNamesFieldNumber = 9,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrackEventConfig"; }
+
+
+  using FieldMetadata_DisabledCategories =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrackEventConfig>;
+
+  static constexpr FieldMetadata_DisabledCategories kDisabledCategories{};
+  void add_disabled_categories(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DisabledCategories::kFieldId, data, size);
+  }
+  void add_disabled_categories(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_DisabledCategories::kFieldId, chars.data, chars.size);
+  }
+  void add_disabled_categories(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_DisabledCategories::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_EnabledCategories =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrackEventConfig>;
+
+  static constexpr FieldMetadata_EnabledCategories kEnabledCategories{};
+  void add_enabled_categories(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_EnabledCategories::kFieldId, data, size);
+  }
+  void add_enabled_categories(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_EnabledCategories::kFieldId, chars.data, chars.size);
+  }
+  void add_enabled_categories(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_EnabledCategories::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_DisabledTags =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrackEventConfig>;
+
+  static constexpr FieldMetadata_DisabledTags kDisabledTags{};
+  void add_disabled_tags(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DisabledTags::kFieldId, data, size);
+  }
+  void add_disabled_tags(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_DisabledTags::kFieldId, chars.data, chars.size);
+  }
+  void add_disabled_tags(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_DisabledTags::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_EnabledTags =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrackEventConfig>;
+
+  static constexpr FieldMetadata_EnabledTags kEnabledTags{};
+  void add_enabled_tags(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_EnabledTags::kFieldId, data, size);
+  }
+  void add_enabled_tags(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_EnabledTags::kFieldId, chars.data, chars.size);
+  }
+  void add_enabled_tags(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_EnabledTags::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_DisableIncrementalTimestamps =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TrackEventConfig>;
+
+  static constexpr FieldMetadata_DisableIncrementalTimestamps kDisableIncrementalTimestamps{};
+  void set_disable_incremental_timestamps(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DisableIncrementalTimestamps::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_TimestampUnitMultiplier =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEventConfig>;
+
+  static constexpr FieldMetadata_TimestampUnitMultiplier kTimestampUnitMultiplier{};
+  void set_timestamp_unit_multiplier(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimestampUnitMultiplier::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_FilterDebugAnnotations =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TrackEventConfig>;
+
+  static constexpr FieldMetadata_FilterDebugAnnotations kFilterDebugAnnotations{};
+  void set_filter_debug_annotations(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_FilterDebugAnnotations::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_EnableThreadTimeSampling =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TrackEventConfig>;
+
+  static constexpr FieldMetadata_EnableThreadTimeSampling kEnableThreadTimeSampling{};
+  void set_enable_thread_time_sampling(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_EnableThreadTimeSampling::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_FilterDynamicEventNames =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TrackEventConfig>;
+
+  static constexpr FieldMetadata_FilterDynamicEventNames kFilterDynamicEventNames{};
+  void set_filter_dynamic_event_names(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_FilterDynamicEventNames::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/chrome/chrome_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_CHROME_CHROME_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_CHROME_CHROME_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+namespace perfetto_pbzero_enum_ChromeConfig {
+enum ClientPriority : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeConfig
+using ChromeConfig_ClientPriority = perfetto_pbzero_enum_ChromeConfig::ClientPriority;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_ChromeConfig {
+enum ClientPriority : int32_t {
+  UNKNOWN = 0,
+  BACKGROUND = 1,
+  USER_INITIATED = 2,
+};
+} // namespace perfetto_pbzero_enum_ChromeConfig
+using ChromeConfig_ClientPriority = perfetto_pbzero_enum_ChromeConfig::ClientPriority;
+
+
+constexpr ChromeConfig_ClientPriority ChromeConfig_ClientPriority_MIN = ChromeConfig_ClientPriority::UNKNOWN;
+constexpr ChromeConfig_ClientPriority ChromeConfig_ClientPriority_MAX = ChromeConfig_ClientPriority::USER_INITIATED;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeConfig_ClientPriority_Name(::perfetto::protos::pbzero::ChromeConfig_ClientPriority value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeConfig_ClientPriority::UNKNOWN:
+    return "UNKNOWN";
+
+  case ::perfetto::protos::pbzero::ChromeConfig_ClientPriority::BACKGROUND:
+    return "BACKGROUND";
+
+  case ::perfetto::protos::pbzero::ChromeConfig_ClientPriority::USER_INITIATED:
+    return "USER_INITIATED";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class ChromeConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_trace_config() const { return at<1>().valid(); }
+  ::protozero::ConstChars trace_config() const { return at<1>().as_string(); }
+  bool has_privacy_filtering_enabled() const { return at<2>().valid(); }
+  bool privacy_filtering_enabled() const { return at<2>().as_bool(); }
+  bool has_convert_to_legacy_json() const { return at<3>().valid(); }
+  bool convert_to_legacy_json() const { return at<3>().as_bool(); }
+  bool has_client_priority() const { return at<4>().valid(); }
+  int32_t client_priority() const { return at<4>().as_int32(); }
+  bool has_json_agent_label_filter() const { return at<5>().valid(); }
+  ::protozero::ConstChars json_agent_label_filter() const { return at<5>().as_string(); }
+};
+
+class ChromeConfig : public ::protozero::Message {
+ public:
+  using Decoder = ChromeConfig_Decoder;
+  enum : int32_t {
+    kTraceConfigFieldNumber = 1,
+    kPrivacyFilteringEnabledFieldNumber = 2,
+    kConvertToLegacyJsonFieldNumber = 3,
+    kClientPriorityFieldNumber = 4,
+    kJsonAgentLabelFilterFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeConfig"; }
+
+
+  using ClientPriority = ::perfetto::protos::pbzero::ChromeConfig_ClientPriority;
+  static inline const char* ClientPriority_Name(ClientPriority value) {
+    return ::perfetto::protos::pbzero::ChromeConfig_ClientPriority_Name(value);
+  }
+  static inline const ClientPriority UNKNOWN = ClientPriority::UNKNOWN;
+  static inline const ClientPriority BACKGROUND = ClientPriority::BACKGROUND;
+  static inline const ClientPriority USER_INITIATED = ClientPriority::USER_INITIATED;
+
+  using FieldMetadata_TraceConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeConfig>;
+
+  static constexpr FieldMetadata_TraceConfig kTraceConfig{};
+  void set_trace_config(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TraceConfig::kFieldId, data, size);
+  }
+  void set_trace_config(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_TraceConfig::kFieldId, chars.data, chars.size);
+  }
+  void set_trace_config(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_TraceConfig::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_PrivacyFilteringEnabled =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeConfig>;
+
+  static constexpr FieldMetadata_PrivacyFilteringEnabled kPrivacyFilteringEnabled{};
+  void set_privacy_filtering_enabled(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_PrivacyFilteringEnabled::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_ConvertToLegacyJson =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeConfig>;
+
+  static constexpr FieldMetadata_ConvertToLegacyJson kConvertToLegacyJson{};
+  void set_convert_to_legacy_json(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ConvertToLegacyJson::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_ClientPriority =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ChromeConfig_ClientPriority,
+      ChromeConfig>;
+
+  static constexpr FieldMetadata_ClientPriority kClientPriority{};
+  void set_client_priority(ChromeConfig_ClientPriority value) {
+    static constexpr uint32_t field_id = FieldMetadata_ClientPriority::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_JsonAgentLabelFilter =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeConfig>;
+
+  static constexpr FieldMetadata_JsonAgentLabelFilter kJsonAgentLabelFilter{};
+  void set_json_agent_label_filter(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_JsonAgentLabelFilter::kFieldId, data, size);
+  }
+  void set_json_agent_label_filter(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_JsonAgentLabelFilter::kFieldId, chars.data, chars.size);
+  }
+  void set_json_agent_label_filter(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_JsonAgentLabelFilter::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/chrome/scenario_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_CHROME_SCENARIO_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_CHROME_SCENARIO_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class NestedScenarioConfig;
+class ScenarioConfig;
+class TraceConfig;
+class TriggerRule;
+class TriggerRule_HistogramTrigger;
+class TriggerRule_RepeatingInterval;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class TracingTriggerRulesConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TracingTriggerRulesConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TracingTriggerRulesConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TracingTriggerRulesConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_rules() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> rules() const { return GetRepeated<::protozero::ConstBytes>(1); }
+};
+
+class TracingTriggerRulesConfig : public ::protozero::Message {
+ public:
+  using Decoder = TracingTriggerRulesConfig_Decoder;
+  enum : int32_t {
+    kRulesFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TracingTriggerRulesConfig"; }
+
+
+  using FieldMetadata_Rules =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TriggerRule,
+      TracingTriggerRulesConfig>;
+
+  static constexpr FieldMetadata_Rules kRules{};
+  template <typename T = TriggerRule> T* add_rules() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+class ChromeFieldTracingConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ChromeFieldTracingConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeFieldTracingConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeFieldTracingConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_scenarios() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> scenarios() const { return GetRepeated<::protozero::ConstBytes>(1); }
+};
+
+class ChromeFieldTracingConfig : public ::protozero::Message {
+ public:
+  using Decoder = ChromeFieldTracingConfig_Decoder;
+  enum : int32_t {
+    kScenariosFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeFieldTracingConfig"; }
+
+
+  using FieldMetadata_Scenarios =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ScenarioConfig,
+      ChromeFieldTracingConfig>;
+
+  static constexpr FieldMetadata_Scenarios kScenarios{};
+  template <typename T = ScenarioConfig> T* add_scenarios() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+class ScenarioConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ScenarioConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ScenarioConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ScenarioConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_scenario_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars scenario_name() const { return at<1>().as_string(); }
+  bool has_start_rules() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> start_rules() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_stop_rules() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> stop_rules() const { return GetRepeated<::protozero::ConstBytes>(3); }
+  bool has_upload_rules() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> upload_rules() const { return GetRepeated<::protozero::ConstBytes>(4); }
+  bool has_setup_rules() const { return at<5>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> setup_rules() const { return GetRepeated<::protozero::ConstBytes>(5); }
+  bool has_trace_config() const { return at<6>().valid(); }
+  ::protozero::ConstBytes trace_config() const { return at<6>().as_bytes(); }
+  bool has_nested_scenarios() const { return at<7>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> nested_scenarios() const { return GetRepeated<::protozero::ConstBytes>(7); }
+};
+
+class ScenarioConfig : public ::protozero::Message {
+ public:
+  using Decoder = ScenarioConfig_Decoder;
+  enum : int32_t {
+    kScenarioNameFieldNumber = 1,
+    kStartRulesFieldNumber = 2,
+    kStopRulesFieldNumber = 3,
+    kUploadRulesFieldNumber = 4,
+    kSetupRulesFieldNumber = 5,
+    kTraceConfigFieldNumber = 6,
+    kNestedScenariosFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ScenarioConfig"; }
+
+
+  using FieldMetadata_ScenarioName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ScenarioConfig>;
+
+  static constexpr FieldMetadata_ScenarioName kScenarioName{};
+  void set_scenario_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ScenarioName::kFieldId, data, size);
+  }
+  void set_scenario_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ScenarioName::kFieldId, chars.data, chars.size);
+  }
+  void set_scenario_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ScenarioName::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_StartRules =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TriggerRule,
+      ScenarioConfig>;
+
+  static constexpr FieldMetadata_StartRules kStartRules{};
+  template <typename T = TriggerRule> T* add_start_rules() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_StopRules =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TriggerRule,
+      ScenarioConfig>;
+
+  static constexpr FieldMetadata_StopRules kStopRules{};
+  template <typename T = TriggerRule> T* add_stop_rules() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_UploadRules =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TriggerRule,
+      ScenarioConfig>;
+
+  static constexpr FieldMetadata_UploadRules kUploadRules{};
+  template <typename T = TriggerRule> T* add_upload_rules() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_SetupRules =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TriggerRule,
+      ScenarioConfig>;
+
+  static constexpr FieldMetadata_SetupRules kSetupRules{};
+  template <typename T = TriggerRule> T* add_setup_rules() {
+    return BeginNestedMessage<T>(5);
+  }
+
+
+  using FieldMetadata_TraceConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceConfig,
+      ScenarioConfig>;
+
+  static constexpr FieldMetadata_TraceConfig kTraceConfig{};
+  template <typename T = TraceConfig> T* set_trace_config() {
+    return BeginNestedMessage<T>(6);
+  }
+
+
+  using FieldMetadata_NestedScenarios =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      NestedScenarioConfig,
+      ScenarioConfig>;
+
+  static constexpr FieldMetadata_NestedScenarios kNestedScenarios{};
+  template <typename T = NestedScenarioConfig> T* add_nested_scenarios() {
+    return BeginNestedMessage<T>(7);
+  }
+
+};
+
+class NestedScenarioConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  NestedScenarioConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit NestedScenarioConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit NestedScenarioConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_scenario_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars scenario_name() const { return at<1>().as_string(); }
+  bool has_start_rules() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> start_rules() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_stop_rules() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> stop_rules() const { return GetRepeated<::protozero::ConstBytes>(3); }
+  bool has_upload_rules() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> upload_rules() const { return GetRepeated<::protozero::ConstBytes>(4); }
+};
+
+class NestedScenarioConfig : public ::protozero::Message {
+ public:
+  using Decoder = NestedScenarioConfig_Decoder;
+  enum : int32_t {
+    kScenarioNameFieldNumber = 1,
+    kStartRulesFieldNumber = 2,
+    kStopRulesFieldNumber = 3,
+    kUploadRulesFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.NestedScenarioConfig"; }
+
+
+  using FieldMetadata_ScenarioName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      NestedScenarioConfig>;
+
+  static constexpr FieldMetadata_ScenarioName kScenarioName{};
+  void set_scenario_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ScenarioName::kFieldId, data, size);
+  }
+  void set_scenario_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ScenarioName::kFieldId, chars.data, chars.size);
+  }
+  void set_scenario_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ScenarioName::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_StartRules =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TriggerRule,
+      NestedScenarioConfig>;
+
+  static constexpr FieldMetadata_StartRules kStartRules{};
+  template <typename T = TriggerRule> T* add_start_rules() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_StopRules =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TriggerRule,
+      NestedScenarioConfig>;
+
+  static constexpr FieldMetadata_StopRules kStopRules{};
+  template <typename T = TriggerRule> T* add_stop_rules() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_UploadRules =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TriggerRule,
+      NestedScenarioConfig>;
+
+  static constexpr FieldMetadata_UploadRules kUploadRules{};
+  template <typename T = TriggerRule> T* add_upload_rules() {
+    return BeginNestedMessage<T>(4);
+  }
+
+};
+
+class TriggerRule_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TriggerRule_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TriggerRule_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TriggerRule_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_trigger_chance() const { return at<2>().valid(); }
+  float trigger_chance() const { return at<2>().as_float(); }
+  bool has_delay_ms() const { return at<3>().valid(); }
+  uint64_t delay_ms() const { return at<3>().as_uint64(); }
+  bool has_activation_delay_ms() const { return at<8>().valid(); }
+  uint64_t activation_delay_ms() const { return at<8>().as_uint64(); }
+  bool has_manual_trigger_name() const { return at<4>().valid(); }
+  ::protozero::ConstChars manual_trigger_name() const { return at<4>().as_string(); }
+  bool has_histogram() const { return at<5>().valid(); }
+  ::protozero::ConstBytes histogram() const { return at<5>().as_bytes(); }
+  bool has_repeating_interval() const { return at<6>().valid(); }
+  ::protozero::ConstBytes repeating_interval() const { return at<6>().as_bytes(); }
+};
+
+class TriggerRule : public ::protozero::Message {
+ public:
+  using Decoder = TriggerRule_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kTriggerChanceFieldNumber = 2,
+    kDelayMsFieldNumber = 3,
+    kActivationDelayMsFieldNumber = 8,
+    kManualTriggerNameFieldNumber = 4,
+    kHistogramFieldNumber = 5,
+    kRepeatingIntervalFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TriggerRule"; }
+
+  using HistogramTrigger = ::perfetto::protos::pbzero::TriggerRule_HistogramTrigger;
+  using RepeatingInterval = ::perfetto::protos::pbzero::TriggerRule_RepeatingInterval;
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TriggerRule>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_TriggerChance =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      TriggerRule>;
+
+  static constexpr FieldMetadata_TriggerChance kTriggerChance{};
+  void set_trigger_chance(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_TriggerChance::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DelayMs =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TriggerRule>;
+
+  static constexpr FieldMetadata_DelayMs kDelayMs{};
+  void set_delay_ms(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DelayMs::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_ActivationDelayMs =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TriggerRule>;
+
+  static constexpr FieldMetadata_ActivationDelayMs kActivationDelayMs{};
+  void set_activation_delay_ms(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ActivationDelayMs::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_ManualTriggerName =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TriggerRule>;
+
+  static constexpr FieldMetadata_ManualTriggerName kManualTriggerName{};
+  void set_manual_trigger_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ManualTriggerName::kFieldId, data, size);
+  }
+  void set_manual_trigger_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ManualTriggerName::kFieldId, chars.data, chars.size);
+  }
+  void set_manual_trigger_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ManualTriggerName::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_Histogram =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TriggerRule_HistogramTrigger,
+      TriggerRule>;
+
+  static constexpr FieldMetadata_Histogram kHistogram{};
+  template <typename T = TriggerRule_HistogramTrigger> T* set_histogram() {
+    return BeginNestedMessage<T>(5);
+  }
+
+
+  using FieldMetadata_RepeatingInterval =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TriggerRule_RepeatingInterval,
+      TriggerRule>;
+
+  static constexpr FieldMetadata_RepeatingInterval kRepeatingInterval{};
+  template <typename T = TriggerRule_RepeatingInterval> T* set_repeating_interval() {
+    return BeginNestedMessage<T>(6);
+  }
+
+};
+
+class TriggerRule_RepeatingInterval_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TriggerRule_RepeatingInterval_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TriggerRule_RepeatingInterval_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TriggerRule_RepeatingInterval_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_period_ms() const { return at<1>().valid(); }
+  uint64_t period_ms() const { return at<1>().as_uint64(); }
+  bool has_randomized() const { return at<2>().valid(); }
+  bool randomized() const { return at<2>().as_bool(); }
+};
+
+class TriggerRule_RepeatingInterval : public ::protozero::Message {
+ public:
+  using Decoder = TriggerRule_RepeatingInterval_Decoder;
+  enum : int32_t {
+    kPeriodMsFieldNumber = 1,
+    kRandomizedFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TriggerRule.RepeatingInterval"; }
+
+
+  using FieldMetadata_PeriodMs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TriggerRule_RepeatingInterval>;
+
+  static constexpr FieldMetadata_PeriodMs kPeriodMs{};
+  void set_period_ms(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PeriodMs::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_Randomized =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TriggerRule_RepeatingInterval>;
+
+  static constexpr FieldMetadata_Randomized kRandomized{};
+  void set_randomized(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_Randomized::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 TriggerRule_HistogramTrigger_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TriggerRule_HistogramTrigger_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TriggerRule_HistogramTrigger_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TriggerRule_HistogramTrigger_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_histogram_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars histogram_name() const { return at<1>().as_string(); }
+  bool has_min_value() const { return at<2>().valid(); }
+  int64_t min_value() const { return at<2>().as_int64(); }
+  bool has_max_value() const { return at<3>().valid(); }
+  int64_t max_value() const { return at<3>().as_int64(); }
+};
+
+class TriggerRule_HistogramTrigger : public ::protozero::Message {
+ public:
+  using Decoder = TriggerRule_HistogramTrigger_Decoder;
+  enum : int32_t {
+    kHistogramNameFieldNumber = 1,
+    kMinValueFieldNumber = 2,
+    kMaxValueFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TriggerRule.HistogramTrigger"; }
+
+
+  using FieldMetadata_HistogramName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TriggerRule_HistogramTrigger>;
+
+  static constexpr FieldMetadata_HistogramName kHistogramName{};
+  void set_histogram_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HistogramName::kFieldId, data, size);
+  }
+  void set_histogram_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_HistogramName::kFieldId, chars.data, chars.size);
+  }
+  void set_histogram_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_HistogramName::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_MinValue =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TriggerRule_HistogramTrigger>;
+
+  static constexpr FieldMetadata_MinValue kMinValue{};
+  void set_min_value(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MinValue::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_MaxValue =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TriggerRule_HistogramTrigger>;
+
+  static constexpr FieldMetadata_MaxValue kMaxValue{};
+  void set_max_value(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MaxValue::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/chrome/v8_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_CHROME_V8_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_CHROME_V8_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class V8Config_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  V8Config_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit V8Config_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit V8Config_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_log_script_sources() const { return at<1>().valid(); }
+  bool log_script_sources() const { return at<1>().as_bool(); }
+  bool has_log_instructions() const { return at<2>().valid(); }
+  bool log_instructions() const { return at<2>().as_bool(); }
+};
+
+class V8Config : public ::protozero::Message {
+ public:
+  using Decoder = V8Config_Decoder;
+  enum : int32_t {
+    kLogScriptSourcesFieldNumber = 1,
+    kLogInstructionsFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.V8Config"; }
+
+
+  using FieldMetadata_LogScriptSources =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      V8Config>;
+
+  static constexpr FieldMetadata_LogScriptSources kLogScriptSources{};
+  void set_log_script_sources(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_LogScriptSources::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_LogInstructions =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      V8Config>;
+
+  static constexpr FieldMetadata_LogInstructions kLogInstructions{};
+  void set_log_instructions(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_LogInstructions::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/data_source_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_DATA_SOURCE_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_DATA_SOURCE_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class AndroidGameInterventionListConfig;
+class AndroidInputEventConfig;
+class AndroidLogConfig;
+class AndroidPolledStateConfig;
+class AndroidPowerConfig;
+class AndroidSdkSyspropGuardConfig;
+class AndroidSystemPropertyConfig;
+class ChromeConfig;
+class EtwConfig;
+class FtraceConfig;
+class GpuCounterConfig;
+class HeapprofdConfig;
+class InodeFileConfig;
+class InterceptorConfig;
+class JavaHprofConfig;
+class NetworkPacketTraceConfig;
+class PackagesListConfig;
+class PerfEventConfig;
+class PixelModemConfig;
+class ProcessStatsConfig;
+class ProtoLogConfig;
+class StatsdTracingConfig;
+class SurfaceFlingerLayersConfig;
+class SurfaceFlingerTransactionsConfig;
+class SysStatsConfig;
+class SystemInfoConfig;
+class TestConfig;
+class TrackEventConfig;
+class V8Config;
+class VulkanMemoryConfig;
+namespace perfetto_pbzero_enum_DataSourceConfig {
+enum SessionInitiator : int32_t;
+}  // namespace perfetto_pbzero_enum_DataSourceConfig
+using DataSourceConfig_SessionInitiator = perfetto_pbzero_enum_DataSourceConfig::SessionInitiator;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_DataSourceConfig {
+enum SessionInitiator : int32_t {
+  SESSION_INITIATOR_UNSPECIFIED = 0,
+  SESSION_INITIATOR_TRUSTED_SYSTEM = 1,
+};
+} // namespace perfetto_pbzero_enum_DataSourceConfig
+using DataSourceConfig_SessionInitiator = perfetto_pbzero_enum_DataSourceConfig::SessionInitiator;
+
+
+constexpr DataSourceConfig_SessionInitiator DataSourceConfig_SessionInitiator_MIN = DataSourceConfig_SessionInitiator::SESSION_INITIATOR_UNSPECIFIED;
+constexpr DataSourceConfig_SessionInitiator DataSourceConfig_SessionInitiator_MAX = DataSourceConfig_SessionInitiator::SESSION_INITIATOR_TRUSTED_SYSTEM;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* DataSourceConfig_SessionInitiator_Name(::perfetto::protos::pbzero::DataSourceConfig_SessionInitiator value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::DataSourceConfig_SessionInitiator::SESSION_INITIATOR_UNSPECIFIED:
+    return "SESSION_INITIATOR_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::DataSourceConfig_SessionInitiator::SESSION_INITIATOR_TRUSTED_SYSTEM:
+    return "SESSION_INITIATOR_TRUSTED_SYSTEM";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class DataSourceConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/129, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DataSourceConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DataSourceConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DataSourceConfig_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_target_buffer() const { return at<2>().valid(); }
+  uint32_t target_buffer() const { return at<2>().as_uint32(); }
+  bool has_trace_duration_ms() const { return at<3>().valid(); }
+  uint32_t trace_duration_ms() const { return at<3>().as_uint32(); }
+  bool has_prefer_suspend_clock_for_duration() const { return at<122>().valid(); }
+  bool prefer_suspend_clock_for_duration() const { return at<122>().as_bool(); }
+  bool has_stop_timeout_ms() const { return at<7>().valid(); }
+  uint32_t stop_timeout_ms() const { return at<7>().as_uint32(); }
+  bool has_enable_extra_guardrails() const { return at<6>().valid(); }
+  bool enable_extra_guardrails() const { return at<6>().as_bool(); }
+  bool has_session_initiator() const { return at<8>().valid(); }
+  int32_t session_initiator() const { return at<8>().as_int32(); }
+  bool has_tracing_session_id() const { return at<4>().valid(); }
+  uint64_t tracing_session_id() const { return at<4>().as_uint64(); }
+  bool has_ftrace_config() const { return at<100>().valid(); }
+  ::protozero::ConstBytes ftrace_config() const { return at<100>().as_bytes(); }
+  bool has_inode_file_config() const { return at<102>().valid(); }
+  ::protozero::ConstBytes inode_file_config() const { return at<102>().as_bytes(); }
+  bool has_process_stats_config() const { return at<103>().valid(); }
+  ::protozero::ConstBytes process_stats_config() const { return at<103>().as_bytes(); }
+  bool has_sys_stats_config() const { return at<104>().valid(); }
+  ::protozero::ConstBytes sys_stats_config() const { return at<104>().as_bytes(); }
+  bool has_heapprofd_config() const { return at<105>().valid(); }
+  ::protozero::ConstBytes heapprofd_config() const { return at<105>().as_bytes(); }
+  bool has_java_hprof_config() const { return at<110>().valid(); }
+  ::protozero::ConstBytes java_hprof_config() const { return at<110>().as_bytes(); }
+  bool has_android_power_config() const { return at<106>().valid(); }
+  ::protozero::ConstBytes android_power_config() const { return at<106>().as_bytes(); }
+  bool has_android_log_config() const { return at<107>().valid(); }
+  ::protozero::ConstBytes android_log_config() const { return at<107>().as_bytes(); }
+  bool has_gpu_counter_config() const { return at<108>().valid(); }
+  ::protozero::ConstBytes gpu_counter_config() const { return at<108>().as_bytes(); }
+  bool has_android_game_intervention_list_config() const { return at<116>().valid(); }
+  ::protozero::ConstBytes android_game_intervention_list_config() const { return at<116>().as_bytes(); }
+  bool has_packages_list_config() const { return at<109>().valid(); }
+  ::protozero::ConstBytes packages_list_config() const { return at<109>().as_bytes(); }
+  bool has_perf_event_config() const { return at<111>().valid(); }
+  ::protozero::ConstBytes perf_event_config() const { return at<111>().as_bytes(); }
+  bool has_vulkan_memory_config() const { return at<112>().valid(); }
+  ::protozero::ConstBytes vulkan_memory_config() const { return at<112>().as_bytes(); }
+  bool has_track_event_config() const { return at<113>().valid(); }
+  ::protozero::ConstBytes track_event_config() const { return at<113>().as_bytes(); }
+  bool has_android_polled_state_config() const { return at<114>().valid(); }
+  ::protozero::ConstBytes android_polled_state_config() const { return at<114>().as_bytes(); }
+  bool has_android_system_property_config() const { return at<118>().valid(); }
+  ::protozero::ConstBytes android_system_property_config() const { return at<118>().as_bytes(); }
+  bool has_statsd_tracing_config() const { return at<117>().valid(); }
+  ::protozero::ConstBytes statsd_tracing_config() const { return at<117>().as_bytes(); }
+  bool has_system_info_config() const { return at<119>().valid(); }
+  ::protozero::ConstBytes system_info_config() const { return at<119>().as_bytes(); }
+  bool has_chrome_config() const { return at<101>().valid(); }
+  ::protozero::ConstBytes chrome_config() const { return at<101>().as_bytes(); }
+  bool has_v8_config() const { return at<127>().valid(); }
+  ::protozero::ConstBytes v8_config() const { return at<127>().as_bytes(); }
+  bool has_interceptor_config() const { return at<115>().valid(); }
+  ::protozero::ConstBytes interceptor_config() const { return at<115>().as_bytes(); }
+  bool has_network_packet_trace_config() const { return at<120>().valid(); }
+  ::protozero::ConstBytes network_packet_trace_config() const { return at<120>().as_bytes(); }
+  bool has_surfaceflinger_layers_config() const { return at<121>().valid(); }
+  ::protozero::ConstBytes surfaceflinger_layers_config() const { return at<121>().as_bytes(); }
+  bool has_surfaceflinger_transactions_config() const { return at<123>().valid(); }
+  ::protozero::ConstBytes surfaceflinger_transactions_config() const { return at<123>().as_bytes(); }
+  bool has_android_sdk_sysprop_guard_config() const { return at<124>().valid(); }
+  ::protozero::ConstBytes android_sdk_sysprop_guard_config() const { return at<124>().as_bytes(); }
+  bool has_etw_config() const { return at<125>().valid(); }
+  ::protozero::ConstBytes etw_config() const { return at<125>().as_bytes(); }
+  bool has_protolog_config() const { return at<126>().valid(); }
+  ::protozero::ConstBytes protolog_config() const { return at<126>().as_bytes(); }
+  bool has_android_input_event_config() const { return at<128>().valid(); }
+  ::protozero::ConstBytes android_input_event_config() const { return at<128>().as_bytes(); }
+  bool has_pixel_modem_config() const { return at<129>().valid(); }
+  ::protozero::ConstBytes pixel_modem_config() const { return at<129>().as_bytes(); }
+  // field legacy_config omitted because its id is too high
+  // field for_testing omitted because its id is too high
+};
+
+class DataSourceConfig : public ::protozero::Message {
+ public:
+  using Decoder = DataSourceConfig_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kTargetBufferFieldNumber = 2,
+    kTraceDurationMsFieldNumber = 3,
+    kPreferSuspendClockForDurationFieldNumber = 122,
+    kStopTimeoutMsFieldNumber = 7,
+    kEnableExtraGuardrailsFieldNumber = 6,
+    kSessionInitiatorFieldNumber = 8,
+    kTracingSessionIdFieldNumber = 4,
+    kFtraceConfigFieldNumber = 100,
+    kInodeFileConfigFieldNumber = 102,
+    kProcessStatsConfigFieldNumber = 103,
+    kSysStatsConfigFieldNumber = 104,
+    kHeapprofdConfigFieldNumber = 105,
+    kJavaHprofConfigFieldNumber = 110,
+    kAndroidPowerConfigFieldNumber = 106,
+    kAndroidLogConfigFieldNumber = 107,
+    kGpuCounterConfigFieldNumber = 108,
+    kAndroidGameInterventionListConfigFieldNumber = 116,
+    kPackagesListConfigFieldNumber = 109,
+    kPerfEventConfigFieldNumber = 111,
+    kVulkanMemoryConfigFieldNumber = 112,
+    kTrackEventConfigFieldNumber = 113,
+    kAndroidPolledStateConfigFieldNumber = 114,
+    kAndroidSystemPropertyConfigFieldNumber = 118,
+    kStatsdTracingConfigFieldNumber = 117,
+    kSystemInfoConfigFieldNumber = 119,
+    kChromeConfigFieldNumber = 101,
+    kV8ConfigFieldNumber = 127,
+    kInterceptorConfigFieldNumber = 115,
+    kNetworkPacketTraceConfigFieldNumber = 120,
+    kSurfaceflingerLayersConfigFieldNumber = 121,
+    kSurfaceflingerTransactionsConfigFieldNumber = 123,
+    kAndroidSdkSyspropGuardConfigFieldNumber = 124,
+    kEtwConfigFieldNumber = 125,
+    kProtologConfigFieldNumber = 126,
+    kAndroidInputEventConfigFieldNumber = 128,
+    kPixelModemConfigFieldNumber = 129,
+    kLegacyConfigFieldNumber = 1000,
+    kForTestingFieldNumber = 1001,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DataSourceConfig"; }
+
+
+  using SessionInitiator = ::perfetto::protos::pbzero::DataSourceConfig_SessionInitiator;
+  static inline const char* SessionInitiator_Name(SessionInitiator value) {
+    return ::perfetto::protos::pbzero::DataSourceConfig_SessionInitiator_Name(value);
+  }
+  static inline const SessionInitiator SESSION_INITIATOR_UNSPECIFIED = SessionInitiator::SESSION_INITIATOR_UNSPECIFIED;
+  static inline const SessionInitiator SESSION_INITIATOR_TRUSTED_SYSTEM = SessionInitiator::SESSION_INITIATOR_TRUSTED_SYSTEM;
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_TargetBuffer =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_TargetBuffer kTargetBuffer{};
+  void set_target_buffer(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TargetBuffer::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_TraceDurationMs =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_TraceDurationMs kTraceDurationMs{};
+  void set_trace_duration_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TraceDurationMs::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_PreferSuspendClockForDuration =
+    ::protozero::proto_utils::FieldMetadata<
+      122,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_PreferSuspendClockForDuration kPreferSuspendClockForDuration{};
+  void set_prefer_suspend_clock_for_duration(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_PreferSuspendClockForDuration::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_StopTimeoutMs =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_StopTimeoutMs kStopTimeoutMs{};
+  void set_stop_timeout_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StopTimeoutMs::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<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_EnableExtraGuardrails kEnableExtraGuardrails{};
+  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_SessionInitiator =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      DataSourceConfig_SessionInitiator,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_SessionInitiator kSessionInitiator{};
+  void set_session_initiator(DataSourceConfig_SessionInitiator value) {
+    static constexpr uint32_t field_id = FieldMetadata_SessionInitiator::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_TracingSessionId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_TracingSessionId kTracingSessionId{};
+  void set_tracing_session_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TracingSessionId::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_FtraceConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      100,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FtraceConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_FtraceConfig kFtraceConfig{};
+  template <typename T = FtraceConfig> T* set_ftrace_config() {
+    return BeginNestedMessage<T>(100);
+  }
+
+  void set_ftrace_config_raw(const std::string& raw) {
+    return AppendBytes(100, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_InodeFileConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      102,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InodeFileConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_InodeFileConfig kInodeFileConfig{};
+  template <typename T = InodeFileConfig> T* set_inode_file_config() {
+    return BeginNestedMessage<T>(102);
+  }
+
+  void set_inode_file_config_raw(const std::string& raw) {
+    return AppendBytes(102, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_ProcessStatsConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      103,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProcessStatsConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_ProcessStatsConfig kProcessStatsConfig{};
+  template <typename T = ProcessStatsConfig> T* set_process_stats_config() {
+    return BeginNestedMessage<T>(103);
+  }
+
+  void set_process_stats_config_raw(const std::string& raw) {
+    return AppendBytes(103, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_SysStatsConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      104,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SysStatsConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_SysStatsConfig kSysStatsConfig{};
+  template <typename T = SysStatsConfig> T* set_sys_stats_config() {
+    return BeginNestedMessage<T>(104);
+  }
+
+  void set_sys_stats_config_raw(const std::string& raw) {
+    return AppendBytes(104, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_HeapprofdConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      105,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      HeapprofdConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_HeapprofdConfig kHeapprofdConfig{};
+  template <typename T = HeapprofdConfig> T* set_heapprofd_config() {
+    return BeginNestedMessage<T>(105);
+  }
+
+  void set_heapprofd_config_raw(const std::string& raw) {
+    return AppendBytes(105, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_JavaHprofConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      110,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      JavaHprofConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_JavaHprofConfig kJavaHprofConfig{};
+  template <typename T = JavaHprofConfig> T* set_java_hprof_config() {
+    return BeginNestedMessage<T>(110);
+  }
+
+  void set_java_hprof_config_raw(const std::string& raw) {
+    return AppendBytes(110, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_AndroidPowerConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      106,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidPowerConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_AndroidPowerConfig kAndroidPowerConfig{};
+  template <typename T = AndroidPowerConfig> T* set_android_power_config() {
+    return BeginNestedMessage<T>(106);
+  }
+
+  void set_android_power_config_raw(const std::string& raw) {
+    return AppendBytes(106, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_AndroidLogConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      107,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidLogConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_AndroidLogConfig kAndroidLogConfig{};
+  template <typename T = AndroidLogConfig> T* set_android_log_config() {
+    return BeginNestedMessage<T>(107);
+  }
+
+  void set_android_log_config_raw(const std::string& raw) {
+    return AppendBytes(107, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_GpuCounterConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      108,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuCounterConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_GpuCounterConfig kGpuCounterConfig{};
+  template <typename T = GpuCounterConfig> T* set_gpu_counter_config() {
+    return BeginNestedMessage<T>(108);
+  }
+
+  void set_gpu_counter_config_raw(const std::string& raw) {
+    return AppendBytes(108, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_AndroidGameInterventionListConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      116,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidGameInterventionListConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_AndroidGameInterventionListConfig kAndroidGameInterventionListConfig{};
+  template <typename T = AndroidGameInterventionListConfig> T* set_android_game_intervention_list_config() {
+    return BeginNestedMessage<T>(116);
+  }
+
+  void set_android_game_intervention_list_config_raw(const std::string& raw) {
+    return AppendBytes(116, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_PackagesListConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      109,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PackagesListConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_PackagesListConfig kPackagesListConfig{};
+  template <typename T = PackagesListConfig> T* set_packages_list_config() {
+    return BeginNestedMessage<T>(109);
+  }
+
+  void set_packages_list_config_raw(const std::string& raw) {
+    return AppendBytes(109, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_PerfEventConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      111,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PerfEventConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_PerfEventConfig kPerfEventConfig{};
+  template <typename T = PerfEventConfig> T* set_perf_event_config() {
+    return BeginNestedMessage<T>(111);
+  }
+
+  void set_perf_event_config_raw(const std::string& raw) {
+    return AppendBytes(111, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_VulkanMemoryConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      112,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      VulkanMemoryConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_VulkanMemoryConfig kVulkanMemoryConfig{};
+  template <typename T = VulkanMemoryConfig> T* set_vulkan_memory_config() {
+    return BeginNestedMessage<T>(112);
+  }
+
+  void set_vulkan_memory_config_raw(const std::string& raw) {
+    return AppendBytes(112, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_TrackEventConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      113,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrackEventConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_TrackEventConfig kTrackEventConfig{};
+  template <typename T = TrackEventConfig> T* set_track_event_config() {
+    return BeginNestedMessage<T>(113);
+  }
+
+  void set_track_event_config_raw(const std::string& raw) {
+    return AppendBytes(113, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_AndroidPolledStateConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      114,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidPolledStateConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_AndroidPolledStateConfig kAndroidPolledStateConfig{};
+  template <typename T = AndroidPolledStateConfig> T* set_android_polled_state_config() {
+    return BeginNestedMessage<T>(114);
+  }
+
+  void set_android_polled_state_config_raw(const std::string& raw) {
+    return AppendBytes(114, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_AndroidSystemPropertyConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      118,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidSystemPropertyConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_AndroidSystemPropertyConfig kAndroidSystemPropertyConfig{};
+  template <typename T = AndroidSystemPropertyConfig> T* set_android_system_property_config() {
+    return BeginNestedMessage<T>(118);
+  }
+
+  void set_android_system_property_config_raw(const std::string& raw) {
+    return AppendBytes(118, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_StatsdTracingConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      117,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      StatsdTracingConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_StatsdTracingConfig kStatsdTracingConfig{};
+  template <typename T = StatsdTracingConfig> T* set_statsd_tracing_config() {
+    return BeginNestedMessage<T>(117);
+  }
+
+  void set_statsd_tracing_config_raw(const std::string& raw) {
+    return AppendBytes(117, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_SystemInfoConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      119,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SystemInfoConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_SystemInfoConfig kSystemInfoConfig{};
+  template <typename T = SystemInfoConfig> T* set_system_info_config() {
+    return BeginNestedMessage<T>(119);
+  }
+
+
+  using FieldMetadata_ChromeConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      101,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_ChromeConfig kChromeConfig{};
+  template <typename T = ChromeConfig> T* set_chrome_config() {
+    return BeginNestedMessage<T>(101);
+  }
+
+
+  using FieldMetadata_V8Config =
+    ::protozero::proto_utils::FieldMetadata<
+      127,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      V8Config,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_V8Config kV8Config{};
+  template <typename T = V8Config> T* set_v8_config() {
+    return BeginNestedMessage<T>(127);
+  }
+
+  void set_v8_config_raw(const std::string& raw) {
+    return AppendBytes(127, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_InterceptorConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      115,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InterceptorConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_InterceptorConfig kInterceptorConfig{};
+  template <typename T = InterceptorConfig> T* set_interceptor_config() {
+    return BeginNestedMessage<T>(115);
+  }
+
+
+  using FieldMetadata_NetworkPacketTraceConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      120,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      NetworkPacketTraceConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_NetworkPacketTraceConfig kNetworkPacketTraceConfig{};
+  template <typename T = NetworkPacketTraceConfig> T* set_network_packet_trace_config() {
+    return BeginNestedMessage<T>(120);
+  }
+
+  void set_network_packet_trace_config_raw(const std::string& raw) {
+    return AppendBytes(120, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_SurfaceflingerLayersConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      121,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SurfaceFlingerLayersConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_SurfaceflingerLayersConfig kSurfaceflingerLayersConfig{};
+  template <typename T = SurfaceFlingerLayersConfig> T* set_surfaceflinger_layers_config() {
+    return BeginNestedMessage<T>(121);
+  }
+
+  void set_surfaceflinger_layers_config_raw(const std::string& raw) {
+    return AppendBytes(121, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_SurfaceflingerTransactionsConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      123,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SurfaceFlingerTransactionsConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_SurfaceflingerTransactionsConfig kSurfaceflingerTransactionsConfig{};
+  template <typename T = SurfaceFlingerTransactionsConfig> T* set_surfaceflinger_transactions_config() {
+    return BeginNestedMessage<T>(123);
+  }
+
+  void set_surfaceflinger_transactions_config_raw(const std::string& raw) {
+    return AppendBytes(123, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_AndroidSdkSyspropGuardConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      124,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidSdkSyspropGuardConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_AndroidSdkSyspropGuardConfig kAndroidSdkSyspropGuardConfig{};
+  template <typename T = AndroidSdkSyspropGuardConfig> T* set_android_sdk_sysprop_guard_config() {
+    return BeginNestedMessage<T>(124);
+  }
+
+  void set_android_sdk_sysprop_guard_config_raw(const std::string& raw) {
+    return AppendBytes(124, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_EtwConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      125,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      EtwConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_EtwConfig kEtwConfig{};
+  template <typename T = EtwConfig> T* set_etw_config() {
+    return BeginNestedMessage<T>(125);
+  }
+
+  void set_etw_config_raw(const std::string& raw) {
+    return AppendBytes(125, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_ProtologConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      126,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProtoLogConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_ProtologConfig kProtologConfig{};
+  template <typename T = ProtoLogConfig> T* set_protolog_config() {
+    return BeginNestedMessage<T>(126);
+  }
+
+  void set_protolog_config_raw(const std::string& raw) {
+    return AppendBytes(126, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_AndroidInputEventConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      128,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidInputEventConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_AndroidInputEventConfig kAndroidInputEventConfig{};
+  template <typename T = AndroidInputEventConfig> T* set_android_input_event_config() {
+    return BeginNestedMessage<T>(128);
+  }
+
+  void set_android_input_event_config_raw(const std::string& raw) {
+    return AppendBytes(128, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_PixelModemConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      129,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PixelModemConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_PixelModemConfig kPixelModemConfig{};
+  template <typename T = PixelModemConfig> T* set_pixel_modem_config() {
+    return BeginNestedMessage<T>(129);
+  }
+
+  void set_pixel_modem_config_raw(const std::string& raw) {
+    return AppendBytes(129, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_LegacyConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      1000,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_LegacyConfig kLegacyConfig{};
+  void set_legacy_config(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_LegacyConfig::kFieldId, data, size);
+  }
+  void set_legacy_config(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_LegacyConfig::kFieldId, chars.data, chars.size);
+  }
+  void set_legacy_config(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_LegacyConfig::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_ForTesting =
+    ::protozero::proto_utils::FieldMetadata<
+      1001,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TestConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_ForTesting kForTesting{};
+  template <typename T = TestConfig> T* set_for_testing() {
+    return BeginNestedMessage<T>(1001);
+  }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/etw/etw_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ETW_ETW_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ETW_ETW_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+namespace perfetto_pbzero_enum_EtwConfig {
+enum KernelFlag : int32_t;
+}  // namespace perfetto_pbzero_enum_EtwConfig
+using EtwConfig_KernelFlag = perfetto_pbzero_enum_EtwConfig::KernelFlag;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_EtwConfig {
+enum KernelFlag : int32_t {
+  CSWITCH = 0,
+  DISPATCHER = 1,
+};
+} // namespace perfetto_pbzero_enum_EtwConfig
+using EtwConfig_KernelFlag = perfetto_pbzero_enum_EtwConfig::KernelFlag;
+
+
+constexpr EtwConfig_KernelFlag EtwConfig_KernelFlag_MIN = EtwConfig_KernelFlag::CSWITCH;
+constexpr EtwConfig_KernelFlag EtwConfig_KernelFlag_MAX = EtwConfig_KernelFlag::DISPATCHER;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* EtwConfig_KernelFlag_Name(::perfetto::protos::pbzero::EtwConfig_KernelFlag value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::EtwConfig_KernelFlag::CSWITCH:
+    return "CSWITCH";
+
+  case ::perfetto::protos::pbzero::EtwConfig_KernelFlag::DISPATCHER:
+    return "DISPATCHER";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class EtwConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  EtwConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit EtwConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit EtwConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_kernel_flags() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> kernel_flags() const { return GetRepeated<int32_t>(1); }
+};
+
+class EtwConfig : public ::protozero::Message {
+ public:
+  using Decoder = EtwConfig_Decoder;
+  enum : int32_t {
+    kKernelFlagsFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.EtwConfig"; }
+
+
+  using KernelFlag = ::perfetto::protos::pbzero::EtwConfig_KernelFlag;
+  static inline const char* KernelFlag_Name(KernelFlag value) {
+    return ::perfetto::protos::pbzero::EtwConfig_KernelFlag_Name(value);
+  }
+  static inline const KernelFlag CSWITCH = KernelFlag::CSWITCH;
+  static inline const KernelFlag DISPATCHER = KernelFlag::DISPATCHER;
+
+  using FieldMetadata_KernelFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      EtwConfig_KernelFlag,
+      EtwConfig>;
+
+  static constexpr FieldMetadata_KernelFlags kKernelFlags{};
+  void add_kernel_flags(EtwConfig_KernelFlag value) {
+    static constexpr uint32_t field_id = FieldMetadata_KernelFlags::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.
+// gen_amalgamated begin header: gen/protos/perfetto/config/interceptor_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INTERCEPTOR_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INTERCEPTOR_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class ConsoleConfig;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class InterceptorConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/100, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  InterceptorConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit InterceptorConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit InterceptorConfig_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_console_config() const { return at<100>().valid(); }
+  ::protozero::ConstBytes console_config() const { return at<100>().as_bytes(); }
+};
+
+class InterceptorConfig : public ::protozero::Message {
+ public:
+  using Decoder = InterceptorConfig_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kConsoleConfigFieldNumber = 100,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.InterceptorConfig"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      InterceptorConfig>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_ConsoleConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      100,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ConsoleConfig,
+      InterceptorConfig>;
+
+  static constexpr FieldMetadata_ConsoleConfig kConsoleConfig{};
+  template <typename T = ConsoleConfig> T* set_console_config() {
+    return BeginNestedMessage<T>(100);
+  }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/stress_test_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STRESS_TEST_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STRESS_TEST_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class StressTestConfig_WriterTiming;
+class TraceConfig;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class StressTestConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/11, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  StressTestConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit StressTestConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit StressTestConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_trace_config() const { return at<1>().valid(); }
+  ::protozero::ConstBytes trace_config() const { return at<1>().as_bytes(); }
+  bool has_shmem_size_kb() const { return at<2>().valid(); }
+  uint32_t shmem_size_kb() const { return at<2>().as_uint32(); }
+  bool has_shmem_page_size_kb() const { return at<3>().valid(); }
+  uint32_t shmem_page_size_kb() const { return at<3>().as_uint32(); }
+  bool has_num_processes() const { return at<4>().valid(); }
+  uint32_t num_processes() const { return at<4>().as_uint32(); }
+  bool has_num_threads() const { return at<5>().valid(); }
+  uint32_t num_threads() const { return at<5>().as_uint32(); }
+  bool has_max_events() const { return at<6>().valid(); }
+  uint32_t max_events() const { return at<6>().as_uint32(); }
+  bool has_nesting() const { return at<7>().valid(); }
+  uint32_t nesting() const { return at<7>().as_uint32(); }
+  bool has_steady_state_timings() const { return at<8>().valid(); }
+  ::protozero::ConstBytes steady_state_timings() const { return at<8>().as_bytes(); }
+  bool has_burst_period_ms() const { return at<9>().valid(); }
+  uint32_t burst_period_ms() const { return at<9>().as_uint32(); }
+  bool has_burst_duration_ms() const { return at<10>().valid(); }
+  uint32_t burst_duration_ms() const { return at<10>().as_uint32(); }
+  bool has_burst_timings() const { return at<11>().valid(); }
+  ::protozero::ConstBytes burst_timings() const { return at<11>().as_bytes(); }
+};
+
+class StressTestConfig : public ::protozero::Message {
+ public:
+  using Decoder = StressTestConfig_Decoder;
+  enum : int32_t {
+    kTraceConfigFieldNumber = 1,
+    kShmemSizeKbFieldNumber = 2,
+    kShmemPageSizeKbFieldNumber = 3,
+    kNumProcessesFieldNumber = 4,
+    kNumThreadsFieldNumber = 5,
+    kMaxEventsFieldNumber = 6,
+    kNestingFieldNumber = 7,
+    kSteadyStateTimingsFieldNumber = 8,
+    kBurstPeriodMsFieldNumber = 9,
+    kBurstDurationMsFieldNumber = 10,
+    kBurstTimingsFieldNumber = 11,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.StressTestConfig"; }
+
+  using WriterTiming = ::perfetto::protos::pbzero::StressTestConfig_WriterTiming;
+
+  using FieldMetadata_TraceConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceConfig,
+      StressTestConfig>;
+
+  static constexpr FieldMetadata_TraceConfig kTraceConfig{};
+  template <typename T = TraceConfig> T* set_trace_config() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_ShmemSizeKb =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      StressTestConfig>;
+
+  static constexpr FieldMetadata_ShmemSizeKb kShmemSizeKb{};
+  void set_shmem_size_kb(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ShmemSizeKb::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_ShmemPageSizeKb =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      StressTestConfig>;
+
+  static constexpr FieldMetadata_ShmemPageSizeKb kShmemPageSizeKb{};
+  void set_shmem_page_size_kb(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ShmemPageSizeKb::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_NumProcesses =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      StressTestConfig>;
+
+  static constexpr FieldMetadata_NumProcesses kNumProcesses{};
+  void set_num_processes(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NumProcesses::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_NumThreads =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      StressTestConfig>;
+
+  static constexpr FieldMetadata_NumThreads kNumThreads{};
+  void set_num_threads(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NumThreads::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_MaxEvents =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      StressTestConfig>;
+
+  static constexpr FieldMetadata_MaxEvents kMaxEvents{};
+  void set_max_events(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MaxEvents::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_Nesting =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      StressTestConfig>;
+
+  static constexpr FieldMetadata_Nesting kNesting{};
+  void set_nesting(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nesting::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_SteadyStateTimings =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      StressTestConfig_WriterTiming,
+      StressTestConfig>;
+
+  static constexpr FieldMetadata_SteadyStateTimings kSteadyStateTimings{};
+  template <typename T = StressTestConfig_WriterTiming> T* set_steady_state_timings() {
+    return BeginNestedMessage<T>(8);
+  }
+
+
+  using FieldMetadata_BurstPeriodMs =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      StressTestConfig>;
+
+  static constexpr FieldMetadata_BurstPeriodMs kBurstPeriodMs{};
+  void set_burst_period_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BurstPeriodMs::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_BurstDurationMs =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      StressTestConfig>;
+
+  static constexpr FieldMetadata_BurstDurationMs kBurstDurationMs{};
+  void set_burst_duration_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BurstDurationMs::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_BurstTimings =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      StressTestConfig_WriterTiming,
+      StressTestConfig>;
+
+  static constexpr FieldMetadata_BurstTimings kBurstTimings{};
+  template <typename T = StressTestConfig_WriterTiming> T* set_burst_timings() {
+    return BeginNestedMessage<T>(11);
+  }
+
+};
+
+class StressTestConfig_WriterTiming_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  StressTestConfig_WriterTiming_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit StressTestConfig_WriterTiming_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit StressTestConfig_WriterTiming_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_payload_mean() const { return at<1>().valid(); }
+  double payload_mean() const { return at<1>().as_double(); }
+  bool has_payload_stddev() const { return at<2>().valid(); }
+  double payload_stddev() const { return at<2>().as_double(); }
+  bool has_rate_mean() const { return at<3>().valid(); }
+  double rate_mean() const { return at<3>().as_double(); }
+  bool has_rate_stddev() const { return at<4>().valid(); }
+  double rate_stddev() const { return at<4>().as_double(); }
+  bool has_payload_write_time_ms() const { return at<5>().valid(); }
+  uint32_t payload_write_time_ms() const { return at<5>().as_uint32(); }
+};
+
+class StressTestConfig_WriterTiming : public ::protozero::Message {
+ public:
+  using Decoder = StressTestConfig_WriterTiming_Decoder;
+  enum : int32_t {
+    kPayloadMeanFieldNumber = 1,
+    kPayloadStddevFieldNumber = 2,
+    kRateMeanFieldNumber = 3,
+    kRateStddevFieldNumber = 4,
+    kPayloadWriteTimeMsFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.StressTestConfig.WriterTiming"; }
+
+
+  using FieldMetadata_PayloadMean =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      StressTestConfig_WriterTiming>;
+
+  static constexpr FieldMetadata_PayloadMean kPayloadMean{};
+  void set_payload_mean(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_PayloadMean::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);
+  }
+
+  using FieldMetadata_PayloadStddev =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      StressTestConfig_WriterTiming>;
+
+  static constexpr FieldMetadata_PayloadStddev kPayloadStddev{};
+  void set_payload_stddev(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_PayloadStddev::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);
+  }
+
+  using FieldMetadata_RateMean =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      StressTestConfig_WriterTiming>;
+
+  static constexpr FieldMetadata_RateMean kRateMean{};
+  void set_rate_mean(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_RateMean::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);
+  }
+
+  using FieldMetadata_RateStddev =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      StressTestConfig_WriterTiming>;
+
+  static constexpr FieldMetadata_RateStddev kRateStddev{};
+  void set_rate_stddev(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_RateStddev::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);
+  }
+
+  using FieldMetadata_PayloadWriteTimeMs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      StressTestConfig_WriterTiming>;
+
+  static constexpr FieldMetadata_PayloadWriteTimeMs kPayloadWriteTimeMs{};
+  void set_payload_write_time_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PayloadWriteTimeMs::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/test_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TEST_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TEST_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class TestConfig_DummyFields;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class TestConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TestConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TestConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TestConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_message_count() const { return at<1>().valid(); }
+  uint32_t message_count() const { return at<1>().as_uint32(); }
+  bool has_max_messages_per_second() const { return at<2>().valid(); }
+  uint32_t max_messages_per_second() const { return at<2>().as_uint32(); }
+  bool has_seed() const { return at<3>().valid(); }
+  uint32_t seed() const { return at<3>().as_uint32(); }
+  bool has_message_size() const { return at<4>().valid(); }
+  uint32_t message_size() const { return at<4>().as_uint32(); }
+  bool has_send_batch_on_register() const { return at<5>().valid(); }
+  bool send_batch_on_register() const { return at<5>().as_bool(); }
+  bool has_dummy_fields() const { return at<6>().valid(); }
+  ::protozero::ConstBytes dummy_fields() const { return at<6>().as_bytes(); }
+};
+
+class TestConfig : public ::protozero::Message {
+ public:
+  using Decoder = TestConfig_Decoder;
+  enum : int32_t {
+    kMessageCountFieldNumber = 1,
+    kMaxMessagesPerSecondFieldNumber = 2,
+    kSeedFieldNumber = 3,
+    kMessageSizeFieldNumber = 4,
+    kSendBatchOnRegisterFieldNumber = 5,
+    kDummyFieldsFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TestConfig"; }
+
+  using DummyFields = ::perfetto::protos::pbzero::TestConfig_DummyFields;
+
+  using FieldMetadata_MessageCount =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TestConfig>;
+
+  static constexpr FieldMetadata_MessageCount kMessageCount{};
+  void set_message_count(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MessageCount::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_MaxMessagesPerSecond =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TestConfig>;
+
+  static constexpr FieldMetadata_MaxMessagesPerSecond kMaxMessagesPerSecond{};
+  void set_max_messages_per_second(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MaxMessagesPerSecond::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_Seed =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TestConfig>;
+
+  static constexpr FieldMetadata_Seed kSeed{};
+  void set_seed(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Seed::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_MessageSize =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TestConfig>;
+
+  static constexpr FieldMetadata_MessageSize kMessageSize{};
+  void set_message_size(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MessageSize::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_SendBatchOnRegister =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TestConfig>;
+
+  static constexpr FieldMetadata_SendBatchOnRegister kSendBatchOnRegister{};
+  void set_send_batch_on_register(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_SendBatchOnRegister::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_DummyFields =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TestConfig_DummyFields,
+      TestConfig>;
+
+  static constexpr FieldMetadata_DummyFields kDummyFields{};
+  template <typename T = TestConfig_DummyFields> T* set_dummy_fields() {
+    return BeginNestedMessage<T>(6);
+  }
+
+};
+
+class TestConfig_DummyFields_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/14, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TestConfig_DummyFields_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TestConfig_DummyFields_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TestConfig_DummyFields_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_field_uint32() const { return at<1>().valid(); }
+  uint32_t field_uint32() const { return at<1>().as_uint32(); }
+  bool has_field_int32() const { return at<2>().valid(); }
+  int32_t field_int32() const { return at<2>().as_int32(); }
+  bool has_field_uint64() const { return at<3>().valid(); }
+  uint64_t field_uint64() const { return at<3>().as_uint64(); }
+  bool has_field_int64() const { return at<4>().valid(); }
+  int64_t field_int64() const { return at<4>().as_int64(); }
+  bool has_field_fixed64() const { return at<5>().valid(); }
+  uint64_t field_fixed64() const { return at<5>().as_uint64(); }
+  bool has_field_sfixed64() const { return at<6>().valid(); }
+  int64_t field_sfixed64() const { return at<6>().as_int64(); }
+  bool has_field_fixed32() const { return at<7>().valid(); }
+  uint32_t field_fixed32() const { return at<7>().as_uint32(); }
+  bool has_field_sfixed32() const { return at<8>().valid(); }
+  int32_t field_sfixed32() const { return at<8>().as_int32(); }
+  bool has_field_double() const { return at<9>().valid(); }
+  double field_double() const { return at<9>().as_double(); }
+  bool has_field_float() const { return at<10>().valid(); }
+  float field_float() const { return at<10>().as_float(); }
+  bool has_field_sint64() const { return at<11>().valid(); }
+  int64_t field_sint64() const { return at<11>().as_sint64(); }
+  bool has_field_sint32() const { return at<12>().valid(); }
+  int32_t field_sint32() const { return at<12>().as_sint32(); }
+  bool has_field_string() const { return at<13>().valid(); }
+  ::protozero::ConstChars field_string() const { return at<13>().as_string(); }
+  bool has_field_bytes() const { return at<14>().valid(); }
+  ::protozero::ConstBytes field_bytes() const { return at<14>().as_bytes(); }
+};
+
+class TestConfig_DummyFields : public ::protozero::Message {
+ public:
+  using Decoder = TestConfig_DummyFields_Decoder;
+  enum : int32_t {
+    kFieldUint32FieldNumber = 1,
+    kFieldInt32FieldNumber = 2,
+    kFieldUint64FieldNumber = 3,
+    kFieldInt64FieldNumber = 4,
+    kFieldFixed64FieldNumber = 5,
+    kFieldSfixed64FieldNumber = 6,
+    kFieldFixed32FieldNumber = 7,
+    kFieldSfixed32FieldNumber = 8,
+    kFieldDoubleFieldNumber = 9,
+    kFieldFloatFieldNumber = 10,
+    kFieldSint64FieldNumber = 11,
+    kFieldSint32FieldNumber = 12,
+    kFieldStringFieldNumber = 13,
+    kFieldBytesFieldNumber = 14,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TestConfig.DummyFields"; }
+
+
+  using FieldMetadata_FieldUint32 =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TestConfig_DummyFields>;
+
+  static constexpr FieldMetadata_FieldUint32 kFieldUint32{};
+  void set_field_uint32(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FieldUint32::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_FieldInt32 =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TestConfig_DummyFields>;
+
+  static constexpr FieldMetadata_FieldInt32 kFieldInt32{};
+  void set_field_int32(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FieldInt32::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_FieldUint64 =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TestConfig_DummyFields>;
+
+  static constexpr FieldMetadata_FieldUint64 kFieldUint64{};
+  void set_field_uint64(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FieldUint64::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_FieldInt64 =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TestConfig_DummyFields>;
+
+  static constexpr FieldMetadata_FieldInt64 kFieldInt64{};
+  void set_field_int64(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FieldInt64::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_FieldFixed64 =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64,
+      uint64_t,
+      TestConfig_DummyFields>;
+
+  static constexpr FieldMetadata_FieldFixed64 kFieldFixed64{};
+  void set_field_fixed64(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FieldFixed64::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FieldSfixed64 =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kSfixed64,
+      int64_t,
+      TestConfig_DummyFields>;
+
+  static constexpr FieldMetadata_FieldSfixed64 kFieldSfixed64{};
+  void set_field_sfixed64(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FieldSfixed64::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kSfixed64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FieldFixed32 =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed32,
+      uint32_t,
+      TestConfig_DummyFields>;
+
+  static constexpr FieldMetadata_FieldFixed32 kFieldFixed32{};
+  void set_field_fixed32(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FieldFixed32::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FieldSfixed32 =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kSfixed32,
+      int32_t,
+      TestConfig_DummyFields>;
+
+  static constexpr FieldMetadata_FieldSfixed32 kFieldSfixed32{};
+  void set_field_sfixed32(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FieldSfixed32::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kSfixed32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FieldDouble =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      TestConfig_DummyFields>;
+
+  static constexpr FieldMetadata_FieldDouble kFieldDouble{};
+  void set_field_double(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_FieldDouble::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);
+  }
+
+  using FieldMetadata_FieldFloat =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      TestConfig_DummyFields>;
+
+  static constexpr FieldMetadata_FieldFloat kFieldFloat{};
+  void set_field_float(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_FieldFloat::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FieldSint64 =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kSint64,
+      int64_t,
+      TestConfig_DummyFields>;
+
+  static constexpr FieldMetadata_FieldSint64 kFieldSint64{};
+  void set_field_sint64(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FieldSint64::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kSint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FieldSint32 =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kSint32,
+      int32_t,
+      TestConfig_DummyFields>;
+
+  static constexpr FieldMetadata_FieldSint32 kFieldSint32{};
+  void set_field_sint32(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FieldSint32::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kSint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FieldString =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TestConfig_DummyFields>;
+
+  static constexpr FieldMetadata_FieldString kFieldString{};
+  void set_field_string(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_FieldString::kFieldId, data, size);
+  }
+  void set_field_string(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_FieldString::kFieldId, chars.data, chars.size);
+  }
+  void set_field_string(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_FieldString::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_FieldBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      TestConfig_DummyFields>;
+
+  static constexpr FieldMetadata_FieldBytes kFieldBytes{};
+  void set_field_bytes(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_FieldBytes::kFieldId, data, size);
+  }
+  void set_field_bytes(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_FieldBytes::kFieldId, bytes.data, bytes.size);
+  }
+  void set_field_bytes(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_FieldBytes::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/trace_config.pbzero.h
+// 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>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class DataSourceConfig;
+class TraceConfig_AndroidReportConfig;
+class TraceConfig_BufferConfig;
+class TraceConfig_BuiltinDataSource;
+class TraceConfig_CmdTraceStartDelay;
+class TraceConfig_DataSource;
+class TraceConfig_GuardrailOverrides;
+class TraceConfig_IncidentReportConfig;
+class TraceConfig_IncrementalStateConfig;
+class TraceConfig_ProducerConfig;
+class TraceConfig_StatsdMetadata;
+class TraceConfig_TraceFilter;
+class TraceConfig_TraceFilter_StringFilterChain;
+class TraceConfig_TraceFilter_StringFilterRule;
+class TraceConfig_TriggerConfig;
+class TraceConfig_TriggerConfig_Trigger;
+enum BuiltinClock : int32_t;
+namespace perfetto_pbzero_enum_TraceConfig_BufferConfig {
+enum FillPolicy : int32_t;
+}  // namespace perfetto_pbzero_enum_TraceConfig_BufferConfig
+using TraceConfig_BufferConfig_FillPolicy = perfetto_pbzero_enum_TraceConfig_BufferConfig::FillPolicy;
+namespace perfetto_pbzero_enum_TraceConfig {
+enum CompressionType : int32_t;
+}  // namespace perfetto_pbzero_enum_TraceConfig
+using TraceConfig_CompressionType = perfetto_pbzero_enum_TraceConfig::CompressionType;
+namespace perfetto_pbzero_enum_TraceConfig {
+enum LockdownModeOperation : int32_t;
+}  // namespace perfetto_pbzero_enum_TraceConfig
+using TraceConfig_LockdownModeOperation = perfetto_pbzero_enum_TraceConfig::LockdownModeOperation;
+namespace perfetto_pbzero_enum_TraceConfig {
+enum StatsdLogging : int32_t;
+}  // namespace perfetto_pbzero_enum_TraceConfig
+using TraceConfig_StatsdLogging = perfetto_pbzero_enum_TraceConfig::StatsdLogging;
+namespace perfetto_pbzero_enum_TraceConfig_TraceFilter {
+enum StringFilterPolicy : int32_t;
+}  // namespace perfetto_pbzero_enum_TraceConfig_TraceFilter
+using TraceConfig_TraceFilter_StringFilterPolicy = perfetto_pbzero_enum_TraceConfig_TraceFilter::StringFilterPolicy;
+namespace perfetto_pbzero_enum_TraceConfig_TriggerConfig {
+enum TriggerMode : int32_t;
+}  // namespace perfetto_pbzero_enum_TraceConfig_TriggerConfig
+using TraceConfig_TriggerConfig_TriggerMode = perfetto_pbzero_enum_TraceConfig_TriggerConfig::TriggerMode;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_TraceConfig {
+enum LockdownModeOperation : int32_t {
+  LOCKDOWN_UNCHANGED = 0,
+  LOCKDOWN_CLEAR = 1,
+  LOCKDOWN_SET = 2,
+};
+} // namespace perfetto_pbzero_enum_TraceConfig
+using TraceConfig_LockdownModeOperation = perfetto_pbzero_enum_TraceConfig::LockdownModeOperation;
+
+
+constexpr TraceConfig_LockdownModeOperation TraceConfig_LockdownModeOperation_MIN = TraceConfig_LockdownModeOperation::LOCKDOWN_UNCHANGED;
+constexpr TraceConfig_LockdownModeOperation TraceConfig_LockdownModeOperation_MAX = TraceConfig_LockdownModeOperation::LOCKDOWN_SET;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* TraceConfig_LockdownModeOperation_Name(::perfetto::protos::pbzero::TraceConfig_LockdownModeOperation value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::TraceConfig_LockdownModeOperation::LOCKDOWN_UNCHANGED:
+    return "LOCKDOWN_UNCHANGED";
+
+  case ::perfetto::protos::pbzero::TraceConfig_LockdownModeOperation::LOCKDOWN_CLEAR:
+    return "LOCKDOWN_CLEAR";
+
+  case ::perfetto::protos::pbzero::TraceConfig_LockdownModeOperation::LOCKDOWN_SET:
+    return "LOCKDOWN_SET";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_TraceConfig {
+enum CompressionType : int32_t {
+  COMPRESSION_TYPE_UNSPECIFIED = 0,
+  COMPRESSION_TYPE_DEFLATE = 1,
+};
+} // namespace perfetto_pbzero_enum_TraceConfig
+using TraceConfig_CompressionType = perfetto_pbzero_enum_TraceConfig::CompressionType;
+
+
+constexpr TraceConfig_CompressionType TraceConfig_CompressionType_MIN = TraceConfig_CompressionType::COMPRESSION_TYPE_UNSPECIFIED;
+constexpr TraceConfig_CompressionType TraceConfig_CompressionType_MAX = TraceConfig_CompressionType::COMPRESSION_TYPE_DEFLATE;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* TraceConfig_CompressionType_Name(::perfetto::protos::pbzero::TraceConfig_CompressionType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::TraceConfig_CompressionType::COMPRESSION_TYPE_UNSPECIFIED:
+    return "COMPRESSION_TYPE_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::TraceConfig_CompressionType::COMPRESSION_TYPE_DEFLATE:
+    return "COMPRESSION_TYPE_DEFLATE";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_TraceConfig {
+enum StatsdLogging : int32_t {
+  STATSD_LOGGING_UNSPECIFIED = 0,
+  STATSD_LOGGING_ENABLED = 1,
+  STATSD_LOGGING_DISABLED = 2,
+};
+} // namespace perfetto_pbzero_enum_TraceConfig
+using TraceConfig_StatsdLogging = perfetto_pbzero_enum_TraceConfig::StatsdLogging;
+
+
+constexpr TraceConfig_StatsdLogging TraceConfig_StatsdLogging_MIN = TraceConfig_StatsdLogging::STATSD_LOGGING_UNSPECIFIED;
+constexpr TraceConfig_StatsdLogging TraceConfig_StatsdLogging_MAX = TraceConfig_StatsdLogging::STATSD_LOGGING_DISABLED;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* TraceConfig_StatsdLogging_Name(::perfetto::protos::pbzero::TraceConfig_StatsdLogging value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::TraceConfig_StatsdLogging::STATSD_LOGGING_UNSPECIFIED:
+    return "STATSD_LOGGING_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::TraceConfig_StatsdLogging::STATSD_LOGGING_ENABLED:
+    return "STATSD_LOGGING_ENABLED";
+
+  case ::perfetto::protos::pbzero::TraceConfig_StatsdLogging::STATSD_LOGGING_DISABLED:
+    return "STATSD_LOGGING_DISABLED";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_TraceConfig_TraceFilter {
+enum StringFilterPolicy : int32_t {
+  SFP_UNSPECIFIED = 0,
+  SFP_MATCH_REDACT_GROUPS = 1,
+  SFP_ATRACE_MATCH_REDACT_GROUPS = 2,
+  SFP_MATCH_BREAK = 3,
+  SFP_ATRACE_MATCH_BREAK = 4,
+  SFP_ATRACE_REPEATED_SEARCH_REDACT_GROUPS = 5,
+};
+} // namespace perfetto_pbzero_enum_TraceConfig_TraceFilter
+using TraceConfig_TraceFilter_StringFilterPolicy = perfetto_pbzero_enum_TraceConfig_TraceFilter::StringFilterPolicy;
+
+
+constexpr TraceConfig_TraceFilter_StringFilterPolicy TraceConfig_TraceFilter_StringFilterPolicy_MIN = TraceConfig_TraceFilter_StringFilterPolicy::SFP_UNSPECIFIED;
+constexpr TraceConfig_TraceFilter_StringFilterPolicy TraceConfig_TraceFilter_StringFilterPolicy_MAX = TraceConfig_TraceFilter_StringFilterPolicy::SFP_ATRACE_REPEATED_SEARCH_REDACT_GROUPS;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* TraceConfig_TraceFilter_StringFilterPolicy_Name(::perfetto::protos::pbzero::TraceConfig_TraceFilter_StringFilterPolicy value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::TraceConfig_TraceFilter_StringFilterPolicy::SFP_UNSPECIFIED:
+    return "SFP_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::TraceConfig_TraceFilter_StringFilterPolicy::SFP_MATCH_REDACT_GROUPS:
+    return "SFP_MATCH_REDACT_GROUPS";
+
+  case ::perfetto::protos::pbzero::TraceConfig_TraceFilter_StringFilterPolicy::SFP_ATRACE_MATCH_REDACT_GROUPS:
+    return "SFP_ATRACE_MATCH_REDACT_GROUPS";
+
+  case ::perfetto::protos::pbzero::TraceConfig_TraceFilter_StringFilterPolicy::SFP_MATCH_BREAK:
+    return "SFP_MATCH_BREAK";
+
+  case ::perfetto::protos::pbzero::TraceConfig_TraceFilter_StringFilterPolicy::SFP_ATRACE_MATCH_BREAK:
+    return "SFP_ATRACE_MATCH_BREAK";
+
+  case ::perfetto::protos::pbzero::TraceConfig_TraceFilter_StringFilterPolicy::SFP_ATRACE_REPEATED_SEARCH_REDACT_GROUPS:
+    return "SFP_ATRACE_REPEATED_SEARCH_REDACT_GROUPS";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_TraceConfig_TriggerConfig {
+enum TriggerMode : int32_t {
+  UNSPECIFIED = 0,
+  START_TRACING = 1,
+  STOP_TRACING = 2,
+  CLONE_SNAPSHOT = 4,
+};
+} // namespace perfetto_pbzero_enum_TraceConfig_TriggerConfig
+using TraceConfig_TriggerConfig_TriggerMode = perfetto_pbzero_enum_TraceConfig_TriggerConfig::TriggerMode;
+
+
+constexpr TraceConfig_TriggerConfig_TriggerMode TraceConfig_TriggerConfig_TriggerMode_MIN = TraceConfig_TriggerConfig_TriggerMode::UNSPECIFIED;
+constexpr TraceConfig_TriggerConfig_TriggerMode TraceConfig_TriggerConfig_TriggerMode_MAX = TraceConfig_TriggerConfig_TriggerMode::CLONE_SNAPSHOT;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* TraceConfig_TriggerConfig_TriggerMode_Name(::perfetto::protos::pbzero::TraceConfig_TriggerConfig_TriggerMode value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::TraceConfig_TriggerConfig_TriggerMode::UNSPECIFIED:
+    return "UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::TraceConfig_TriggerConfig_TriggerMode::START_TRACING:
+    return "START_TRACING";
+
+  case ::perfetto::protos::pbzero::TraceConfig_TriggerConfig_TriggerMode::STOP_TRACING:
+    return "STOP_TRACING";
+
+  case ::perfetto::protos::pbzero::TraceConfig_TriggerConfig_TriggerMode::CLONE_SNAPSHOT:
+    return "CLONE_SNAPSHOT";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_TraceConfig_BufferConfig {
+enum FillPolicy : int32_t {
+  UNSPECIFIED = 0,
+  RING_BUFFER = 1,
+  DISCARD = 2,
+};
+} // namespace perfetto_pbzero_enum_TraceConfig_BufferConfig
+using TraceConfig_BufferConfig_FillPolicy = perfetto_pbzero_enum_TraceConfig_BufferConfig::FillPolicy;
+
+
+constexpr TraceConfig_BufferConfig_FillPolicy TraceConfig_BufferConfig_FillPolicy_MIN = TraceConfig_BufferConfig_FillPolicy::UNSPECIFIED;
+constexpr TraceConfig_BufferConfig_FillPolicy TraceConfig_BufferConfig_FillPolicy_MAX = TraceConfig_BufferConfig_FillPolicy::DISCARD;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* TraceConfig_BufferConfig_FillPolicy_Name(::perfetto::protos::pbzero::TraceConfig_BufferConfig_FillPolicy value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::TraceConfig_BufferConfig_FillPolicy::UNSPECIFIED:
+    return "UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::TraceConfig_BufferConfig_FillPolicy::RING_BUFFER:
+    return "RING_BUFFER";
+
+  case ::perfetto::protos::pbzero::TraceConfig_BufferConfig_FillPolicy::DISCARD:
+    return "DISCARD";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class TraceConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/38, /*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_prefer_suspend_clock_for_duration() const { return at<36>().valid(); }
+  bool prefer_suspend_clock_for_duration() const { return at<36>().as_bool(); }
+  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_bugreport_filename() const { return at<38>().valid(); }
+  ::protozero::ConstChars bugreport_filename() const { return at<38>().as_string(); }
+  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(); }
+  bool has_android_report_config() const { return at<34>().valid(); }
+  ::protozero::ConstBytes android_report_config() const { return at<34>().as_bytes(); }
+  bool has_cmd_trace_start_delay() const { return at<35>().valid(); }
+  ::protozero::ConstBytes cmd_trace_start_delay() const { return at<35>().as_bytes(); }
+};
+
+class TraceConfig : public ::protozero::Message {
+ public:
+  using Decoder = TraceConfig_Decoder;
+  enum : int32_t {
+    kBuffersFieldNumber = 1,
+    kDataSourcesFieldNumber = 2,
+    kBuiltinDataSourcesFieldNumber = 20,
+    kDurationMsFieldNumber = 3,
+    kPreferSuspendClockForDurationFieldNumber = 36,
+    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,
+    kBugreportFilenameFieldNumber = 38,
+    kTriggerConfigFieldNumber = 17,
+    kActivateTriggersFieldNumber = 18,
+    kIncrementalStateConfigFieldNumber = 21,
+    kAllowUserBuildTracingFieldNumber = 19,
+    kUniqueSessionNameFieldNumber = 22,
+    kCompressionTypeFieldNumber = 24,
+    kIncidentReportConfigFieldNumber = 25,
+    kStatsdLoggingFieldNumber = 31,
+    kTraceUuidMsbFieldNumber = 27,
+    kTraceUuidLsbFieldNumber = 28,
+    kTraceFilterFieldNumber = 33,
+    kAndroidReportConfigFieldNumber = 34,
+    kCmdTraceStartDelayFieldNumber = 35,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceConfig"; }
+
+  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 AndroidReportConfig = ::perfetto::protos::pbzero::TraceConfig_AndroidReportConfig;
+  using CmdTraceStartDelay = ::perfetto::protos::pbzero::TraceConfig_CmdTraceStartDelay;
+
+  using LockdownModeOperation = ::perfetto::protos::pbzero::TraceConfig_LockdownModeOperation;
+  static inline const char* LockdownModeOperation_Name(LockdownModeOperation value) {
+    return ::perfetto::protos::pbzero::TraceConfig_LockdownModeOperation_Name(value);
+  }
+
+  using CompressionType = ::perfetto::protos::pbzero::TraceConfig_CompressionType;
+  static inline const char* CompressionType_Name(CompressionType value) {
+    return ::perfetto::protos::pbzero::TraceConfig_CompressionType_Name(value);
+  }
+
+  using StatsdLogging = ::perfetto::protos::pbzero::TraceConfig_StatsdLogging;
+  static inline const char* StatsdLogging_Name(StatsdLogging value) {
+    return ::perfetto::protos::pbzero::TraceConfig_StatsdLogging_Name(value);
+  }
+  static inline const LockdownModeOperation LOCKDOWN_UNCHANGED = LockdownModeOperation::LOCKDOWN_UNCHANGED;
+  static inline const LockdownModeOperation LOCKDOWN_CLEAR = LockdownModeOperation::LOCKDOWN_CLEAR;
+  static inline const LockdownModeOperation LOCKDOWN_SET = LockdownModeOperation::LOCKDOWN_SET;
+  static inline const CompressionType COMPRESSION_TYPE_UNSPECIFIED = CompressionType::COMPRESSION_TYPE_UNSPECIFIED;
+  static inline const CompressionType COMPRESSION_TYPE_DEFLATE = CompressionType::COMPRESSION_TYPE_DEFLATE;
+  static inline const StatsdLogging STATSD_LOGGING_UNSPECIFIED = StatsdLogging::STATSD_LOGGING_UNSPECIFIED;
+  static inline const StatsdLogging STATSD_LOGGING_ENABLED = StatsdLogging::STATSD_LOGGING_ENABLED;
+  static inline const StatsdLogging STATSD_LOGGING_DISABLED = 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>;
+
+  static constexpr FieldMetadata_Buffers kBuffers{};
+  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>;
+
+  static constexpr FieldMetadata_DataSources kDataSources{};
+  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>;
+
+  static constexpr FieldMetadata_BuiltinDataSources kBuiltinDataSources{};
+  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>;
+
+  static constexpr FieldMetadata_DurationMs kDurationMs{};
+  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_PreferSuspendClockForDuration =
+    ::protozero::proto_utils::FieldMetadata<
+      36,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_PreferSuspendClockForDuration kPreferSuspendClockForDuration{};
+  void set_prefer_suspend_clock_for_duration(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_PreferSuspendClockForDuration::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_EnableExtraGuardrails =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_EnableExtraGuardrails kEnableExtraGuardrails{};
+  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,
+      TraceConfig_LockdownModeOperation,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_LockdownMode kLockdownMode{};
+  void set_lockdown_mode(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>;
+
+  static constexpr FieldMetadata_Producers kProducers{};
+  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>;
+
+  static constexpr FieldMetadata_StatsdMetadata kStatsdMetadata{};
+  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>;
+
+  static constexpr FieldMetadata_WriteIntoFile kWriteIntoFile{};
+  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>;
+
+  static constexpr FieldMetadata_OutputPath kOutputPath{};
+  void set_output_path(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_OutputPath::kFieldId, data, size);
+  }
+  void set_output_path(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_OutputPath::kFieldId, chars.data, chars.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>;
+
+  static constexpr FieldMetadata_FileWritePeriodMs kFileWritePeriodMs{};
+  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>;
+
+  static constexpr FieldMetadata_MaxFileSizeBytes kMaxFileSizeBytes{};
+  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>;
+
+  static constexpr FieldMetadata_GuardrailOverrides kGuardrailOverrides{};
+  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>;
+
+  static constexpr FieldMetadata_DeferredStart kDeferredStart{};
+  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>;
+
+  static constexpr FieldMetadata_FlushPeriodMs kFlushPeriodMs{};
+  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>;
+
+  static constexpr FieldMetadata_FlushTimeoutMs kFlushTimeoutMs{};
+  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>;
+
+  static constexpr FieldMetadata_DataSourceStopTimeoutMs kDataSourceStopTimeoutMs{};
+  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>;
+
+  static constexpr FieldMetadata_NotifyTraceur kNotifyTraceur{};
+  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>;
+
+  static constexpr FieldMetadata_BugreportScore kBugreportScore{};
+  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_BugreportFilename =
+    ::protozero::proto_utils::FieldMetadata<
+      38,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_BugreportFilename kBugreportFilename{};
+  void set_bugreport_filename(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_BugreportFilename::kFieldId, data, size);
+  }
+  void set_bugreport_filename(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_BugreportFilename::kFieldId, chars.data, chars.size);
+  }
+  void set_bugreport_filename(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_BugreportFilename::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_TriggerConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceConfig_TriggerConfig,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_TriggerConfig kTriggerConfig{};
+  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>;
+
+  static constexpr FieldMetadata_ActivateTriggers kActivateTriggers{};
+  void add_activate_triggers(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ActivateTriggers::kFieldId, data, size);
+  }
+  void add_activate_triggers(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ActivateTriggers::kFieldId, chars.data, chars.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>;
+
+  static constexpr FieldMetadata_IncrementalStateConfig kIncrementalStateConfig{};
+  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>;
+
+  static constexpr FieldMetadata_AllowUserBuildTracing kAllowUserBuildTracing{};
+  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>;
+
+  static constexpr FieldMetadata_UniqueSessionName kUniqueSessionName{};
+  void set_unique_session_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_UniqueSessionName::kFieldId, data, size);
+  }
+  void set_unique_session_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_UniqueSessionName::kFieldId, chars.data, chars.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,
+      TraceConfig_CompressionType,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_CompressionType kCompressionType{};
+  void set_compression_type(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>;
+
+  static constexpr FieldMetadata_IncidentReportConfig kIncidentReportConfig{};
+  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,
+      TraceConfig_StatsdLogging,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_StatsdLogging kStatsdLogging{};
+  void set_statsd_logging(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>;
+
+  static constexpr FieldMetadata_TraceUuidMsb kTraceUuidMsb{};
+  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>;
+
+  static constexpr FieldMetadata_TraceUuidLsb kTraceUuidLsb{};
+  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>;
+
+  static constexpr FieldMetadata_TraceFilter kTraceFilter{};
+  template <typename T = TraceConfig_TraceFilter> T* set_trace_filter() {
+    return BeginNestedMessage<T>(33);
+  }
+
+
+  using FieldMetadata_AndroidReportConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      34,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceConfig_AndroidReportConfig,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_AndroidReportConfig kAndroidReportConfig{};
+  template <typename T = TraceConfig_AndroidReportConfig> T* set_android_report_config() {
+    return BeginNestedMessage<T>(34);
+  }
+
+
+  using FieldMetadata_CmdTraceStartDelay =
+    ::protozero::proto_utils::FieldMetadata<
+      35,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceConfig_CmdTraceStartDelay,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_CmdTraceStartDelay kCmdTraceStartDelay{};
+  template <typename T = TraceConfig_CmdTraceStartDelay> T* set_cmd_trace_start_delay() {
+    return BeginNestedMessage<T>(35);
+  }
+
+};
+
+class TraceConfig_CmdTraceStartDelay_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TraceConfig_CmdTraceStartDelay_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TraceConfig_CmdTraceStartDelay_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TraceConfig_CmdTraceStartDelay_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_min_delay_ms() const { return at<1>().valid(); }
+  uint32_t min_delay_ms() const { return at<1>().as_uint32(); }
+  bool has_max_delay_ms() const { return at<2>().valid(); }
+  uint32_t max_delay_ms() const { return at<2>().as_uint32(); }
+};
+
+class TraceConfig_CmdTraceStartDelay : public ::protozero::Message {
+ public:
+  using Decoder = TraceConfig_CmdTraceStartDelay_Decoder;
+  enum : int32_t {
+    kMinDelayMsFieldNumber = 1,
+    kMaxDelayMsFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceConfig.CmdTraceStartDelay"; }
+
+
+  using FieldMetadata_MinDelayMs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TraceConfig_CmdTraceStartDelay>;
+
+  static constexpr FieldMetadata_MinDelayMs kMinDelayMs{};
+  void set_min_delay_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MinDelayMs::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_MaxDelayMs =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TraceConfig_CmdTraceStartDelay>;
+
+  static constexpr FieldMetadata_MaxDelayMs kMaxDelayMs{};
+  void set_max_delay_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MaxDelayMs::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_AndroidReportConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TraceConfig_AndroidReportConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TraceConfig_AndroidReportConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TraceConfig_AndroidReportConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_reporter_service_package() const { return at<1>().valid(); }
+  ::protozero::ConstChars reporter_service_package() const { return at<1>().as_string(); }
+  bool has_reporter_service_class() const { return at<2>().valid(); }
+  ::protozero::ConstChars reporter_service_class() const { return at<2>().as_string(); }
+  bool has_skip_report() const { return at<3>().valid(); }
+  bool skip_report() const { return at<3>().as_bool(); }
+  bool has_use_pipe_in_framework_for_testing() const { return at<4>().valid(); }
+  bool use_pipe_in_framework_for_testing() const { return at<4>().as_bool(); }
+};
+
+class TraceConfig_AndroidReportConfig : public ::protozero::Message {
+ public:
+  using Decoder = TraceConfig_AndroidReportConfig_Decoder;
+  enum : int32_t {
+    kReporterServicePackageFieldNumber = 1,
+    kReporterServiceClassFieldNumber = 2,
+    kSkipReportFieldNumber = 3,
+    kUsePipeInFrameworkForTestingFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceConfig.AndroidReportConfig"; }
+
+
+  using FieldMetadata_ReporterServicePackage =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TraceConfig_AndroidReportConfig>;
+
+  static constexpr FieldMetadata_ReporterServicePackage kReporterServicePackage{};
+  void set_reporter_service_package(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ReporterServicePackage::kFieldId, data, size);
+  }
+  void set_reporter_service_package(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ReporterServicePackage::kFieldId, chars.data, chars.size);
+  }
+  void set_reporter_service_package(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReporterServicePackage::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_ReporterServiceClass =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TraceConfig_AndroidReportConfig>;
+
+  static constexpr FieldMetadata_ReporterServiceClass kReporterServiceClass{};
+  void set_reporter_service_class(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ReporterServiceClass::kFieldId, data, size);
+  }
+  void set_reporter_service_class(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ReporterServiceClass::kFieldId, chars.data, chars.size);
+  }
+  void set_reporter_service_class(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReporterServiceClass::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_SkipReport =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TraceConfig_AndroidReportConfig>;
+
+  static constexpr FieldMetadata_SkipReport kSkipReport{};
+  void set_skip_report(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_SkipReport::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_UsePipeInFrameworkForTesting =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TraceConfig_AndroidReportConfig>;
+
+  static constexpr FieldMetadata_UsePipeInFrameworkForTesting kUsePipeInFrameworkForTesting{};
+  void set_use_pipe_in_framework_for_testing(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_UsePipeInFrameworkForTesting::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_TraceFilter_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*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(); }
+  bool has_bytecode_v2() const { return at<2>().valid(); }
+  ::protozero::ConstBytes bytecode_v2() const { return at<2>().as_bytes(); }
+  bool has_string_filter_chain() const { return at<3>().valid(); }
+  ::protozero::ConstBytes string_filter_chain() const { return at<3>().as_bytes(); }
+};
+
+class TraceConfig_TraceFilter : public ::protozero::Message {
+ public:
+  using Decoder = TraceConfig_TraceFilter_Decoder;
+  enum : int32_t {
+    kBytecodeFieldNumber = 1,
+    kBytecodeV2FieldNumber = 2,
+    kStringFilterChainFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceConfig.TraceFilter"; }
+
+  using StringFilterRule = ::perfetto::protos::pbzero::TraceConfig_TraceFilter_StringFilterRule;
+  using StringFilterChain = ::perfetto::protos::pbzero::TraceConfig_TraceFilter_StringFilterChain;
+
+  using StringFilterPolicy = ::perfetto::protos::pbzero::TraceConfig_TraceFilter_StringFilterPolicy;
+  static inline const char* StringFilterPolicy_Name(StringFilterPolicy value) {
+    return ::perfetto::protos::pbzero::TraceConfig_TraceFilter_StringFilterPolicy_Name(value);
+  }
+  static inline const StringFilterPolicy SFP_UNSPECIFIED = StringFilterPolicy::SFP_UNSPECIFIED;
+  static inline const StringFilterPolicy SFP_MATCH_REDACT_GROUPS = StringFilterPolicy::SFP_MATCH_REDACT_GROUPS;
+  static inline const StringFilterPolicy SFP_ATRACE_MATCH_REDACT_GROUPS = StringFilterPolicy::SFP_ATRACE_MATCH_REDACT_GROUPS;
+  static inline const StringFilterPolicy SFP_MATCH_BREAK = StringFilterPolicy::SFP_MATCH_BREAK;
+  static inline const StringFilterPolicy SFP_ATRACE_MATCH_BREAK = StringFilterPolicy::SFP_ATRACE_MATCH_BREAK;
+  static inline const StringFilterPolicy SFP_ATRACE_REPEATED_SEARCH_REDACT_GROUPS = StringFilterPolicy::SFP_ATRACE_REPEATED_SEARCH_REDACT_GROUPS;
+
+  using FieldMetadata_Bytecode =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      TraceConfig_TraceFilter>;
+
+  static constexpr FieldMetadata_Bytecode kBytecode{};
+  void set_bytecode(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_Bytecode::kFieldId, data, size);
+  }
+  void set_bytecode(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_Bytecode::kFieldId, bytes.data, bytes.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);
+  }
+
+  using FieldMetadata_BytecodeV2 =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      TraceConfig_TraceFilter>;
+
+  static constexpr FieldMetadata_BytecodeV2 kBytecodeV2{};
+  void set_bytecode_v2(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_BytecodeV2::kFieldId, data, size);
+  }
+  void set_bytecode_v2(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_BytecodeV2::kFieldId, bytes.data, bytes.size);
+  }
+  void set_bytecode_v2(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_BytecodeV2::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);
+  }
+
+  using FieldMetadata_StringFilterChain =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceConfig_TraceFilter_StringFilterChain,
+      TraceConfig_TraceFilter>;
+
+  static constexpr FieldMetadata_StringFilterChain kStringFilterChain{};
+  template <typename T = TraceConfig_TraceFilter_StringFilterChain> T* set_string_filter_chain() {
+    return BeginNestedMessage<T>(3);
+  }
+
+};
+
+class TraceConfig_TraceFilter_StringFilterChain_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TraceConfig_TraceFilter_StringFilterChain_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TraceConfig_TraceFilter_StringFilterChain_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TraceConfig_TraceFilter_StringFilterChain_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_rules() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> rules() const { return GetRepeated<::protozero::ConstBytes>(1); }
+};
+
+class TraceConfig_TraceFilter_StringFilterChain : public ::protozero::Message {
+ public:
+  using Decoder = TraceConfig_TraceFilter_StringFilterChain_Decoder;
+  enum : int32_t {
+    kRulesFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceConfig.TraceFilter.StringFilterChain"; }
+
+
+  using FieldMetadata_Rules =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceConfig_TraceFilter_StringFilterRule,
+      TraceConfig_TraceFilter_StringFilterChain>;
+
+  static constexpr FieldMetadata_Rules kRules{};
+  template <typename T = TraceConfig_TraceFilter_StringFilterRule> T* add_rules() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+class TraceConfig_TraceFilter_StringFilterRule_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TraceConfig_TraceFilter_StringFilterRule_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TraceConfig_TraceFilter_StringFilterRule_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TraceConfig_TraceFilter_StringFilterRule_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_policy() const { return at<1>().valid(); }
+  int32_t policy() const { return at<1>().as_int32(); }
+  bool has_regex_pattern() const { return at<2>().valid(); }
+  ::protozero::ConstChars regex_pattern() const { return at<2>().as_string(); }
+  bool has_atrace_payload_starts_with() const { return at<3>().valid(); }
+  ::protozero::ConstChars atrace_payload_starts_with() const { return at<3>().as_string(); }
+};
+
+class TraceConfig_TraceFilter_StringFilterRule : public ::protozero::Message {
+ public:
+  using Decoder = TraceConfig_TraceFilter_StringFilterRule_Decoder;
+  enum : int32_t {
+    kPolicyFieldNumber = 1,
+    kRegexPatternFieldNumber = 2,
+    kAtracePayloadStartsWithFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceConfig.TraceFilter.StringFilterRule"; }
+
+
+  using FieldMetadata_Policy =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      TraceConfig_TraceFilter_StringFilterPolicy,
+      TraceConfig_TraceFilter_StringFilterRule>;
+
+  static constexpr FieldMetadata_Policy kPolicy{};
+  void set_policy(TraceConfig_TraceFilter_StringFilterPolicy value) {
+    static constexpr uint32_t field_id = FieldMetadata_Policy::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_RegexPattern =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TraceConfig_TraceFilter_StringFilterRule>;
+
+  static constexpr FieldMetadata_RegexPattern kRegexPattern{};
+  void set_regex_pattern(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_RegexPattern::kFieldId, data, size);
+  }
+  void set_regex_pattern(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_RegexPattern::kFieldId, chars.data, chars.size);
+  }
+  void set_regex_pattern(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_RegexPattern::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_AtracePayloadStartsWith =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TraceConfig_TraceFilter_StringFilterRule>;
+
+  static constexpr FieldMetadata_AtracePayloadStartsWith kAtracePayloadStartsWith{};
+  void set_atrace_payload_starts_with(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_AtracePayloadStartsWith::kFieldId, data, size);
+  }
+  void set_atrace_payload_starts_with(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_AtracePayloadStartsWith::kFieldId, chars.data, chars.size);
+  }
+  void set_atrace_payload_starts_with(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_AtracePayloadStartsWith::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_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,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceConfig.IncidentReportConfig"; }
+
+
+  using FieldMetadata_DestinationPackage =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TraceConfig_IncidentReportConfig>;
+
+  static constexpr FieldMetadata_DestinationPackage kDestinationPackage{};
+  void set_destination_package(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DestinationPackage::kFieldId, data, size);
+  }
+  void set_destination_package(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_DestinationPackage::kFieldId, chars.data, chars.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>;
+
+  static constexpr FieldMetadata_DestinationClass kDestinationClass{};
+  void set_destination_class(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DestinationClass::kFieldId, data, size);
+  }
+  void set_destination_class(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_DestinationClass::kFieldId, chars.data, chars.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>;
+
+  static constexpr FieldMetadata_PrivacyLevel kPrivacyLevel{};
+  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>;
+
+  static constexpr FieldMetadata_SkipIncidentd kSkipIncidentd{};
+  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>;
+
+  static constexpr FieldMetadata_SkipDropbox kSkipDropbox{};
+  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,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceConfig.IncrementalStateConfig"; }
+
+
+  using FieldMetadata_ClearPeriodMs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TraceConfig_IncrementalStateConfig>;
+
+  static constexpr FieldMetadata_ClearPeriodMs kClearPeriodMs{};
+  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=*/5, /*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_use_clone_snapshot_if_available() const { return at<5>().valid(); }
+  bool use_clone_snapshot_if_available() const { return at<5>().as_bool(); }
+  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,
+    kUseCloneSnapshotIfAvailableFieldNumber = 5,
+    kTriggersFieldNumber = 2,
+    kTriggerTimeoutMsFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceConfig.TriggerConfig"; }
+
+  using Trigger = ::perfetto::protos::pbzero::TraceConfig_TriggerConfig_Trigger;
+
+  using TriggerMode = ::perfetto::protos::pbzero::TraceConfig_TriggerConfig_TriggerMode;
+  static inline const char* TriggerMode_Name(TriggerMode value) {
+    return ::perfetto::protos::pbzero::TraceConfig_TriggerConfig_TriggerMode_Name(value);
+  }
+  static inline const TriggerMode UNSPECIFIED = TriggerMode::UNSPECIFIED;
+  static inline const TriggerMode START_TRACING = TriggerMode::START_TRACING;
+  static inline const TriggerMode STOP_TRACING = TriggerMode::STOP_TRACING;
+  static inline const TriggerMode CLONE_SNAPSHOT = TriggerMode::CLONE_SNAPSHOT;
+
+  using FieldMetadata_TriggerMode =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      TraceConfig_TriggerConfig_TriggerMode,
+      TraceConfig_TriggerConfig>;
+
+  static constexpr FieldMetadata_TriggerMode kTriggerMode{};
+  void set_trigger_mode(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_UseCloneSnapshotIfAvailable =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TraceConfig_TriggerConfig>;
+
+  static constexpr FieldMetadata_UseCloneSnapshotIfAvailable kUseCloneSnapshotIfAvailable{};
+  void set_use_clone_snapshot_if_available(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_UseCloneSnapshotIfAvailable::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_Triggers =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceConfig_TriggerConfig_Trigger,
+      TraceConfig_TriggerConfig>;
+
+  static constexpr FieldMetadata_Triggers kTriggers{};
+  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>;
+
+  static constexpr FieldMetadata_TriggerTimeoutMs kTriggerTimeoutMs{};
+  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,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceConfig.TriggerConfig.Trigger"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TraceConfig_TriggerConfig_Trigger>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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>;
+
+  static constexpr FieldMetadata_ProducerNameRegex kProducerNameRegex{};
+  void set_producer_name_regex(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ProducerNameRegex::kFieldId, data, size);
+  }
+  void set_producer_name_regex(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ProducerNameRegex::kFieldId, chars.data, chars.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>;
+
+  static constexpr FieldMetadata_StopDelayMs kStopDelayMs{};
+  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>;
+
+  static constexpr FieldMetadata_MaxPer24H kMaxPer24H{};
+  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>;
+
+  static constexpr FieldMetadata_SkipProbability kSkipProbability{};
+  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=*/2, /*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(); }
+  bool has_max_tracing_buffer_size_kb() const { return at<2>().valid(); }
+  uint32_t max_tracing_buffer_size_kb() const { return at<2>().as_uint32(); }
+};
+
+class TraceConfig_GuardrailOverrides : public ::protozero::Message {
+ public:
+  using Decoder = TraceConfig_GuardrailOverrides_Decoder;
+  enum : int32_t {
+    kMaxUploadPerDayBytesFieldNumber = 1,
+    kMaxTracingBufferSizeKbFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceConfig.GuardrailOverrides"; }
+
+
+  using FieldMetadata_MaxUploadPerDayBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceConfig_GuardrailOverrides>;
+
+  static constexpr FieldMetadata_MaxUploadPerDayBytes kMaxUploadPerDayBytes{};
+  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);
+  }
+
+  using FieldMetadata_MaxTracingBufferSizeKb =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TraceConfig_GuardrailOverrides>;
+
+  static constexpr FieldMetadata_MaxTracingBufferSizeKb kMaxTracingBufferSizeKb{};
+  void set_max_tracing_buffer_size_kb(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MaxTracingBufferSizeKb::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_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,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceConfig.StatsdMetadata"; }
+
+
+  using FieldMetadata_TriggeringAlertId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TraceConfig_StatsdMetadata>;
+
+  static constexpr FieldMetadata_TriggeringAlertId kTriggeringAlertId{};
+  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>;
+
+  static constexpr FieldMetadata_TriggeringConfigUid kTriggeringConfigUid{};
+  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>;
+
+  static constexpr FieldMetadata_TriggeringConfigId kTriggeringConfigId{};
+  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>;
+
+  static constexpr FieldMetadata_TriggeringSubscriptionId kTriggeringSubscriptionId{};
+  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,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceConfig.ProducerConfig"; }
+
+
+  using FieldMetadata_ProducerName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TraceConfig_ProducerConfig>;
+
+  static constexpr FieldMetadata_ProducerName kProducerName{};
+  void set_producer_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ProducerName::kFieldId, data, size);
+  }
+  void set_producer_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ProducerName::kFieldId, chars.data, chars.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>;
+
+  static constexpr FieldMetadata_ShmSizeKb kShmSizeKb{};
+  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>;
+
+  static constexpr FieldMetadata_PageSizeKb kPageSizeKb{};
+  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=*/8, /*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(); }
+  bool has_disable_chunk_usage_histograms() const { return at<8>().valid(); }
+  bool disable_chunk_usage_histograms() const { return at<8>().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,
+    kDisableChunkUsageHistogramsFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceConfig.BuiltinDataSource"; }
+
+
+  using FieldMetadata_DisableClockSnapshotting =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TraceConfig_BuiltinDataSource>;
+
+  static constexpr FieldMetadata_DisableClockSnapshotting kDisableClockSnapshotting{};
+  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>;
+
+  static constexpr FieldMetadata_DisableTraceConfig kDisableTraceConfig{};
+  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>;
+
+  static constexpr FieldMetadata_DisableSystemInfo kDisableSystemInfo{};
+  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>;
+
+  static constexpr FieldMetadata_DisableServiceEvents kDisableServiceEvents{};
+  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,
+      BuiltinClock,
+      TraceConfig_BuiltinDataSource>;
+
+  static constexpr FieldMetadata_PrimaryTraceClock kPrimaryTraceClock{};
+  void set_primary_trace_clock(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>;
+
+  static constexpr FieldMetadata_SnapshotIntervalMs kSnapshotIntervalMs{};
+  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>;
+
+  static constexpr FieldMetadata_PreferSuspendClockForSnapshot kPreferSuspendClockForSnapshot{};
+  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);
+  }
+
+  using FieldMetadata_DisableChunkUsageHistograms =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TraceConfig_BuiltinDataSource>;
+
+  static constexpr FieldMetadata_DisableChunkUsageHistograms kDisableChunkUsageHistograms{};
+  void set_disable_chunk_usage_histograms(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DisableChunkUsageHistograms::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,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceConfig.DataSource"; }
+
+
+  using FieldMetadata_Config =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DataSourceConfig,
+      TraceConfig_DataSource>;
+
+  static constexpr FieldMetadata_Config kConfig{};
+  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>;
+
+  static constexpr FieldMetadata_ProducerNameFilter kProducerNameFilter{};
+  void add_producer_name_filter(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ProducerNameFilter::kFieldId, data, size);
+  }
+  void add_producer_name_filter(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ProducerNameFilter::kFieldId, chars.data, chars.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>;
+
+  static constexpr FieldMetadata_ProducerNameRegexFilter kProducerNameRegexFilter{};
+  void add_producer_name_regex_filter(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ProducerNameRegexFilter::kFieldId, data, size);
+  }
+  void add_producer_name_regex_filter(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ProducerNameRegexFilter::kFieldId, chars.data, chars.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=*/6, /*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(); }
+  bool has_transfer_on_clone() const { return at<5>().valid(); }
+  bool transfer_on_clone() const { return at<5>().as_bool(); }
+  bool has_clear_before_clone() const { return at<6>().valid(); }
+  bool clear_before_clone() const { return at<6>().as_bool(); }
+};
+
+class TraceConfig_BufferConfig : public ::protozero::Message {
+ public:
+  using Decoder = TraceConfig_BufferConfig_Decoder;
+  enum : int32_t {
+    kSizeKbFieldNumber = 1,
+    kFillPolicyFieldNumber = 4,
+    kTransferOnCloneFieldNumber = 5,
+    kClearBeforeCloneFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceConfig.BufferConfig"; }
+
+
+  using FillPolicy = ::perfetto::protos::pbzero::TraceConfig_BufferConfig_FillPolicy;
+  static inline const char* FillPolicy_Name(FillPolicy value) {
+    return ::perfetto::protos::pbzero::TraceConfig_BufferConfig_FillPolicy_Name(value);
+  }
+  static inline const FillPolicy UNSPECIFIED = FillPolicy::UNSPECIFIED;
+  static inline const FillPolicy RING_BUFFER = FillPolicy::RING_BUFFER;
+  static inline const FillPolicy DISCARD = FillPolicy::DISCARD;
+
+  using FieldMetadata_SizeKb =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TraceConfig_BufferConfig>;
+
+  static constexpr FieldMetadata_SizeKb kSizeKb{};
+  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,
+      TraceConfig_BufferConfig_FillPolicy,
+      TraceConfig_BufferConfig>;
+
+  static constexpr FieldMetadata_FillPolicy kFillPolicy{};
+  void set_fill_policy(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);
+  }
+
+  using FieldMetadata_TransferOnClone =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TraceConfig_BufferConfig>;
+
+  static constexpr FieldMetadata_TransferOnClone kTransferOnClone{};
+  void set_transfer_on_clone(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_TransferOnClone::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_ClearBeforeClone =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TraceConfig_BufferConfig>;
+
+  static constexpr FieldMetadata_ClearBeforeClone kClearBeforeClone{};
+  void set_clear_before_clone(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ClearBeforeClone::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/clock_snapshot.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_CLOCK_SNAPSHOT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_CLOCK_SNAPSHOT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class ClockSnapshot_Clock;
+enum BuiltinClock : int32_t;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_ClockSnapshot_Clock {
+enum BuiltinClocks : int32_t {
+  UNKNOWN = 0,
+  REALTIME = 1,
+  REALTIME_COARSE = 2,
+  MONOTONIC = 3,
+  MONOTONIC_COARSE = 4,
+  MONOTONIC_RAW = 5,
+  BOOTTIME = 6,
+  BUILTIN_CLOCK_MAX_ID = 63,
+};
+} // namespace perfetto_pbzero_enum_ClockSnapshot_Clock
+using ClockSnapshot_Clock_BuiltinClocks = perfetto_pbzero_enum_ClockSnapshot_Clock::BuiltinClocks;
+
+
+constexpr ClockSnapshot_Clock_BuiltinClocks ClockSnapshot_Clock_BuiltinClocks_MIN = ClockSnapshot_Clock_BuiltinClocks::UNKNOWN;
+constexpr ClockSnapshot_Clock_BuiltinClocks ClockSnapshot_Clock_BuiltinClocks_MAX = ClockSnapshot_Clock_BuiltinClocks::BUILTIN_CLOCK_MAX_ID;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ClockSnapshot_Clock_BuiltinClocks_Name(::perfetto::protos::pbzero::ClockSnapshot_Clock_BuiltinClocks value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ClockSnapshot_Clock_BuiltinClocks::UNKNOWN:
+    return "UNKNOWN";
+
+  case ::perfetto::protos::pbzero::ClockSnapshot_Clock_BuiltinClocks::REALTIME:
+    return "REALTIME";
+
+  case ::perfetto::protos::pbzero::ClockSnapshot_Clock_BuiltinClocks::REALTIME_COARSE:
+    return "REALTIME_COARSE";
+
+  case ::perfetto::protos::pbzero::ClockSnapshot_Clock_BuiltinClocks::MONOTONIC:
+    return "MONOTONIC";
+
+  case ::perfetto::protos::pbzero::ClockSnapshot_Clock_BuiltinClocks::MONOTONIC_COARSE:
+    return "MONOTONIC_COARSE";
+
+  case ::perfetto::protos::pbzero::ClockSnapshot_Clock_BuiltinClocks::MONOTONIC_RAW:
+    return "MONOTONIC_RAW";
+
+  case ::perfetto::protos::pbzero::ClockSnapshot_Clock_BuiltinClocks::BOOTTIME:
+    return "BOOTTIME";
+
+  case ::perfetto::protos::pbzero::ClockSnapshot_Clock_BuiltinClocks::BUILTIN_CLOCK_MAX_ID:
+    return "BUILTIN_CLOCK_MAX_ID";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class ClockSnapshot_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ClockSnapshot_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ClockSnapshot_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ClockSnapshot_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_clocks() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> clocks() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_primary_trace_clock() const { return at<2>().valid(); }
+  int32_t primary_trace_clock() const { return at<2>().as_int32(); }
+};
+
+class ClockSnapshot : public ::protozero::Message {
+ public:
+  using Decoder = ClockSnapshot_Decoder;
+  enum : int32_t {
+    kClocksFieldNumber = 1,
+    kPrimaryTraceClockFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ClockSnapshot"; }
+
+  using Clock = ::perfetto::protos::pbzero::ClockSnapshot_Clock;
+
+  using FieldMetadata_Clocks =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ClockSnapshot_Clock,
+      ClockSnapshot>;
+
+  static constexpr FieldMetadata_Clocks kClocks{};
+  template <typename T = ClockSnapshot_Clock> T* add_clocks() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_PrimaryTraceClock =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      BuiltinClock,
+      ClockSnapshot>;
+
+  static constexpr FieldMetadata_PrimaryTraceClock kPrimaryTraceClock{};
+  void set_primary_trace_clock(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);
+  }
+};
+
+class ClockSnapshot_Clock_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ClockSnapshot_Clock_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ClockSnapshot_Clock_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ClockSnapshot_Clock_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_clock_id() const { return at<1>().valid(); }
+  uint32_t clock_id() const { return at<1>().as_uint32(); }
+  bool has_timestamp() const { return at<2>().valid(); }
+  uint64_t timestamp() const { return at<2>().as_uint64(); }
+  bool has_is_incremental() const { return at<3>().valid(); }
+  bool is_incremental() const { return at<3>().as_bool(); }
+  bool has_unit_multiplier_ns() const { return at<4>().valid(); }
+  uint64_t unit_multiplier_ns() const { return at<4>().as_uint64(); }
+};
+
+class ClockSnapshot_Clock : public ::protozero::Message {
+ public:
+  using Decoder = ClockSnapshot_Clock_Decoder;
+  enum : int32_t {
+    kClockIdFieldNumber = 1,
+    kTimestampFieldNumber = 2,
+    kIsIncrementalFieldNumber = 3,
+    kUnitMultiplierNsFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ClockSnapshot.Clock"; }
+
+
+  using BuiltinClocks = ::perfetto::protos::pbzero::ClockSnapshot_Clock_BuiltinClocks;
+  static inline const char* BuiltinClocks_Name(BuiltinClocks value) {
+    return ::perfetto::protos::pbzero::ClockSnapshot_Clock_BuiltinClocks_Name(value);
+  }
+  static inline const BuiltinClocks UNKNOWN = BuiltinClocks::UNKNOWN;
+  static inline const BuiltinClocks REALTIME = BuiltinClocks::REALTIME;
+  static inline const BuiltinClocks REALTIME_COARSE = BuiltinClocks::REALTIME_COARSE;
+  static inline const BuiltinClocks MONOTONIC = BuiltinClocks::MONOTONIC;
+  static inline const BuiltinClocks MONOTONIC_COARSE = BuiltinClocks::MONOTONIC_COARSE;
+  static inline const BuiltinClocks MONOTONIC_RAW = BuiltinClocks::MONOTONIC_RAW;
+  static inline const BuiltinClocks BOOTTIME = BuiltinClocks::BOOTTIME;
+  static inline const BuiltinClocks BUILTIN_CLOCK_MAX_ID = BuiltinClocks::BUILTIN_CLOCK_MAX_ID;
+
+  using FieldMetadata_ClockId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ClockSnapshot_Clock>;
+
+  static constexpr FieldMetadata_ClockId kClockId{};
+  void set_clock_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ClockId::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_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ClockSnapshot_Clock>;
+
+  static constexpr FieldMetadata_Timestamp kTimestamp{};
+  void set_timestamp(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timestamp::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_IsIncremental =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ClockSnapshot_Clock>;
+
+  static constexpr FieldMetadata_IsIncremental kIsIncremental{};
+  void set_is_incremental(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsIncremental::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_UnitMultiplierNs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ClockSnapshot_Clock>;
+
+  static constexpr FieldMetadata_UnitMultiplierNs kUnitMultiplierNs{};
+  void set_unit_multiplier_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UnitMultiplierNs::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/trace_uuid.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACE_UUID_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACE_UUID_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class TraceUuid_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TraceUuid_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TraceUuid_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TraceUuid_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_msb() const { return at<1>().valid(); }
+  int64_t msb() const { return at<1>().as_int64(); }
+  bool has_lsb() const { return at<2>().valid(); }
+  int64_t lsb() const { return at<2>().as_int64(); }
+};
+
+class TraceUuid : public ::protozero::Message {
+ public:
+  using Decoder = TraceUuid_Decoder;
+  enum : int32_t {
+    kMsbFieldNumber = 1,
+    kLsbFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceUuid"; }
+
+
+  using FieldMetadata_Msb =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TraceUuid>;
+
+  static constexpr FieldMetadata_Msb kMsb{};
+  void set_msb(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Msb::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_Lsb =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TraceUuid>;
+
+  static constexpr FieldMetadata_Lsb kLsb{};
+  void set_lsb(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lsb::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/trigger.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRIGGER_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRIGGER_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class Trigger_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Trigger_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Trigger_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Trigger_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_trigger_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars trigger_name() const { return at<1>().as_string(); }
+  bool has_producer_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars producer_name() const { return at<2>().as_string(); }
+  bool has_trusted_producer_uid() const { return at<3>().valid(); }
+  int32_t trusted_producer_uid() const { return at<3>().as_int32(); }
+};
+
+class Trigger : public ::protozero::Message {
+ public:
+  using Decoder = Trigger_Decoder;
+  enum : int32_t {
+    kTriggerNameFieldNumber = 1,
+    kProducerNameFieldNumber = 2,
+    kTrustedProducerUidFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Trigger"; }
+
+
+  using FieldMetadata_TriggerName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      Trigger>;
+
+  static constexpr FieldMetadata_TriggerName kTriggerName{};
+  void set_trigger_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TriggerName::kFieldId, data, size);
+  }
+  void set_trigger_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_TriggerName::kFieldId, chars.data, chars.size);
+  }
+  void set_trigger_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_TriggerName::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_ProducerName =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      Trigger>;
+
+  static constexpr FieldMetadata_ProducerName kProducerName{};
+  void set_producer_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ProducerName::kFieldId, data, size);
+  }
+  void set_producer_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ProducerName::kFieldId, chars.data, chars.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_TrustedProducerUid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Trigger>;
+
+  static constexpr FieldMetadata_TrustedProducerUid kTrustedProducerUid{};
+  void set_trusted_producer_uid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TrustedProducerUid::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/system_info.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_SYSTEM_INFO_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_SYSTEM_INFO_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class Utsname;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class SystemInfo_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SystemInfo_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SystemInfo_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SystemInfo_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_utsname() const { return at<1>().valid(); }
+  ::protozero::ConstBytes utsname() const { return at<1>().as_bytes(); }
+  bool has_android_build_fingerprint() const { return at<2>().valid(); }
+  ::protozero::ConstChars android_build_fingerprint() const { return at<2>().as_string(); }
+  bool has_tracing_service_version() const { return at<4>().valid(); }
+  ::protozero::ConstChars tracing_service_version() const { return at<4>().as_string(); }
+  bool has_android_sdk_version() const { return at<5>().valid(); }
+  uint64_t android_sdk_version() const { return at<5>().as_uint64(); }
+  bool has_page_size() const { return at<6>().valid(); }
+  uint32_t page_size() const { return at<6>().as_uint32(); }
+  bool has_num_cpus() const { return at<8>().valid(); }
+  uint32_t num_cpus() const { return at<8>().as_uint32(); }
+  bool has_timezone_off_mins() const { return at<7>().valid(); }
+  int32_t timezone_off_mins() const { return at<7>().as_int32(); }
+  bool has_hz() const { return at<3>().valid(); }
+  int64_t hz() const { return at<3>().as_int64(); }
+};
+
+class SystemInfo : public ::protozero::Message {
+ public:
+  using Decoder = SystemInfo_Decoder;
+  enum : int32_t {
+    kUtsnameFieldNumber = 1,
+    kAndroidBuildFingerprintFieldNumber = 2,
+    kTracingServiceVersionFieldNumber = 4,
+    kAndroidSdkVersionFieldNumber = 5,
+    kPageSizeFieldNumber = 6,
+    kNumCpusFieldNumber = 8,
+    kTimezoneOffMinsFieldNumber = 7,
+    kHzFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SystemInfo"; }
+
+
+  using FieldMetadata_Utsname =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Utsname,
+      SystemInfo>;
+
+  static constexpr FieldMetadata_Utsname kUtsname{};
+  template <typename T = Utsname> T* set_utsname() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_AndroidBuildFingerprint =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SystemInfo>;
+
+  static constexpr FieldMetadata_AndroidBuildFingerprint kAndroidBuildFingerprint{};
+  void set_android_build_fingerprint(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_AndroidBuildFingerprint::kFieldId, data, size);
+  }
+  void set_android_build_fingerprint(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_AndroidBuildFingerprint::kFieldId, chars.data, chars.size);
+  }
+  void set_android_build_fingerprint(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_AndroidBuildFingerprint::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_TracingServiceVersion =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SystemInfo>;
+
+  static constexpr FieldMetadata_TracingServiceVersion kTracingServiceVersion{};
+  void set_tracing_service_version(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TracingServiceVersion::kFieldId, data, size);
+  }
+  void set_tracing_service_version(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_TracingServiceVersion::kFieldId, chars.data, chars.size);
+  }
+  void set_tracing_service_version(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_TracingServiceVersion::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_AndroidSdkVersion =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SystemInfo>;
+
+  static constexpr FieldMetadata_AndroidSdkVersion kAndroidSdkVersion{};
+  void set_android_sdk_version(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AndroidSdkVersion::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_PageSize =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SystemInfo>;
+
+  static constexpr FieldMetadata_PageSize kPageSize{};
+  void set_page_size(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PageSize::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_NumCpus =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SystemInfo>;
+
+  static constexpr FieldMetadata_NumCpus kNumCpus{};
+  void set_num_cpus(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NumCpus::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_TimezoneOffMins =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SystemInfo>;
+
+  static constexpr FieldMetadata_TimezoneOffMins kTimezoneOffMins{};
+  void set_timezone_off_mins(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimezoneOffMins::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_Hz =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      SystemInfo>;
+
+  static constexpr FieldMetadata_Hz kHz{};
+  void set_hz(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Hz::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 Utsname_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Utsname_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Utsname_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Utsname_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_sysname() const { return at<1>().valid(); }
+  ::protozero::ConstChars sysname() const { return at<1>().as_string(); }
+  bool has_version() const { return at<2>().valid(); }
+  ::protozero::ConstChars version() const { return at<2>().as_string(); }
+  bool has_release() const { return at<3>().valid(); }
+  ::protozero::ConstChars release() const { return at<3>().as_string(); }
+  bool has_machine() const { return at<4>().valid(); }
+  ::protozero::ConstChars machine() const { return at<4>().as_string(); }
+};
+
+class Utsname : public ::protozero::Message {
+ public:
+  using Decoder = Utsname_Decoder;
+  enum : int32_t {
+    kSysnameFieldNumber = 1,
+    kVersionFieldNumber = 2,
+    kReleaseFieldNumber = 3,
+    kMachineFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Utsname"; }
+
+
+  using FieldMetadata_Sysname =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      Utsname>;
+
+  static constexpr FieldMetadata_Sysname kSysname{};
+  void set_sysname(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Sysname::kFieldId, data, size);
+  }
+  void set_sysname(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Sysname::kFieldId, chars.data, chars.size);
+  }
+  void set_sysname(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sysname::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_Version =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      Utsname>;
+
+  static constexpr FieldMetadata_Version kVersion{};
+  void set_version(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Version::kFieldId, data, size);
+  }
+  void set_version(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Version::kFieldId, chars.data, chars.size);
+  }
+  void set_version(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Version::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_Release =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      Utsname>;
+
+  static constexpr FieldMetadata_Release kRelease{};
+  void set_release(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Release::kFieldId, data, size);
+  }
+  void set_release(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Release::kFieldId, chars.data, chars.size);
+  }
+  void set_release(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Release::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_Machine =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      Utsname>;
+
+  static constexpr FieldMetadata_Machine kMachine{};
+  void set_machine(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Machine::kFieldId, data, size);
+  }
+  void set_machine(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Machine::kFieldId, chars.data, chars.size);
+  }
+  void set_machine(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Machine::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/android/graphics/point.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_GRAPHICS_POINT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_GRAPHICS_POINT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class PointProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  PointProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PointProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PointProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_x() const { return at<1>().valid(); }
+  int32_t x() const { return at<1>().as_int32(); }
+  bool has_y() const { return at<2>().valid(); }
+  int32_t y() const { return at<2>().as_int32(); }
+};
+
+class PointProto : public ::protozero::Message {
+ public:
+  using Decoder = PointProto_Decoder;
+  enum : int32_t {
+    kXFieldNumber = 1,
+    kYFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PointProto"; }
+
+
+  using FieldMetadata_X =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      PointProto>;
+
+  static constexpr FieldMetadata_X kX{};
+  void set_x(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_X::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_Y =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      PointProto>;
+
+  static constexpr FieldMetadata_Y kY{};
+  void set_y(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Y::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/android/graphics/rect.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_GRAPHICS_RECT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_GRAPHICS_RECT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class RectProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  RectProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit RectProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit RectProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_left() const { return at<1>().valid(); }
+  int32_t left() const { return at<1>().as_int32(); }
+  bool has_top() const { return at<2>().valid(); }
+  int32_t top() const { return at<2>().as_int32(); }
+  bool has_right() const { return at<3>().valid(); }
+  int32_t right() const { return at<3>().as_int32(); }
+  bool has_bottom() const { return at<4>().valid(); }
+  int32_t bottom() const { return at<4>().as_int32(); }
+};
+
+class RectProto : public ::protozero::Message {
+ public:
+  using Decoder = RectProto_Decoder;
+  enum : int32_t {
+    kLeftFieldNumber = 1,
+    kTopFieldNumber = 2,
+    kRightFieldNumber = 3,
+    kBottomFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.RectProto"; }
+
+
+  using FieldMetadata_Left =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      RectProto>;
+
+  static constexpr FieldMetadata_Left kLeft{};
+  void set_left(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Left::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_Top =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      RectProto>;
+
+  static constexpr FieldMetadata_Top kTop{};
+  void set_top(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Top::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_Right =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      RectProto>;
+
+  static constexpr FieldMetadata_Right kRight{};
+  void set_right(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Right::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_Bottom =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      RectProto>;
+
+  static constexpr FieldMetadata_Bottom kBottom{};
+  void set_bottom(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Bottom::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/android/winscope_extensions.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_WINSCOPE_EXTENSIONS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_WINSCOPE_EXTENSIONS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class WinscopeExtensions_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  WinscopeExtensions_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit WinscopeExtensions_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit WinscopeExtensions_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+};
+
+class WinscopeExtensions : public ::protozero::Message {
+ public:
+  using Decoder = WinscopeExtensions_Decoder;
+  static constexpr const char* GetName() { return ".perfetto.protos.WinscopeExtensions"; }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/android/protolog.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_PROTOLOG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_PROTOLOG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class ProtoLogViewerConfig_Group;
+class ProtoLogViewerConfig_MessageData;
+enum ProtoLogLevel : int32_t;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class ProtoLogViewerConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ProtoLogViewerConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProtoLogViewerConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProtoLogViewerConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_messages() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> messages() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_groups() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> groups() const { return GetRepeated<::protozero::ConstBytes>(2); }
+};
+
+class ProtoLogViewerConfig : public ::protozero::Message {
+ public:
+  using Decoder = ProtoLogViewerConfig_Decoder;
+  enum : int32_t {
+    kMessagesFieldNumber = 1,
+    kGroupsFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProtoLogViewerConfig"; }
+
+  using MessageData = ::perfetto::protos::pbzero::ProtoLogViewerConfig_MessageData;
+  using Group = ::perfetto::protos::pbzero::ProtoLogViewerConfig_Group;
+
+  using FieldMetadata_Messages =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProtoLogViewerConfig_MessageData,
+      ProtoLogViewerConfig>;
+
+  static constexpr FieldMetadata_Messages kMessages{};
+  template <typename T = ProtoLogViewerConfig_MessageData> T* add_messages() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_Groups =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProtoLogViewerConfig_Group,
+      ProtoLogViewerConfig>;
+
+  static constexpr FieldMetadata_Groups kGroups{};
+  template <typename T = ProtoLogViewerConfig_Group> T* add_groups() {
+    return BeginNestedMessage<T>(2);
+  }
+
+};
+
+class ProtoLogViewerConfig_Group_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ProtoLogViewerConfig_Group_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProtoLogViewerConfig_Group_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProtoLogViewerConfig_Group_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  uint32_t id() const { return at<1>().as_uint32(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+  bool has_tag() const { return at<3>().valid(); }
+  ::protozero::ConstChars tag() const { return at<3>().as_string(); }
+};
+
+class ProtoLogViewerConfig_Group : public ::protozero::Message {
+ public:
+  using Decoder = ProtoLogViewerConfig_Group_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kNameFieldNumber = 2,
+    kTagFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProtoLogViewerConfig.Group"; }
+
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ProtoLogViewerConfig_Group>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ProtoLogViewerConfig_Group>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Tag =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ProtoLogViewerConfig_Group>;
+
+  static constexpr FieldMetadata_Tag kTag{};
+  void set_tag(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Tag::kFieldId, data, size);
+  }
+  void set_tag(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Tag::kFieldId, chars.data, chars.size);
+  }
+  void set_tag(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tag::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 ProtoLogViewerConfig_MessageData_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ProtoLogViewerConfig_MessageData_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProtoLogViewerConfig_MessageData_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProtoLogViewerConfig_MessageData_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_message_id() const { return at<1>().valid(); }
+  uint64_t message_id() const { return at<1>().as_uint64(); }
+  bool has_message() const { return at<2>().valid(); }
+  ::protozero::ConstChars message() const { return at<2>().as_string(); }
+  bool has_level() const { return at<3>().valid(); }
+  int32_t level() const { return at<3>().as_int32(); }
+  bool has_group_id() const { return at<4>().valid(); }
+  uint32_t group_id() const { return at<4>().as_uint32(); }
+};
+
+class ProtoLogViewerConfig_MessageData : public ::protozero::Message {
+ public:
+  using Decoder = ProtoLogViewerConfig_MessageData_Decoder;
+  enum : int32_t {
+    kMessageIdFieldNumber = 1,
+    kMessageFieldNumber = 2,
+    kLevelFieldNumber = 3,
+    kGroupIdFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProtoLogViewerConfig.MessageData"; }
+
+
+  using FieldMetadata_MessageId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64,
+      uint64_t,
+      ProtoLogViewerConfig_MessageData>;
+
+  static constexpr FieldMetadata_MessageId kMessageId{};
+  void set_message_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MessageId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Message =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ProtoLogViewerConfig_MessageData>;
+
+  static constexpr FieldMetadata_Message kMessage{};
+  void set_message(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Message::kFieldId, data, size);
+  }
+  void set_message(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Message::kFieldId, chars.data, chars.size);
+  }
+  void set_message(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Message::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_Level =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ProtoLogLevel,
+      ProtoLogViewerConfig_MessageData>;
+
+  static constexpr FieldMetadata_Level kLevel{};
+  void set_level(ProtoLogLevel value) {
+    static constexpr uint32_t field_id = FieldMetadata_Level::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_GroupId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ProtoLogViewerConfig_MessageData>;
+
+  static constexpr FieldMetadata_GroupId kGroupId{};
+  void set_group_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GroupId::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 ProtoLogMessage_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ProtoLogMessage_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProtoLogMessage_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProtoLogMessage_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_message_id() const { return at<1>().valid(); }
+  uint64_t message_id() const { return at<1>().as_uint64(); }
+  bool has_str_param_iids() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint32_t> str_param_iids() const { return GetRepeated<uint32_t>(2); }
+  bool has_sint64_params() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<int64_t> sint64_params() const { return GetRepeated<int64_t>(3); }
+  bool has_double_params() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<double> double_params() const { return GetRepeated<double>(4); }
+  bool has_boolean_params() const { return at<5>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> boolean_params() const { return GetRepeated<int32_t>(5); }
+  bool has_stacktrace_iid() const { return at<6>().valid(); }
+  uint32_t stacktrace_iid() const { return at<6>().as_uint32(); }
+};
+
+class ProtoLogMessage : public ::protozero::Message {
+ public:
+  using Decoder = ProtoLogMessage_Decoder;
+  enum : int32_t {
+    kMessageIdFieldNumber = 1,
+    kStrParamIidsFieldNumber = 2,
+    kSint64ParamsFieldNumber = 3,
+    kDoubleParamsFieldNumber = 4,
+    kBooleanParamsFieldNumber = 5,
+    kStacktraceIidFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProtoLogMessage"; }
+
+
+  using FieldMetadata_MessageId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64,
+      uint64_t,
+      ProtoLogMessage>;
+
+  static constexpr FieldMetadata_MessageId kMessageId{};
+  void set_message_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MessageId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StrParamIids =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ProtoLogMessage>;
+
+  static constexpr FieldMetadata_StrParamIids kStrParamIids{};
+  void add_str_param_iids(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StrParamIids::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_Sint64Params =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kSint64,
+      int64_t,
+      ProtoLogMessage>;
+
+  static constexpr FieldMetadata_Sint64Params kSint64Params{};
+  void add_sint64_params(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sint64Params::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kSint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DoubleParams =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      ProtoLogMessage>;
+
+  static constexpr FieldMetadata_DoubleParams kDoubleParams{};
+  void add_double_params(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_DoubleParams::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);
+  }
+
+  using FieldMetadata_BooleanParams =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ProtoLogMessage>;
+
+  static constexpr FieldMetadata_BooleanParams kBooleanParams{};
+  void add_boolean_params(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BooleanParams::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_StacktraceIid =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ProtoLogMessage>;
+
+  static constexpr FieldMetadata_StacktraceIid kStacktraceIid{};
+  void set_stacktrace_iid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StacktraceIid::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/android/shell_transition.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_SHELL_TRANSITION_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_SHELL_TRANSITION_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class ShellHandlerMapping;
+class ShellTransition_Target;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class ShellHandlerMapping_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ShellHandlerMapping_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ShellHandlerMapping_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ShellHandlerMapping_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  int32_t id() const { return at<1>().as_int32(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+};
+
+class ShellHandlerMapping : public ::protozero::Message {
+ public:
+  using Decoder = ShellHandlerMapping_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kNameFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ShellHandlerMapping"; }
+
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ShellHandlerMapping>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ShellHandlerMapping>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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);
+  }
+};
+
+class ShellHandlerMappings_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ShellHandlerMappings_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ShellHandlerMappings_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ShellHandlerMappings_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_mapping() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> mapping() const { return GetRepeated<::protozero::ConstBytes>(1); }
+};
+
+class ShellHandlerMappings : public ::protozero::Message {
+ public:
+  using Decoder = ShellHandlerMappings_Decoder;
+  enum : int32_t {
+    kMappingFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ShellHandlerMappings"; }
+
+
+  using FieldMetadata_Mapping =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ShellHandlerMapping,
+      ShellHandlerMappings>;
+
+  static constexpr FieldMetadata_Mapping kMapping{};
+  template <typename T = ShellHandlerMapping> T* add_mapping() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+class ShellTransition_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/17, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ShellTransition_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ShellTransition_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ShellTransition_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  int32_t id() const { return at<1>().as_int32(); }
+  bool has_create_time_ns() const { return at<2>().valid(); }
+  int64_t create_time_ns() const { return at<2>().as_int64(); }
+  bool has_send_time_ns() const { return at<3>().valid(); }
+  int64_t send_time_ns() const { return at<3>().as_int64(); }
+  bool has_dispatch_time_ns() const { return at<4>().valid(); }
+  int64_t dispatch_time_ns() const { return at<4>().as_int64(); }
+  bool has_merge_time_ns() const { return at<5>().valid(); }
+  int64_t merge_time_ns() const { return at<5>().as_int64(); }
+  bool has_merge_request_time_ns() const { return at<6>().valid(); }
+  int64_t merge_request_time_ns() const { return at<6>().as_int64(); }
+  bool has_shell_abort_time_ns() const { return at<7>().valid(); }
+  int64_t shell_abort_time_ns() const { return at<7>().as_int64(); }
+  bool has_wm_abort_time_ns() const { return at<8>().valid(); }
+  int64_t wm_abort_time_ns() const { return at<8>().as_int64(); }
+  bool has_finish_time_ns() const { return at<9>().valid(); }
+  int64_t finish_time_ns() const { return at<9>().as_int64(); }
+  bool has_start_transaction_id() const { return at<10>().valid(); }
+  uint64_t start_transaction_id() const { return at<10>().as_uint64(); }
+  bool has_finish_transaction_id() const { return at<11>().valid(); }
+  uint64_t finish_transaction_id() const { return at<11>().as_uint64(); }
+  bool has_handler() const { return at<12>().valid(); }
+  int32_t handler() const { return at<12>().as_int32(); }
+  bool has_type() const { return at<13>().valid(); }
+  int32_t type() const { return at<13>().as_int32(); }
+  bool has_targets() const { return at<14>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> targets() const { return GetRepeated<::protozero::ConstBytes>(14); }
+  bool has_merge_target() const { return at<15>().valid(); }
+  int32_t merge_target() const { return at<15>().as_int32(); }
+  bool has_flags() const { return at<16>().valid(); }
+  int32_t flags() const { return at<16>().as_int32(); }
+  bool has_starting_window_remove_time_ns() const { return at<17>().valid(); }
+  int64_t starting_window_remove_time_ns() const { return at<17>().as_int64(); }
+};
+
+class ShellTransition : public ::protozero::Message {
+ public:
+  using Decoder = ShellTransition_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kCreateTimeNsFieldNumber = 2,
+    kSendTimeNsFieldNumber = 3,
+    kDispatchTimeNsFieldNumber = 4,
+    kMergeTimeNsFieldNumber = 5,
+    kMergeRequestTimeNsFieldNumber = 6,
+    kShellAbortTimeNsFieldNumber = 7,
+    kWmAbortTimeNsFieldNumber = 8,
+    kFinishTimeNsFieldNumber = 9,
+    kStartTransactionIdFieldNumber = 10,
+    kFinishTransactionIdFieldNumber = 11,
+    kHandlerFieldNumber = 12,
+    kTypeFieldNumber = 13,
+    kTargetsFieldNumber = 14,
+    kMergeTargetFieldNumber = 15,
+    kFlagsFieldNumber = 16,
+    kStartingWindowRemoveTimeNsFieldNumber = 17,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ShellTransition"; }
+
+  using Target = ::perfetto::protos::pbzero::ShellTransition_Target;
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ShellTransition>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::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_CreateTimeNs =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ShellTransition>;
+
+  static constexpr FieldMetadata_CreateTimeNs kCreateTimeNs{};
+  void set_create_time_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CreateTimeNs::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_SendTimeNs =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ShellTransition>;
+
+  static constexpr FieldMetadata_SendTimeNs kSendTimeNs{};
+  void set_send_time_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SendTimeNs::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_DispatchTimeNs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ShellTransition>;
+
+  static constexpr FieldMetadata_DispatchTimeNs kDispatchTimeNs{};
+  void set_dispatch_time_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DispatchTimeNs::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_MergeTimeNs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ShellTransition>;
+
+  static constexpr FieldMetadata_MergeTimeNs kMergeTimeNs{};
+  void set_merge_time_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MergeTimeNs::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_MergeRequestTimeNs =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ShellTransition>;
+
+  static constexpr FieldMetadata_MergeRequestTimeNs kMergeRequestTimeNs{};
+  void set_merge_request_time_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MergeRequestTimeNs::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_ShellAbortTimeNs =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ShellTransition>;
+
+  static constexpr FieldMetadata_ShellAbortTimeNs kShellAbortTimeNs{};
+  void set_shell_abort_time_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ShellAbortTimeNs::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_WmAbortTimeNs =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ShellTransition>;
+
+  static constexpr FieldMetadata_WmAbortTimeNs kWmAbortTimeNs{};
+  void set_wm_abort_time_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_WmAbortTimeNs::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_FinishTimeNs =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ShellTransition>;
+
+  static constexpr FieldMetadata_FinishTimeNs kFinishTimeNs{};
+  void set_finish_time_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FinishTimeNs::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_StartTransactionId =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ShellTransition>;
+
+  static constexpr FieldMetadata_StartTransactionId kStartTransactionId{};
+  void set_start_transaction_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StartTransactionId::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_FinishTransactionId =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ShellTransition>;
+
+  static constexpr FieldMetadata_FinishTransactionId kFinishTransactionId{};
+  void set_finish_transaction_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FinishTransactionId::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_Handler =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ShellTransition>;
+
+  static constexpr FieldMetadata_Handler kHandler{};
+  void set_handler(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Handler::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_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ShellTransition>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::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_Targets =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ShellTransition_Target,
+      ShellTransition>;
+
+  static constexpr FieldMetadata_Targets kTargets{};
+  template <typename T = ShellTransition_Target> T* add_targets() {
+    return BeginNestedMessage<T>(14);
+  }
+
+
+  using FieldMetadata_MergeTarget =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ShellTransition>;
+
+  static constexpr FieldMetadata_MergeTarget kMergeTarget{};
+  void set_merge_target(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MergeTarget::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ShellTransition>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_StartingWindowRemoveTimeNs =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ShellTransition>;
+
+  static constexpr FieldMetadata_StartingWindowRemoveTimeNs kStartingWindowRemoveTimeNs{};
+  void set_starting_window_remove_time_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StartingWindowRemoveTimeNs::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 ShellTransition_Target_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ShellTransition_Target_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ShellTransition_Target_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ShellTransition_Target_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_mode() const { return at<1>().valid(); }
+  int32_t mode() const { return at<1>().as_int32(); }
+  bool has_layer_id() const { return at<2>().valid(); }
+  int32_t layer_id() const { return at<2>().as_int32(); }
+  bool has_window_id() const { return at<3>().valid(); }
+  int32_t window_id() const { return at<3>().as_int32(); }
+  bool has_flags() const { return at<4>().valid(); }
+  int32_t flags() const { return at<4>().as_int32(); }
+};
+
+class ShellTransition_Target : public ::protozero::Message {
+ public:
+  using Decoder = ShellTransition_Target_Decoder;
+  enum : int32_t {
+    kModeFieldNumber = 1,
+    kLayerIdFieldNumber = 2,
+    kWindowIdFieldNumber = 3,
+    kFlagsFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ShellTransition.Target"; }
+
+
+  using FieldMetadata_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ShellTransition_Target>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::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_LayerId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ShellTransition_Target>;
+
+  static constexpr FieldMetadata_LayerId kLayerId{};
+  void set_layer_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LayerId::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_WindowId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ShellTransition_Target>;
+
+  static constexpr FieldMetadata_WindowId kWindowId{};
+  void set_window_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_WindowId::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ShellTransition_Target>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/android/surfaceflinger_common.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_SURFACEFLINGER_COMMON_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_SURFACEFLINGER_COMMON_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class RectProto;
+class RegionProto;
+class TransformProto;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class ColorTransformProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ColorTransformProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ColorTransformProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ColorTransformProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_val() const { return at<1>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kFixed32, float> val(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kFixed32, float>(1, parse_error_ptr); }
+};
+
+class ColorTransformProto : public ::protozero::Message {
+ public:
+  using Decoder = ColorTransformProto_Decoder;
+  enum : int32_t {
+    kValFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ColorTransformProto"; }
+
+
+  using FieldMetadata_Val =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      ColorTransformProto>;
+
+  static constexpr FieldMetadata_Val kVal{};
+  void set_val(const ::protozero::PackedFixedSizeInt<float>& packed_buffer) {
+    AppendBytes(FieldMetadata_Val::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+};
+
+class BlurRegion_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/10, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlurRegion_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlurRegion_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlurRegion_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_blur_radius() const { return at<1>().valid(); }
+  uint32_t blur_radius() const { return at<1>().as_uint32(); }
+  bool has_corner_radius_tl() const { return at<2>().valid(); }
+  uint32_t corner_radius_tl() const { return at<2>().as_uint32(); }
+  bool has_corner_radius_tr() const { return at<3>().valid(); }
+  uint32_t corner_radius_tr() const { return at<3>().as_uint32(); }
+  bool has_corner_radius_bl() const { return at<4>().valid(); }
+  uint32_t corner_radius_bl() const { return at<4>().as_uint32(); }
+  bool has_corner_radius_br() const { return at<5>().valid(); }
+  float corner_radius_br() const { return at<5>().as_float(); }
+  bool has_alpha() const { return at<6>().valid(); }
+  float alpha() const { return at<6>().as_float(); }
+  bool has_left() const { return at<7>().valid(); }
+  int32_t left() const { return at<7>().as_int32(); }
+  bool has_top() const { return at<8>().valid(); }
+  int32_t top() const { return at<8>().as_int32(); }
+  bool has_right() const { return at<9>().valid(); }
+  int32_t right() const { return at<9>().as_int32(); }
+  bool has_bottom() const { return at<10>().valid(); }
+  int32_t bottom() const { return at<10>().as_int32(); }
+};
+
+class BlurRegion : public ::protozero::Message {
+ public:
+  using Decoder = BlurRegion_Decoder;
+  enum : int32_t {
+    kBlurRadiusFieldNumber = 1,
+    kCornerRadiusTlFieldNumber = 2,
+    kCornerRadiusTrFieldNumber = 3,
+    kCornerRadiusBlFieldNumber = 4,
+    kCornerRadiusBrFieldNumber = 5,
+    kAlphaFieldNumber = 6,
+    kLeftFieldNumber = 7,
+    kTopFieldNumber = 8,
+    kRightFieldNumber = 9,
+    kBottomFieldNumber = 10,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlurRegion"; }
+
+
+  using FieldMetadata_BlurRadius =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlurRegion>;
+
+  static constexpr FieldMetadata_BlurRadius kBlurRadius{};
+  void set_blur_radius(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BlurRadius::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_CornerRadiusTl =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlurRegion>;
+
+  static constexpr FieldMetadata_CornerRadiusTl kCornerRadiusTl{};
+  void set_corner_radius_tl(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CornerRadiusTl::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_CornerRadiusTr =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlurRegion>;
+
+  static constexpr FieldMetadata_CornerRadiusTr kCornerRadiusTr{};
+  void set_corner_radius_tr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CornerRadiusTr::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_CornerRadiusBl =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlurRegion>;
+
+  static constexpr FieldMetadata_CornerRadiusBl kCornerRadiusBl{};
+  void set_corner_radius_bl(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CornerRadiusBl::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_CornerRadiusBr =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      BlurRegion>;
+
+  static constexpr FieldMetadata_CornerRadiusBr kCornerRadiusBr{};
+  void set_corner_radius_br(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_CornerRadiusBr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Alpha =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      BlurRegion>;
+
+  static constexpr FieldMetadata_Alpha kAlpha{};
+  void set_alpha(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Alpha::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Left =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BlurRegion>;
+
+  static constexpr FieldMetadata_Left kLeft{};
+  void set_left(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Left::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_Top =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BlurRegion>;
+
+  static constexpr FieldMetadata_Top kTop{};
+  void set_top(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Top::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_Right =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BlurRegion>;
+
+  static constexpr FieldMetadata_Right kRight{};
+  void set_right(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Right::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_Bottom =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BlurRegion>;
+
+  static constexpr FieldMetadata_Bottom kBottom{};
+  void set_bottom(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Bottom::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);
+  }
+};
+
+class InputWindowInfoProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/17, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  InputWindowInfoProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit InputWindowInfoProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit InputWindowInfoProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_layout_params_flags() const { return at<1>().valid(); }
+  uint32_t layout_params_flags() const { return at<1>().as_uint32(); }
+  bool has_layout_params_type() const { return at<2>().valid(); }
+  int32_t layout_params_type() const { return at<2>().as_int32(); }
+  bool has_frame() const { return at<3>().valid(); }
+  ::protozero::ConstBytes frame() const { return at<3>().as_bytes(); }
+  bool has_touchable_region() const { return at<4>().valid(); }
+  ::protozero::ConstBytes touchable_region() const { return at<4>().as_bytes(); }
+  bool has_surface_inset() const { return at<5>().valid(); }
+  int32_t surface_inset() const { return at<5>().as_int32(); }
+  bool has_visible() const { return at<6>().valid(); }
+  bool visible() const { return at<6>().as_bool(); }
+  bool has_can_receive_keys() const { return at<7>().valid(); }
+  bool can_receive_keys() const { return at<7>().as_bool(); }
+  bool has_focusable() const { return at<8>().valid(); }
+  bool focusable() const { return at<8>().as_bool(); }
+  bool has_has_wallpaper() const { return at<9>().valid(); }
+  bool has_wallpaper() const { return at<9>().as_bool(); }
+  bool has_global_scale_factor() const { return at<10>().valid(); }
+  float global_scale_factor() const { return at<10>().as_float(); }
+  bool has_window_x_scale() const { return at<11>().valid(); }
+  float window_x_scale() const { return at<11>().as_float(); }
+  bool has_window_y_scale() const { return at<12>().valid(); }
+  float window_y_scale() const { return at<12>().as_float(); }
+  bool has_crop_layer_id() const { return at<13>().valid(); }
+  int32_t crop_layer_id() const { return at<13>().as_int32(); }
+  bool has_replace_touchable_region_with_crop() const { return at<14>().valid(); }
+  bool replace_touchable_region_with_crop() const { return at<14>().as_bool(); }
+  bool has_touchable_region_crop() const { return at<15>().valid(); }
+  ::protozero::ConstBytes touchable_region_crop() const { return at<15>().as_bytes(); }
+  bool has_transform() const { return at<16>().valid(); }
+  ::protozero::ConstBytes transform() const { return at<16>().as_bytes(); }
+  bool has_input_config() const { return at<17>().valid(); }
+  uint32_t input_config() const { return at<17>().as_uint32(); }
+};
+
+class InputWindowInfoProto : public ::protozero::Message {
+ public:
+  using Decoder = InputWindowInfoProto_Decoder;
+  enum : int32_t {
+    kLayoutParamsFlagsFieldNumber = 1,
+    kLayoutParamsTypeFieldNumber = 2,
+    kFrameFieldNumber = 3,
+    kTouchableRegionFieldNumber = 4,
+    kSurfaceInsetFieldNumber = 5,
+    kVisibleFieldNumber = 6,
+    kCanReceiveKeysFieldNumber = 7,
+    kFocusableFieldNumber = 8,
+    kHasWallpaperFieldNumber = 9,
+    kGlobalScaleFactorFieldNumber = 10,
+    kWindowXScaleFieldNumber = 11,
+    kWindowYScaleFieldNumber = 12,
+    kCropLayerIdFieldNumber = 13,
+    kReplaceTouchableRegionWithCropFieldNumber = 14,
+    kTouchableRegionCropFieldNumber = 15,
+    kTransformFieldNumber = 16,
+    kInputConfigFieldNumber = 17,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.InputWindowInfoProto"; }
+
+
+  using FieldMetadata_LayoutParamsFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      InputWindowInfoProto>;
+
+  static constexpr FieldMetadata_LayoutParamsFlags kLayoutParamsFlags{};
+  void set_layout_params_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LayoutParamsFlags::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_LayoutParamsType =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      InputWindowInfoProto>;
+
+  static constexpr FieldMetadata_LayoutParamsType kLayoutParamsType{};
+  void set_layout_params_type(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LayoutParamsType::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_Frame =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RectProto,
+      InputWindowInfoProto>;
+
+  static constexpr FieldMetadata_Frame kFrame{};
+  template <typename T = RectProto> T* set_frame() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_TouchableRegion =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RegionProto,
+      InputWindowInfoProto>;
+
+  static constexpr FieldMetadata_TouchableRegion kTouchableRegion{};
+  template <typename T = RegionProto> T* set_touchable_region() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_SurfaceInset =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      InputWindowInfoProto>;
+
+  static constexpr FieldMetadata_SurfaceInset kSurfaceInset{};
+  void set_surface_inset(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SurfaceInset::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_Visible =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      InputWindowInfoProto>;
+
+  static constexpr FieldMetadata_Visible kVisible{};
+  void set_visible(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_Visible::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_CanReceiveKeys =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      InputWindowInfoProto>;
+
+  static constexpr FieldMetadata_CanReceiveKeys kCanReceiveKeys{};
+  void set_can_receive_keys(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_CanReceiveKeys::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_Focusable =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      InputWindowInfoProto>;
+
+  static constexpr FieldMetadata_Focusable kFocusable{};
+  void set_focusable(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_Focusable::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_HasWallpaper =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      InputWindowInfoProto>;
+
+  static constexpr FieldMetadata_HasWallpaper kHasWallpaper{};
+  void set_has_wallpaper(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_HasWallpaper::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_GlobalScaleFactor =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      InputWindowInfoProto>;
+
+  static constexpr FieldMetadata_GlobalScaleFactor kGlobalScaleFactor{};
+  void set_global_scale_factor(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_GlobalScaleFactor::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_WindowXScale =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      InputWindowInfoProto>;
+
+  static constexpr FieldMetadata_WindowXScale kWindowXScale{};
+  void set_window_x_scale(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_WindowXScale::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_WindowYScale =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      InputWindowInfoProto>;
+
+  static constexpr FieldMetadata_WindowYScale kWindowYScale{};
+  void set_window_y_scale(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_WindowYScale::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CropLayerId =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      InputWindowInfoProto>;
+
+  static constexpr FieldMetadata_CropLayerId kCropLayerId{};
+  void set_crop_layer_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CropLayerId::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_ReplaceTouchableRegionWithCrop =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      InputWindowInfoProto>;
+
+  static constexpr FieldMetadata_ReplaceTouchableRegionWithCrop kReplaceTouchableRegionWithCrop{};
+  void set_replace_touchable_region_with_crop(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReplaceTouchableRegionWithCrop::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_TouchableRegionCrop =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RectProto,
+      InputWindowInfoProto>;
+
+  static constexpr FieldMetadata_TouchableRegionCrop kTouchableRegionCrop{};
+  template <typename T = RectProto> T* set_touchable_region_crop() {
+    return BeginNestedMessage<T>(15);
+  }
+
+
+  using FieldMetadata_Transform =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TransformProto,
+      InputWindowInfoProto>;
+
+  static constexpr FieldMetadata_Transform kTransform{};
+  template <typename T = TransformProto> T* set_transform() {
+    return BeginNestedMessage<T>(16);
+  }
+
+
+  using FieldMetadata_InputConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      InputWindowInfoProto>;
+
+  static constexpr FieldMetadata_InputConfig kInputConfig{};
+  void set_input_config(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InputConfig::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 ColorProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ColorProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ColorProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ColorProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_r() const { return at<1>().valid(); }
+  float r() const { return at<1>().as_float(); }
+  bool has_g() const { return at<2>().valid(); }
+  float g() const { return at<2>().as_float(); }
+  bool has_b() const { return at<3>().valid(); }
+  float b() const { return at<3>().as_float(); }
+  bool has_a() const { return at<4>().valid(); }
+  float a() const { return at<4>().as_float(); }
+};
+
+class ColorProto : public ::protozero::Message {
+ public:
+  using Decoder = ColorProto_Decoder;
+  enum : int32_t {
+    kRFieldNumber = 1,
+    kGFieldNumber = 2,
+    kBFieldNumber = 3,
+    kAFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ColorProto"; }
+
+
+  using FieldMetadata_R =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      ColorProto>;
+
+  static constexpr FieldMetadata_R kR{};
+  void set_r(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_R::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_G =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      ColorProto>;
+
+  static constexpr FieldMetadata_G kG{};
+  void set_g(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_G::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_B =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      ColorProto>;
+
+  static constexpr FieldMetadata_B kB{};
+  void set_b(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_B::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_A =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      ColorProto>;
+
+  static constexpr FieldMetadata_A kA{};
+  void set_a(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_A::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TransformProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TransformProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TransformProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TransformProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dsdx() const { return at<1>().valid(); }
+  float dsdx() const { return at<1>().as_float(); }
+  bool has_dtdx() const { return at<2>().valid(); }
+  float dtdx() const { return at<2>().as_float(); }
+  bool has_dsdy() const { return at<3>().valid(); }
+  float dsdy() const { return at<3>().as_float(); }
+  bool has_dtdy() const { return at<4>().valid(); }
+  float dtdy() const { return at<4>().as_float(); }
+  bool has_type() const { return at<5>().valid(); }
+  int32_t type() const { return at<5>().as_int32(); }
+};
+
+class TransformProto : public ::protozero::Message {
+ public:
+  using Decoder = TransformProto_Decoder;
+  enum : int32_t {
+    kDsdxFieldNumber = 1,
+    kDtdxFieldNumber = 2,
+    kDsdyFieldNumber = 3,
+    kDtdyFieldNumber = 4,
+    kTypeFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TransformProto"; }
+
+
+  using FieldMetadata_Dsdx =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      TransformProto>;
+
+  static constexpr FieldMetadata_Dsdx kDsdx{};
+  void set_dsdx(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dsdx::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Dtdx =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      TransformProto>;
+
+  static constexpr FieldMetadata_Dtdx kDtdx{};
+  void set_dtdx(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dtdx::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Dsdy =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      TransformProto>;
+
+  static constexpr FieldMetadata_Dsdy kDsdy{};
+  void set_dsdy(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dsdy::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Dtdy =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      TransformProto>;
+
+  static constexpr FieldMetadata_Dtdy kDtdy{};
+  void set_dtdy(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dtdy::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TransformProto>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::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);
+  }
+};
+
+class SizeProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SizeProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SizeProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SizeProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_w() const { return at<1>().valid(); }
+  int32_t w() const { return at<1>().as_int32(); }
+  bool has_h() const { return at<2>().valid(); }
+  int32_t h() const { return at<2>().as_int32(); }
+};
+
+class SizeProto : public ::protozero::Message {
+ public:
+  using Decoder = SizeProto_Decoder;
+  enum : int32_t {
+    kWFieldNumber = 1,
+    kHFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SizeProto"; }
+
+
+  using FieldMetadata_W =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SizeProto>;
+
+  static constexpr FieldMetadata_W kW{};
+  void set_w(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_W::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_H =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SizeProto>;
+
+  static constexpr FieldMetadata_H kH{};
+  void set_h(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_H::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);
+  }
+};
+
+class RegionProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  RegionProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit RegionProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit RegionProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_rect() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> rect() const { return GetRepeated<::protozero::ConstBytes>(2); }
+};
+
+class RegionProto : public ::protozero::Message {
+ public:
+  using Decoder = RegionProto_Decoder;
+  enum : int32_t {
+    kRectFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.RegionProto"; }
+
+
+  using FieldMetadata_Rect =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RectProto,
+      RegionProto>;
+
+  static constexpr FieldMetadata_Rect kRect{};
+  template <typename T = RectProto> T* add_rect() {
+    return BeginNestedMessage<T>(2);
+  }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/android/surfaceflinger_layers.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_SURFACEFLINGER_LAYERS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_SURFACEFLINGER_LAYERS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class ActiveBufferProto;
+class BarrierLayerProto;
+class BlurRegion;
+class ColorProto;
+class ColorTransformProto;
+class DisplayProto;
+class FloatRectProto;
+class InputWindowInfoProto;
+class LayerProto;
+class LayerProto_MetadataEntry;
+class LayersProto;
+class LayersSnapshotProto;
+class PositionProto;
+class RectProto;
+class RegionProto;
+class SizeProto;
+class TransformProto;
+enum HwcCompositionType : int32_t;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+enum HwcCompositionType : int32_t {
+  HWC_TYPE_UNSPECIFIED = 0,
+  HWC_TYPE_CLIENT = 1,
+  HWC_TYPE_DEVICE = 2,
+  HWC_TYPE_SOLID_COLOR = 3,
+  HWC_TYPE_CURSOR = 4,
+  HWC_TYPE_SIDEBAND = 5,
+  HWC_TYPE_DISPLAY_DECORATION = 6,
+};
+
+constexpr HwcCompositionType HwcCompositionType_MIN = HwcCompositionType::HWC_TYPE_UNSPECIFIED;
+constexpr HwcCompositionType HwcCompositionType_MAX = HwcCompositionType::HWC_TYPE_DISPLAY_DECORATION;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* HwcCompositionType_Name(::perfetto::protos::pbzero::HwcCompositionType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::HwcCompositionType::HWC_TYPE_UNSPECIFIED:
+    return "HWC_TYPE_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::HwcCompositionType::HWC_TYPE_CLIENT:
+    return "HWC_TYPE_CLIENT";
+
+  case ::perfetto::protos::pbzero::HwcCompositionType::HWC_TYPE_DEVICE:
+    return "HWC_TYPE_DEVICE";
+
+  case ::perfetto::protos::pbzero::HwcCompositionType::HWC_TYPE_SOLID_COLOR:
+    return "HWC_TYPE_SOLID_COLOR";
+
+  case ::perfetto::protos::pbzero::HwcCompositionType::HWC_TYPE_CURSOR:
+    return "HWC_TYPE_CURSOR";
+
+  case ::perfetto::protos::pbzero::HwcCompositionType::HWC_TYPE_SIDEBAND:
+    return "HWC_TYPE_SIDEBAND";
+
+  case ::perfetto::protos::pbzero::HwcCompositionType::HWC_TYPE_DISPLAY_DECORATION:
+    return "HWC_TYPE_DISPLAY_DECORATION";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_LayersTraceFileProto {
+enum MagicNumber : int32_t {
+  INVALID = 0,
+  MAGIC_NUMBER_L = 1414682956,
+  MAGIC_NUMBER_H = 1162035538,
+};
+} // namespace perfetto_pbzero_enum_LayersTraceFileProto
+using LayersTraceFileProto_MagicNumber = perfetto_pbzero_enum_LayersTraceFileProto::MagicNumber;
+
+
+constexpr LayersTraceFileProto_MagicNumber LayersTraceFileProto_MagicNumber_MIN = LayersTraceFileProto_MagicNumber::INVALID;
+constexpr LayersTraceFileProto_MagicNumber LayersTraceFileProto_MagicNumber_MAX = LayersTraceFileProto_MagicNumber::MAGIC_NUMBER_L;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* LayersTraceFileProto_MagicNumber_Name(::perfetto::protos::pbzero::LayersTraceFileProto_MagicNumber value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::LayersTraceFileProto_MagicNumber::INVALID:
+    return "INVALID";
+
+  case ::perfetto::protos::pbzero::LayersTraceFileProto_MagicNumber::MAGIC_NUMBER_L:
+    return "MAGIC_NUMBER_L";
+
+  case ::perfetto::protos::pbzero::LayersTraceFileProto_MagicNumber::MAGIC_NUMBER_H:
+    return "MAGIC_NUMBER_H";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class BarrierLayerProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BarrierLayerProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BarrierLayerProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BarrierLayerProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  int32_t id() const { return at<1>().as_int32(); }
+  bool has_frame_number() const { return at<2>().valid(); }
+  uint64_t frame_number() const { return at<2>().as_uint64(); }
+};
+
+class BarrierLayerProto : public ::protozero::Message {
+ public:
+  using Decoder = BarrierLayerProto_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kFrameNumberFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BarrierLayerProto"; }
+
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BarrierLayerProto>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::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_FrameNumber =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BarrierLayerProto>;
+
+  static constexpr FieldMetadata_FrameNumber kFrameNumber{};
+  void set_frame_number(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FrameNumber::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 ActiveBufferProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ActiveBufferProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ActiveBufferProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ActiveBufferProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_width() const { return at<1>().valid(); }
+  uint32_t width() const { return at<1>().as_uint32(); }
+  bool has_height() const { return at<2>().valid(); }
+  uint32_t height() const { return at<2>().as_uint32(); }
+  bool has_stride() const { return at<3>().valid(); }
+  uint32_t stride() const { return at<3>().as_uint32(); }
+  bool has_format() const { return at<4>().valid(); }
+  int32_t format() const { return at<4>().as_int32(); }
+  bool has_usage() const { return at<5>().valid(); }
+  uint64_t usage() const { return at<5>().as_uint64(); }
+};
+
+class ActiveBufferProto : public ::protozero::Message {
+ public:
+  using Decoder = ActiveBufferProto_Decoder;
+  enum : int32_t {
+    kWidthFieldNumber = 1,
+    kHeightFieldNumber = 2,
+    kStrideFieldNumber = 3,
+    kFormatFieldNumber = 4,
+    kUsageFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ActiveBufferProto"; }
+
+
+  using FieldMetadata_Width =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ActiveBufferProto>;
+
+  static constexpr FieldMetadata_Width kWidth{};
+  void set_width(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Width::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_Height =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ActiveBufferProto>;
+
+  static constexpr FieldMetadata_Height kHeight{};
+  void set_height(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Height::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_Stride =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ActiveBufferProto>;
+
+  static constexpr FieldMetadata_Stride kStride{};
+  void set_stride(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Stride::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_Format =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ActiveBufferProto>;
+
+  static constexpr FieldMetadata_Format kFormat{};
+  void set_format(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Format::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_Usage =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ActiveBufferProto>;
+
+  static constexpr FieldMetadata_Usage kUsage{};
+  void set_usage(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Usage::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 FloatRectProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FloatRectProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FloatRectProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FloatRectProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_left() const { return at<1>().valid(); }
+  float left() const { return at<1>().as_float(); }
+  bool has_top() const { return at<2>().valid(); }
+  float top() const { return at<2>().as_float(); }
+  bool has_right() const { return at<3>().valid(); }
+  float right() const { return at<3>().as_float(); }
+  bool has_bottom() const { return at<4>().valid(); }
+  float bottom() const { return at<4>().as_float(); }
+};
+
+class FloatRectProto : public ::protozero::Message {
+ public:
+  using Decoder = FloatRectProto_Decoder;
+  enum : int32_t {
+    kLeftFieldNumber = 1,
+    kTopFieldNumber = 2,
+    kRightFieldNumber = 3,
+    kBottomFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FloatRectProto"; }
+
+
+  using FieldMetadata_Left =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      FloatRectProto>;
+
+  static constexpr FieldMetadata_Left kLeft{};
+  void set_left(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Left::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Top =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      FloatRectProto>;
+
+  static constexpr FieldMetadata_Top kTop{};
+  void set_top(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Top::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Right =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      FloatRectProto>;
+
+  static constexpr FieldMetadata_Right kRight{};
+  void set_right(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Right::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Bottom =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      FloatRectProto>;
+
+  static constexpr FieldMetadata_Bottom kBottom{};
+  void set_bottom(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Bottom::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class PositionProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  PositionProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PositionProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PositionProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_x() const { return at<1>().valid(); }
+  float x() const { return at<1>().as_float(); }
+  bool has_y() const { return at<2>().valid(); }
+  float y() const { return at<2>().as_float(); }
+};
+
+class PositionProto : public ::protozero::Message {
+ public:
+  using Decoder = PositionProto_Decoder;
+  enum : int32_t {
+    kXFieldNumber = 1,
+    kYFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PositionProto"; }
+
+
+  using FieldMetadata_X =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      PositionProto>;
+
+  static constexpr FieldMetadata_X kX{};
+  void set_x(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_X::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Y =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      PositionProto>;
+
+  static constexpr FieldMetadata_Y kY{};
+  void set_y(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Y::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class LayerProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/58, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  LayerProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit LayerProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit LayerProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  int32_t id() const { return at<1>().as_int32(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+  bool has_children() const { return at<3>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, int32_t> children(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, int32_t>(3, parse_error_ptr); }
+  bool has_relatives() const { return at<4>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, int32_t> relatives(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, int32_t>(4, parse_error_ptr); }
+  bool has_type() const { return at<5>().valid(); }
+  ::protozero::ConstChars type() const { return at<5>().as_string(); }
+  bool has_transparent_region() const { return at<6>().valid(); }
+  ::protozero::ConstBytes transparent_region() const { return at<6>().as_bytes(); }
+  bool has_visible_region() const { return at<7>().valid(); }
+  ::protozero::ConstBytes visible_region() const { return at<7>().as_bytes(); }
+  bool has_damage_region() const { return at<8>().valid(); }
+  ::protozero::ConstBytes damage_region() const { return at<8>().as_bytes(); }
+  bool has_layer_stack() const { return at<9>().valid(); }
+  uint32_t layer_stack() const { return at<9>().as_uint32(); }
+  bool has_z() const { return at<10>().valid(); }
+  int32_t z() const { return at<10>().as_int32(); }
+  bool has_position() const { return at<11>().valid(); }
+  ::protozero::ConstBytes position() const { return at<11>().as_bytes(); }
+  bool has_requested_position() const { return at<12>().valid(); }
+  ::protozero::ConstBytes requested_position() const { return at<12>().as_bytes(); }
+  bool has_size() const { return at<13>().valid(); }
+  ::protozero::ConstBytes size() const { return at<13>().as_bytes(); }
+  bool has_crop() const { return at<14>().valid(); }
+  ::protozero::ConstBytes crop() const { return at<14>().as_bytes(); }
+  bool has_final_crop() const { return at<15>().valid(); }
+  ::protozero::ConstBytes final_crop() const { return at<15>().as_bytes(); }
+  bool has_is_opaque() const { return at<16>().valid(); }
+  bool is_opaque() const { return at<16>().as_bool(); }
+  bool has_invalidate() const { return at<17>().valid(); }
+  bool invalidate() const { return at<17>().as_bool(); }
+  bool has_dataspace() const { return at<18>().valid(); }
+  ::protozero::ConstChars dataspace() const { return at<18>().as_string(); }
+  bool has_pixel_format() const { return at<19>().valid(); }
+  ::protozero::ConstChars pixel_format() const { return at<19>().as_string(); }
+  bool has_color() const { return at<20>().valid(); }
+  ::protozero::ConstBytes color() const { return at<20>().as_bytes(); }
+  bool has_requested_color() const { return at<21>().valid(); }
+  ::protozero::ConstBytes requested_color() const { return at<21>().as_bytes(); }
+  bool has_flags() const { return at<22>().valid(); }
+  uint32_t flags() const { return at<22>().as_uint32(); }
+  bool has_transform() const { return at<23>().valid(); }
+  ::protozero::ConstBytes transform() const { return at<23>().as_bytes(); }
+  bool has_requested_transform() const { return at<24>().valid(); }
+  ::protozero::ConstBytes requested_transform() const { return at<24>().as_bytes(); }
+  bool has_parent() const { return at<25>().valid(); }
+  int32_t parent() const { return at<25>().as_int32(); }
+  bool has_z_order_relative_of() const { return at<26>().valid(); }
+  int32_t z_order_relative_of() const { return at<26>().as_int32(); }
+  bool has_active_buffer() const { return at<27>().valid(); }
+  ::protozero::ConstBytes active_buffer() const { return at<27>().as_bytes(); }
+  bool has_queued_frames() const { return at<28>().valid(); }
+  int32_t queued_frames() const { return at<28>().as_int32(); }
+  bool has_refresh_pending() const { return at<29>().valid(); }
+  bool refresh_pending() const { return at<29>().as_bool(); }
+  bool has_hwc_frame() const { return at<30>().valid(); }
+  ::protozero::ConstBytes hwc_frame() const { return at<30>().as_bytes(); }
+  bool has_hwc_crop() const { return at<31>().valid(); }
+  ::protozero::ConstBytes hwc_crop() const { return at<31>().as_bytes(); }
+  bool has_hwc_transform() const { return at<32>().valid(); }
+  int32_t hwc_transform() const { return at<32>().as_int32(); }
+  bool has_window_type() const { return at<33>().valid(); }
+  int32_t window_type() const { return at<33>().as_int32(); }
+  bool has_app_id() const { return at<34>().valid(); }
+  int32_t app_id() const { return at<34>().as_int32(); }
+  bool has_hwc_composition_type() const { return at<35>().valid(); }
+  int32_t hwc_composition_type() const { return at<35>().as_int32(); }
+  bool has_is_protected() const { return at<36>().valid(); }
+  bool is_protected() const { return at<36>().as_bool(); }
+  bool has_curr_frame() const { return at<37>().valid(); }
+  uint64_t curr_frame() const { return at<37>().as_uint64(); }
+  bool has_barrier_layer() const { return at<38>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> barrier_layer() const { return GetRepeated<::protozero::ConstBytes>(38); }
+  bool has_buffer_transform() const { return at<39>().valid(); }
+  ::protozero::ConstBytes buffer_transform() const { return at<39>().as_bytes(); }
+  bool has_effective_scaling_mode() const { return at<40>().valid(); }
+  int32_t effective_scaling_mode() const { return at<40>().as_int32(); }
+  bool has_corner_radius() const { return at<41>().valid(); }
+  float corner_radius() const { return at<41>().as_float(); }
+  bool has_metadata() const { return at<42>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> metadata() const { return GetRepeated<::protozero::ConstBytes>(42); }
+  bool has_effective_transform() const { return at<43>().valid(); }
+  ::protozero::ConstBytes effective_transform() const { return at<43>().as_bytes(); }
+  bool has_source_bounds() const { return at<44>().valid(); }
+  ::protozero::ConstBytes source_bounds() const { return at<44>().as_bytes(); }
+  bool has_bounds() const { return at<45>().valid(); }
+  ::protozero::ConstBytes bounds() const { return at<45>().as_bytes(); }
+  bool has_screen_bounds() const { return at<46>().valid(); }
+  ::protozero::ConstBytes screen_bounds() const { return at<46>().as_bytes(); }
+  bool has_input_window_info() const { return at<47>().valid(); }
+  ::protozero::ConstBytes input_window_info() const { return at<47>().as_bytes(); }
+  bool has_corner_radius_crop() const { return at<48>().valid(); }
+  ::protozero::ConstBytes corner_radius_crop() const { return at<48>().as_bytes(); }
+  bool has_shadow_radius() const { return at<49>().valid(); }
+  float shadow_radius() const { return at<49>().as_float(); }
+  bool has_color_transform() const { return at<50>().valid(); }
+  ::protozero::ConstBytes color_transform() const { return at<50>().as_bytes(); }
+  bool has_is_relative_of() const { return at<51>().valid(); }
+  bool is_relative_of() const { return at<51>().as_bool(); }
+  bool has_background_blur_radius() const { return at<52>().valid(); }
+  int32_t background_blur_radius() const { return at<52>().as_int32(); }
+  bool has_owner_uid() const { return at<53>().valid(); }
+  uint32_t owner_uid() const { return at<53>().as_uint32(); }
+  bool has_blur_regions() const { return at<54>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> blur_regions() const { return GetRepeated<::protozero::ConstBytes>(54); }
+  bool has_is_trusted_overlay() const { return at<55>().valid(); }
+  bool is_trusted_overlay() const { return at<55>().as_bool(); }
+  bool has_requested_corner_radius() const { return at<56>().valid(); }
+  float requested_corner_radius() const { return at<56>().as_float(); }
+  bool has_destination_frame() const { return at<57>().valid(); }
+  ::protozero::ConstBytes destination_frame() const { return at<57>().as_bytes(); }
+  bool has_original_id() const { return at<58>().valid(); }
+  uint32_t original_id() const { return at<58>().as_uint32(); }
+};
+
+class LayerProto : public ::protozero::Message {
+ public:
+  using Decoder = LayerProto_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kNameFieldNumber = 2,
+    kChildrenFieldNumber = 3,
+    kRelativesFieldNumber = 4,
+    kTypeFieldNumber = 5,
+    kTransparentRegionFieldNumber = 6,
+    kVisibleRegionFieldNumber = 7,
+    kDamageRegionFieldNumber = 8,
+    kLayerStackFieldNumber = 9,
+    kZFieldNumber = 10,
+    kPositionFieldNumber = 11,
+    kRequestedPositionFieldNumber = 12,
+    kSizeFieldNumber = 13,
+    kCropFieldNumber = 14,
+    kFinalCropFieldNumber = 15,
+    kIsOpaqueFieldNumber = 16,
+    kInvalidateFieldNumber = 17,
+    kDataspaceFieldNumber = 18,
+    kPixelFormatFieldNumber = 19,
+    kColorFieldNumber = 20,
+    kRequestedColorFieldNumber = 21,
+    kFlagsFieldNumber = 22,
+    kTransformFieldNumber = 23,
+    kRequestedTransformFieldNumber = 24,
+    kParentFieldNumber = 25,
+    kZOrderRelativeOfFieldNumber = 26,
+    kActiveBufferFieldNumber = 27,
+    kQueuedFramesFieldNumber = 28,
+    kRefreshPendingFieldNumber = 29,
+    kHwcFrameFieldNumber = 30,
+    kHwcCropFieldNumber = 31,
+    kHwcTransformFieldNumber = 32,
+    kWindowTypeFieldNumber = 33,
+    kAppIdFieldNumber = 34,
+    kHwcCompositionTypeFieldNumber = 35,
+    kIsProtectedFieldNumber = 36,
+    kCurrFrameFieldNumber = 37,
+    kBarrierLayerFieldNumber = 38,
+    kBufferTransformFieldNumber = 39,
+    kEffectiveScalingModeFieldNumber = 40,
+    kCornerRadiusFieldNumber = 41,
+    kMetadataFieldNumber = 42,
+    kEffectiveTransformFieldNumber = 43,
+    kSourceBoundsFieldNumber = 44,
+    kBoundsFieldNumber = 45,
+    kScreenBoundsFieldNumber = 46,
+    kInputWindowInfoFieldNumber = 47,
+    kCornerRadiusCropFieldNumber = 48,
+    kShadowRadiusFieldNumber = 49,
+    kColorTransformFieldNumber = 50,
+    kIsRelativeOfFieldNumber = 51,
+    kBackgroundBlurRadiusFieldNumber = 52,
+    kOwnerUidFieldNumber = 53,
+    kBlurRegionsFieldNumber = 54,
+    kIsTrustedOverlayFieldNumber = 55,
+    kRequestedCornerRadiusFieldNumber = 56,
+    kDestinationFrameFieldNumber = 57,
+    kOriginalIdFieldNumber = 58,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.LayerProto"; }
+
+  using MetadataEntry = ::perfetto::protos::pbzero::LayerProto_MetadataEntry;
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerProto>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      LayerProto>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Children =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerProto>;
+
+  static constexpr FieldMetadata_Children kChildren{};
+  void set_children(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_Children::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_Relatives =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerProto>;
+
+  static constexpr FieldMetadata_Relatives kRelatives{};
+  void set_relatives(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_Relatives::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      LayerProto>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Type::kFieldId, data, size);
+  }
+  void set_type(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Type::kFieldId, chars.data, chars.size);
+  }
+  void set_type(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::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_TransparentRegion =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RegionProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_TransparentRegion kTransparentRegion{};
+  template <typename T = RegionProto> T* set_transparent_region() {
+    return BeginNestedMessage<T>(6);
+  }
+
+
+  using FieldMetadata_VisibleRegion =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RegionProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_VisibleRegion kVisibleRegion{};
+  template <typename T = RegionProto> T* set_visible_region() {
+    return BeginNestedMessage<T>(7);
+  }
+
+
+  using FieldMetadata_DamageRegion =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RegionProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_DamageRegion kDamageRegion{};
+  template <typename T = RegionProto> T* set_damage_region() {
+    return BeginNestedMessage<T>(8);
+  }
+
+
+  using FieldMetadata_LayerStack =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerProto>;
+
+  static constexpr FieldMetadata_LayerStack kLayerStack{};
+  void set_layer_stack(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LayerStack::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_Z =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerProto>;
+
+  static constexpr FieldMetadata_Z kZ{};
+  void set_z(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Z::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_Position =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PositionProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_Position kPosition{};
+  template <typename T = PositionProto> T* set_position() {
+    return BeginNestedMessage<T>(11);
+  }
+
+
+  using FieldMetadata_RequestedPosition =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PositionProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_RequestedPosition kRequestedPosition{};
+  template <typename T = PositionProto> T* set_requested_position() {
+    return BeginNestedMessage<T>(12);
+  }
+
+
+  using FieldMetadata_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SizeProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  template <typename T = SizeProto> T* set_size() {
+    return BeginNestedMessage<T>(13);
+  }
+
+
+  using FieldMetadata_Crop =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RectProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_Crop kCrop{};
+  template <typename T = RectProto> T* set_crop() {
+    return BeginNestedMessage<T>(14);
+  }
+
+
+  using FieldMetadata_FinalCrop =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RectProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_FinalCrop kFinalCrop{};
+  template <typename T = RectProto> T* set_final_crop() {
+    return BeginNestedMessage<T>(15);
+  }
+
+
+  using FieldMetadata_IsOpaque =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      LayerProto>;
+
+  static constexpr FieldMetadata_IsOpaque kIsOpaque{};
+  void set_is_opaque(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsOpaque::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_Invalidate =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      LayerProto>;
+
+  static constexpr FieldMetadata_Invalidate kInvalidate{};
+  void set_invalidate(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_Invalidate::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_Dataspace =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      LayerProto>;
+
+  static constexpr FieldMetadata_Dataspace kDataspace{};
+  void set_dataspace(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Dataspace::kFieldId, data, size);
+  }
+  void set_dataspace(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Dataspace::kFieldId, chars.data, chars.size);
+  }
+  void set_dataspace(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dataspace::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_PixelFormat =
+    ::protozero::proto_utils::FieldMetadata<
+      19,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      LayerProto>;
+
+  static constexpr FieldMetadata_PixelFormat kPixelFormat{};
+  void set_pixel_format(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_PixelFormat::kFieldId, data, size);
+  }
+  void set_pixel_format(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_PixelFormat::kFieldId, chars.data, chars.size);
+  }
+  void set_pixel_format(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_PixelFormat::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_Color =
+    ::protozero::proto_utils::FieldMetadata<
+      20,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ColorProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_Color kColor{};
+  template <typename T = ColorProto> T* set_color() {
+    return BeginNestedMessage<T>(20);
+  }
+
+
+  using FieldMetadata_RequestedColor =
+    ::protozero::proto_utils::FieldMetadata<
+      21,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ColorProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_RequestedColor kRequestedColor{};
+  template <typename T = ColorProto> T* set_requested_color() {
+    return BeginNestedMessage<T>(21);
+  }
+
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      22,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerProto>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_Transform =
+    ::protozero::proto_utils::FieldMetadata<
+      23,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TransformProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_Transform kTransform{};
+  template <typename T = TransformProto> T* set_transform() {
+    return BeginNestedMessage<T>(23);
+  }
+
+
+  using FieldMetadata_RequestedTransform =
+    ::protozero::proto_utils::FieldMetadata<
+      24,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TransformProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_RequestedTransform kRequestedTransform{};
+  template <typename T = TransformProto> T* set_requested_transform() {
+    return BeginNestedMessage<T>(24);
+  }
+
+
+  using FieldMetadata_Parent =
+    ::protozero::proto_utils::FieldMetadata<
+      25,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerProto>;
+
+  static constexpr FieldMetadata_Parent kParent{};
+  void set_parent(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Parent::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_ZOrderRelativeOf =
+    ::protozero::proto_utils::FieldMetadata<
+      26,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerProto>;
+
+  static constexpr FieldMetadata_ZOrderRelativeOf kZOrderRelativeOf{};
+  void set_z_order_relative_of(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ZOrderRelativeOf::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_ActiveBuffer =
+    ::protozero::proto_utils::FieldMetadata<
+      27,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ActiveBufferProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_ActiveBuffer kActiveBuffer{};
+  template <typename T = ActiveBufferProto> T* set_active_buffer() {
+    return BeginNestedMessage<T>(27);
+  }
+
+
+  using FieldMetadata_QueuedFrames =
+    ::protozero::proto_utils::FieldMetadata<
+      28,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerProto>;
+
+  static constexpr FieldMetadata_QueuedFrames kQueuedFrames{};
+  void set_queued_frames(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_QueuedFrames::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_RefreshPending =
+    ::protozero::proto_utils::FieldMetadata<
+      29,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      LayerProto>;
+
+  static constexpr FieldMetadata_RefreshPending kRefreshPending{};
+  void set_refresh_pending(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_RefreshPending::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_HwcFrame =
+    ::protozero::proto_utils::FieldMetadata<
+      30,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RectProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_HwcFrame kHwcFrame{};
+  template <typename T = RectProto> T* set_hwc_frame() {
+    return BeginNestedMessage<T>(30);
+  }
+
+
+  using FieldMetadata_HwcCrop =
+    ::protozero::proto_utils::FieldMetadata<
+      31,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FloatRectProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_HwcCrop kHwcCrop{};
+  template <typename T = FloatRectProto> T* set_hwc_crop() {
+    return BeginNestedMessage<T>(31);
+  }
+
+
+  using FieldMetadata_HwcTransform =
+    ::protozero::proto_utils::FieldMetadata<
+      32,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerProto>;
+
+  static constexpr FieldMetadata_HwcTransform kHwcTransform{};
+  void set_hwc_transform(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_HwcTransform::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_WindowType =
+    ::protozero::proto_utils::FieldMetadata<
+      33,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerProto>;
+
+  static constexpr FieldMetadata_WindowType kWindowType{};
+  void set_window_type(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_WindowType::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_AppId =
+    ::protozero::proto_utils::FieldMetadata<
+      34,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerProto>;
+
+  static constexpr FieldMetadata_AppId kAppId{};
+  void set_app_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AppId::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_HwcCompositionType =
+    ::protozero::proto_utils::FieldMetadata<
+      35,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      HwcCompositionType,
+      LayerProto>;
+
+  static constexpr FieldMetadata_HwcCompositionType kHwcCompositionType{};
+  void set_hwc_composition_type(HwcCompositionType value) {
+    static constexpr uint32_t field_id = FieldMetadata_HwcCompositionType::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_IsProtected =
+    ::protozero::proto_utils::FieldMetadata<
+      36,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      LayerProto>;
+
+  static constexpr FieldMetadata_IsProtected kIsProtected{};
+  void set_is_protected(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsProtected::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_CurrFrame =
+    ::protozero::proto_utils::FieldMetadata<
+      37,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      LayerProto>;
+
+  static constexpr FieldMetadata_CurrFrame kCurrFrame{};
+  void set_curr_frame(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CurrFrame::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_BarrierLayer =
+    ::protozero::proto_utils::FieldMetadata<
+      38,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BarrierLayerProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_BarrierLayer kBarrierLayer{};
+  template <typename T = BarrierLayerProto> T* add_barrier_layer() {
+    return BeginNestedMessage<T>(38);
+  }
+
+
+  using FieldMetadata_BufferTransform =
+    ::protozero::proto_utils::FieldMetadata<
+      39,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TransformProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_BufferTransform kBufferTransform{};
+  template <typename T = TransformProto> T* set_buffer_transform() {
+    return BeginNestedMessage<T>(39);
+  }
+
+
+  using FieldMetadata_EffectiveScalingMode =
+    ::protozero::proto_utils::FieldMetadata<
+      40,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerProto>;
+
+  static constexpr FieldMetadata_EffectiveScalingMode kEffectiveScalingMode{};
+  void set_effective_scaling_mode(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EffectiveScalingMode::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_CornerRadius =
+    ::protozero::proto_utils::FieldMetadata<
+      41,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      LayerProto>;
+
+  static constexpr FieldMetadata_CornerRadius kCornerRadius{};
+  void set_corner_radius(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_CornerRadius::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Metadata =
+    ::protozero::proto_utils::FieldMetadata<
+      42,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      LayerProto_MetadataEntry,
+      LayerProto>;
+
+  static constexpr FieldMetadata_Metadata kMetadata{};
+  template <typename T = LayerProto_MetadataEntry> T* add_metadata() {
+    return BeginNestedMessage<T>(42);
+  }
+
+
+  using FieldMetadata_EffectiveTransform =
+    ::protozero::proto_utils::FieldMetadata<
+      43,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TransformProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_EffectiveTransform kEffectiveTransform{};
+  template <typename T = TransformProto> T* set_effective_transform() {
+    return BeginNestedMessage<T>(43);
+  }
+
+
+  using FieldMetadata_SourceBounds =
+    ::protozero::proto_utils::FieldMetadata<
+      44,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FloatRectProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_SourceBounds kSourceBounds{};
+  template <typename T = FloatRectProto> T* set_source_bounds() {
+    return BeginNestedMessage<T>(44);
+  }
+
+
+  using FieldMetadata_Bounds =
+    ::protozero::proto_utils::FieldMetadata<
+      45,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FloatRectProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_Bounds kBounds{};
+  template <typename T = FloatRectProto> T* set_bounds() {
+    return BeginNestedMessage<T>(45);
+  }
+
+
+  using FieldMetadata_ScreenBounds =
+    ::protozero::proto_utils::FieldMetadata<
+      46,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FloatRectProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_ScreenBounds kScreenBounds{};
+  template <typename T = FloatRectProto> T* set_screen_bounds() {
+    return BeginNestedMessage<T>(46);
+  }
+
+
+  using FieldMetadata_InputWindowInfo =
+    ::protozero::proto_utils::FieldMetadata<
+      47,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InputWindowInfoProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_InputWindowInfo kInputWindowInfo{};
+  template <typename T = InputWindowInfoProto> T* set_input_window_info() {
+    return BeginNestedMessage<T>(47);
+  }
+
+
+  using FieldMetadata_CornerRadiusCrop =
+    ::protozero::proto_utils::FieldMetadata<
+      48,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FloatRectProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_CornerRadiusCrop kCornerRadiusCrop{};
+  template <typename T = FloatRectProto> T* set_corner_radius_crop() {
+    return BeginNestedMessage<T>(48);
+  }
+
+
+  using FieldMetadata_ShadowRadius =
+    ::protozero::proto_utils::FieldMetadata<
+      49,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      LayerProto>;
+
+  static constexpr FieldMetadata_ShadowRadius kShadowRadius{};
+  void set_shadow_radius(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_ShadowRadius::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ColorTransform =
+    ::protozero::proto_utils::FieldMetadata<
+      50,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ColorTransformProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_ColorTransform kColorTransform{};
+  template <typename T = ColorTransformProto> T* set_color_transform() {
+    return BeginNestedMessage<T>(50);
+  }
+
+
+  using FieldMetadata_IsRelativeOf =
+    ::protozero::proto_utils::FieldMetadata<
+      51,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      LayerProto>;
+
+  static constexpr FieldMetadata_IsRelativeOf kIsRelativeOf{};
+  void set_is_relative_of(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsRelativeOf::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_BackgroundBlurRadius =
+    ::protozero::proto_utils::FieldMetadata<
+      52,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerProto>;
+
+  static constexpr FieldMetadata_BackgroundBlurRadius kBackgroundBlurRadius{};
+  void set_background_blur_radius(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BackgroundBlurRadius::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_OwnerUid =
+    ::protozero::proto_utils::FieldMetadata<
+      53,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerProto>;
+
+  static constexpr FieldMetadata_OwnerUid kOwnerUid{};
+  void set_owner_uid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OwnerUid::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_BlurRegions =
+    ::protozero::proto_utils::FieldMetadata<
+      54,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlurRegion,
+      LayerProto>;
+
+  static constexpr FieldMetadata_BlurRegions kBlurRegions{};
+  template <typename T = BlurRegion> T* add_blur_regions() {
+    return BeginNestedMessage<T>(54);
+  }
+
+
+  using FieldMetadata_IsTrustedOverlay =
+    ::protozero::proto_utils::FieldMetadata<
+      55,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      LayerProto>;
+
+  static constexpr FieldMetadata_IsTrustedOverlay kIsTrustedOverlay{};
+  void set_is_trusted_overlay(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsTrustedOverlay::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_RequestedCornerRadius =
+    ::protozero::proto_utils::FieldMetadata<
+      56,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      LayerProto>;
+
+  static constexpr FieldMetadata_RequestedCornerRadius kRequestedCornerRadius{};
+  void set_requested_corner_radius(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_RequestedCornerRadius::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DestinationFrame =
+    ::protozero::proto_utils::FieldMetadata<
+      57,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RectProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_DestinationFrame kDestinationFrame{};
+  template <typename T = RectProto> T* set_destination_frame() {
+    return BeginNestedMessage<T>(57);
+  }
+
+
+  using FieldMetadata_OriginalId =
+    ::protozero::proto_utils::FieldMetadata<
+      58,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerProto>;
+
+  static constexpr FieldMetadata_OriginalId kOriginalId{};
+  void set_original_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OriginalId::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 LayerProto_MetadataEntry_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  LayerProto_MetadataEntry_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit LayerProto_MetadataEntry_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit LayerProto_MetadataEntry_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_key() const { return at<1>().valid(); }
+  int32_t key() const { return at<1>().as_int32(); }
+  bool has_value() const { return at<2>().valid(); }
+  ::protozero::ConstChars value() const { return at<2>().as_string(); }
+};
+
+class LayerProto_MetadataEntry : public ::protozero::Message {
+ public:
+  using Decoder = LayerProto_MetadataEntry_Decoder;
+  enum : int32_t {
+    kKeyFieldNumber = 1,
+    kValueFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.LayerProto.MetadataEntry"; }
+
+
+  using FieldMetadata_Key =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerProto_MetadataEntry>;
+
+  static constexpr FieldMetadata_Key kKey{};
+  void set_key(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Key::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_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      LayerProto_MetadataEntry>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Value::kFieldId, data, size);
+  }
+  void set_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Value::kFieldId, chars.data, chars.size);
+  }
+  void set_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::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 DisplayProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DisplayProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DisplayProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DisplayProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  uint64_t id() const { return at<1>().as_uint64(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+  bool has_layer_stack() const { return at<3>().valid(); }
+  uint32_t layer_stack() const { return at<3>().as_uint32(); }
+  bool has_size() const { return at<4>().valid(); }
+  ::protozero::ConstBytes size() const { return at<4>().as_bytes(); }
+  bool has_layer_stack_space_rect() const { return at<5>().valid(); }
+  ::protozero::ConstBytes layer_stack_space_rect() const { return at<5>().as_bytes(); }
+  bool has_transform() const { return at<6>().valid(); }
+  ::protozero::ConstBytes transform() const { return at<6>().as_bytes(); }
+  bool has_is_virtual() const { return at<7>().valid(); }
+  bool is_virtual() const { return at<7>().as_bool(); }
+  bool has_dpi_x() const { return at<8>().valid(); }
+  double dpi_x() const { return at<8>().as_double(); }
+  bool has_dpi_y() const { return at<9>().valid(); }
+  double dpi_y() const { return at<9>().as_double(); }
+};
+
+class DisplayProto : public ::protozero::Message {
+ public:
+  using Decoder = DisplayProto_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kNameFieldNumber = 2,
+    kLayerStackFieldNumber = 3,
+    kSizeFieldNumber = 4,
+    kLayerStackSpaceRectFieldNumber = 5,
+    kTransformFieldNumber = 6,
+    kIsVirtualFieldNumber = 7,
+    kDpiXFieldNumber = 8,
+    kDpiYFieldNumber = 9,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DisplayProto"; }
+
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DisplayProto>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DisplayProto>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_LayerStack =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DisplayProto>;
+
+  static constexpr FieldMetadata_LayerStack kLayerStack{};
+  void set_layer_stack(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LayerStack::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_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SizeProto,
+      DisplayProto>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  template <typename T = SizeProto> T* set_size() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_LayerStackSpaceRect =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RectProto,
+      DisplayProto>;
+
+  static constexpr FieldMetadata_LayerStackSpaceRect kLayerStackSpaceRect{};
+  template <typename T = RectProto> T* set_layer_stack_space_rect() {
+    return BeginNestedMessage<T>(5);
+  }
+
+
+  using FieldMetadata_Transform =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TransformProto,
+      DisplayProto>;
+
+  static constexpr FieldMetadata_Transform kTransform{};
+  template <typename T = TransformProto> T* set_transform() {
+    return BeginNestedMessage<T>(6);
+  }
+
+
+  using FieldMetadata_IsVirtual =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      DisplayProto>;
+
+  static constexpr FieldMetadata_IsVirtual kIsVirtual{};
+  void set_is_virtual(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsVirtual::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_DpiX =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      DisplayProto>;
+
+  static constexpr FieldMetadata_DpiX kDpiX{};
+  void set_dpi_x(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_DpiX::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);
+  }
+
+  using FieldMetadata_DpiY =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      DisplayProto>;
+
+  static constexpr FieldMetadata_DpiY kDpiY{};
+  void set_dpi_y(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_DpiY::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 LayersProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  LayersProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit LayersProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit LayersProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_layers() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> layers() const { return GetRepeated<::protozero::ConstBytes>(1); }
+};
+
+class LayersProto : public ::protozero::Message {
+ public:
+  using Decoder = LayersProto_Decoder;
+  enum : int32_t {
+    kLayersFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.LayersProto"; }
+
+
+  using FieldMetadata_Layers =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      LayerProto,
+      LayersProto>;
+
+  static constexpr FieldMetadata_Layers kLayers{};
+  template <typename T = LayerProto> T* add_layers() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+class LayersSnapshotProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  LayersSnapshotProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit LayersSnapshotProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit LayersSnapshotProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_elapsed_realtime_nanos() const { return at<1>().valid(); }
+  int64_t elapsed_realtime_nanos() const { return at<1>().as_int64(); }
+  bool has_where() const { return at<2>().valid(); }
+  ::protozero::ConstChars where() const { return at<2>().as_string(); }
+  bool has_layers() const { return at<3>().valid(); }
+  ::protozero::ConstBytes layers() const { return at<3>().as_bytes(); }
+  bool has_hwc_blob() const { return at<4>().valid(); }
+  ::protozero::ConstChars hwc_blob() const { return at<4>().as_string(); }
+  bool has_excludes_composition_state() const { return at<5>().valid(); }
+  bool excludes_composition_state() const { return at<5>().as_bool(); }
+  bool has_missed_entries() const { return at<6>().valid(); }
+  uint32_t missed_entries() const { return at<6>().as_uint32(); }
+  bool has_displays() const { return at<7>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> displays() const { return GetRepeated<::protozero::ConstBytes>(7); }
+  bool has_vsync_id() const { return at<8>().valid(); }
+  int64_t vsync_id() const { return at<8>().as_int64(); }
+};
+
+class LayersSnapshotProto : public ::protozero::Message {
+ public:
+  using Decoder = LayersSnapshotProto_Decoder;
+  enum : int32_t {
+    kElapsedRealtimeNanosFieldNumber = 1,
+    kWhereFieldNumber = 2,
+    kLayersFieldNumber = 3,
+    kHwcBlobFieldNumber = 4,
+    kExcludesCompositionStateFieldNumber = 5,
+    kMissedEntriesFieldNumber = 6,
+    kDisplaysFieldNumber = 7,
+    kVsyncIdFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.LayersSnapshotProto"; }
+
+
+  using FieldMetadata_ElapsedRealtimeNanos =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kSfixed64,
+      int64_t,
+      LayersSnapshotProto>;
+
+  static constexpr FieldMetadata_ElapsedRealtimeNanos kElapsedRealtimeNanos{};
+  void set_elapsed_realtime_nanos(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ElapsedRealtimeNanos::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kSfixed64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Where =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      LayersSnapshotProto>;
+
+  static constexpr FieldMetadata_Where kWhere{};
+  void set_where(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Where::kFieldId, data, size);
+  }
+  void set_where(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Where::kFieldId, chars.data, chars.size);
+  }
+  void set_where(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Where::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_Layers =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      LayersProto,
+      LayersSnapshotProto>;
+
+  static constexpr FieldMetadata_Layers kLayers{};
+  template <typename T = LayersProto> T* set_layers() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_HwcBlob =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      LayersSnapshotProto>;
+
+  static constexpr FieldMetadata_HwcBlob kHwcBlob{};
+  void set_hwc_blob(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HwcBlob::kFieldId, data, size);
+  }
+  void set_hwc_blob(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_HwcBlob::kFieldId, chars.data, chars.size);
+  }
+  void set_hwc_blob(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_HwcBlob::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_ExcludesCompositionState =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      LayersSnapshotProto>;
+
+  static constexpr FieldMetadata_ExcludesCompositionState kExcludesCompositionState{};
+  void set_excludes_composition_state(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ExcludesCompositionState::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_MissedEntries =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayersSnapshotProto>;
+
+  static constexpr FieldMetadata_MissedEntries kMissedEntries{};
+  void set_missed_entries(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MissedEntries::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_Displays =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DisplayProto,
+      LayersSnapshotProto>;
+
+  static constexpr FieldMetadata_Displays kDisplays{};
+  template <typename T = DisplayProto> T* add_displays() {
+    return BeginNestedMessage<T>(7);
+  }
+
+
+  using FieldMetadata_VsyncId =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      LayersSnapshotProto>;
+
+  static constexpr FieldMetadata_VsyncId kVsyncId{};
+  void set_vsync_id(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VsyncId::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 LayersTraceFileProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  LayersTraceFileProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit LayersTraceFileProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit LayersTraceFileProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_magic_number() const { return at<1>().valid(); }
+  uint64_t magic_number() const { return at<1>().as_uint64(); }
+  bool has_entry() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> entry() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_real_to_elapsed_time_offset_nanos() const { return at<3>().valid(); }
+  uint64_t real_to_elapsed_time_offset_nanos() const { return at<3>().as_uint64(); }
+};
+
+class LayersTraceFileProto : public ::protozero::Message {
+ public:
+  using Decoder = LayersTraceFileProto_Decoder;
+  enum : int32_t {
+    kMagicNumberFieldNumber = 1,
+    kEntryFieldNumber = 2,
+    kRealToElapsedTimeOffsetNanosFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.LayersTraceFileProto"; }
+
+
+  using MagicNumber = ::perfetto::protos::pbzero::LayersTraceFileProto_MagicNumber;
+  static inline const char* MagicNumber_Name(MagicNumber value) {
+    return ::perfetto::protos::pbzero::LayersTraceFileProto_MagicNumber_Name(value);
+  }
+  static inline const MagicNumber INVALID = MagicNumber::INVALID;
+  static inline const MagicNumber MAGIC_NUMBER_L = MagicNumber::MAGIC_NUMBER_L;
+  static inline const MagicNumber MAGIC_NUMBER_H = MagicNumber::MAGIC_NUMBER_H;
+
+  using FieldMetadata_MagicNumber =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64,
+      uint64_t,
+      LayersTraceFileProto>;
+
+  static constexpr FieldMetadata_MagicNumber kMagicNumber{};
+  void set_magic_number(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MagicNumber::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Entry =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      LayersSnapshotProto,
+      LayersTraceFileProto>;
+
+  static constexpr FieldMetadata_Entry kEntry{};
+  template <typename T = LayersSnapshotProto> T* add_entry() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_RealToElapsedTimeOffsetNanos =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64,
+      uint64_t,
+      LayersTraceFileProto>;
+
+  static constexpr FieldMetadata_RealToElapsedTimeOffsetNanos kRealToElapsedTimeOffsetNanos{};
+  void set_real_to_elapsed_time_offset_nanos(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RealToElapsedTimeOffsetNanos::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/android/surfaceflinger_transactions.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_SURFACEFLINGER_TRANSACTIONS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_SURFACEFLINGER_TRANSACTIONS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class BlurRegion;
+class ColorTransformProto;
+class DisplayInfo;
+class DisplayState;
+class LayerCreationArgs;
+class LayerState;
+class LayerState_BufferData;
+class LayerState_Color3;
+class LayerState_Matrix22;
+class LayerState_WindowInfo;
+class RectProto;
+class RegionProto;
+class TransactionState;
+class TransactionTraceEntry;
+class Transform;
+namespace perfetto_pbzero_enum_LayerState_BufferData {
+enum PixelFormat : int32_t;
+}  // namespace perfetto_pbzero_enum_LayerState_BufferData
+using LayerState_BufferData_PixelFormat = perfetto_pbzero_enum_LayerState_BufferData::PixelFormat;
+namespace perfetto_pbzero_enum_LayerState {
+enum DropInputMode : int32_t;
+}  // namespace perfetto_pbzero_enum_LayerState
+using LayerState_DropInputMode = perfetto_pbzero_enum_LayerState::DropInputMode;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_DisplayState {
+enum Changes : int32_t {
+  eChangesNone = 0,
+  eSurfaceChanged = 1,
+  eLayerStackChanged = 2,
+  eDisplayProjectionChanged = 4,
+  eDisplaySizeChanged = 8,
+  eFlagsChanged = 16,
+};
+} // namespace perfetto_pbzero_enum_DisplayState
+using DisplayState_Changes = perfetto_pbzero_enum_DisplayState::Changes;
+
+
+constexpr DisplayState_Changes DisplayState_Changes_MIN = DisplayState_Changes::eChangesNone;
+constexpr DisplayState_Changes DisplayState_Changes_MAX = DisplayState_Changes::eFlagsChanged;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* DisplayState_Changes_Name(::perfetto::protos::pbzero::DisplayState_Changes value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::DisplayState_Changes::eChangesNone:
+    return "eChangesNone";
+
+  case ::perfetto::protos::pbzero::DisplayState_Changes::eSurfaceChanged:
+    return "eSurfaceChanged";
+
+  case ::perfetto::protos::pbzero::DisplayState_Changes::eLayerStackChanged:
+    return "eLayerStackChanged";
+
+  case ::perfetto::protos::pbzero::DisplayState_Changes::eDisplayProjectionChanged:
+    return "eDisplayProjectionChanged";
+
+  case ::perfetto::protos::pbzero::DisplayState_Changes::eDisplaySizeChanged:
+    return "eDisplaySizeChanged";
+
+  case ::perfetto::protos::pbzero::DisplayState_Changes::eFlagsChanged:
+    return "eFlagsChanged";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_LayerState {
+enum ChangesLsb : int32_t {
+  eChangesLsbNone = 0,
+  ePositionChanged = 1,
+  eLayerChanged = 2,
+  eAlphaChanged = 8,
+  eMatrixChanged = 16,
+  eTransparentRegionChanged = 32,
+  eFlagsChanged = 64,
+  eLayerStackChanged = 128,
+  eReleaseBufferListenerChanged = 1024,
+  eShadowRadiusChanged = 2048,
+  eBufferCropChanged = 8192,
+  eRelativeLayerChanged = 16384,
+  eReparent = 32768,
+  eColorChanged = 65536,
+  eBufferTransformChanged = 262144,
+  eTransformToDisplayInverseChanged = 524288,
+  eCropChanged = 1048576,
+  eBufferChanged = 2097152,
+  eAcquireFenceChanged = 4194304,
+  eDataspaceChanged = 8388608,
+  eHdrMetadataChanged = 16777216,
+  eSurfaceDamageRegionChanged = 33554432,
+  eApiChanged = 67108864,
+  eSidebandStreamChanged = 134217728,
+  eColorTransformChanged = 268435456,
+  eHasListenerCallbacksChanged = 536870912,
+  eInputInfoChanged = 1073741824,
+  eCornerRadiusChanged = -2147483648,
+};
+} // namespace perfetto_pbzero_enum_LayerState
+using LayerState_ChangesLsb = perfetto_pbzero_enum_LayerState::ChangesLsb;
+
+
+constexpr LayerState_ChangesLsb LayerState_ChangesLsb_MIN = LayerState_ChangesLsb::eCornerRadiusChanged;
+constexpr LayerState_ChangesLsb LayerState_ChangesLsb_MAX = LayerState_ChangesLsb::eInputInfoChanged;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* LayerState_ChangesLsb_Name(::perfetto::protos::pbzero::LayerState_ChangesLsb value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eChangesLsbNone:
+    return "eChangesLsbNone";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::ePositionChanged:
+    return "ePositionChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eLayerChanged:
+    return "eLayerChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eAlphaChanged:
+    return "eAlphaChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eMatrixChanged:
+    return "eMatrixChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eTransparentRegionChanged:
+    return "eTransparentRegionChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eFlagsChanged:
+    return "eFlagsChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eLayerStackChanged:
+    return "eLayerStackChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eReleaseBufferListenerChanged:
+    return "eReleaseBufferListenerChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eShadowRadiusChanged:
+    return "eShadowRadiusChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eBufferCropChanged:
+    return "eBufferCropChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eRelativeLayerChanged:
+    return "eRelativeLayerChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eReparent:
+    return "eReparent";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eColorChanged:
+    return "eColorChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eBufferTransformChanged:
+    return "eBufferTransformChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eTransformToDisplayInverseChanged:
+    return "eTransformToDisplayInverseChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eCropChanged:
+    return "eCropChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eBufferChanged:
+    return "eBufferChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eAcquireFenceChanged:
+    return "eAcquireFenceChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eDataspaceChanged:
+    return "eDataspaceChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eHdrMetadataChanged:
+    return "eHdrMetadataChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eSurfaceDamageRegionChanged:
+    return "eSurfaceDamageRegionChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eApiChanged:
+    return "eApiChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eSidebandStreamChanged:
+    return "eSidebandStreamChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eColorTransformChanged:
+    return "eColorTransformChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eHasListenerCallbacksChanged:
+    return "eHasListenerCallbacksChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eInputInfoChanged:
+    return "eInputInfoChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eCornerRadiusChanged:
+    return "eCornerRadiusChanged";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_LayerState {
+enum ChangesMsb : int32_t {
+  eChangesMsbNone = 0,
+  eDestinationFrameChanged = 1,
+  eCachedBufferChanged = 2,
+  eBackgroundColorChanged = 4,
+  eMetadataChanged = 8,
+  eColorSpaceAgnosticChanged = 16,
+  eFrameRateSelectionPriority = 32,
+  eFrameRateChanged = 64,
+  eBackgroundBlurRadiusChanged = 128,
+  eProducerDisconnect = 256,
+  eFixedTransformHintChanged = 512,
+  eFrameNumberChanged = 1024,
+  eBlurRegionsChanged = 2048,
+  eAutoRefreshChanged = 4096,
+  eStretchChanged = 8192,
+  eTrustedOverlayChanged = 16384,
+  eDropInputModeChanged = 32768,
+};
+} // namespace perfetto_pbzero_enum_LayerState
+using LayerState_ChangesMsb = perfetto_pbzero_enum_LayerState::ChangesMsb;
+
+
+constexpr LayerState_ChangesMsb LayerState_ChangesMsb_MIN = LayerState_ChangesMsb::eChangesMsbNone;
+constexpr LayerState_ChangesMsb LayerState_ChangesMsb_MAX = LayerState_ChangesMsb::eDropInputModeChanged;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* LayerState_ChangesMsb_Name(::perfetto::protos::pbzero::LayerState_ChangesMsb value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::LayerState_ChangesMsb::eChangesMsbNone:
+    return "eChangesMsbNone";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesMsb::eDestinationFrameChanged:
+    return "eDestinationFrameChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesMsb::eCachedBufferChanged:
+    return "eCachedBufferChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesMsb::eBackgroundColorChanged:
+    return "eBackgroundColorChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesMsb::eMetadataChanged:
+    return "eMetadataChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesMsb::eColorSpaceAgnosticChanged:
+    return "eColorSpaceAgnosticChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesMsb::eFrameRateSelectionPriority:
+    return "eFrameRateSelectionPriority";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesMsb::eFrameRateChanged:
+    return "eFrameRateChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesMsb::eBackgroundBlurRadiusChanged:
+    return "eBackgroundBlurRadiusChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesMsb::eProducerDisconnect:
+    return "eProducerDisconnect";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesMsb::eFixedTransformHintChanged:
+    return "eFixedTransformHintChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesMsb::eFrameNumberChanged:
+    return "eFrameNumberChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesMsb::eBlurRegionsChanged:
+    return "eBlurRegionsChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesMsb::eAutoRefreshChanged:
+    return "eAutoRefreshChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesMsb::eStretchChanged:
+    return "eStretchChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesMsb::eTrustedOverlayChanged:
+    return "eTrustedOverlayChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesMsb::eDropInputModeChanged:
+    return "eDropInputModeChanged";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_LayerState {
+enum Flags : int32_t {
+  eFlagsNone = 0,
+  eLayerHidden = 1,
+  eLayerOpaque = 2,
+  eLayerSkipScreenshot = 64,
+  eLayerSecure = 128,
+  eEnableBackpressure = 256,
+  eLayerIsDisplayDecoration = 512,
+};
+} // namespace perfetto_pbzero_enum_LayerState
+using LayerState_Flags = perfetto_pbzero_enum_LayerState::Flags;
+
+
+constexpr LayerState_Flags LayerState_Flags_MIN = LayerState_Flags::eFlagsNone;
+constexpr LayerState_Flags LayerState_Flags_MAX = LayerState_Flags::eLayerIsDisplayDecoration;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* LayerState_Flags_Name(::perfetto::protos::pbzero::LayerState_Flags value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::LayerState_Flags::eFlagsNone:
+    return "eFlagsNone";
+
+  case ::perfetto::protos::pbzero::LayerState_Flags::eLayerHidden:
+    return "eLayerHidden";
+
+  case ::perfetto::protos::pbzero::LayerState_Flags::eLayerOpaque:
+    return "eLayerOpaque";
+
+  case ::perfetto::protos::pbzero::LayerState_Flags::eLayerSkipScreenshot:
+    return "eLayerSkipScreenshot";
+
+  case ::perfetto::protos::pbzero::LayerState_Flags::eLayerSecure:
+    return "eLayerSecure";
+
+  case ::perfetto::protos::pbzero::LayerState_Flags::eEnableBackpressure:
+    return "eEnableBackpressure";
+
+  case ::perfetto::protos::pbzero::LayerState_Flags::eLayerIsDisplayDecoration:
+    return "eLayerIsDisplayDecoration";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_LayerState {
+enum DropInputMode : int32_t {
+  NONE = 0,
+  ALL = 1,
+  OBSCURED = 2,
+};
+} // namespace perfetto_pbzero_enum_LayerState
+using LayerState_DropInputMode = perfetto_pbzero_enum_LayerState::DropInputMode;
+
+
+constexpr LayerState_DropInputMode LayerState_DropInputMode_MIN = LayerState_DropInputMode::NONE;
+constexpr LayerState_DropInputMode LayerState_DropInputMode_MAX = LayerState_DropInputMode::OBSCURED;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* LayerState_DropInputMode_Name(::perfetto::protos::pbzero::LayerState_DropInputMode value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::LayerState_DropInputMode::NONE:
+    return "NONE";
+
+  case ::perfetto::protos::pbzero::LayerState_DropInputMode::ALL:
+    return "ALL";
+
+  case ::perfetto::protos::pbzero::LayerState_DropInputMode::OBSCURED:
+    return "OBSCURED";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_LayerState_BufferData {
+enum BufferDataChange : int32_t {
+  BufferDataChangeNone = 0,
+  fenceChanged = 1,
+  frameNumberChanged = 2,
+  cachedBufferChanged = 4,
+};
+} // namespace perfetto_pbzero_enum_LayerState_BufferData
+using LayerState_BufferData_BufferDataChange = perfetto_pbzero_enum_LayerState_BufferData::BufferDataChange;
+
+
+constexpr LayerState_BufferData_BufferDataChange LayerState_BufferData_BufferDataChange_MIN = LayerState_BufferData_BufferDataChange::BufferDataChangeNone;
+constexpr LayerState_BufferData_BufferDataChange LayerState_BufferData_BufferDataChange_MAX = LayerState_BufferData_BufferDataChange::cachedBufferChanged;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* LayerState_BufferData_BufferDataChange_Name(::perfetto::protos::pbzero::LayerState_BufferData_BufferDataChange value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::LayerState_BufferData_BufferDataChange::BufferDataChangeNone:
+    return "BufferDataChangeNone";
+
+  case ::perfetto::protos::pbzero::LayerState_BufferData_BufferDataChange::fenceChanged:
+    return "fenceChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_BufferData_BufferDataChange::frameNumberChanged:
+    return "frameNumberChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_BufferData_BufferDataChange::cachedBufferChanged:
+    return "cachedBufferChanged";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_LayerState_BufferData {
+enum PixelFormat : int32_t {
+  PIXEL_FORMAT_UNKNOWN = 0,
+  PIXEL_FORMAT_CUSTOM = -4,
+  PIXEL_FORMAT_TRANSLUCENT = -3,
+  PIXEL_FORMAT_TRANSPARENT = -2,
+  PIXEL_FORMAT_OPAQUE = -1,
+  PIXEL_FORMAT_RGBA_8888 = 1,
+  PIXEL_FORMAT_RGBX_8888 = 2,
+  PIXEL_FORMAT_RGB_888 = 3,
+  PIXEL_FORMAT_RGB_565 = 4,
+  PIXEL_FORMAT_BGRA_8888 = 5,
+  PIXEL_FORMAT_RGBA_5551 = 6,
+  PIXEL_FORMAT_RGBA_4444 = 7,
+  PIXEL_FORMAT_RGBA_FP16 = 22,
+  PIXEL_FORMAT_RGBA_1010102 = 43,
+  PIXEL_FORMAT_R_8 = 56,
+};
+} // namespace perfetto_pbzero_enum_LayerState_BufferData
+using LayerState_BufferData_PixelFormat = perfetto_pbzero_enum_LayerState_BufferData::PixelFormat;
+
+
+constexpr LayerState_BufferData_PixelFormat LayerState_BufferData_PixelFormat_MIN = LayerState_BufferData_PixelFormat::PIXEL_FORMAT_CUSTOM;
+constexpr LayerState_BufferData_PixelFormat LayerState_BufferData_PixelFormat_MAX = LayerState_BufferData_PixelFormat::PIXEL_FORMAT_R_8;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* LayerState_BufferData_PixelFormat_Name(::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat::PIXEL_FORMAT_UNKNOWN:
+    return "PIXEL_FORMAT_UNKNOWN";
+
+  case ::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat::PIXEL_FORMAT_CUSTOM:
+    return "PIXEL_FORMAT_CUSTOM";
+
+  case ::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat::PIXEL_FORMAT_TRANSLUCENT:
+    return "PIXEL_FORMAT_TRANSLUCENT";
+
+  case ::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat::PIXEL_FORMAT_TRANSPARENT:
+    return "PIXEL_FORMAT_TRANSPARENT";
+
+  case ::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat::PIXEL_FORMAT_OPAQUE:
+    return "PIXEL_FORMAT_OPAQUE";
+
+  case ::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat::PIXEL_FORMAT_RGBA_8888:
+    return "PIXEL_FORMAT_RGBA_8888";
+
+  case ::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat::PIXEL_FORMAT_RGBX_8888:
+    return "PIXEL_FORMAT_RGBX_8888";
+
+  case ::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat::PIXEL_FORMAT_RGB_888:
+    return "PIXEL_FORMAT_RGB_888";
+
+  case ::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat::PIXEL_FORMAT_RGB_565:
+    return "PIXEL_FORMAT_RGB_565";
+
+  case ::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat::PIXEL_FORMAT_BGRA_8888:
+    return "PIXEL_FORMAT_BGRA_8888";
+
+  case ::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat::PIXEL_FORMAT_RGBA_5551:
+    return "PIXEL_FORMAT_RGBA_5551";
+
+  case ::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat::PIXEL_FORMAT_RGBA_4444:
+    return "PIXEL_FORMAT_RGBA_4444";
+
+  case ::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat::PIXEL_FORMAT_RGBA_FP16:
+    return "PIXEL_FORMAT_RGBA_FP16";
+
+  case ::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat::PIXEL_FORMAT_RGBA_1010102:
+    return "PIXEL_FORMAT_RGBA_1010102";
+
+  case ::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat::PIXEL_FORMAT_R_8:
+    return "PIXEL_FORMAT_R_8";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_TransactionTraceFile {
+enum MagicNumber : int32_t {
+  INVALID = 0,
+  MAGIC_NUMBER_L = 1415073364,
+  MAGIC_NUMBER_H = 1162035538,
+};
+} // namespace perfetto_pbzero_enum_TransactionTraceFile
+using TransactionTraceFile_MagicNumber = perfetto_pbzero_enum_TransactionTraceFile::MagicNumber;
+
+
+constexpr TransactionTraceFile_MagicNumber TransactionTraceFile_MagicNumber_MIN = TransactionTraceFile_MagicNumber::INVALID;
+constexpr TransactionTraceFile_MagicNumber TransactionTraceFile_MagicNumber_MAX = TransactionTraceFile_MagicNumber::MAGIC_NUMBER_L;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* TransactionTraceFile_MagicNumber_Name(::perfetto::protos::pbzero::TransactionTraceFile_MagicNumber value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::TransactionTraceFile_MagicNumber::INVALID:
+    return "INVALID";
+
+  case ::perfetto::protos::pbzero::TransactionTraceFile_MagicNumber::MAGIC_NUMBER_L:
+    return "MAGIC_NUMBER_L";
+
+  case ::perfetto::protos::pbzero::TransactionTraceFile_MagicNumber::MAGIC_NUMBER_H:
+    return "MAGIC_NUMBER_H";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class DisplayState_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DisplayState_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DisplayState_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DisplayState_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  int32_t id() const { return at<1>().as_int32(); }
+  bool has_what() const { return at<2>().valid(); }
+  uint32_t what() const { return at<2>().as_uint32(); }
+  bool has_flags() const { return at<3>().valid(); }
+  uint32_t flags() const { return at<3>().as_uint32(); }
+  bool has_layer_stack() const { return at<4>().valid(); }
+  uint32_t layer_stack() const { return at<4>().as_uint32(); }
+  bool has_orientation() const { return at<5>().valid(); }
+  uint32_t orientation() const { return at<5>().as_uint32(); }
+  bool has_layer_stack_space_rect() const { return at<6>().valid(); }
+  ::protozero::ConstBytes layer_stack_space_rect() const { return at<6>().as_bytes(); }
+  bool has_oriented_display_space_rect() const { return at<7>().valid(); }
+  ::protozero::ConstBytes oriented_display_space_rect() const { return at<7>().as_bytes(); }
+  bool has_width() const { return at<8>().valid(); }
+  uint32_t width() const { return at<8>().as_uint32(); }
+  bool has_height() const { return at<9>().valid(); }
+  uint32_t height() const { return at<9>().as_uint32(); }
+};
+
+class DisplayState : public ::protozero::Message {
+ public:
+  using Decoder = DisplayState_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kWhatFieldNumber = 2,
+    kFlagsFieldNumber = 3,
+    kLayerStackFieldNumber = 4,
+    kOrientationFieldNumber = 5,
+    kLayerStackSpaceRectFieldNumber = 6,
+    kOrientedDisplaySpaceRectFieldNumber = 7,
+    kWidthFieldNumber = 8,
+    kHeightFieldNumber = 9,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DisplayState"; }
+
+
+  using Changes = ::perfetto::protos::pbzero::DisplayState_Changes;
+  static inline const char* Changes_Name(Changes value) {
+    return ::perfetto::protos::pbzero::DisplayState_Changes_Name(value);
+  }
+  static inline const Changes eChangesNone = Changes::eChangesNone;
+  static inline const Changes eSurfaceChanged = Changes::eSurfaceChanged;
+  static inline const Changes eLayerStackChanged = Changes::eLayerStackChanged;
+  static inline const Changes eDisplayProjectionChanged = Changes::eDisplayProjectionChanged;
+  static inline const Changes eDisplaySizeChanged = Changes::eDisplaySizeChanged;
+  static inline const Changes eFlagsChanged = Changes::eFlagsChanged;
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      DisplayState>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::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_What =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DisplayState>;
+
+  static constexpr FieldMetadata_What kWhat{};
+  void set_what(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_What::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DisplayState>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_LayerStack =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DisplayState>;
+
+  static constexpr FieldMetadata_LayerStack kLayerStack{};
+  void set_layer_stack(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LayerStack::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_Orientation =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DisplayState>;
+
+  static constexpr FieldMetadata_Orientation kOrientation{};
+  void set_orientation(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Orientation::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_LayerStackSpaceRect =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RectProto,
+      DisplayState>;
+
+  static constexpr FieldMetadata_LayerStackSpaceRect kLayerStackSpaceRect{};
+  template <typename T = RectProto> T* set_layer_stack_space_rect() {
+    return BeginNestedMessage<T>(6);
+  }
+
+
+  using FieldMetadata_OrientedDisplaySpaceRect =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RectProto,
+      DisplayState>;
+
+  static constexpr FieldMetadata_OrientedDisplaySpaceRect kOrientedDisplaySpaceRect{};
+  template <typename T = RectProto> T* set_oriented_display_space_rect() {
+    return BeginNestedMessage<T>(7);
+  }
+
+
+  using FieldMetadata_Width =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DisplayState>;
+
+  static constexpr FieldMetadata_Width kWidth{};
+  void set_width(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Width::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_Height =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DisplayState>;
+
+  static constexpr FieldMetadata_Height kHeight{};
+  void set_height(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Height::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 LayerState_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/42, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  LayerState_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit LayerState_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit LayerState_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_layer_id() const { return at<1>().valid(); }
+  uint32_t layer_id() const { return at<1>().as_uint32(); }
+  bool has_what() const { return at<2>().valid(); }
+  uint64_t what() const { return at<2>().as_uint64(); }
+  bool has_x() const { return at<3>().valid(); }
+  float x() const { return at<3>().as_float(); }
+  bool has_y() const { return at<4>().valid(); }
+  float y() const { return at<4>().as_float(); }
+  bool has_z() const { return at<5>().valid(); }
+  int32_t z() const { return at<5>().as_int32(); }
+  bool has_w() const { return at<6>().valid(); }
+  uint32_t w() const { return at<6>().as_uint32(); }
+  bool has_h() const { return at<7>().valid(); }
+  uint32_t h() const { return at<7>().as_uint32(); }
+  bool has_layer_stack() const { return at<8>().valid(); }
+  uint32_t layer_stack() const { return at<8>().as_uint32(); }
+  bool has_flags() const { return at<9>().valid(); }
+  uint32_t flags() const { return at<9>().as_uint32(); }
+  bool has_mask() const { return at<10>().valid(); }
+  uint32_t mask() const { return at<10>().as_uint32(); }
+  bool has_matrix() const { return at<11>().valid(); }
+  ::protozero::ConstBytes matrix() const { return at<11>().as_bytes(); }
+  bool has_corner_radius() const { return at<12>().valid(); }
+  float corner_radius() const { return at<12>().as_float(); }
+  bool has_background_blur_radius() const { return at<13>().valid(); }
+  uint32_t background_blur_radius() const { return at<13>().as_uint32(); }
+  bool has_parent_id() const { return at<14>().valid(); }
+  uint32_t parent_id() const { return at<14>().as_uint32(); }
+  bool has_relative_parent_id() const { return at<15>().valid(); }
+  uint32_t relative_parent_id() const { return at<15>().as_uint32(); }
+  bool has_alpha() const { return at<16>().valid(); }
+  float alpha() const { return at<16>().as_float(); }
+  bool has_color() const { return at<17>().valid(); }
+  ::protozero::ConstBytes color() const { return at<17>().as_bytes(); }
+  bool has_transparent_region() const { return at<18>().valid(); }
+  ::protozero::ConstBytes transparent_region() const { return at<18>().as_bytes(); }
+  bool has_transform() const { return at<19>().valid(); }
+  uint32_t transform() const { return at<19>().as_uint32(); }
+  bool has_transform_to_display_inverse() const { return at<20>().valid(); }
+  bool transform_to_display_inverse() const { return at<20>().as_bool(); }
+  bool has_crop() const { return at<21>().valid(); }
+  ::protozero::ConstBytes crop() const { return at<21>().as_bytes(); }
+  bool has_buffer_data() const { return at<22>().valid(); }
+  ::protozero::ConstBytes buffer_data() const { return at<22>().as_bytes(); }
+  bool has_api() const { return at<23>().valid(); }
+  int32_t api() const { return at<23>().as_int32(); }
+  bool has_has_sideband_stream() const { return at<24>().valid(); }
+  bool has_sideband_stream() const { return at<24>().as_bool(); }
+  bool has_color_transform() const { return at<25>().valid(); }
+  ::protozero::ConstBytes color_transform() const { return at<25>().as_bytes(); }
+  bool has_blur_regions() const { return at<26>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> blur_regions() const { return GetRepeated<::protozero::ConstBytes>(26); }
+  bool has_window_info_handle() const { return at<27>().valid(); }
+  ::protozero::ConstBytes window_info_handle() const { return at<27>().as_bytes(); }
+  bool has_bg_color_alpha() const { return at<28>().valid(); }
+  float bg_color_alpha() const { return at<28>().as_float(); }
+  bool has_bg_color_dataspace() const { return at<29>().valid(); }
+  int32_t bg_color_dataspace() const { return at<29>().as_int32(); }
+  bool has_color_space_agnostic() const { return at<30>().valid(); }
+  bool color_space_agnostic() const { return at<30>().as_bool(); }
+  bool has_shadow_radius() const { return at<31>().valid(); }
+  float shadow_radius() const { return at<31>().as_float(); }
+  bool has_frame_rate_selection_priority() const { return at<32>().valid(); }
+  int32_t frame_rate_selection_priority() const { return at<32>().as_int32(); }
+  bool has_frame_rate() const { return at<33>().valid(); }
+  float frame_rate() const { return at<33>().as_float(); }
+  bool has_frame_rate_compatibility() const { return at<34>().valid(); }
+  int32_t frame_rate_compatibility() const { return at<34>().as_int32(); }
+  bool has_change_frame_rate_strategy() const { return at<35>().valid(); }
+  int32_t change_frame_rate_strategy() const { return at<35>().as_int32(); }
+  bool has_fixed_transform_hint() const { return at<36>().valid(); }
+  uint32_t fixed_transform_hint() const { return at<36>().as_uint32(); }
+  bool has_frame_number() const { return at<37>().valid(); }
+  uint64_t frame_number() const { return at<37>().as_uint64(); }
+  bool has_auto_refresh() const { return at<38>().valid(); }
+  bool auto_refresh() const { return at<38>().as_bool(); }
+  bool has_is_trusted_overlay() const { return at<39>().valid(); }
+  bool is_trusted_overlay() const { return at<39>().as_bool(); }
+  bool has_buffer_crop() const { return at<40>().valid(); }
+  ::protozero::ConstBytes buffer_crop() const { return at<40>().as_bytes(); }
+  bool has_destination_frame() const { return at<41>().valid(); }
+  ::protozero::ConstBytes destination_frame() const { return at<41>().as_bytes(); }
+  bool has_drop_input_mode() const { return at<42>().valid(); }
+  int32_t drop_input_mode() const { return at<42>().as_int32(); }
+};
+
+class LayerState : public ::protozero::Message {
+ public:
+  using Decoder = LayerState_Decoder;
+  enum : int32_t {
+    kLayerIdFieldNumber = 1,
+    kWhatFieldNumber = 2,
+    kXFieldNumber = 3,
+    kYFieldNumber = 4,
+    kZFieldNumber = 5,
+    kWFieldNumber = 6,
+    kHFieldNumber = 7,
+    kLayerStackFieldNumber = 8,
+    kFlagsFieldNumber = 9,
+    kMaskFieldNumber = 10,
+    kMatrixFieldNumber = 11,
+    kCornerRadiusFieldNumber = 12,
+    kBackgroundBlurRadiusFieldNumber = 13,
+    kParentIdFieldNumber = 14,
+    kRelativeParentIdFieldNumber = 15,
+    kAlphaFieldNumber = 16,
+    kColorFieldNumber = 17,
+    kTransparentRegionFieldNumber = 18,
+    kTransformFieldNumber = 19,
+    kTransformToDisplayInverseFieldNumber = 20,
+    kCropFieldNumber = 21,
+    kBufferDataFieldNumber = 22,
+    kApiFieldNumber = 23,
+    kHasSidebandStreamFieldNumber = 24,
+    kColorTransformFieldNumber = 25,
+    kBlurRegionsFieldNumber = 26,
+    kWindowInfoHandleFieldNumber = 27,
+    kBgColorAlphaFieldNumber = 28,
+    kBgColorDataspaceFieldNumber = 29,
+    kColorSpaceAgnosticFieldNumber = 30,
+    kShadowRadiusFieldNumber = 31,
+    kFrameRateSelectionPriorityFieldNumber = 32,
+    kFrameRateFieldNumber = 33,
+    kFrameRateCompatibilityFieldNumber = 34,
+    kChangeFrameRateStrategyFieldNumber = 35,
+    kFixedTransformHintFieldNumber = 36,
+    kFrameNumberFieldNumber = 37,
+    kAutoRefreshFieldNumber = 38,
+    kIsTrustedOverlayFieldNumber = 39,
+    kBufferCropFieldNumber = 40,
+    kDestinationFrameFieldNumber = 41,
+    kDropInputModeFieldNumber = 42,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.LayerState"; }
+
+  using Matrix22 = ::perfetto::protos::pbzero::LayerState_Matrix22;
+  using Color3 = ::perfetto::protos::pbzero::LayerState_Color3;
+  using BufferData = ::perfetto::protos::pbzero::LayerState_BufferData;
+  using WindowInfo = ::perfetto::protos::pbzero::LayerState_WindowInfo;
+
+  using ChangesLsb = ::perfetto::protos::pbzero::LayerState_ChangesLsb;
+  static inline const char* ChangesLsb_Name(ChangesLsb value) {
+    return ::perfetto::protos::pbzero::LayerState_ChangesLsb_Name(value);
+  }
+
+  using ChangesMsb = ::perfetto::protos::pbzero::LayerState_ChangesMsb;
+  static inline const char* ChangesMsb_Name(ChangesMsb value) {
+    return ::perfetto::protos::pbzero::LayerState_ChangesMsb_Name(value);
+  }
+
+  using Flags = ::perfetto::protos::pbzero::LayerState_Flags;
+  static inline const char* Flags_Name(Flags value) {
+    return ::perfetto::protos::pbzero::LayerState_Flags_Name(value);
+  }
+
+  using DropInputMode = ::perfetto::protos::pbzero::LayerState_DropInputMode;
+  static inline const char* DropInputMode_Name(DropInputMode value) {
+    return ::perfetto::protos::pbzero::LayerState_DropInputMode_Name(value);
+  }
+  static inline const ChangesLsb eChangesLsbNone = ChangesLsb::eChangesLsbNone;
+  static inline const ChangesLsb ePositionChanged = ChangesLsb::ePositionChanged;
+  static inline const ChangesLsb eLayerChanged = ChangesLsb::eLayerChanged;
+  static inline const ChangesLsb eAlphaChanged = ChangesLsb::eAlphaChanged;
+  static inline const ChangesLsb eMatrixChanged = ChangesLsb::eMatrixChanged;
+  static inline const ChangesLsb eTransparentRegionChanged = ChangesLsb::eTransparentRegionChanged;
+  static inline const ChangesLsb eFlagsChanged = ChangesLsb::eFlagsChanged;
+  static inline const ChangesLsb eLayerStackChanged = ChangesLsb::eLayerStackChanged;
+  static inline const ChangesLsb eReleaseBufferListenerChanged = ChangesLsb::eReleaseBufferListenerChanged;
+  static inline const ChangesLsb eShadowRadiusChanged = ChangesLsb::eShadowRadiusChanged;
+  static inline const ChangesLsb eBufferCropChanged = ChangesLsb::eBufferCropChanged;
+  static inline const ChangesLsb eRelativeLayerChanged = ChangesLsb::eRelativeLayerChanged;
+  static inline const ChangesLsb eReparent = ChangesLsb::eReparent;
+  static inline const ChangesLsb eColorChanged = ChangesLsb::eColorChanged;
+  static inline const ChangesLsb eBufferTransformChanged = ChangesLsb::eBufferTransformChanged;
+  static inline const ChangesLsb eTransformToDisplayInverseChanged = ChangesLsb::eTransformToDisplayInverseChanged;
+  static inline const ChangesLsb eCropChanged = ChangesLsb::eCropChanged;
+  static inline const ChangesLsb eBufferChanged = ChangesLsb::eBufferChanged;
+  static inline const ChangesLsb eAcquireFenceChanged = ChangesLsb::eAcquireFenceChanged;
+  static inline const ChangesLsb eDataspaceChanged = ChangesLsb::eDataspaceChanged;
+  static inline const ChangesLsb eHdrMetadataChanged = ChangesLsb::eHdrMetadataChanged;
+  static inline const ChangesLsb eSurfaceDamageRegionChanged = ChangesLsb::eSurfaceDamageRegionChanged;
+  static inline const ChangesLsb eApiChanged = ChangesLsb::eApiChanged;
+  static inline const ChangesLsb eSidebandStreamChanged = ChangesLsb::eSidebandStreamChanged;
+  static inline const ChangesLsb eColorTransformChanged = ChangesLsb::eColorTransformChanged;
+  static inline const ChangesLsb eHasListenerCallbacksChanged = ChangesLsb::eHasListenerCallbacksChanged;
+  static inline const ChangesLsb eInputInfoChanged = ChangesLsb::eInputInfoChanged;
+  static inline const ChangesLsb eCornerRadiusChanged = ChangesLsb::eCornerRadiusChanged;
+  static inline const ChangesMsb eChangesMsbNone = ChangesMsb::eChangesMsbNone;
+  static inline const ChangesMsb eDestinationFrameChanged = ChangesMsb::eDestinationFrameChanged;
+  static inline const ChangesMsb eCachedBufferChanged = ChangesMsb::eCachedBufferChanged;
+  static inline const ChangesMsb eBackgroundColorChanged = ChangesMsb::eBackgroundColorChanged;
+  static inline const ChangesMsb eMetadataChanged = ChangesMsb::eMetadataChanged;
+  static inline const ChangesMsb eColorSpaceAgnosticChanged = ChangesMsb::eColorSpaceAgnosticChanged;
+  static inline const ChangesMsb eFrameRateSelectionPriority = ChangesMsb::eFrameRateSelectionPriority;
+  static inline const ChangesMsb eFrameRateChanged = ChangesMsb::eFrameRateChanged;
+  static inline const ChangesMsb eBackgroundBlurRadiusChanged = ChangesMsb::eBackgroundBlurRadiusChanged;
+  static inline const ChangesMsb eProducerDisconnect = ChangesMsb::eProducerDisconnect;
+  static inline const ChangesMsb eFixedTransformHintChanged = ChangesMsb::eFixedTransformHintChanged;
+  static inline const ChangesMsb eFrameNumberChanged = ChangesMsb::eFrameNumberChanged;
+  static inline const ChangesMsb eBlurRegionsChanged = ChangesMsb::eBlurRegionsChanged;
+  static inline const ChangesMsb eAutoRefreshChanged = ChangesMsb::eAutoRefreshChanged;
+  static inline const ChangesMsb eStretchChanged = ChangesMsb::eStretchChanged;
+  static inline const ChangesMsb eTrustedOverlayChanged = ChangesMsb::eTrustedOverlayChanged;
+  static inline const ChangesMsb eDropInputModeChanged = ChangesMsb::eDropInputModeChanged;
+  static inline const Flags eFlagsNone = Flags::eFlagsNone;
+  static inline const Flags eLayerHidden = Flags::eLayerHidden;
+  static inline const Flags eLayerOpaque = Flags::eLayerOpaque;
+  static inline const Flags eLayerSkipScreenshot = Flags::eLayerSkipScreenshot;
+  static inline const Flags eLayerSecure = Flags::eLayerSecure;
+  static inline const Flags eEnableBackpressure = Flags::eEnableBackpressure;
+  static inline const Flags eLayerIsDisplayDecoration = Flags::eLayerIsDisplayDecoration;
+  static inline const DropInputMode NONE = DropInputMode::NONE;
+  static inline const DropInputMode ALL = DropInputMode::ALL;
+  static inline const DropInputMode OBSCURED = DropInputMode::OBSCURED;
+
+  using FieldMetadata_LayerId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_LayerId kLayerId{};
+  void set_layer_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LayerId::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_What =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_What kWhat{};
+  void set_what(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_What::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_X =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      LayerState>;
+
+  static constexpr FieldMetadata_X kX{};
+  void set_x(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_X::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Y =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      LayerState>;
+
+  static constexpr FieldMetadata_Y kY{};
+  void set_y(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Y::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Z =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_Z kZ{};
+  void set_z(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Z::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_W =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_W kW{};
+  void set_w(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_W::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_H =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_H kH{};
+  void set_h(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_H::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_LayerStack =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_LayerStack kLayerStack{};
+  void set_layer_stack(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LayerStack::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_Mask =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_Mask kMask{};
+  void set_mask(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mask::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_Matrix =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      LayerState_Matrix22,
+      LayerState>;
+
+  static constexpr FieldMetadata_Matrix kMatrix{};
+  template <typename T = LayerState_Matrix22> T* set_matrix() {
+    return BeginNestedMessage<T>(11);
+  }
+
+
+  using FieldMetadata_CornerRadius =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      LayerState>;
+
+  static constexpr FieldMetadata_CornerRadius kCornerRadius{};
+  void set_corner_radius(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_CornerRadius::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BackgroundBlurRadius =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_BackgroundBlurRadius kBackgroundBlurRadius{};
+  void set_background_blur_radius(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BackgroundBlurRadius::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_ParentId =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_ParentId kParentId{};
+  void set_parent_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ParentId::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_RelativeParentId =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_RelativeParentId kRelativeParentId{};
+  void set_relative_parent_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RelativeParentId::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_Alpha =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      LayerState>;
+
+  static constexpr FieldMetadata_Alpha kAlpha{};
+  void set_alpha(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Alpha::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Color =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      LayerState_Color3,
+      LayerState>;
+
+  static constexpr FieldMetadata_Color kColor{};
+  template <typename T = LayerState_Color3> T* set_color() {
+    return BeginNestedMessage<T>(17);
+  }
+
+
+  using FieldMetadata_TransparentRegion =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RegionProto,
+      LayerState>;
+
+  static constexpr FieldMetadata_TransparentRegion kTransparentRegion{};
+  template <typename T = RegionProto> T* set_transparent_region() {
+    return BeginNestedMessage<T>(18);
+  }
+
+
+  using FieldMetadata_Transform =
+    ::protozero::proto_utils::FieldMetadata<
+      19,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_Transform kTransform{};
+  void set_transform(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Transform::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_TransformToDisplayInverse =
+    ::protozero::proto_utils::FieldMetadata<
+      20,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      LayerState>;
+
+  static constexpr FieldMetadata_TransformToDisplayInverse kTransformToDisplayInverse{};
+  void set_transform_to_display_inverse(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_TransformToDisplayInverse::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_Crop =
+    ::protozero::proto_utils::FieldMetadata<
+      21,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RectProto,
+      LayerState>;
+
+  static constexpr FieldMetadata_Crop kCrop{};
+  template <typename T = RectProto> T* set_crop() {
+    return BeginNestedMessage<T>(21);
+  }
+
+
+  using FieldMetadata_BufferData =
+    ::protozero::proto_utils::FieldMetadata<
+      22,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      LayerState_BufferData,
+      LayerState>;
+
+  static constexpr FieldMetadata_BufferData kBufferData{};
+  template <typename T = LayerState_BufferData> T* set_buffer_data() {
+    return BeginNestedMessage<T>(22);
+  }
+
+
+  using FieldMetadata_Api =
+    ::protozero::proto_utils::FieldMetadata<
+      23,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_Api kApi{};
+  void set_api(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Api::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_HasSidebandStream =
+    ::protozero::proto_utils::FieldMetadata<
+      24,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      LayerState>;
+
+  static constexpr FieldMetadata_HasSidebandStream kHasSidebandStream{};
+  void set_has_sideband_stream(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_HasSidebandStream::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_ColorTransform =
+    ::protozero::proto_utils::FieldMetadata<
+      25,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ColorTransformProto,
+      LayerState>;
+
+  static constexpr FieldMetadata_ColorTransform kColorTransform{};
+  template <typename T = ColorTransformProto> T* set_color_transform() {
+    return BeginNestedMessage<T>(25);
+  }
+
+
+  using FieldMetadata_BlurRegions =
+    ::protozero::proto_utils::FieldMetadata<
+      26,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlurRegion,
+      LayerState>;
+
+  static constexpr FieldMetadata_BlurRegions kBlurRegions{};
+  template <typename T = BlurRegion> T* add_blur_regions() {
+    return BeginNestedMessage<T>(26);
+  }
+
+
+  using FieldMetadata_WindowInfoHandle =
+    ::protozero::proto_utils::FieldMetadata<
+      27,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      LayerState_WindowInfo,
+      LayerState>;
+
+  static constexpr FieldMetadata_WindowInfoHandle kWindowInfoHandle{};
+  template <typename T = LayerState_WindowInfo> T* set_window_info_handle() {
+    return BeginNestedMessage<T>(27);
+  }
+
+
+  using FieldMetadata_BgColorAlpha =
+    ::protozero::proto_utils::FieldMetadata<
+      28,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      LayerState>;
+
+  static constexpr FieldMetadata_BgColorAlpha kBgColorAlpha{};
+  void set_bg_color_alpha(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_BgColorAlpha::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BgColorDataspace =
+    ::protozero::proto_utils::FieldMetadata<
+      29,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_BgColorDataspace kBgColorDataspace{};
+  void set_bg_color_dataspace(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BgColorDataspace::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_ColorSpaceAgnostic =
+    ::protozero::proto_utils::FieldMetadata<
+      30,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      LayerState>;
+
+  static constexpr FieldMetadata_ColorSpaceAgnostic kColorSpaceAgnostic{};
+  void set_color_space_agnostic(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ColorSpaceAgnostic::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_ShadowRadius =
+    ::protozero::proto_utils::FieldMetadata<
+      31,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      LayerState>;
+
+  static constexpr FieldMetadata_ShadowRadius kShadowRadius{};
+  void set_shadow_radius(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_ShadowRadius::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FrameRateSelectionPriority =
+    ::protozero::proto_utils::FieldMetadata<
+      32,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_FrameRateSelectionPriority kFrameRateSelectionPriority{};
+  void set_frame_rate_selection_priority(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FrameRateSelectionPriority::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_FrameRate =
+    ::protozero::proto_utils::FieldMetadata<
+      33,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      LayerState>;
+
+  static constexpr FieldMetadata_FrameRate kFrameRate{};
+  void set_frame_rate(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_FrameRate::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FrameRateCompatibility =
+    ::protozero::proto_utils::FieldMetadata<
+      34,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_FrameRateCompatibility kFrameRateCompatibility{};
+  void set_frame_rate_compatibility(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FrameRateCompatibility::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_ChangeFrameRateStrategy =
+    ::protozero::proto_utils::FieldMetadata<
+      35,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_ChangeFrameRateStrategy kChangeFrameRateStrategy{};
+  void set_change_frame_rate_strategy(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChangeFrameRateStrategy::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_FixedTransformHint =
+    ::protozero::proto_utils::FieldMetadata<
+      36,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_FixedTransformHint kFixedTransformHint{};
+  void set_fixed_transform_hint(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FixedTransformHint::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_FrameNumber =
+    ::protozero::proto_utils::FieldMetadata<
+      37,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_FrameNumber kFrameNumber{};
+  void set_frame_number(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FrameNumber::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_AutoRefresh =
+    ::protozero::proto_utils::FieldMetadata<
+      38,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      LayerState>;
+
+  static constexpr FieldMetadata_AutoRefresh kAutoRefresh{};
+  void set_auto_refresh(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_AutoRefresh::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_IsTrustedOverlay =
+    ::protozero::proto_utils::FieldMetadata<
+      39,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      LayerState>;
+
+  static constexpr FieldMetadata_IsTrustedOverlay kIsTrustedOverlay{};
+  void set_is_trusted_overlay(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsTrustedOverlay::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_BufferCrop =
+    ::protozero::proto_utils::FieldMetadata<
+      40,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RectProto,
+      LayerState>;
+
+  static constexpr FieldMetadata_BufferCrop kBufferCrop{};
+  template <typename T = RectProto> T* set_buffer_crop() {
+    return BeginNestedMessage<T>(40);
+  }
+
+
+  using FieldMetadata_DestinationFrame =
+    ::protozero::proto_utils::FieldMetadata<
+      41,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RectProto,
+      LayerState>;
+
+  static constexpr FieldMetadata_DestinationFrame kDestinationFrame{};
+  template <typename T = RectProto> T* set_destination_frame() {
+    return BeginNestedMessage<T>(41);
+  }
+
+
+  using FieldMetadata_DropInputMode =
+    ::protozero::proto_utils::FieldMetadata<
+      42,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      LayerState_DropInputMode,
+      LayerState>;
+
+  static constexpr FieldMetadata_DropInputMode kDropInputMode{};
+  void set_drop_input_mode(LayerState_DropInputMode value) {
+    static constexpr uint32_t field_id = FieldMetadata_DropInputMode::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);
+  }
+};
+
+class LayerState_WindowInfo_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/12, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  LayerState_WindowInfo_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit LayerState_WindowInfo_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit LayerState_WindowInfo_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_layout_params_flags() const { return at<1>().valid(); }
+  uint32_t layout_params_flags() const { return at<1>().as_uint32(); }
+  bool has_layout_params_type() const { return at<2>().valid(); }
+  int32_t layout_params_type() const { return at<2>().as_int32(); }
+  bool has_touchable_region() const { return at<3>().valid(); }
+  ::protozero::ConstBytes touchable_region() const { return at<3>().as_bytes(); }
+  bool has_surface_inset() const { return at<4>().valid(); }
+  int32_t surface_inset() const { return at<4>().as_int32(); }
+  bool has_focusable() const { return at<5>().valid(); }
+  bool focusable() const { return at<5>().as_bool(); }
+  bool has_has_wallpaper() const { return at<6>().valid(); }
+  bool has_wallpaper() const { return at<6>().as_bool(); }
+  bool has_global_scale_factor() const { return at<7>().valid(); }
+  float global_scale_factor() const { return at<7>().as_float(); }
+  bool has_crop_layer_id() const { return at<8>().valid(); }
+  uint32_t crop_layer_id() const { return at<8>().as_uint32(); }
+  bool has_replace_touchable_region_with_crop() const { return at<9>().valid(); }
+  bool replace_touchable_region_with_crop() const { return at<9>().as_bool(); }
+  bool has_touchable_region_crop() const { return at<10>().valid(); }
+  ::protozero::ConstBytes touchable_region_crop() const { return at<10>().as_bytes(); }
+  bool has_transform() const { return at<11>().valid(); }
+  ::protozero::ConstBytes transform() const { return at<11>().as_bytes(); }
+  bool has_input_config() const { return at<12>().valid(); }
+  uint32_t input_config() const { return at<12>().as_uint32(); }
+};
+
+class LayerState_WindowInfo : public ::protozero::Message {
+ public:
+  using Decoder = LayerState_WindowInfo_Decoder;
+  enum : int32_t {
+    kLayoutParamsFlagsFieldNumber = 1,
+    kLayoutParamsTypeFieldNumber = 2,
+    kTouchableRegionFieldNumber = 3,
+    kSurfaceInsetFieldNumber = 4,
+    kFocusableFieldNumber = 5,
+    kHasWallpaperFieldNumber = 6,
+    kGlobalScaleFactorFieldNumber = 7,
+    kCropLayerIdFieldNumber = 8,
+    kReplaceTouchableRegionWithCropFieldNumber = 9,
+    kTouchableRegionCropFieldNumber = 10,
+    kTransformFieldNumber = 11,
+    kInputConfigFieldNumber = 12,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.LayerState.WindowInfo"; }
+
+
+  using FieldMetadata_LayoutParamsFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerState_WindowInfo>;
+
+  static constexpr FieldMetadata_LayoutParamsFlags kLayoutParamsFlags{};
+  void set_layout_params_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LayoutParamsFlags::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_LayoutParamsType =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerState_WindowInfo>;
+
+  static constexpr FieldMetadata_LayoutParamsType kLayoutParamsType{};
+  void set_layout_params_type(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LayoutParamsType::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_TouchableRegion =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RegionProto,
+      LayerState_WindowInfo>;
+
+  static constexpr FieldMetadata_TouchableRegion kTouchableRegion{};
+  template <typename T = RegionProto> T* set_touchable_region() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_SurfaceInset =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerState_WindowInfo>;
+
+  static constexpr FieldMetadata_SurfaceInset kSurfaceInset{};
+  void set_surface_inset(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SurfaceInset::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_Focusable =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      LayerState_WindowInfo>;
+
+  static constexpr FieldMetadata_Focusable kFocusable{};
+  void set_focusable(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_Focusable::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_HasWallpaper =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      LayerState_WindowInfo>;
+
+  static constexpr FieldMetadata_HasWallpaper kHasWallpaper{};
+  void set_has_wallpaper(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_HasWallpaper::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_GlobalScaleFactor =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      LayerState_WindowInfo>;
+
+  static constexpr FieldMetadata_GlobalScaleFactor kGlobalScaleFactor{};
+  void set_global_scale_factor(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_GlobalScaleFactor::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CropLayerId =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerState_WindowInfo>;
+
+  static constexpr FieldMetadata_CropLayerId kCropLayerId{};
+  void set_crop_layer_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CropLayerId::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_ReplaceTouchableRegionWithCrop =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      LayerState_WindowInfo>;
+
+  static constexpr FieldMetadata_ReplaceTouchableRegionWithCrop kReplaceTouchableRegionWithCrop{};
+  void set_replace_touchable_region_with_crop(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReplaceTouchableRegionWithCrop::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_TouchableRegionCrop =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RectProto,
+      LayerState_WindowInfo>;
+
+  static constexpr FieldMetadata_TouchableRegionCrop kTouchableRegionCrop{};
+  template <typename T = RectProto> T* set_touchable_region_crop() {
+    return BeginNestedMessage<T>(10);
+  }
+
+
+  using FieldMetadata_Transform =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Transform,
+      LayerState_WindowInfo>;
+
+  static constexpr FieldMetadata_Transform kTransform{};
+  template <typename T = Transform> T* set_transform() {
+    return BeginNestedMessage<T>(11);
+  }
+
+
+  using FieldMetadata_InputConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerState_WindowInfo>;
+
+  static constexpr FieldMetadata_InputConfig kInputConfig{};
+  void set_input_config(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InputConfig::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 LayerState_BufferData_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  LayerState_BufferData_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit LayerState_BufferData_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit LayerState_BufferData_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_buffer_id() const { return at<1>().valid(); }
+  uint64_t buffer_id() const { return at<1>().as_uint64(); }
+  bool has_width() const { return at<2>().valid(); }
+  uint32_t width() const { return at<2>().as_uint32(); }
+  bool has_height() const { return at<3>().valid(); }
+  uint32_t height() const { return at<3>().as_uint32(); }
+  bool has_frame_number() const { return at<4>().valid(); }
+  uint64_t frame_number() const { return at<4>().as_uint64(); }
+  bool has_flags() const { return at<5>().valid(); }
+  uint32_t flags() const { return at<5>().as_uint32(); }
+  bool has_cached_buffer_id() const { return at<6>().valid(); }
+  uint64_t cached_buffer_id() const { return at<6>().as_uint64(); }
+  bool has_pixel_format() const { return at<7>().valid(); }
+  int32_t pixel_format() const { return at<7>().as_int32(); }
+  bool has_usage() const { return at<8>().valid(); }
+  uint64_t usage() const { return at<8>().as_uint64(); }
+};
+
+class LayerState_BufferData : public ::protozero::Message {
+ public:
+  using Decoder = LayerState_BufferData_Decoder;
+  enum : int32_t {
+    kBufferIdFieldNumber = 1,
+    kWidthFieldNumber = 2,
+    kHeightFieldNumber = 3,
+    kFrameNumberFieldNumber = 4,
+    kFlagsFieldNumber = 5,
+    kCachedBufferIdFieldNumber = 6,
+    kPixelFormatFieldNumber = 7,
+    kUsageFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.LayerState.BufferData"; }
+
+
+  using BufferDataChange = ::perfetto::protos::pbzero::LayerState_BufferData_BufferDataChange;
+  static inline const char* BufferDataChange_Name(BufferDataChange value) {
+    return ::perfetto::protos::pbzero::LayerState_BufferData_BufferDataChange_Name(value);
+  }
+
+  using PixelFormat = ::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat;
+  static inline const char* PixelFormat_Name(PixelFormat value) {
+    return ::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat_Name(value);
+  }
+  static inline const BufferDataChange BufferDataChangeNone = BufferDataChange::BufferDataChangeNone;
+  static inline const BufferDataChange fenceChanged = BufferDataChange::fenceChanged;
+  static inline const BufferDataChange frameNumberChanged = BufferDataChange::frameNumberChanged;
+  static inline const BufferDataChange cachedBufferChanged = BufferDataChange::cachedBufferChanged;
+  static inline const PixelFormat PIXEL_FORMAT_UNKNOWN = PixelFormat::PIXEL_FORMAT_UNKNOWN;
+  static inline const PixelFormat PIXEL_FORMAT_CUSTOM = PixelFormat::PIXEL_FORMAT_CUSTOM;
+  static inline const PixelFormat PIXEL_FORMAT_TRANSLUCENT = PixelFormat::PIXEL_FORMAT_TRANSLUCENT;
+  static inline const PixelFormat PIXEL_FORMAT_TRANSPARENT = PixelFormat::PIXEL_FORMAT_TRANSPARENT;
+  static inline const PixelFormat PIXEL_FORMAT_OPAQUE = PixelFormat::PIXEL_FORMAT_OPAQUE;
+  static inline const PixelFormat PIXEL_FORMAT_RGBA_8888 = PixelFormat::PIXEL_FORMAT_RGBA_8888;
+  static inline const PixelFormat PIXEL_FORMAT_RGBX_8888 = PixelFormat::PIXEL_FORMAT_RGBX_8888;
+  static inline const PixelFormat PIXEL_FORMAT_RGB_888 = PixelFormat::PIXEL_FORMAT_RGB_888;
+  static inline const PixelFormat PIXEL_FORMAT_RGB_565 = PixelFormat::PIXEL_FORMAT_RGB_565;
+  static inline const PixelFormat PIXEL_FORMAT_BGRA_8888 = PixelFormat::PIXEL_FORMAT_BGRA_8888;
+  static inline const PixelFormat PIXEL_FORMAT_RGBA_5551 = PixelFormat::PIXEL_FORMAT_RGBA_5551;
+  static inline const PixelFormat PIXEL_FORMAT_RGBA_4444 = PixelFormat::PIXEL_FORMAT_RGBA_4444;
+  static inline const PixelFormat PIXEL_FORMAT_RGBA_FP16 = PixelFormat::PIXEL_FORMAT_RGBA_FP16;
+  static inline const PixelFormat PIXEL_FORMAT_RGBA_1010102 = PixelFormat::PIXEL_FORMAT_RGBA_1010102;
+  static inline const PixelFormat PIXEL_FORMAT_R_8 = PixelFormat::PIXEL_FORMAT_R_8;
+
+  using FieldMetadata_BufferId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      LayerState_BufferData>;
+
+  static constexpr FieldMetadata_BufferId kBufferId{};
+  void set_buffer_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BufferId::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_Width =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerState_BufferData>;
+
+  static constexpr FieldMetadata_Width kWidth{};
+  void set_width(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Width::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_Height =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerState_BufferData>;
+
+  static constexpr FieldMetadata_Height kHeight{};
+  void set_height(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Height::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_FrameNumber =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      LayerState_BufferData>;
+
+  static constexpr FieldMetadata_FrameNumber kFrameNumber{};
+  void set_frame_number(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FrameNumber::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerState_BufferData>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_CachedBufferId =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      LayerState_BufferData>;
+
+  static constexpr FieldMetadata_CachedBufferId kCachedBufferId{};
+  void set_cached_buffer_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CachedBufferId::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_PixelFormat =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      LayerState_BufferData_PixelFormat,
+      LayerState_BufferData>;
+
+  static constexpr FieldMetadata_PixelFormat kPixelFormat{};
+  void set_pixel_format(LayerState_BufferData_PixelFormat value) {
+    static constexpr uint32_t field_id = FieldMetadata_PixelFormat::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_Usage =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      LayerState_BufferData>;
+
+  static constexpr FieldMetadata_Usage kUsage{};
+  void set_usage(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Usage::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 LayerState_Color3_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  LayerState_Color3_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit LayerState_Color3_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit LayerState_Color3_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_r() const { return at<1>().valid(); }
+  float r() const { return at<1>().as_float(); }
+  bool has_g() const { return at<2>().valid(); }
+  float g() const { return at<2>().as_float(); }
+  bool has_b() const { return at<3>().valid(); }
+  float b() const { return at<3>().as_float(); }
+};
+
+class LayerState_Color3 : public ::protozero::Message {
+ public:
+  using Decoder = LayerState_Color3_Decoder;
+  enum : int32_t {
+    kRFieldNumber = 1,
+    kGFieldNumber = 2,
+    kBFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.LayerState.Color3"; }
+
+
+  using FieldMetadata_R =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      LayerState_Color3>;
+
+  static constexpr FieldMetadata_R kR{};
+  void set_r(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_R::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_G =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      LayerState_Color3>;
+
+  static constexpr FieldMetadata_G kG{};
+  void set_g(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_G::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_B =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      LayerState_Color3>;
+
+  static constexpr FieldMetadata_B kB{};
+  void set_b(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_B::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class LayerState_Matrix22_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  LayerState_Matrix22_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit LayerState_Matrix22_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit LayerState_Matrix22_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dsdx() const { return at<1>().valid(); }
+  float dsdx() const { return at<1>().as_float(); }
+  bool has_dtdx() const { return at<2>().valid(); }
+  float dtdx() const { return at<2>().as_float(); }
+  bool has_dtdy() const { return at<3>().valid(); }
+  float dtdy() const { return at<3>().as_float(); }
+  bool has_dsdy() const { return at<4>().valid(); }
+  float dsdy() const { return at<4>().as_float(); }
+};
+
+class LayerState_Matrix22 : public ::protozero::Message {
+ public:
+  using Decoder = LayerState_Matrix22_Decoder;
+  enum : int32_t {
+    kDsdxFieldNumber = 1,
+    kDtdxFieldNumber = 2,
+    kDtdyFieldNumber = 3,
+    kDsdyFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.LayerState.Matrix22"; }
+
+
+  using FieldMetadata_Dsdx =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      LayerState_Matrix22>;
+
+  static constexpr FieldMetadata_Dsdx kDsdx{};
+  void set_dsdx(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dsdx::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Dtdx =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      LayerState_Matrix22>;
+
+  static constexpr FieldMetadata_Dtdx kDtdx{};
+  void set_dtdx(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dtdx::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Dtdy =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      LayerState_Matrix22>;
+
+  static constexpr FieldMetadata_Dtdy kDtdy{};
+  void set_dtdy(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dtdy::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Dsdy =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      LayerState_Matrix22>;
+
+  static constexpr FieldMetadata_Dsdy kDsdy{};
+  void set_dsdy(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dsdy::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TransactionState_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TransactionState_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TransactionState_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TransactionState_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  int32_t pid() const { return at<1>().as_int32(); }
+  bool has_uid() const { return at<2>().valid(); }
+  int32_t uid() const { return at<2>().as_int32(); }
+  bool has_vsync_id() const { return at<3>().valid(); }
+  int64_t vsync_id() const { return at<3>().as_int64(); }
+  bool has_input_event_id() const { return at<4>().valid(); }
+  int32_t input_event_id() const { return at<4>().as_int32(); }
+  bool has_post_time() const { return at<5>().valid(); }
+  int64_t post_time() const { return at<5>().as_int64(); }
+  bool has_transaction_id() const { return at<6>().valid(); }
+  uint64_t transaction_id() const { return at<6>().as_uint64(); }
+  bool has_layer_changes() const { return at<7>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> layer_changes() const { return GetRepeated<::protozero::ConstBytes>(7); }
+  bool has_display_changes() const { return at<8>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> display_changes() const { return GetRepeated<::protozero::ConstBytes>(8); }
+  bool has_merged_transaction_ids() const { return at<9>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> merged_transaction_ids() const { return GetRepeated<uint64_t>(9); }
+};
+
+class TransactionState : public ::protozero::Message {
+ public:
+  using Decoder = TransactionState_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kUidFieldNumber = 2,
+    kVsyncIdFieldNumber = 3,
+    kInputEventIdFieldNumber = 4,
+    kPostTimeFieldNumber = 5,
+    kTransactionIdFieldNumber = 6,
+    kLayerChangesFieldNumber = 7,
+    kDisplayChangesFieldNumber = 8,
+    kMergedTransactionIdsFieldNumber = 9,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TransactionState"; }
+
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TransactionState>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_Uid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TransactionState>;
+
+  static constexpr FieldMetadata_Uid kUid{};
+  void set_uid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Uid::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_VsyncId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TransactionState>;
+
+  static constexpr FieldMetadata_VsyncId kVsyncId{};
+  void set_vsync_id(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VsyncId::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_InputEventId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TransactionState>;
+
+  static constexpr FieldMetadata_InputEventId kInputEventId{};
+  void set_input_event_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InputEventId::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_PostTime =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TransactionState>;
+
+  static constexpr FieldMetadata_PostTime kPostTime{};
+  void set_post_time(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PostTime::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_TransactionId =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TransactionState>;
+
+  static constexpr FieldMetadata_TransactionId kTransactionId{};
+  void set_transaction_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TransactionId::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_LayerChanges =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      LayerState,
+      TransactionState>;
+
+  static constexpr FieldMetadata_LayerChanges kLayerChanges{};
+  template <typename T = LayerState> T* add_layer_changes() {
+    return BeginNestedMessage<T>(7);
+  }
+
+
+  using FieldMetadata_DisplayChanges =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DisplayState,
+      TransactionState>;
+
+  static constexpr FieldMetadata_DisplayChanges kDisplayChanges{};
+  template <typename T = DisplayState> T* add_display_changes() {
+    return BeginNestedMessage<T>(8);
+  }
+
+
+  using FieldMetadata_MergedTransactionIds =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TransactionState>;
+
+  static constexpr FieldMetadata_MergedTransactionIds kMergedTransactionIds{};
+  void add_merged_transaction_ids(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MergedTransactionIds::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 Transform_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Transform_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Transform_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Transform_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dsdx() const { return at<1>().valid(); }
+  float dsdx() const { return at<1>().as_float(); }
+  bool has_dtdx() const { return at<2>().valid(); }
+  float dtdx() const { return at<2>().as_float(); }
+  bool has_dtdy() const { return at<3>().valid(); }
+  float dtdy() const { return at<3>().as_float(); }
+  bool has_dsdy() const { return at<4>().valid(); }
+  float dsdy() const { return at<4>().as_float(); }
+  bool has_tx() const { return at<5>().valid(); }
+  float tx() const { return at<5>().as_float(); }
+  bool has_ty() const { return at<6>().valid(); }
+  float ty() const { return at<6>().as_float(); }
+};
+
+class Transform : public ::protozero::Message {
+ public:
+  using Decoder = Transform_Decoder;
+  enum : int32_t {
+    kDsdxFieldNumber = 1,
+    kDtdxFieldNumber = 2,
+    kDtdyFieldNumber = 3,
+    kDsdyFieldNumber = 4,
+    kTxFieldNumber = 5,
+    kTyFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Transform"; }
+
+
+  using FieldMetadata_Dsdx =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      Transform>;
+
+  static constexpr FieldMetadata_Dsdx kDsdx{};
+  void set_dsdx(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dsdx::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Dtdx =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      Transform>;
+
+  static constexpr FieldMetadata_Dtdx kDtdx{};
+  void set_dtdx(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dtdx::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Dtdy =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      Transform>;
+
+  static constexpr FieldMetadata_Dtdy kDtdy{};
+  void set_dtdy(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dtdy::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Dsdy =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      Transform>;
+
+  static constexpr FieldMetadata_Dsdy kDsdy{};
+  void set_dsdy(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dsdy::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Tx =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      Transform>;
+
+  static constexpr FieldMetadata_Tx kTx{};
+  void set_tx(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tx::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ty =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      Transform>;
+
+  static constexpr FieldMetadata_Ty kTy{};
+  void set_ty(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ty::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class LayerCreationArgs_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  LayerCreationArgs_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit LayerCreationArgs_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit LayerCreationArgs_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_layer_id() const { return at<1>().valid(); }
+  uint32_t layer_id() const { return at<1>().as_uint32(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+  bool has_flags() const { return at<3>().valid(); }
+  uint32_t flags() const { return at<3>().as_uint32(); }
+  bool has_parent_id() const { return at<4>().valid(); }
+  uint32_t parent_id() const { return at<4>().as_uint32(); }
+  bool has_mirror_from_id() const { return at<5>().valid(); }
+  uint32_t mirror_from_id() const { return at<5>().as_uint32(); }
+  bool has_add_to_root() const { return at<6>().valid(); }
+  bool add_to_root() const { return at<6>().as_bool(); }
+  bool has_layer_stack_to_mirror() const { return at<7>().valid(); }
+  uint32_t layer_stack_to_mirror() const { return at<7>().as_uint32(); }
+};
+
+class LayerCreationArgs : public ::protozero::Message {
+ public:
+  using Decoder = LayerCreationArgs_Decoder;
+  enum : int32_t {
+    kLayerIdFieldNumber = 1,
+    kNameFieldNumber = 2,
+    kFlagsFieldNumber = 3,
+    kParentIdFieldNumber = 4,
+    kMirrorFromIdFieldNumber = 5,
+    kAddToRootFieldNumber = 6,
+    kLayerStackToMirrorFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.LayerCreationArgs"; }
+
+
+  using FieldMetadata_LayerId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerCreationArgs>;
+
+  static constexpr FieldMetadata_LayerId kLayerId{};
+  void set_layer_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LayerId::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      LayerCreationArgs>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerCreationArgs>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_ParentId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerCreationArgs>;
+
+  static constexpr FieldMetadata_ParentId kParentId{};
+  void set_parent_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ParentId::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_MirrorFromId =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerCreationArgs>;
+
+  static constexpr FieldMetadata_MirrorFromId kMirrorFromId{};
+  void set_mirror_from_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MirrorFromId::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_AddToRoot =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      LayerCreationArgs>;
+
+  static constexpr FieldMetadata_AddToRoot kAddToRoot{};
+  void set_add_to_root(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_AddToRoot::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_LayerStackToMirror =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerCreationArgs>;
+
+  static constexpr FieldMetadata_LayerStackToMirror kLayerStackToMirror{};
+  void set_layer_stack_to_mirror(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LayerStackToMirror::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 DisplayInfo_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/12, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DisplayInfo_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DisplayInfo_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DisplayInfo_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_layer_stack() const { return at<1>().valid(); }
+  uint32_t layer_stack() const { return at<1>().as_uint32(); }
+  bool has_display_id() const { return at<2>().valid(); }
+  int32_t display_id() const { return at<2>().as_int32(); }
+  bool has_logical_width() const { return at<3>().valid(); }
+  int32_t logical_width() const { return at<3>().as_int32(); }
+  bool has_logical_height() const { return at<4>().valid(); }
+  int32_t logical_height() const { return at<4>().as_int32(); }
+  bool has_transform_inverse() const { return at<5>().valid(); }
+  ::protozero::ConstBytes transform_inverse() const { return at<5>().as_bytes(); }
+  bool has_transform() const { return at<6>().valid(); }
+  ::protozero::ConstBytes transform() const { return at<6>().as_bytes(); }
+  bool has_receives_input() const { return at<7>().valid(); }
+  bool receives_input() const { return at<7>().as_bool(); }
+  bool has_is_secure() const { return at<8>().valid(); }
+  bool is_secure() const { return at<8>().as_bool(); }
+  bool has_is_primary() const { return at<9>().valid(); }
+  bool is_primary() const { return at<9>().as_bool(); }
+  bool has_is_virtual() const { return at<10>().valid(); }
+  bool is_virtual() const { return at<10>().as_bool(); }
+  bool has_rotation_flags() const { return at<11>().valid(); }
+  int32_t rotation_flags() const { return at<11>().as_int32(); }
+  bool has_transform_hint() const { return at<12>().valid(); }
+  int32_t transform_hint() const { return at<12>().as_int32(); }
+};
+
+class DisplayInfo : public ::protozero::Message {
+ public:
+  using Decoder = DisplayInfo_Decoder;
+  enum : int32_t {
+    kLayerStackFieldNumber = 1,
+    kDisplayIdFieldNumber = 2,
+    kLogicalWidthFieldNumber = 3,
+    kLogicalHeightFieldNumber = 4,
+    kTransformInverseFieldNumber = 5,
+    kTransformFieldNumber = 6,
+    kReceivesInputFieldNumber = 7,
+    kIsSecureFieldNumber = 8,
+    kIsPrimaryFieldNumber = 9,
+    kIsVirtualFieldNumber = 10,
+    kRotationFlagsFieldNumber = 11,
+    kTransformHintFieldNumber = 12,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DisplayInfo"; }
+
+
+  using FieldMetadata_LayerStack =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DisplayInfo>;
+
+  static constexpr FieldMetadata_LayerStack kLayerStack{};
+  void set_layer_stack(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LayerStack::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_DisplayId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      DisplayInfo>;
+
+  static constexpr FieldMetadata_DisplayId kDisplayId{};
+  void set_display_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DisplayId::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_LogicalWidth =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      DisplayInfo>;
+
+  static constexpr FieldMetadata_LogicalWidth kLogicalWidth{};
+  void set_logical_width(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LogicalWidth::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_LogicalHeight =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      DisplayInfo>;
+
+  static constexpr FieldMetadata_LogicalHeight kLogicalHeight{};
+  void set_logical_height(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LogicalHeight::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_TransformInverse =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Transform,
+      DisplayInfo>;
+
+  static constexpr FieldMetadata_TransformInverse kTransformInverse{};
+  template <typename T = Transform> T* set_transform_inverse() {
+    return BeginNestedMessage<T>(5);
+  }
+
+
+  using FieldMetadata_Transform =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Transform,
+      DisplayInfo>;
+
+  static constexpr FieldMetadata_Transform kTransform{};
+  template <typename T = Transform> T* set_transform() {
+    return BeginNestedMessage<T>(6);
+  }
+
+
+  using FieldMetadata_ReceivesInput =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      DisplayInfo>;
+
+  static constexpr FieldMetadata_ReceivesInput kReceivesInput{};
+  void set_receives_input(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReceivesInput::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_IsSecure =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      DisplayInfo>;
+
+  static constexpr FieldMetadata_IsSecure kIsSecure{};
+  void set_is_secure(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsSecure::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_IsPrimary =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      DisplayInfo>;
+
+  static constexpr FieldMetadata_IsPrimary kIsPrimary{};
+  void set_is_primary(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsPrimary::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_IsVirtual =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      DisplayInfo>;
+
+  static constexpr FieldMetadata_IsVirtual kIsVirtual{};
+  void set_is_virtual(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsVirtual::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_RotationFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      DisplayInfo>;
+
+  static constexpr FieldMetadata_RotationFlags kRotationFlags{};
+  void set_rotation_flags(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RotationFlags::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_TransformHint =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      DisplayInfo>;
+
+  static constexpr FieldMetadata_TransformHint kTransformHint{};
+  void set_transform_hint(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TransformHint::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);
+  }
+};
+
+class TransactionTraceEntry_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/10, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TransactionTraceEntry_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TransactionTraceEntry_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TransactionTraceEntry_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_elapsed_realtime_nanos() const { return at<1>().valid(); }
+  int64_t elapsed_realtime_nanos() const { return at<1>().as_int64(); }
+  bool has_vsync_id() const { return at<2>().valid(); }
+  int64_t vsync_id() const { return at<2>().as_int64(); }
+  bool has_transactions() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> transactions() const { return GetRepeated<::protozero::ConstBytes>(3); }
+  bool has_added_layers() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> added_layers() const { return GetRepeated<::protozero::ConstBytes>(4); }
+  bool has_destroyed_layers() const { return at<5>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint32_t> destroyed_layers() const { return GetRepeated<uint32_t>(5); }
+  bool has_added_displays() const { return at<6>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> added_displays() const { return GetRepeated<::protozero::ConstBytes>(6); }
+  bool has_removed_displays() const { return at<7>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> removed_displays() const { return GetRepeated<int32_t>(7); }
+  bool has_destroyed_layer_handles() const { return at<8>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint32_t> destroyed_layer_handles() const { return GetRepeated<uint32_t>(8); }
+  bool has_displays_changed() const { return at<9>().valid(); }
+  bool displays_changed() const { return at<9>().as_bool(); }
+  bool has_displays() const { return at<10>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> displays() const { return GetRepeated<::protozero::ConstBytes>(10); }
+};
+
+class TransactionTraceEntry : public ::protozero::Message {
+ public:
+  using Decoder = TransactionTraceEntry_Decoder;
+  enum : int32_t {
+    kElapsedRealtimeNanosFieldNumber = 1,
+    kVsyncIdFieldNumber = 2,
+    kTransactionsFieldNumber = 3,
+    kAddedLayersFieldNumber = 4,
+    kDestroyedLayersFieldNumber = 5,
+    kAddedDisplaysFieldNumber = 6,
+    kRemovedDisplaysFieldNumber = 7,
+    kDestroyedLayerHandlesFieldNumber = 8,
+    kDisplaysChangedFieldNumber = 9,
+    kDisplaysFieldNumber = 10,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TransactionTraceEntry"; }
+
+
+  using FieldMetadata_ElapsedRealtimeNanos =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TransactionTraceEntry>;
+
+  static constexpr FieldMetadata_ElapsedRealtimeNanos kElapsedRealtimeNanos{};
+  void set_elapsed_realtime_nanos(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ElapsedRealtimeNanos::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_VsyncId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TransactionTraceEntry>;
+
+  static constexpr FieldMetadata_VsyncId kVsyncId{};
+  void set_vsync_id(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VsyncId::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_Transactions =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TransactionState,
+      TransactionTraceEntry>;
+
+  static constexpr FieldMetadata_Transactions kTransactions{};
+  template <typename T = TransactionState> T* add_transactions() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_AddedLayers =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      LayerCreationArgs,
+      TransactionTraceEntry>;
+
+  static constexpr FieldMetadata_AddedLayers kAddedLayers{};
+  template <typename T = LayerCreationArgs> T* add_added_layers() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_DestroyedLayers =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TransactionTraceEntry>;
+
+  static constexpr FieldMetadata_DestroyedLayers kDestroyedLayers{};
+  void add_destroyed_layers(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DestroyedLayers::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_AddedDisplays =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DisplayState,
+      TransactionTraceEntry>;
+
+  static constexpr FieldMetadata_AddedDisplays kAddedDisplays{};
+  template <typename T = DisplayState> T* add_added_displays() {
+    return BeginNestedMessage<T>(6);
+  }
+
+
+  using FieldMetadata_RemovedDisplays =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TransactionTraceEntry>;
+
+  static constexpr FieldMetadata_RemovedDisplays kRemovedDisplays{};
+  void add_removed_displays(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RemovedDisplays::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_DestroyedLayerHandles =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TransactionTraceEntry>;
+
+  static constexpr FieldMetadata_DestroyedLayerHandles kDestroyedLayerHandles{};
+  void add_destroyed_layer_handles(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DestroyedLayerHandles::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_DisplaysChanged =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TransactionTraceEntry>;
+
+  static constexpr FieldMetadata_DisplaysChanged kDisplaysChanged{};
+  void set_displays_changed(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DisplaysChanged::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_Displays =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DisplayInfo,
+      TransactionTraceEntry>;
+
+  static constexpr FieldMetadata_Displays kDisplays{};
+  template <typename T = DisplayInfo> T* add_displays() {
+    return BeginNestedMessage<T>(10);
+  }
+
+};
+
+class TransactionTraceFile_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TransactionTraceFile_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TransactionTraceFile_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TransactionTraceFile_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_magic_number() const { return at<1>().valid(); }
+  uint64_t magic_number() const { return at<1>().as_uint64(); }
+  bool has_entry() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> entry() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_real_to_elapsed_time_offset_nanos() const { return at<3>().valid(); }
+  uint64_t real_to_elapsed_time_offset_nanos() const { return at<3>().as_uint64(); }
+  bool has_version() const { return at<4>().valid(); }
+  uint32_t version() const { return at<4>().as_uint32(); }
+};
+
+class TransactionTraceFile : public ::protozero::Message {
+ public:
+  using Decoder = TransactionTraceFile_Decoder;
+  enum : int32_t {
+    kMagicNumberFieldNumber = 1,
+    kEntryFieldNumber = 2,
+    kRealToElapsedTimeOffsetNanosFieldNumber = 3,
+    kVersionFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TransactionTraceFile"; }
+
+
+  using MagicNumber = ::perfetto::protos::pbzero::TransactionTraceFile_MagicNumber;
+  static inline const char* MagicNumber_Name(MagicNumber value) {
+    return ::perfetto::protos::pbzero::TransactionTraceFile_MagicNumber_Name(value);
+  }
+  static inline const MagicNumber INVALID = MagicNumber::INVALID;
+  static inline const MagicNumber MAGIC_NUMBER_L = MagicNumber::MAGIC_NUMBER_L;
+  static inline const MagicNumber MAGIC_NUMBER_H = MagicNumber::MAGIC_NUMBER_H;
+
+  using FieldMetadata_MagicNumber =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64,
+      uint64_t,
+      TransactionTraceFile>;
+
+  static constexpr FieldMetadata_MagicNumber kMagicNumber{};
+  void set_magic_number(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MagicNumber::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Entry =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TransactionTraceEntry,
+      TransactionTraceFile>;
+
+  static constexpr FieldMetadata_Entry kEntry{};
+  template <typename T = TransactionTraceEntry> T* add_entry() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_RealToElapsedTimeOffsetNanos =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64,
+      uint64_t,
+      TransactionTraceFile>;
+
+  static constexpr FieldMetadata_RealToElapsedTimeOffsetNanos kRealToElapsedTimeOffsetNanos{};
+  void set_real_to_elapsed_time_offset_nanos(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RealToElapsedTimeOffsetNanos::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Version =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TransactionTraceFile>;
+
+  static constexpr FieldMetadata_Version kVersion{};
+  void set_version(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Version::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/android/android_game_intervention_list.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_ANDROID_GAME_INTERVENTION_LIST_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_ANDROID_GAME_INTERVENTION_LIST_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class AndroidGameInterventionList_GameModeInfo;
+class AndroidGameInterventionList_GamePackageInfo;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class AndroidGameInterventionList_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AndroidGameInterventionList_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidGameInterventionList_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidGameInterventionList_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_game_packages() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> game_packages() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_parse_error() const { return at<2>().valid(); }
+  bool parse_error() const { return at<2>().as_bool(); }
+  bool has_read_error() const { return at<3>().valid(); }
+  bool read_error() const { return at<3>().as_bool(); }
+};
+
+class AndroidGameInterventionList : public ::protozero::Message {
+ public:
+  using Decoder = AndroidGameInterventionList_Decoder;
+  enum : int32_t {
+    kGamePackagesFieldNumber = 1,
+    kParseErrorFieldNumber = 2,
+    kReadErrorFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidGameInterventionList"; }
+
+  using GameModeInfo = ::perfetto::protos::pbzero::AndroidGameInterventionList_GameModeInfo;
+  using GamePackageInfo = ::perfetto::protos::pbzero::AndroidGameInterventionList_GamePackageInfo;
+
+  using FieldMetadata_GamePackages =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidGameInterventionList_GamePackageInfo,
+      AndroidGameInterventionList>;
+
+  static constexpr FieldMetadata_GamePackages kGamePackages{};
+  template <typename T = AndroidGameInterventionList_GamePackageInfo> T* add_game_packages() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_ParseError =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      AndroidGameInterventionList>;
+
+  static constexpr FieldMetadata_ParseError kParseError{};
+  void set_parse_error(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ParseError::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_ReadError =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      AndroidGameInterventionList>;
+
+  static constexpr FieldMetadata_ReadError kReadError{};
+  void set_read_error(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReadError::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 AndroidGameInterventionList_GamePackageInfo_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AndroidGameInterventionList_GamePackageInfo_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidGameInterventionList_GamePackageInfo_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidGameInterventionList_GamePackageInfo_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_uid() const { return at<2>().valid(); }
+  uint64_t uid() const { return at<2>().as_uint64(); }
+  bool has_current_mode() const { return at<3>().valid(); }
+  uint32_t current_mode() const { return at<3>().as_uint32(); }
+  bool has_game_mode_info() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> game_mode_info() const { return GetRepeated<::protozero::ConstBytes>(4); }
+};
+
+class AndroidGameInterventionList_GamePackageInfo : public ::protozero::Message {
+ public:
+  using Decoder = AndroidGameInterventionList_GamePackageInfo_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kUidFieldNumber = 2,
+    kCurrentModeFieldNumber = 3,
+    kGameModeInfoFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidGameInterventionList.GamePackageInfo"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidGameInterventionList_GamePackageInfo>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Uid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      AndroidGameInterventionList_GamePackageInfo>;
+
+  static constexpr FieldMetadata_Uid kUid{};
+  void set_uid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Uid::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_CurrentMode =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AndroidGameInterventionList_GamePackageInfo>;
+
+  static constexpr FieldMetadata_CurrentMode kCurrentMode{};
+  void set_current_mode(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CurrentMode::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_GameModeInfo =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidGameInterventionList_GameModeInfo,
+      AndroidGameInterventionList_GamePackageInfo>;
+
+  static constexpr FieldMetadata_GameModeInfo kGameModeInfo{};
+  template <typename T = AndroidGameInterventionList_GameModeInfo> T* add_game_mode_info() {
+    return BeginNestedMessage<T>(4);
+  }
+
+};
+
+class AndroidGameInterventionList_GameModeInfo_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AndroidGameInterventionList_GameModeInfo_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidGameInterventionList_GameModeInfo_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidGameInterventionList_GameModeInfo_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_mode() const { return at<1>().valid(); }
+  uint32_t mode() const { return at<1>().as_uint32(); }
+  bool has_use_angle() const { return at<2>().valid(); }
+  bool use_angle() const { return at<2>().as_bool(); }
+  bool has_resolution_downscale() const { return at<3>().valid(); }
+  float resolution_downscale() const { return at<3>().as_float(); }
+  bool has_fps() const { return at<4>().valid(); }
+  float fps() const { return at<4>().as_float(); }
+};
+
+class AndroidGameInterventionList_GameModeInfo : public ::protozero::Message {
+ public:
+  using Decoder = AndroidGameInterventionList_GameModeInfo_Decoder;
+  enum : int32_t {
+    kModeFieldNumber = 1,
+    kUseAngleFieldNumber = 2,
+    kResolutionDownscaleFieldNumber = 3,
+    kFpsFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidGameInterventionList.GameModeInfo"; }
+
+
+  using FieldMetadata_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AndroidGameInterventionList_GameModeInfo>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::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_UseAngle =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      AndroidGameInterventionList_GameModeInfo>;
+
+  static constexpr FieldMetadata_UseAngle kUseAngle{};
+  void set_use_angle(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_UseAngle::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_ResolutionDownscale =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      AndroidGameInterventionList_GameModeInfo>;
+
+  static constexpr FieldMetadata_ResolutionDownscale kResolutionDownscale{};
+  void set_resolution_downscale(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResolutionDownscale::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Fps =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      AndroidGameInterventionList_GameModeInfo>;
+
+  static constexpr FieldMetadata_Fps kFps{};
+  void set_fps(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Fps::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/android/android_input_event.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_ANDROID_INPUT_EVENT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_ANDROID_INPUT_EVENT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class AndroidKeyEvent;
+class AndroidMotionEvent;
+class AndroidMotionEvent_Pointer;
+class AndroidMotionEvent_Pointer_AxisValue;
+class AndroidWindowInputDispatchEvent;
+class AndroidWindowInputDispatchEvent_DispatchedPointer;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class AndroidInputEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AndroidInputEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidInputEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidInputEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dispatcher_motion_event() const { return at<1>().valid(); }
+  ::protozero::ConstBytes dispatcher_motion_event() const { return at<1>().as_bytes(); }
+  bool has_dispatcher_motion_event_redacted() const { return at<2>().valid(); }
+  ::protozero::ConstBytes dispatcher_motion_event_redacted() const { return at<2>().as_bytes(); }
+  bool has_dispatcher_key_event() const { return at<3>().valid(); }
+  ::protozero::ConstBytes dispatcher_key_event() const { return at<3>().as_bytes(); }
+  bool has_dispatcher_key_event_redacted() const { return at<4>().valid(); }
+  ::protozero::ConstBytes dispatcher_key_event_redacted() const { return at<4>().as_bytes(); }
+  bool has_dispatcher_window_dispatch_event() const { return at<5>().valid(); }
+  ::protozero::ConstBytes dispatcher_window_dispatch_event() const { return at<5>().as_bytes(); }
+  bool has_dispatcher_window_dispatch_event_redacted() const { return at<6>().valid(); }
+  ::protozero::ConstBytes dispatcher_window_dispatch_event_redacted() const { return at<6>().as_bytes(); }
+};
+
+class AndroidInputEvent : public ::protozero::Message {
+ public:
+  using Decoder = AndroidInputEvent_Decoder;
+  enum : int32_t {
+    kDispatcherMotionEventFieldNumber = 1,
+    kDispatcherMotionEventRedactedFieldNumber = 2,
+    kDispatcherKeyEventFieldNumber = 3,
+    kDispatcherKeyEventRedactedFieldNumber = 4,
+    kDispatcherWindowDispatchEventFieldNumber = 5,
+    kDispatcherWindowDispatchEventRedactedFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidInputEvent"; }
+
+
+  using FieldMetadata_DispatcherMotionEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidMotionEvent,
+      AndroidInputEvent>;
+
+  static constexpr FieldMetadata_DispatcherMotionEvent kDispatcherMotionEvent{};
+  template <typename T = AndroidMotionEvent> T* set_dispatcher_motion_event() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_DispatcherMotionEventRedacted =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidMotionEvent,
+      AndroidInputEvent>;
+
+  static constexpr FieldMetadata_DispatcherMotionEventRedacted kDispatcherMotionEventRedacted{};
+  template <typename T = AndroidMotionEvent> T* set_dispatcher_motion_event_redacted() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_DispatcherKeyEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidKeyEvent,
+      AndroidInputEvent>;
+
+  static constexpr FieldMetadata_DispatcherKeyEvent kDispatcherKeyEvent{};
+  template <typename T = AndroidKeyEvent> T* set_dispatcher_key_event() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_DispatcherKeyEventRedacted =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidKeyEvent,
+      AndroidInputEvent>;
+
+  static constexpr FieldMetadata_DispatcherKeyEventRedacted kDispatcherKeyEventRedacted{};
+  template <typename T = AndroidKeyEvent> T* set_dispatcher_key_event_redacted() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_DispatcherWindowDispatchEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidWindowInputDispatchEvent,
+      AndroidInputEvent>;
+
+  static constexpr FieldMetadata_DispatcherWindowDispatchEvent kDispatcherWindowDispatchEvent{};
+  template <typename T = AndroidWindowInputDispatchEvent> T* set_dispatcher_window_dispatch_event() {
+    return BeginNestedMessage<T>(5);
+  }
+
+
+  using FieldMetadata_DispatcherWindowDispatchEventRedacted =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidWindowInputDispatchEvent,
+      AndroidInputEvent>;
+
+  static constexpr FieldMetadata_DispatcherWindowDispatchEventRedacted kDispatcherWindowDispatchEventRedacted{};
+  template <typename T = AndroidWindowInputDispatchEvent> T* set_dispatcher_window_dispatch_event_redacted() {
+    return BeginNestedMessage<T>(6);
+  }
+
+};
+
+class AndroidWindowInputDispatchEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AndroidWindowInputDispatchEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidWindowInputDispatchEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidWindowInputDispatchEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_event_id() const { return at<1>().valid(); }
+  uint32_t event_id() const { return at<1>().as_uint32(); }
+  bool has_vsync_id() const { return at<2>().valid(); }
+  int64_t vsync_id() const { return at<2>().as_int64(); }
+  bool has_window_id() const { return at<3>().valid(); }
+  int32_t window_id() const { return at<3>().as_int32(); }
+  bool has_dispatched_pointer() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> dispatched_pointer() const { return GetRepeated<::protozero::ConstBytes>(4); }
+  bool has_resolved_flags() const { return at<5>().valid(); }
+  uint32_t resolved_flags() const { return at<5>().as_uint32(); }
+};
+
+class AndroidWindowInputDispatchEvent : public ::protozero::Message {
+ public:
+  using Decoder = AndroidWindowInputDispatchEvent_Decoder;
+  enum : int32_t {
+    kEventIdFieldNumber = 1,
+    kVsyncIdFieldNumber = 2,
+    kWindowIdFieldNumber = 3,
+    kDispatchedPointerFieldNumber = 4,
+    kResolvedFlagsFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidWindowInputDispatchEvent"; }
+
+  using DispatchedPointer = ::perfetto::protos::pbzero::AndroidWindowInputDispatchEvent_DispatchedPointer;
+
+  using FieldMetadata_EventId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed32,
+      uint32_t,
+      AndroidWindowInputDispatchEvent>;
+
+  static constexpr FieldMetadata_EventId kEventId{};
+  void set_event_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EventId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VsyncId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidWindowInputDispatchEvent>;
+
+  static constexpr FieldMetadata_VsyncId kVsyncId{};
+  void set_vsync_id(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VsyncId::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_WindowId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidWindowInputDispatchEvent>;
+
+  static constexpr FieldMetadata_WindowId kWindowId{};
+  void set_window_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_WindowId::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_DispatchedPointer =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidWindowInputDispatchEvent_DispatchedPointer,
+      AndroidWindowInputDispatchEvent>;
+
+  static constexpr FieldMetadata_DispatchedPointer kDispatchedPointer{};
+  template <typename T = AndroidWindowInputDispatchEvent_DispatchedPointer> T* add_dispatched_pointer() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_ResolvedFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AndroidWindowInputDispatchEvent>;
+
+  static constexpr FieldMetadata_ResolvedFlags kResolvedFlags{};
+  void set_resolved_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResolvedFlags::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 AndroidWindowInputDispatchEvent_DispatchedPointer_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AndroidWindowInputDispatchEvent_DispatchedPointer_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidWindowInputDispatchEvent_DispatchedPointer_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidWindowInputDispatchEvent_DispatchedPointer_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pointer_id() const { return at<1>().valid(); }
+  int32_t pointer_id() const { return at<1>().as_int32(); }
+  bool has_x_in_display() const { return at<2>().valid(); }
+  float x_in_display() const { return at<2>().as_float(); }
+  bool has_y_in_display() const { return at<3>().valid(); }
+  float y_in_display() const { return at<3>().as_float(); }
+  bool has_axis_value_in_window() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> axis_value_in_window() const { return GetRepeated<::protozero::ConstBytes>(4); }
+};
+
+class AndroidWindowInputDispatchEvent_DispatchedPointer : public ::protozero::Message {
+ public:
+  using Decoder = AndroidWindowInputDispatchEvent_DispatchedPointer_Decoder;
+  enum : int32_t {
+    kPointerIdFieldNumber = 1,
+    kXInDisplayFieldNumber = 2,
+    kYInDisplayFieldNumber = 3,
+    kAxisValueInWindowFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidWindowInputDispatchEvent.DispatchedPointer"; }
+
+
+  using FieldMetadata_PointerId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidWindowInputDispatchEvent_DispatchedPointer>;
+
+  static constexpr FieldMetadata_PointerId kPointerId{};
+  void set_pointer_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PointerId::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_XInDisplay =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      AndroidWindowInputDispatchEvent_DispatchedPointer>;
+
+  static constexpr FieldMetadata_XInDisplay kXInDisplay{};
+  void set_x_in_display(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_XInDisplay::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_YInDisplay =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      AndroidWindowInputDispatchEvent_DispatchedPointer>;
+
+  static constexpr FieldMetadata_YInDisplay kYInDisplay{};
+  void set_y_in_display(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_YInDisplay::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AxisValueInWindow =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidMotionEvent_Pointer_AxisValue,
+      AndroidWindowInputDispatchEvent_DispatchedPointer>;
+
+  static constexpr FieldMetadata_AxisValueInWindow kAxisValueInWindow{};
+  template <typename T = AndroidMotionEvent_Pointer_AxisValue> T* add_axis_value_in_window() {
+    return BeginNestedMessage<T>(4);
+  }
+
+};
+
+class AndroidKeyEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/13, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AndroidKeyEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidKeyEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidKeyEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_event_id() const { return at<1>().valid(); }
+  uint32_t event_id() const { return at<1>().as_uint32(); }
+  bool has_event_time_nanos() const { return at<2>().valid(); }
+  int64_t event_time_nanos() const { return at<2>().as_int64(); }
+  bool has_down_time_nanos() const { return at<3>().valid(); }
+  int64_t down_time_nanos() const { return at<3>().as_int64(); }
+  bool has_source() const { return at<4>().valid(); }
+  uint32_t source() const { return at<4>().as_uint32(); }
+  bool has_action() const { return at<5>().valid(); }
+  int32_t action() const { return at<5>().as_int32(); }
+  bool has_device_id() const { return at<6>().valid(); }
+  int32_t device_id() const { return at<6>().as_int32(); }
+  bool has_display_id() const { return at<7>().valid(); }
+  int32_t display_id() const { return at<7>().as_sint32(); }
+  bool has_key_code() const { return at<8>().valid(); }
+  int32_t key_code() const { return at<8>().as_int32(); }
+  bool has_scan_code() const { return at<9>().valid(); }
+  uint32_t scan_code() const { return at<9>().as_uint32(); }
+  bool has_meta_state() const { return at<10>().valid(); }
+  uint32_t meta_state() const { return at<10>().as_uint32(); }
+  bool has_repeat_count() const { return at<11>().valid(); }
+  int32_t repeat_count() const { return at<11>().as_int32(); }
+  bool has_flags() const { return at<12>().valid(); }
+  uint32_t flags() const { return at<12>().as_uint32(); }
+  bool has_policy_flags() const { return at<13>().valid(); }
+  uint32_t policy_flags() const { return at<13>().as_uint32(); }
+};
+
+class AndroidKeyEvent : public ::protozero::Message {
+ public:
+  using Decoder = AndroidKeyEvent_Decoder;
+  enum : int32_t {
+    kEventIdFieldNumber = 1,
+    kEventTimeNanosFieldNumber = 2,
+    kDownTimeNanosFieldNumber = 3,
+    kSourceFieldNumber = 4,
+    kActionFieldNumber = 5,
+    kDeviceIdFieldNumber = 6,
+    kDisplayIdFieldNumber = 7,
+    kKeyCodeFieldNumber = 8,
+    kScanCodeFieldNumber = 9,
+    kMetaStateFieldNumber = 10,
+    kRepeatCountFieldNumber = 11,
+    kFlagsFieldNumber = 12,
+    kPolicyFlagsFieldNumber = 13,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidKeyEvent"; }
+
+
+  using FieldMetadata_EventId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed32,
+      uint32_t,
+      AndroidKeyEvent>;
+
+  static constexpr FieldMetadata_EventId kEventId{};
+  void set_event_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EventId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_EventTimeNanos =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidKeyEvent>;
+
+  static constexpr FieldMetadata_EventTimeNanos kEventTimeNanos{};
+  void set_event_time_nanos(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EventTimeNanos::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_DownTimeNanos =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidKeyEvent>;
+
+  static constexpr FieldMetadata_DownTimeNanos kDownTimeNanos{};
+  void set_down_time_nanos(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DownTimeNanos::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_Source =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AndroidKeyEvent>;
+
+  static constexpr FieldMetadata_Source kSource{};
+  void set_source(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Source::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_Action =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidKeyEvent>;
+
+  static constexpr FieldMetadata_Action kAction{};
+  void set_action(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Action::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_DeviceId =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidKeyEvent>;
+
+  static constexpr FieldMetadata_DeviceId kDeviceId{};
+  void set_device_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DeviceId::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_DisplayId =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kSint32,
+      int32_t,
+      AndroidKeyEvent>;
+
+  static constexpr FieldMetadata_DisplayId kDisplayId{};
+  void set_display_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DisplayId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kSint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_KeyCode =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidKeyEvent>;
+
+  static constexpr FieldMetadata_KeyCode kKeyCode{};
+  void set_key_code(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KeyCode::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_ScanCode =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AndroidKeyEvent>;
+
+  static constexpr FieldMetadata_ScanCode kScanCode{};
+  void set_scan_code(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ScanCode::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_MetaState =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AndroidKeyEvent>;
+
+  static constexpr FieldMetadata_MetaState kMetaState{};
+  void set_meta_state(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MetaState::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_RepeatCount =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidKeyEvent>;
+
+  static constexpr FieldMetadata_RepeatCount kRepeatCount{};
+  void set_repeat_count(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RepeatCount::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AndroidKeyEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_PolicyFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AndroidKeyEvent>;
+
+  static constexpr FieldMetadata_PolicyFlags kPolicyFlags{};
+  void set_policy_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PolicyFlags::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 AndroidMotionEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/25, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AndroidMotionEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidMotionEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidMotionEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_event_id() const { return at<1>().valid(); }
+  uint32_t event_id() const { return at<1>().as_uint32(); }
+  bool has_event_time_nanos() const { return at<2>().valid(); }
+  int64_t event_time_nanos() const { return at<2>().as_int64(); }
+  bool has_source() const { return at<3>().valid(); }
+  uint32_t source() const { return at<3>().as_uint32(); }
+  bool has_action() const { return at<4>().valid(); }
+  int32_t action() const { return at<4>().as_int32(); }
+  bool has_device_id() const { return at<5>().valid(); }
+  int32_t device_id() const { return at<5>().as_int32(); }
+  bool has_display_id() const { return at<6>().valid(); }
+  int32_t display_id() const { return at<6>().as_sint32(); }
+  bool has_classification() const { return at<7>().valid(); }
+  int32_t classification() const { return at<7>().as_int32(); }
+  bool has_flags() const { return at<8>().valid(); }
+  uint32_t flags() const { return at<8>().as_uint32(); }
+  bool has_pointer() const { return at<9>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> pointer() const { return GetRepeated<::protozero::ConstBytes>(9); }
+  bool has_original_event_id() const { return at<16>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kFixed32, uint32_t> original_event_id(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kFixed32, uint32_t>(16, parse_error_ptr); }
+  bool has_down_time_nanos() const { return at<17>().valid(); }
+  int64_t down_time_nanos() const { return at<17>().as_int64(); }
+  bool has_cursor_position_x() const { return at<18>().valid(); }
+  float cursor_position_x() const { return at<18>().as_float(); }
+  bool has_cursor_position_y() const { return at<19>().valid(); }
+  float cursor_position_y() const { return at<19>().as_float(); }
+  bool has_action_button() const { return at<20>().valid(); }
+  int32_t action_button() const { return at<20>().as_int32(); }
+  bool has_button_state() const { return at<21>().valid(); }
+  uint32_t button_state() const { return at<21>().as_uint32(); }
+  bool has_meta_state() const { return at<22>().valid(); }
+  uint32_t meta_state() const { return at<22>().as_uint32(); }
+  bool has_policy_flags() const { return at<23>().valid(); }
+  uint32_t policy_flags() const { return at<23>().as_uint32(); }
+  bool has_precision_x() const { return at<24>().valid(); }
+  float precision_x() const { return at<24>().as_float(); }
+  bool has_precision_y() const { return at<25>().valid(); }
+  float precision_y() const { return at<25>().as_float(); }
+};
+
+class AndroidMotionEvent : public ::protozero::Message {
+ public:
+  using Decoder = AndroidMotionEvent_Decoder;
+  enum : int32_t {
+    kEventIdFieldNumber = 1,
+    kEventTimeNanosFieldNumber = 2,
+    kSourceFieldNumber = 3,
+    kActionFieldNumber = 4,
+    kDeviceIdFieldNumber = 5,
+    kDisplayIdFieldNumber = 6,
+    kClassificationFieldNumber = 7,
+    kFlagsFieldNumber = 8,
+    kPointerFieldNumber = 9,
+    kOriginalEventIdFieldNumber = 16,
+    kDownTimeNanosFieldNumber = 17,
+    kCursorPositionXFieldNumber = 18,
+    kCursorPositionYFieldNumber = 19,
+    kActionButtonFieldNumber = 20,
+    kButtonStateFieldNumber = 21,
+    kMetaStateFieldNumber = 22,
+    kPolicyFlagsFieldNumber = 23,
+    kPrecisionXFieldNumber = 24,
+    kPrecisionYFieldNumber = 25,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidMotionEvent"; }
+
+  using Pointer = ::perfetto::protos::pbzero::AndroidMotionEvent_Pointer;
+
+  using FieldMetadata_EventId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed32,
+      uint32_t,
+      AndroidMotionEvent>;
+
+  static constexpr FieldMetadata_EventId kEventId{};
+  void set_event_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EventId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_EventTimeNanos =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidMotionEvent>;
+
+  static constexpr FieldMetadata_EventTimeNanos kEventTimeNanos{};
+  void set_event_time_nanos(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EventTimeNanos::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_Source =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AndroidMotionEvent>;
+
+  static constexpr FieldMetadata_Source kSource{};
+  void set_source(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Source::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_Action =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidMotionEvent>;
+
+  static constexpr FieldMetadata_Action kAction{};
+  void set_action(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Action::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_DeviceId =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidMotionEvent>;
+
+  static constexpr FieldMetadata_DeviceId kDeviceId{};
+  void set_device_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DeviceId::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_DisplayId =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kSint32,
+      int32_t,
+      AndroidMotionEvent>;
+
+  static constexpr FieldMetadata_DisplayId kDisplayId{};
+  void set_display_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DisplayId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kSint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Classification =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidMotionEvent>;
+
+  static constexpr FieldMetadata_Classification kClassification{};
+  void set_classification(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Classification::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AndroidMotionEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_Pointer =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidMotionEvent_Pointer,
+      AndroidMotionEvent>;
+
+  static constexpr FieldMetadata_Pointer kPointer{};
+  template <typename T = AndroidMotionEvent_Pointer> T* add_pointer() {
+    return BeginNestedMessage<T>(9);
+  }
+
+
+  using FieldMetadata_OriginalEventId =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed32,
+      uint32_t,
+      AndroidMotionEvent>;
+
+  static constexpr FieldMetadata_OriginalEventId kOriginalEventId{};
+  void set_original_event_id(const ::protozero::PackedFixedSizeInt<uint32_t>& packed_buffer) {
+    AppendBytes(FieldMetadata_OriginalEventId::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_DownTimeNanos =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidMotionEvent>;
+
+  static constexpr FieldMetadata_DownTimeNanos kDownTimeNanos{};
+  void set_down_time_nanos(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DownTimeNanos::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_CursorPositionX =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      AndroidMotionEvent>;
+
+  static constexpr FieldMetadata_CursorPositionX kCursorPositionX{};
+  void set_cursor_position_x(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_CursorPositionX::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CursorPositionY =
+    ::protozero::proto_utils::FieldMetadata<
+      19,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      AndroidMotionEvent>;
+
+  static constexpr FieldMetadata_CursorPositionY kCursorPositionY{};
+  void set_cursor_position_y(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_CursorPositionY::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ActionButton =
+    ::protozero::proto_utils::FieldMetadata<
+      20,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidMotionEvent>;
+
+  static constexpr FieldMetadata_ActionButton kActionButton{};
+  void set_action_button(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ActionButton::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_ButtonState =
+    ::protozero::proto_utils::FieldMetadata<
+      21,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AndroidMotionEvent>;
+
+  static constexpr FieldMetadata_ButtonState kButtonState{};
+  void set_button_state(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ButtonState::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_MetaState =
+    ::protozero::proto_utils::FieldMetadata<
+      22,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AndroidMotionEvent>;
+
+  static constexpr FieldMetadata_MetaState kMetaState{};
+  void set_meta_state(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MetaState::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_PolicyFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      23,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AndroidMotionEvent>;
+
+  static constexpr FieldMetadata_PolicyFlags kPolicyFlags{};
+  void set_policy_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PolicyFlags::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_PrecisionX =
+    ::protozero::proto_utils::FieldMetadata<
+      24,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      AndroidMotionEvent>;
+
+  static constexpr FieldMetadata_PrecisionX kPrecisionX{};
+  void set_precision_x(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_PrecisionX::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PrecisionY =
+    ::protozero::proto_utils::FieldMetadata<
+      25,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      AndroidMotionEvent>;
+
+  static constexpr FieldMetadata_PrecisionY kPrecisionY{};
+  void set_precision_y(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_PrecisionY::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class AndroidMotionEvent_Pointer_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AndroidMotionEvent_Pointer_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidMotionEvent_Pointer_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidMotionEvent_Pointer_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_axis_value() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> axis_value() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_pointer_id() const { return at<2>().valid(); }
+  int32_t pointer_id() const { return at<2>().as_int32(); }
+  bool has_tool_type() const { return at<3>().valid(); }
+  int32_t tool_type() const { return at<3>().as_int32(); }
+};
+
+class AndroidMotionEvent_Pointer : public ::protozero::Message {
+ public:
+  using Decoder = AndroidMotionEvent_Pointer_Decoder;
+  enum : int32_t {
+    kAxisValueFieldNumber = 1,
+    kPointerIdFieldNumber = 2,
+    kToolTypeFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidMotionEvent.Pointer"; }
+
+  using AxisValue = ::perfetto::protos::pbzero::AndroidMotionEvent_Pointer_AxisValue;
+
+  using FieldMetadata_AxisValue =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidMotionEvent_Pointer_AxisValue,
+      AndroidMotionEvent_Pointer>;
+
+  static constexpr FieldMetadata_AxisValue kAxisValue{};
+  template <typename T = AndroidMotionEvent_Pointer_AxisValue> T* add_axis_value() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_PointerId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidMotionEvent_Pointer>;
+
+  static constexpr FieldMetadata_PointerId kPointerId{};
+  void set_pointer_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PointerId::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_ToolType =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidMotionEvent_Pointer>;
+
+  static constexpr FieldMetadata_ToolType kToolType{};
+  void set_tool_type(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ToolType::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);
+  }
+};
+
+class AndroidMotionEvent_Pointer_AxisValue_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AndroidMotionEvent_Pointer_AxisValue_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidMotionEvent_Pointer_AxisValue_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidMotionEvent_Pointer_AxisValue_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_axis() const { return at<1>().valid(); }
+  int32_t axis() const { return at<1>().as_int32(); }
+  bool has_value() const { return at<2>().valid(); }
+  float value() const { return at<2>().as_float(); }
+};
+
+class AndroidMotionEvent_Pointer_AxisValue : public ::protozero::Message {
+ public:
+  using Decoder = AndroidMotionEvent_Pointer_AxisValue_Decoder;
+  enum : int32_t {
+    kAxisFieldNumber = 1,
+    kValueFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidMotionEvent.Pointer.AxisValue"; }
+
+
+  using FieldMetadata_Axis =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidMotionEvent_Pointer_AxisValue>;
+
+  static constexpr FieldMetadata_Axis kAxis{};
+  void set_axis(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Axis::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_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      AndroidMotionEvent_Pointer_AxisValue>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/android/android_log.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_ANDROID_LOG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_ANDROID_LOG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class AndroidLogPacket_LogEvent;
+class AndroidLogPacket_LogEvent_Arg;
+class AndroidLogPacket_Stats;
+enum AndroidLogId : int32_t;
+enum AndroidLogPriority : int32_t;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class AndroidLogPacket_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AndroidLogPacket_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidLogPacket_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidLogPacket_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_events() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> events() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_stats() const { return at<2>().valid(); }
+  ::protozero::ConstBytes stats() const { return at<2>().as_bytes(); }
+};
+
+class AndroidLogPacket : public ::protozero::Message {
+ public:
+  using Decoder = AndroidLogPacket_Decoder;
+  enum : int32_t {
+    kEventsFieldNumber = 1,
+    kStatsFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidLogPacket"; }
+
+  using LogEvent = ::perfetto::protos::pbzero::AndroidLogPacket_LogEvent;
+  using Stats = ::perfetto::protos::pbzero::AndroidLogPacket_Stats;
+
+  using FieldMetadata_Events =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidLogPacket_LogEvent,
+      AndroidLogPacket>;
+
+  static constexpr FieldMetadata_Events kEvents{};
+  template <typename T = AndroidLogPacket_LogEvent> T* add_events() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_Stats =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidLogPacket_Stats,
+      AndroidLogPacket>;
+
+  static constexpr FieldMetadata_Stats kStats{};
+  template <typename T = AndroidLogPacket_Stats> T* set_stats() {
+    return BeginNestedMessage<T>(2);
+  }
+
+};
+
+class AndroidLogPacket_Stats_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AndroidLogPacket_Stats_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidLogPacket_Stats_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidLogPacket_Stats_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_num_total() const { return at<1>().valid(); }
+  uint64_t num_total() const { return at<1>().as_uint64(); }
+  bool has_num_failed() const { return at<2>().valid(); }
+  uint64_t num_failed() const { return at<2>().as_uint64(); }
+  bool has_num_skipped() const { return at<3>().valid(); }
+  uint64_t num_skipped() const { return at<3>().as_uint64(); }
+};
+
+class AndroidLogPacket_Stats : public ::protozero::Message {
+ public:
+  using Decoder = AndroidLogPacket_Stats_Decoder;
+  enum : int32_t {
+    kNumTotalFieldNumber = 1,
+    kNumFailedFieldNumber = 2,
+    kNumSkippedFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidLogPacket.Stats"; }
+
+
+  using FieldMetadata_NumTotal =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      AndroidLogPacket_Stats>;
+
+  static constexpr FieldMetadata_NumTotal kNumTotal{};
+  void set_num_total(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NumTotal::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_NumFailed =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      AndroidLogPacket_Stats>;
+
+  static constexpr FieldMetadata_NumFailed kNumFailed{};
+  void set_num_failed(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NumFailed::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_NumSkipped =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      AndroidLogPacket_Stats>;
+
+  static constexpr FieldMetadata_NumSkipped kNumSkipped{};
+  void set_num_skipped(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NumSkipped::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 AndroidLogPacket_LogEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AndroidLogPacket_LogEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidLogPacket_LogEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidLogPacket_LogEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_log_id() const { return at<1>().valid(); }
+  int32_t log_id() const { return at<1>().as_int32(); }
+  bool has_pid() const { return at<2>().valid(); }
+  int32_t pid() const { return at<2>().as_int32(); }
+  bool has_tid() const { return at<3>().valid(); }
+  int32_t tid() const { return at<3>().as_int32(); }
+  bool has_uid() const { return at<4>().valid(); }
+  int32_t uid() const { return at<4>().as_int32(); }
+  bool has_timestamp() const { return at<5>().valid(); }
+  uint64_t timestamp() const { return at<5>().as_uint64(); }
+  bool has_tag() const { return at<6>().valid(); }
+  ::protozero::ConstChars tag() const { return at<6>().as_string(); }
+  bool has_prio() const { return at<7>().valid(); }
+  int32_t prio() const { return at<7>().as_int32(); }
+  bool has_message() const { return at<8>().valid(); }
+  ::protozero::ConstChars message() const { return at<8>().as_string(); }
+  bool has_args() const { return at<9>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> args() const { return GetRepeated<::protozero::ConstBytes>(9); }
+};
+
+class AndroidLogPacket_LogEvent : public ::protozero::Message {
+ public:
+  using Decoder = AndroidLogPacket_LogEvent_Decoder;
+  enum : int32_t {
+    kLogIdFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kTidFieldNumber = 3,
+    kUidFieldNumber = 4,
+    kTimestampFieldNumber = 5,
+    kTagFieldNumber = 6,
+    kPrioFieldNumber = 7,
+    kMessageFieldNumber = 8,
+    kArgsFieldNumber = 9,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidLogPacket.LogEvent"; }
+
+  using Arg = ::perfetto::protos::pbzero::AndroidLogPacket_LogEvent_Arg;
+
+  using FieldMetadata_LogId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      AndroidLogId,
+      AndroidLogPacket_LogEvent>;
+
+  static constexpr FieldMetadata_LogId kLogId{};
+  void set_log_id(AndroidLogId value) {
+    static constexpr uint32_t field_id = FieldMetadata_LogId::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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidLogPacket_LogEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_Tid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidLogPacket_LogEvent>;
+
+  static constexpr FieldMetadata_Tid kTid{};
+  void set_tid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tid::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_Uid =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidLogPacket_LogEvent>;
+
+  static constexpr FieldMetadata_Uid kUid{};
+  void set_uid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Uid::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_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      AndroidLogPacket_LogEvent>;
+
+  static constexpr FieldMetadata_Timestamp kTimestamp{};
+  void set_timestamp(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timestamp::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_Tag =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidLogPacket_LogEvent>;
+
+  static constexpr FieldMetadata_Tag kTag{};
+  void set_tag(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Tag::kFieldId, data, size);
+  }
+  void set_tag(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Tag::kFieldId, chars.data, chars.size);
+  }
+  void set_tag(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tag::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_Prio =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      AndroidLogPriority,
+      AndroidLogPacket_LogEvent>;
+
+  static constexpr FieldMetadata_Prio kPrio{};
+  void set_prio(AndroidLogPriority value) {
+    static constexpr uint32_t field_id = FieldMetadata_Prio::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_Message =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidLogPacket_LogEvent>;
+
+  static constexpr FieldMetadata_Message kMessage{};
+  void set_message(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Message::kFieldId, data, size);
+  }
+  void set_message(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Message::kFieldId, chars.data, chars.size);
+  }
+  void set_message(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Message::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_Args =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidLogPacket_LogEvent_Arg,
+      AndroidLogPacket_LogEvent>;
+
+  static constexpr FieldMetadata_Args kArgs{};
+  template <typename T = AndroidLogPacket_LogEvent_Arg> T* add_args() {
+    return BeginNestedMessage<T>(9);
+  }
+
+};
+
+class AndroidLogPacket_LogEvent_Arg_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AndroidLogPacket_LogEvent_Arg_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidLogPacket_LogEvent_Arg_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidLogPacket_LogEvent_Arg_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_int_value() const { return at<2>().valid(); }
+  int64_t int_value() const { return at<2>().as_int64(); }
+  bool has_float_value() const { return at<3>().valid(); }
+  float float_value() const { return at<3>().as_float(); }
+  bool has_string_value() const { return at<4>().valid(); }
+  ::protozero::ConstChars string_value() const { return at<4>().as_string(); }
+};
+
+class AndroidLogPacket_LogEvent_Arg : public ::protozero::Message {
+ public:
+  using Decoder = AndroidLogPacket_LogEvent_Arg_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kIntValueFieldNumber = 2,
+    kFloatValueFieldNumber = 3,
+    kStringValueFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidLogPacket.LogEvent.Arg"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidLogPacket_LogEvent_Arg>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_IntValue =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidLogPacket_LogEvent_Arg>;
+
+  static constexpr FieldMetadata_IntValue kIntValue{};
+  void set_int_value(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IntValue::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_FloatValue =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      AndroidLogPacket_LogEvent_Arg>;
+
+  static constexpr FieldMetadata_FloatValue kFloatValue{};
+  void set_float_value(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_FloatValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StringValue =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidLogPacket_LogEvent_Arg>;
+
+  static constexpr FieldMetadata_StringValue kStringValue{};
+  void set_string_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_StringValue::kFieldId, data, size);
+  }
+  void set_string_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_StringValue::kFieldId, chars.data, chars.size);
+  }
+  void set_string_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_StringValue::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/android/android_system_property.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_ANDROID_SYSTEM_PROPERTY_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_ANDROID_SYSTEM_PROPERTY_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class AndroidSystemProperty_PropertyValue;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class AndroidSystemProperty_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AndroidSystemProperty_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidSystemProperty_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidSystemProperty_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_values() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> values() const { return GetRepeated<::protozero::ConstBytes>(1); }
+};
+
+class AndroidSystemProperty : public ::protozero::Message {
+ public:
+  using Decoder = AndroidSystemProperty_Decoder;
+  enum : int32_t {
+    kValuesFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidSystemProperty"; }
+
+  using PropertyValue = ::perfetto::protos::pbzero::AndroidSystemProperty_PropertyValue;
+
+  using FieldMetadata_Values =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidSystemProperty_PropertyValue,
+      AndroidSystemProperty>;
+
+  static constexpr FieldMetadata_Values kValues{};
+  template <typename T = AndroidSystemProperty_PropertyValue> T* add_values() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+class AndroidSystemProperty_PropertyValue_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AndroidSystemProperty_PropertyValue_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidSystemProperty_PropertyValue_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidSystemProperty_PropertyValue_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_value() const { return at<2>().valid(); }
+  ::protozero::ConstChars value() const { return at<2>().as_string(); }
+};
+
+class AndroidSystemProperty_PropertyValue : public ::protozero::Message {
+ public:
+  using Decoder = AndroidSystemProperty_PropertyValue_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kValueFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidSystemProperty.PropertyValue"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidSystemProperty_PropertyValue>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidSystemProperty_PropertyValue>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Value::kFieldId, data, size);
+  }
+  void set_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Value::kFieldId, chars.data, chars.size);
+  }
+  void set_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/android/camera_event.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_CAMERA_EVENT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_CAMERA_EVENT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class AndroidCameraFrameEvent_CameraNodeProcessingDetails;
+class AndroidCameraSessionStats_CameraGraph;
+class AndroidCameraSessionStats_CameraGraph_CameraEdge;
+class AndroidCameraSessionStats_CameraGraph_CameraNode;
+namespace perfetto_pbzero_enum_AndroidCameraFrameEvent {
+enum CaptureResultStatus : int32_t;
+}  // namespace perfetto_pbzero_enum_AndroidCameraFrameEvent
+using AndroidCameraFrameEvent_CaptureResultStatus = perfetto_pbzero_enum_AndroidCameraFrameEvent::CaptureResultStatus;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_AndroidCameraFrameEvent {
+enum CaptureResultStatus : int32_t {
+  STATUS_UNSPECIFIED = 0,
+  STATUS_OK = 1,
+  STATUS_EARLY_METADATA_ERROR = 2,
+  STATUS_FINAL_METADATA_ERROR = 3,
+  STATUS_BUFFER_ERROR = 4,
+  STATUS_FLUSH_ERROR = 5,
+};
+} // namespace perfetto_pbzero_enum_AndroidCameraFrameEvent
+using AndroidCameraFrameEvent_CaptureResultStatus = perfetto_pbzero_enum_AndroidCameraFrameEvent::CaptureResultStatus;
+
+
+constexpr AndroidCameraFrameEvent_CaptureResultStatus AndroidCameraFrameEvent_CaptureResultStatus_MIN = AndroidCameraFrameEvent_CaptureResultStatus::STATUS_UNSPECIFIED;
+constexpr AndroidCameraFrameEvent_CaptureResultStatus AndroidCameraFrameEvent_CaptureResultStatus_MAX = AndroidCameraFrameEvent_CaptureResultStatus::STATUS_FLUSH_ERROR;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* AndroidCameraFrameEvent_CaptureResultStatus_Name(::perfetto::protos::pbzero::AndroidCameraFrameEvent_CaptureResultStatus value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::AndroidCameraFrameEvent_CaptureResultStatus::STATUS_UNSPECIFIED:
+    return "STATUS_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::AndroidCameraFrameEvent_CaptureResultStatus::STATUS_OK:
+    return "STATUS_OK";
+
+  case ::perfetto::protos::pbzero::AndroidCameraFrameEvent_CaptureResultStatus::STATUS_EARLY_METADATA_ERROR:
+    return "STATUS_EARLY_METADATA_ERROR";
+
+  case ::perfetto::protos::pbzero::AndroidCameraFrameEvent_CaptureResultStatus::STATUS_FINAL_METADATA_ERROR:
+    return "STATUS_FINAL_METADATA_ERROR";
+
+  case ::perfetto::protos::pbzero::AndroidCameraFrameEvent_CaptureResultStatus::STATUS_BUFFER_ERROR:
+    return "STATUS_BUFFER_ERROR";
+
+  case ::perfetto::protos::pbzero::AndroidCameraFrameEvent_CaptureResultStatus::STATUS_FLUSH_ERROR:
+    return "STATUS_FLUSH_ERROR";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class AndroidCameraSessionStats_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AndroidCameraSessionStats_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidCameraSessionStats_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidCameraSessionStats_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_session_id() const { return at<1>().valid(); }
+  uint64_t session_id() const { return at<1>().as_uint64(); }
+  bool has_graph() const { return at<2>().valid(); }
+  ::protozero::ConstBytes graph() const { return at<2>().as_bytes(); }
+};
+
+class AndroidCameraSessionStats : public ::protozero::Message {
+ public:
+  using Decoder = AndroidCameraSessionStats_Decoder;
+  enum : int32_t {
+    kSessionIdFieldNumber = 1,
+    kGraphFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidCameraSessionStats"; }
+
+  using CameraGraph = ::perfetto::protos::pbzero::AndroidCameraSessionStats_CameraGraph;
+
+  using FieldMetadata_SessionId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      AndroidCameraSessionStats>;
+
+  static constexpr FieldMetadata_SessionId kSessionId{};
+  void set_session_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SessionId::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_Graph =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidCameraSessionStats_CameraGraph,
+      AndroidCameraSessionStats>;
+
+  static constexpr FieldMetadata_Graph kGraph{};
+  template <typename T = AndroidCameraSessionStats_CameraGraph> T* set_graph() {
+    return BeginNestedMessage<T>(2);
+  }
+
+};
+
+class AndroidCameraSessionStats_CameraGraph_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AndroidCameraSessionStats_CameraGraph_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidCameraSessionStats_CameraGraph_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidCameraSessionStats_CameraGraph_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_nodes() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> nodes() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_edges() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> edges() const { return GetRepeated<::protozero::ConstBytes>(2); }
+};
+
+class AndroidCameraSessionStats_CameraGraph : public ::protozero::Message {
+ public:
+  using Decoder = AndroidCameraSessionStats_CameraGraph_Decoder;
+  enum : int32_t {
+    kNodesFieldNumber = 1,
+    kEdgesFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidCameraSessionStats.CameraGraph"; }
+
+  using CameraNode = ::perfetto::protos::pbzero::AndroidCameraSessionStats_CameraGraph_CameraNode;
+  using CameraEdge = ::perfetto::protos::pbzero::AndroidCameraSessionStats_CameraGraph_CameraEdge;
+
+  using FieldMetadata_Nodes =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidCameraSessionStats_CameraGraph_CameraNode,
+      AndroidCameraSessionStats_CameraGraph>;
+
+  static constexpr FieldMetadata_Nodes kNodes{};
+  template <typename T = AndroidCameraSessionStats_CameraGraph_CameraNode> T* add_nodes() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_Edges =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidCameraSessionStats_CameraGraph_CameraEdge,
+      AndroidCameraSessionStats_CameraGraph>;
+
+  static constexpr FieldMetadata_Edges kEdges{};
+  template <typename T = AndroidCameraSessionStats_CameraGraph_CameraEdge> T* add_edges() {
+    return BeginNestedMessage<T>(2);
+  }
+
+};
+
+class AndroidCameraSessionStats_CameraGraph_CameraEdge_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AndroidCameraSessionStats_CameraGraph_CameraEdge_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidCameraSessionStats_CameraGraph_CameraEdge_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidCameraSessionStats_CameraGraph_CameraEdge_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_output_node_id() const { return at<1>().valid(); }
+  int64_t output_node_id() const { return at<1>().as_int64(); }
+  bool has_output_id() const { return at<2>().valid(); }
+  int64_t output_id() const { return at<2>().as_int64(); }
+  bool has_input_node_id() const { return at<3>().valid(); }
+  int64_t input_node_id() const { return at<3>().as_int64(); }
+  bool has_input_id() const { return at<4>().valid(); }
+  int64_t input_id() const { return at<4>().as_int64(); }
+  bool has_vendor_data_version() const { return at<5>().valid(); }
+  int32_t vendor_data_version() const { return at<5>().as_int32(); }
+  bool has_vendor_data() const { return at<6>().valid(); }
+  ::protozero::ConstBytes vendor_data() const { return at<6>().as_bytes(); }
+};
+
+class AndroidCameraSessionStats_CameraGraph_CameraEdge : public ::protozero::Message {
+ public:
+  using Decoder = AndroidCameraSessionStats_CameraGraph_CameraEdge_Decoder;
+  enum : int32_t {
+    kOutputNodeIdFieldNumber = 1,
+    kOutputIdFieldNumber = 2,
+    kInputNodeIdFieldNumber = 3,
+    kInputIdFieldNumber = 4,
+    kVendorDataVersionFieldNumber = 5,
+    kVendorDataFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidCameraSessionStats.CameraGraph.CameraEdge"; }
+
+
+  using FieldMetadata_OutputNodeId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidCameraSessionStats_CameraGraph_CameraEdge>;
+
+  static constexpr FieldMetadata_OutputNodeId kOutputNodeId{};
+  void set_output_node_id(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OutputNodeId::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_OutputId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidCameraSessionStats_CameraGraph_CameraEdge>;
+
+  static constexpr FieldMetadata_OutputId kOutputId{};
+  void set_output_id(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OutputId::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_InputNodeId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidCameraSessionStats_CameraGraph_CameraEdge>;
+
+  static constexpr FieldMetadata_InputNodeId kInputNodeId{};
+  void set_input_node_id(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InputNodeId::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_InputId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidCameraSessionStats_CameraGraph_CameraEdge>;
+
+  static constexpr FieldMetadata_InputId kInputId{};
+  void set_input_id(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InputId::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_VendorDataVersion =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidCameraSessionStats_CameraGraph_CameraEdge>;
+
+  static constexpr FieldMetadata_VendorDataVersion kVendorDataVersion{};
+  void set_vendor_data_version(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VendorDataVersion::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_VendorData =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      AndroidCameraSessionStats_CameraGraph_CameraEdge>;
+
+  static constexpr FieldMetadata_VendorData kVendorData{};
+  void set_vendor_data(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_VendorData::kFieldId, data, size);
+  }
+  void set_vendor_data(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_VendorData::kFieldId, bytes.data, bytes.size);
+  }
+  void set_vendor_data(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_VendorData::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 AndroidCameraSessionStats_CameraGraph_CameraNode_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AndroidCameraSessionStats_CameraGraph_CameraNode_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidCameraSessionStats_CameraGraph_CameraNode_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidCameraSessionStats_CameraGraph_CameraNode_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_node_id() const { return at<1>().valid(); }
+  int64_t node_id() const { return at<1>().as_int64(); }
+  bool has_input_ids() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<int64_t> input_ids() const { return GetRepeated<int64_t>(2); }
+  bool has_output_ids() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<int64_t> output_ids() const { return GetRepeated<int64_t>(3); }
+  bool has_vendor_data_version() const { return at<4>().valid(); }
+  int32_t vendor_data_version() const { return at<4>().as_int32(); }
+  bool has_vendor_data() const { return at<5>().valid(); }
+  ::protozero::ConstBytes vendor_data() const { return at<5>().as_bytes(); }
+};
+
+class AndroidCameraSessionStats_CameraGraph_CameraNode : public ::protozero::Message {
+ public:
+  using Decoder = AndroidCameraSessionStats_CameraGraph_CameraNode_Decoder;
+  enum : int32_t {
+    kNodeIdFieldNumber = 1,
+    kInputIdsFieldNumber = 2,
+    kOutputIdsFieldNumber = 3,
+    kVendorDataVersionFieldNumber = 4,
+    kVendorDataFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidCameraSessionStats.CameraGraph.CameraNode"; }
+
+
+  using FieldMetadata_NodeId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidCameraSessionStats_CameraGraph_CameraNode>;
+
+  static constexpr FieldMetadata_NodeId kNodeId{};
+  void set_node_id(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NodeId::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_InputIds =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidCameraSessionStats_CameraGraph_CameraNode>;
+
+  static constexpr FieldMetadata_InputIds kInputIds{};
+  void add_input_ids(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InputIds::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_OutputIds =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidCameraSessionStats_CameraGraph_CameraNode>;
+
+  static constexpr FieldMetadata_OutputIds kOutputIds{};
+  void add_output_ids(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OutputIds::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_VendorDataVersion =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidCameraSessionStats_CameraGraph_CameraNode>;
+
+  static constexpr FieldMetadata_VendorDataVersion kVendorDataVersion{};
+  void set_vendor_data_version(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VendorDataVersion::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_VendorData =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      AndroidCameraSessionStats_CameraGraph_CameraNode>;
+
+  static constexpr FieldMetadata_VendorData kVendorData{};
+  void set_vendor_data(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_VendorData::kFieldId, data, size);
+  }
+  void set_vendor_data(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_VendorData::kFieldId, bytes.data, bytes.size);
+  }
+  void set_vendor_data(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_VendorData::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 AndroidCameraFrameEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/16, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AndroidCameraFrameEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidCameraFrameEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidCameraFrameEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_session_id() const { return at<1>().valid(); }
+  uint64_t session_id() const { return at<1>().as_uint64(); }
+  bool has_camera_id() const { return at<2>().valid(); }
+  uint32_t camera_id() const { return at<2>().as_uint32(); }
+  bool has_frame_number() const { return at<3>().valid(); }
+  int64_t frame_number() const { return at<3>().as_int64(); }
+  bool has_request_id() const { return at<4>().valid(); }
+  int64_t request_id() const { return at<4>().as_int64(); }
+  bool has_request_received_ns() const { return at<5>().valid(); }
+  int64_t request_received_ns() const { return at<5>().as_int64(); }
+  bool has_request_processing_started_ns() const { return at<6>().valid(); }
+  int64_t request_processing_started_ns() const { return at<6>().as_int64(); }
+  bool has_start_of_exposure_ns() const { return at<7>().valid(); }
+  int64_t start_of_exposure_ns() const { return at<7>().as_int64(); }
+  bool has_start_of_frame_ns() const { return at<8>().valid(); }
+  int64_t start_of_frame_ns() const { return at<8>().as_int64(); }
+  bool has_responses_all_sent_ns() const { return at<9>().valid(); }
+  int64_t responses_all_sent_ns() const { return at<9>().as_int64(); }
+  bool has_capture_result_status() const { return at<10>().valid(); }
+  int32_t capture_result_status() const { return at<10>().as_int32(); }
+  bool has_skipped_sensor_frames() const { return at<11>().valid(); }
+  int32_t skipped_sensor_frames() const { return at<11>().as_int32(); }
+  bool has_capture_intent() const { return at<12>().valid(); }
+  int32_t capture_intent() const { return at<12>().as_int32(); }
+  bool has_num_streams() const { return at<13>().valid(); }
+  int32_t num_streams() const { return at<13>().as_int32(); }
+  bool has_node_processing_details() const { return at<14>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> node_processing_details() const { return GetRepeated<::protozero::ConstBytes>(14); }
+  bool has_vendor_data_version() const { return at<15>().valid(); }
+  int32_t vendor_data_version() const { return at<15>().as_int32(); }
+  bool has_vendor_data() const { return at<16>().valid(); }
+  ::protozero::ConstBytes vendor_data() const { return at<16>().as_bytes(); }
+};
+
+class AndroidCameraFrameEvent : public ::protozero::Message {
+ public:
+  using Decoder = AndroidCameraFrameEvent_Decoder;
+  enum : int32_t {
+    kSessionIdFieldNumber = 1,
+    kCameraIdFieldNumber = 2,
+    kFrameNumberFieldNumber = 3,
+    kRequestIdFieldNumber = 4,
+    kRequestReceivedNsFieldNumber = 5,
+    kRequestProcessingStartedNsFieldNumber = 6,
+    kStartOfExposureNsFieldNumber = 7,
+    kStartOfFrameNsFieldNumber = 8,
+    kResponsesAllSentNsFieldNumber = 9,
+    kCaptureResultStatusFieldNumber = 10,
+    kSkippedSensorFramesFieldNumber = 11,
+    kCaptureIntentFieldNumber = 12,
+    kNumStreamsFieldNumber = 13,
+    kNodeProcessingDetailsFieldNumber = 14,
+    kVendorDataVersionFieldNumber = 15,
+    kVendorDataFieldNumber = 16,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidCameraFrameEvent"; }
+
+  using CameraNodeProcessingDetails = ::perfetto::protos::pbzero::AndroidCameraFrameEvent_CameraNodeProcessingDetails;
+
+  using CaptureResultStatus = ::perfetto::protos::pbzero::AndroidCameraFrameEvent_CaptureResultStatus;
+  static inline const char* CaptureResultStatus_Name(CaptureResultStatus value) {
+    return ::perfetto::protos::pbzero::AndroidCameraFrameEvent_CaptureResultStatus_Name(value);
+  }
+  static inline const CaptureResultStatus STATUS_UNSPECIFIED = CaptureResultStatus::STATUS_UNSPECIFIED;
+  static inline const CaptureResultStatus STATUS_OK = CaptureResultStatus::STATUS_OK;
+  static inline const CaptureResultStatus STATUS_EARLY_METADATA_ERROR = CaptureResultStatus::STATUS_EARLY_METADATA_ERROR;
+  static inline const CaptureResultStatus STATUS_FINAL_METADATA_ERROR = CaptureResultStatus::STATUS_FINAL_METADATA_ERROR;
+  static inline const CaptureResultStatus STATUS_BUFFER_ERROR = CaptureResultStatus::STATUS_BUFFER_ERROR;
+  static inline const CaptureResultStatus STATUS_FLUSH_ERROR = CaptureResultStatus::STATUS_FLUSH_ERROR;
+
+  using FieldMetadata_SessionId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      AndroidCameraFrameEvent>;
+
+  static constexpr FieldMetadata_SessionId kSessionId{};
+  void set_session_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SessionId::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_CameraId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AndroidCameraFrameEvent>;
+
+  static constexpr FieldMetadata_CameraId kCameraId{};
+  void set_camera_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CameraId::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_FrameNumber =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidCameraFrameEvent>;
+
+  static constexpr FieldMetadata_FrameNumber kFrameNumber{};
+  void set_frame_number(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FrameNumber::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_RequestId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidCameraFrameEvent>;
+
+  static constexpr FieldMetadata_RequestId kRequestId{};
+  void set_request_id(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RequestId::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_RequestReceivedNs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidCameraFrameEvent>;
+
+  static constexpr FieldMetadata_RequestReceivedNs kRequestReceivedNs{};
+  void set_request_received_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RequestReceivedNs::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_RequestProcessingStartedNs =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidCameraFrameEvent>;
+
+  static constexpr FieldMetadata_RequestProcessingStartedNs kRequestProcessingStartedNs{};
+  void set_request_processing_started_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RequestProcessingStartedNs::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_StartOfExposureNs =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidCameraFrameEvent>;
+
+  static constexpr FieldMetadata_StartOfExposureNs kStartOfExposureNs{};
+  void set_start_of_exposure_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StartOfExposureNs::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_StartOfFrameNs =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidCameraFrameEvent>;
+
+  static constexpr FieldMetadata_StartOfFrameNs kStartOfFrameNs{};
+  void set_start_of_frame_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StartOfFrameNs::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_ResponsesAllSentNs =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidCameraFrameEvent>;
+
+  static constexpr FieldMetadata_ResponsesAllSentNs kResponsesAllSentNs{};
+  void set_responses_all_sent_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResponsesAllSentNs::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_CaptureResultStatus =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      AndroidCameraFrameEvent_CaptureResultStatus,
+      AndroidCameraFrameEvent>;
+
+  static constexpr FieldMetadata_CaptureResultStatus kCaptureResultStatus{};
+  void set_capture_result_status(AndroidCameraFrameEvent_CaptureResultStatus value) {
+    static constexpr uint32_t field_id = FieldMetadata_CaptureResultStatus::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_SkippedSensorFrames =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidCameraFrameEvent>;
+
+  static constexpr FieldMetadata_SkippedSensorFrames kSkippedSensorFrames{};
+  void set_skipped_sensor_frames(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SkippedSensorFrames::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_CaptureIntent =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidCameraFrameEvent>;
+
+  static constexpr FieldMetadata_CaptureIntent kCaptureIntent{};
+  void set_capture_intent(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CaptureIntent::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_NumStreams =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidCameraFrameEvent>;
+
+  static constexpr FieldMetadata_NumStreams kNumStreams{};
+  void set_num_streams(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NumStreams::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_NodeProcessingDetails =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidCameraFrameEvent_CameraNodeProcessingDetails,
+      AndroidCameraFrameEvent>;
+
+  static constexpr FieldMetadata_NodeProcessingDetails kNodeProcessingDetails{};
+  template <typename T = AndroidCameraFrameEvent_CameraNodeProcessingDetails> T* add_node_processing_details() {
+    return BeginNestedMessage<T>(14);
+  }
+
+
+  using FieldMetadata_VendorDataVersion =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidCameraFrameEvent>;
+
+  static constexpr FieldMetadata_VendorDataVersion kVendorDataVersion{};
+  void set_vendor_data_version(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VendorDataVersion::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_VendorData =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      AndroidCameraFrameEvent>;
+
+  static constexpr FieldMetadata_VendorData kVendorData{};
+  void set_vendor_data(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_VendorData::kFieldId, data, size);
+  }
+  void set_vendor_data(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_VendorData::kFieldId, bytes.data, bytes.size);
+  }
+  void set_vendor_data(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_VendorData::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 AndroidCameraFrameEvent_CameraNodeProcessingDetails_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AndroidCameraFrameEvent_CameraNodeProcessingDetails_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidCameraFrameEvent_CameraNodeProcessingDetails_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidCameraFrameEvent_CameraNodeProcessingDetails_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_node_id() const { return at<1>().valid(); }
+  int64_t node_id() const { return at<1>().as_int64(); }
+  bool has_start_processing_ns() const { return at<2>().valid(); }
+  int64_t start_processing_ns() const { return at<2>().as_int64(); }
+  bool has_end_processing_ns() const { return at<3>().valid(); }
+  int64_t end_processing_ns() const { return at<3>().as_int64(); }
+  bool has_scheduling_latency_ns() const { return at<4>().valid(); }
+  int64_t scheduling_latency_ns() const { return at<4>().as_int64(); }
+};
+
+class AndroidCameraFrameEvent_CameraNodeProcessingDetails : public ::protozero::Message {
+ public:
+  using Decoder = AndroidCameraFrameEvent_CameraNodeProcessingDetails_Decoder;
+  enum : int32_t {
+    kNodeIdFieldNumber = 1,
+    kStartProcessingNsFieldNumber = 2,
+    kEndProcessingNsFieldNumber = 3,
+    kSchedulingLatencyNsFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidCameraFrameEvent.CameraNodeProcessingDetails"; }
+
+
+  using FieldMetadata_NodeId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidCameraFrameEvent_CameraNodeProcessingDetails>;
+
+  static constexpr FieldMetadata_NodeId kNodeId{};
+  void set_node_id(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NodeId::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_StartProcessingNs =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidCameraFrameEvent_CameraNodeProcessingDetails>;
+
+  static constexpr FieldMetadata_StartProcessingNs kStartProcessingNs{};
+  void set_start_processing_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StartProcessingNs::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_EndProcessingNs =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidCameraFrameEvent_CameraNodeProcessingDetails>;
+
+  static constexpr FieldMetadata_EndProcessingNs kEndProcessingNs{};
+  void set_end_processing_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EndProcessingNs::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_SchedulingLatencyNs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidCameraFrameEvent_CameraNodeProcessingDetails>;
+
+  static constexpr FieldMetadata_SchedulingLatencyNs kSchedulingLatencyNs{};
+  void set_scheduling_latency_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SchedulingLatencyNs::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/android/frame_timeline_event.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_FRAME_TIMELINE_EVENT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_FRAME_TIMELINE_EVENT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class FrameTimelineEvent_ActualDisplayFrameStart;
+class FrameTimelineEvent_ActualSurfaceFrameStart;
+class FrameTimelineEvent_ExpectedDisplayFrameStart;
+class FrameTimelineEvent_ExpectedSurfaceFrameStart;
+class FrameTimelineEvent_FrameEnd;
+namespace perfetto_pbzero_enum_FrameTimelineEvent {
+enum JankSeverityType : int32_t;
+}  // namespace perfetto_pbzero_enum_FrameTimelineEvent
+using FrameTimelineEvent_JankSeverityType = perfetto_pbzero_enum_FrameTimelineEvent::JankSeverityType;
+namespace perfetto_pbzero_enum_FrameTimelineEvent {
+enum PredictionType : int32_t;
+}  // namespace perfetto_pbzero_enum_FrameTimelineEvent
+using FrameTimelineEvent_PredictionType = perfetto_pbzero_enum_FrameTimelineEvent::PredictionType;
+namespace perfetto_pbzero_enum_FrameTimelineEvent {
+enum PresentType : int32_t;
+}  // namespace perfetto_pbzero_enum_FrameTimelineEvent
+using FrameTimelineEvent_PresentType = perfetto_pbzero_enum_FrameTimelineEvent::PresentType;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_FrameTimelineEvent {
+enum JankType : int32_t {
+  JANK_UNSPECIFIED = 0,
+  JANK_NONE = 1,
+  JANK_SF_SCHEDULING = 2,
+  JANK_PREDICTION_ERROR = 4,
+  JANK_DISPLAY_HAL = 8,
+  JANK_SF_CPU_DEADLINE_MISSED = 16,
+  JANK_SF_GPU_DEADLINE_MISSED = 32,
+  JANK_APP_DEADLINE_MISSED = 64,
+  JANK_BUFFER_STUFFING = 128,
+  JANK_UNKNOWN = 256,
+  JANK_SF_STUFFING = 512,
+  JANK_DROPPED = 1024,
+};
+} // namespace perfetto_pbzero_enum_FrameTimelineEvent
+using FrameTimelineEvent_JankType = perfetto_pbzero_enum_FrameTimelineEvent::JankType;
+
+
+constexpr FrameTimelineEvent_JankType FrameTimelineEvent_JankType_MIN = FrameTimelineEvent_JankType::JANK_UNSPECIFIED;
+constexpr FrameTimelineEvent_JankType FrameTimelineEvent_JankType_MAX = FrameTimelineEvent_JankType::JANK_DROPPED;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* FrameTimelineEvent_JankType_Name(::perfetto::protos::pbzero::FrameTimelineEvent_JankType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_JankType::JANK_UNSPECIFIED:
+    return "JANK_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_JankType::JANK_NONE:
+    return "JANK_NONE";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_JankType::JANK_SF_SCHEDULING:
+    return "JANK_SF_SCHEDULING";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_JankType::JANK_PREDICTION_ERROR:
+    return "JANK_PREDICTION_ERROR";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_JankType::JANK_DISPLAY_HAL:
+    return "JANK_DISPLAY_HAL";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_JankType::JANK_SF_CPU_DEADLINE_MISSED:
+    return "JANK_SF_CPU_DEADLINE_MISSED";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_JankType::JANK_SF_GPU_DEADLINE_MISSED:
+    return "JANK_SF_GPU_DEADLINE_MISSED";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_JankType::JANK_APP_DEADLINE_MISSED:
+    return "JANK_APP_DEADLINE_MISSED";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_JankType::JANK_BUFFER_STUFFING:
+    return "JANK_BUFFER_STUFFING";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_JankType::JANK_UNKNOWN:
+    return "JANK_UNKNOWN";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_JankType::JANK_SF_STUFFING:
+    return "JANK_SF_STUFFING";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_JankType::JANK_DROPPED:
+    return "JANK_DROPPED";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_FrameTimelineEvent {
+enum JankSeverityType : int32_t {
+  SEVERITY_UNKNOWN = 0,
+  SEVERITY_NONE = 1,
+  SEVERITY_PARTIAL = 2,
+  SEVERITY_FULL = 3,
+};
+} // namespace perfetto_pbzero_enum_FrameTimelineEvent
+using FrameTimelineEvent_JankSeverityType = perfetto_pbzero_enum_FrameTimelineEvent::JankSeverityType;
+
+
+constexpr FrameTimelineEvent_JankSeverityType FrameTimelineEvent_JankSeverityType_MIN = FrameTimelineEvent_JankSeverityType::SEVERITY_UNKNOWN;
+constexpr FrameTimelineEvent_JankSeverityType FrameTimelineEvent_JankSeverityType_MAX = FrameTimelineEvent_JankSeverityType::SEVERITY_FULL;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* FrameTimelineEvent_JankSeverityType_Name(::perfetto::protos::pbzero::FrameTimelineEvent_JankSeverityType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_JankSeverityType::SEVERITY_UNKNOWN:
+    return "SEVERITY_UNKNOWN";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_JankSeverityType::SEVERITY_NONE:
+    return "SEVERITY_NONE";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_JankSeverityType::SEVERITY_PARTIAL:
+    return "SEVERITY_PARTIAL";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_JankSeverityType::SEVERITY_FULL:
+    return "SEVERITY_FULL";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_FrameTimelineEvent {
+enum PresentType : int32_t {
+  PRESENT_UNSPECIFIED = 0,
+  PRESENT_ON_TIME = 1,
+  PRESENT_LATE = 2,
+  PRESENT_EARLY = 3,
+  PRESENT_DROPPED = 4,
+  PRESENT_UNKNOWN = 5,
+};
+} // namespace perfetto_pbzero_enum_FrameTimelineEvent
+using FrameTimelineEvent_PresentType = perfetto_pbzero_enum_FrameTimelineEvent::PresentType;
+
+
+constexpr FrameTimelineEvent_PresentType FrameTimelineEvent_PresentType_MIN = FrameTimelineEvent_PresentType::PRESENT_UNSPECIFIED;
+constexpr FrameTimelineEvent_PresentType FrameTimelineEvent_PresentType_MAX = FrameTimelineEvent_PresentType::PRESENT_UNKNOWN;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* FrameTimelineEvent_PresentType_Name(::perfetto::protos::pbzero::FrameTimelineEvent_PresentType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_PresentType::PRESENT_UNSPECIFIED:
+    return "PRESENT_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_PresentType::PRESENT_ON_TIME:
+    return "PRESENT_ON_TIME";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_PresentType::PRESENT_LATE:
+    return "PRESENT_LATE";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_PresentType::PRESENT_EARLY:
+    return "PRESENT_EARLY";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_PresentType::PRESENT_DROPPED:
+    return "PRESENT_DROPPED";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_PresentType::PRESENT_UNKNOWN:
+    return "PRESENT_UNKNOWN";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_FrameTimelineEvent {
+enum PredictionType : int32_t {
+  PREDICTION_UNSPECIFIED = 0,
+  PREDICTION_VALID = 1,
+  PREDICTION_EXPIRED = 2,
+  PREDICTION_UNKNOWN = 3,
+};
+} // namespace perfetto_pbzero_enum_FrameTimelineEvent
+using FrameTimelineEvent_PredictionType = perfetto_pbzero_enum_FrameTimelineEvent::PredictionType;
+
+
+constexpr FrameTimelineEvent_PredictionType FrameTimelineEvent_PredictionType_MIN = FrameTimelineEvent_PredictionType::PREDICTION_UNSPECIFIED;
+constexpr FrameTimelineEvent_PredictionType FrameTimelineEvent_PredictionType_MAX = FrameTimelineEvent_PredictionType::PREDICTION_UNKNOWN;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* FrameTimelineEvent_PredictionType_Name(::perfetto::protos::pbzero::FrameTimelineEvent_PredictionType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_PredictionType::PREDICTION_UNSPECIFIED:
+    return "PREDICTION_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_PredictionType::PREDICTION_VALID:
+    return "PREDICTION_VALID";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_PredictionType::PREDICTION_EXPIRED:
+    return "PREDICTION_EXPIRED";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_PredictionType::PREDICTION_UNKNOWN:
+    return "PREDICTION_UNKNOWN";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class FrameTimelineEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FrameTimelineEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FrameTimelineEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FrameTimelineEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_expected_display_frame_start() const { return at<1>().valid(); }
+  ::protozero::ConstBytes expected_display_frame_start() const { return at<1>().as_bytes(); }
+  bool has_actual_display_frame_start() const { return at<2>().valid(); }
+  ::protozero::ConstBytes actual_display_frame_start() const { return at<2>().as_bytes(); }
+  bool has_expected_surface_frame_start() const { return at<3>().valid(); }
+  ::protozero::ConstBytes expected_surface_frame_start() const { return at<3>().as_bytes(); }
+  bool has_actual_surface_frame_start() const { return at<4>().valid(); }
+  ::protozero::ConstBytes actual_surface_frame_start() const { return at<4>().as_bytes(); }
+  bool has_frame_end() const { return at<5>().valid(); }
+  ::protozero::ConstBytes frame_end() const { return at<5>().as_bytes(); }
+};
+
+class FrameTimelineEvent : public ::protozero::Message {
+ public:
+  using Decoder = FrameTimelineEvent_Decoder;
+  enum : int32_t {
+    kExpectedDisplayFrameStartFieldNumber = 1,
+    kActualDisplayFrameStartFieldNumber = 2,
+    kExpectedSurfaceFrameStartFieldNumber = 3,
+    kActualSurfaceFrameStartFieldNumber = 4,
+    kFrameEndFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FrameTimelineEvent"; }
+
+  using ExpectedSurfaceFrameStart = ::perfetto::protos::pbzero::FrameTimelineEvent_ExpectedSurfaceFrameStart;
+  using ActualSurfaceFrameStart = ::perfetto::protos::pbzero::FrameTimelineEvent_ActualSurfaceFrameStart;
+  using ExpectedDisplayFrameStart = ::perfetto::protos::pbzero::FrameTimelineEvent_ExpectedDisplayFrameStart;
+  using ActualDisplayFrameStart = ::perfetto::protos::pbzero::FrameTimelineEvent_ActualDisplayFrameStart;
+  using FrameEnd = ::perfetto::protos::pbzero::FrameTimelineEvent_FrameEnd;
+
+  using JankType = ::perfetto::protos::pbzero::FrameTimelineEvent_JankType;
+  static inline const char* JankType_Name(JankType value) {
+    return ::perfetto::protos::pbzero::FrameTimelineEvent_JankType_Name(value);
+  }
+
+  using JankSeverityType = ::perfetto::protos::pbzero::FrameTimelineEvent_JankSeverityType;
+  static inline const char* JankSeverityType_Name(JankSeverityType value) {
+    return ::perfetto::protos::pbzero::FrameTimelineEvent_JankSeverityType_Name(value);
+  }
+
+  using PresentType = ::perfetto::protos::pbzero::FrameTimelineEvent_PresentType;
+  static inline const char* PresentType_Name(PresentType value) {
+    return ::perfetto::protos::pbzero::FrameTimelineEvent_PresentType_Name(value);
+  }
+
+  using PredictionType = ::perfetto::protos::pbzero::FrameTimelineEvent_PredictionType;
+  static inline const char* PredictionType_Name(PredictionType value) {
+    return ::perfetto::protos::pbzero::FrameTimelineEvent_PredictionType_Name(value);
+  }
+  static inline const JankType JANK_UNSPECIFIED = JankType::JANK_UNSPECIFIED;
+  static inline const JankType JANK_NONE = JankType::JANK_NONE;
+  static inline const JankType JANK_SF_SCHEDULING = JankType::JANK_SF_SCHEDULING;
+  static inline const JankType JANK_PREDICTION_ERROR = JankType::JANK_PREDICTION_ERROR;
+  static inline const JankType JANK_DISPLAY_HAL = JankType::JANK_DISPLAY_HAL;
+  static inline const JankType JANK_SF_CPU_DEADLINE_MISSED = JankType::JANK_SF_CPU_DEADLINE_MISSED;
+  static inline const JankType JANK_SF_GPU_DEADLINE_MISSED = JankType::JANK_SF_GPU_DEADLINE_MISSED;
+  static inline const JankType JANK_APP_DEADLINE_MISSED = JankType::JANK_APP_DEADLINE_MISSED;
+  static inline const JankType JANK_BUFFER_STUFFING = JankType::JANK_BUFFER_STUFFING;
+  static inline const JankType JANK_UNKNOWN = JankType::JANK_UNKNOWN;
+  static inline const JankType JANK_SF_STUFFING = JankType::JANK_SF_STUFFING;
+  static inline const JankType JANK_DROPPED = JankType::JANK_DROPPED;
+  static inline const JankSeverityType SEVERITY_UNKNOWN = JankSeverityType::SEVERITY_UNKNOWN;
+  static inline const JankSeverityType SEVERITY_NONE = JankSeverityType::SEVERITY_NONE;
+  static inline const JankSeverityType SEVERITY_PARTIAL = JankSeverityType::SEVERITY_PARTIAL;
+  static inline const JankSeverityType SEVERITY_FULL = JankSeverityType::SEVERITY_FULL;
+  static inline const PresentType PRESENT_UNSPECIFIED = PresentType::PRESENT_UNSPECIFIED;
+  static inline const PresentType PRESENT_ON_TIME = PresentType::PRESENT_ON_TIME;
+  static inline const PresentType PRESENT_LATE = PresentType::PRESENT_LATE;
+  static inline const PresentType PRESENT_EARLY = PresentType::PRESENT_EARLY;
+  static inline const PresentType PRESENT_DROPPED = PresentType::PRESENT_DROPPED;
+  static inline const PresentType PRESENT_UNKNOWN = PresentType::PRESENT_UNKNOWN;
+  static inline const PredictionType PREDICTION_UNSPECIFIED = PredictionType::PREDICTION_UNSPECIFIED;
+  static inline const PredictionType PREDICTION_VALID = PredictionType::PREDICTION_VALID;
+  static inline const PredictionType PREDICTION_EXPIRED = PredictionType::PREDICTION_EXPIRED;
+  static inline const PredictionType PREDICTION_UNKNOWN = PredictionType::PREDICTION_UNKNOWN;
+
+  using FieldMetadata_ExpectedDisplayFrameStart =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FrameTimelineEvent_ExpectedDisplayFrameStart,
+      FrameTimelineEvent>;
+
+  static constexpr FieldMetadata_ExpectedDisplayFrameStart kExpectedDisplayFrameStart{};
+  template <typename T = FrameTimelineEvent_ExpectedDisplayFrameStart> T* set_expected_display_frame_start() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_ActualDisplayFrameStart =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FrameTimelineEvent_ActualDisplayFrameStart,
+      FrameTimelineEvent>;
+
+  static constexpr FieldMetadata_ActualDisplayFrameStart kActualDisplayFrameStart{};
+  template <typename T = FrameTimelineEvent_ActualDisplayFrameStart> T* set_actual_display_frame_start() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_ExpectedSurfaceFrameStart =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FrameTimelineEvent_ExpectedSurfaceFrameStart,
+      FrameTimelineEvent>;
+
+  static constexpr FieldMetadata_ExpectedSurfaceFrameStart kExpectedSurfaceFrameStart{};
+  template <typename T = FrameTimelineEvent_ExpectedSurfaceFrameStart> T* set_expected_surface_frame_start() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_ActualSurfaceFrameStart =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FrameTimelineEvent_ActualSurfaceFrameStart,
+      FrameTimelineEvent>;
+
+  static constexpr FieldMetadata_ActualSurfaceFrameStart kActualSurfaceFrameStart{};
+  template <typename T = FrameTimelineEvent_ActualSurfaceFrameStart> T* set_actual_surface_frame_start() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_FrameEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FrameTimelineEvent_FrameEnd,
+      FrameTimelineEvent>;
+
+  static constexpr FieldMetadata_FrameEnd kFrameEnd{};
+  template <typename T = FrameTimelineEvent_FrameEnd> T* set_frame_end() {
+    return BeginNestedMessage<T>(5);
+  }
+
+};
+
+class FrameTimelineEvent_FrameEnd_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FrameTimelineEvent_FrameEnd_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FrameTimelineEvent_FrameEnd_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FrameTimelineEvent_FrameEnd_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cookie() const { return at<1>().valid(); }
+  int64_t cookie() const { return at<1>().as_int64(); }
+};
+
+class FrameTimelineEvent_FrameEnd : public ::protozero::Message {
+ public:
+  using Decoder = FrameTimelineEvent_FrameEnd_Decoder;
+  enum : int32_t {
+    kCookieFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FrameTimelineEvent.FrameEnd"; }
+
+
+  using FieldMetadata_Cookie =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      FrameTimelineEvent_FrameEnd>;
+
+  static constexpr FieldMetadata_Cookie kCookie{};
+  void set_cookie(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cookie::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 FrameTimelineEvent_ActualDisplayFrameStart_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FrameTimelineEvent_ActualDisplayFrameStart_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FrameTimelineEvent_ActualDisplayFrameStart_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FrameTimelineEvent_ActualDisplayFrameStart_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cookie() const { return at<1>().valid(); }
+  int64_t cookie() const { return at<1>().as_int64(); }
+  bool has_token() const { return at<2>().valid(); }
+  int64_t token() const { return at<2>().as_int64(); }
+  bool has_pid() const { return at<3>().valid(); }
+  int32_t pid() const { return at<3>().as_int32(); }
+  bool has_present_type() const { return at<4>().valid(); }
+  int32_t present_type() const { return at<4>().as_int32(); }
+  bool has_on_time_finish() const { return at<5>().valid(); }
+  bool on_time_finish() const { return at<5>().as_bool(); }
+  bool has_gpu_composition() const { return at<6>().valid(); }
+  bool gpu_composition() const { return at<6>().as_bool(); }
+  bool has_jank_type() const { return at<7>().valid(); }
+  int32_t jank_type() const { return at<7>().as_int32(); }
+  bool has_prediction_type() const { return at<8>().valid(); }
+  int32_t prediction_type() const { return at<8>().as_int32(); }
+  bool has_jank_severity_type() const { return at<9>().valid(); }
+  int32_t jank_severity_type() const { return at<9>().as_int32(); }
+};
+
+class FrameTimelineEvent_ActualDisplayFrameStart : public ::protozero::Message {
+ public:
+  using Decoder = FrameTimelineEvent_ActualDisplayFrameStart_Decoder;
+  enum : int32_t {
+    kCookieFieldNumber = 1,
+    kTokenFieldNumber = 2,
+    kPidFieldNumber = 3,
+    kPresentTypeFieldNumber = 4,
+    kOnTimeFinishFieldNumber = 5,
+    kGpuCompositionFieldNumber = 6,
+    kJankTypeFieldNumber = 7,
+    kPredictionTypeFieldNumber = 8,
+    kJankSeverityTypeFieldNumber = 9,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FrameTimelineEvent.ActualDisplayFrameStart"; }
+
+
+  using FieldMetadata_Cookie =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      FrameTimelineEvent_ActualDisplayFrameStart>;
+
+  static constexpr FieldMetadata_Cookie kCookie{};
+  void set_cookie(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cookie::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_Token =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      FrameTimelineEvent_ActualDisplayFrameStart>;
+
+  static constexpr FieldMetadata_Token kToken{};
+  void set_token(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Token::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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FrameTimelineEvent_ActualDisplayFrameStart>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_PresentType =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      FrameTimelineEvent_PresentType,
+      FrameTimelineEvent_ActualDisplayFrameStart>;
+
+  static constexpr FieldMetadata_PresentType kPresentType{};
+  void set_present_type(FrameTimelineEvent_PresentType value) {
+    static constexpr uint32_t field_id = FieldMetadata_PresentType::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_OnTimeFinish =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FrameTimelineEvent_ActualDisplayFrameStart>;
+
+  static constexpr FieldMetadata_OnTimeFinish kOnTimeFinish{};
+  void set_on_time_finish(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_OnTimeFinish::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_GpuComposition =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FrameTimelineEvent_ActualDisplayFrameStart>;
+
+  static constexpr FieldMetadata_GpuComposition kGpuComposition{};
+  void set_gpu_composition(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_GpuComposition::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_JankType =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FrameTimelineEvent_ActualDisplayFrameStart>;
+
+  static constexpr FieldMetadata_JankType kJankType{};
+  void set_jank_type(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_JankType::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_PredictionType =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      FrameTimelineEvent_PredictionType,
+      FrameTimelineEvent_ActualDisplayFrameStart>;
+
+  static constexpr FieldMetadata_PredictionType kPredictionType{};
+  void set_prediction_type(FrameTimelineEvent_PredictionType value) {
+    static constexpr uint32_t field_id = FieldMetadata_PredictionType::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_JankSeverityType =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      FrameTimelineEvent_JankSeverityType,
+      FrameTimelineEvent_ActualDisplayFrameStart>;
+
+  static constexpr FieldMetadata_JankSeverityType kJankSeverityType{};
+  void set_jank_severity_type(FrameTimelineEvent_JankSeverityType value) {
+    static constexpr uint32_t field_id = FieldMetadata_JankSeverityType::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);
+  }
+};
+
+class FrameTimelineEvent_ExpectedDisplayFrameStart_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FrameTimelineEvent_ExpectedDisplayFrameStart_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FrameTimelineEvent_ExpectedDisplayFrameStart_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FrameTimelineEvent_ExpectedDisplayFrameStart_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cookie() const { return at<1>().valid(); }
+  int64_t cookie() const { return at<1>().as_int64(); }
+  bool has_token() const { return at<2>().valid(); }
+  int64_t token() const { return at<2>().as_int64(); }
+  bool has_pid() const { return at<3>().valid(); }
+  int32_t pid() const { return at<3>().as_int32(); }
+};
+
+class FrameTimelineEvent_ExpectedDisplayFrameStart : public ::protozero::Message {
+ public:
+  using Decoder = FrameTimelineEvent_ExpectedDisplayFrameStart_Decoder;
+  enum : int32_t {
+    kCookieFieldNumber = 1,
+    kTokenFieldNumber = 2,
+    kPidFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FrameTimelineEvent.ExpectedDisplayFrameStart"; }
+
+
+  using FieldMetadata_Cookie =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      FrameTimelineEvent_ExpectedDisplayFrameStart>;
+
+  static constexpr FieldMetadata_Cookie kCookie{};
+  void set_cookie(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cookie::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_Token =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      FrameTimelineEvent_ExpectedDisplayFrameStart>;
+
+  static constexpr FieldMetadata_Token kToken{};
+  void set_token(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Token::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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FrameTimelineEvent_ExpectedDisplayFrameStart>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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);
+  }
+};
+
+class FrameTimelineEvent_ActualSurfaceFrameStart_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/12, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FrameTimelineEvent_ActualSurfaceFrameStart_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FrameTimelineEvent_ActualSurfaceFrameStart_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FrameTimelineEvent_ActualSurfaceFrameStart_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cookie() const { return at<1>().valid(); }
+  int64_t cookie() const { return at<1>().as_int64(); }
+  bool has_token() const { return at<2>().valid(); }
+  int64_t token() const { return at<2>().as_int64(); }
+  bool has_display_frame_token() const { return at<3>().valid(); }
+  int64_t display_frame_token() const { return at<3>().as_int64(); }
+  bool has_pid() const { return at<4>().valid(); }
+  int32_t pid() const { return at<4>().as_int32(); }
+  bool has_layer_name() const { return at<5>().valid(); }
+  ::protozero::ConstChars layer_name() const { return at<5>().as_string(); }
+  bool has_present_type() const { return at<6>().valid(); }
+  int32_t present_type() const { return at<6>().as_int32(); }
+  bool has_on_time_finish() const { return at<7>().valid(); }
+  bool on_time_finish() const { return at<7>().as_bool(); }
+  bool has_gpu_composition() const { return at<8>().valid(); }
+  bool gpu_composition() const { return at<8>().as_bool(); }
+  bool has_jank_type() const { return at<9>().valid(); }
+  int32_t jank_type() const { return at<9>().as_int32(); }
+  bool has_prediction_type() const { return at<10>().valid(); }
+  int32_t prediction_type() const { return at<10>().as_int32(); }
+  bool has_is_buffer() const { return at<11>().valid(); }
+  bool is_buffer() const { return at<11>().as_bool(); }
+  bool has_jank_severity_type() const { return at<12>().valid(); }
+  int32_t jank_severity_type() const { return at<12>().as_int32(); }
+};
+
+class FrameTimelineEvent_ActualSurfaceFrameStart : public ::protozero::Message {
+ public:
+  using Decoder = FrameTimelineEvent_ActualSurfaceFrameStart_Decoder;
+  enum : int32_t {
+    kCookieFieldNumber = 1,
+    kTokenFieldNumber = 2,
+    kDisplayFrameTokenFieldNumber = 3,
+    kPidFieldNumber = 4,
+    kLayerNameFieldNumber = 5,
+    kPresentTypeFieldNumber = 6,
+    kOnTimeFinishFieldNumber = 7,
+    kGpuCompositionFieldNumber = 8,
+    kJankTypeFieldNumber = 9,
+    kPredictionTypeFieldNumber = 10,
+    kIsBufferFieldNumber = 11,
+    kJankSeverityTypeFieldNumber = 12,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FrameTimelineEvent.ActualSurfaceFrameStart"; }
+
+
+  using FieldMetadata_Cookie =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      FrameTimelineEvent_ActualSurfaceFrameStart>;
+
+  static constexpr FieldMetadata_Cookie kCookie{};
+  void set_cookie(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cookie::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_Token =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      FrameTimelineEvent_ActualSurfaceFrameStart>;
+
+  static constexpr FieldMetadata_Token kToken{};
+  void set_token(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Token::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_DisplayFrameToken =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      FrameTimelineEvent_ActualSurfaceFrameStart>;
+
+  static constexpr FieldMetadata_DisplayFrameToken kDisplayFrameToken{};
+  void set_display_frame_token(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DisplayFrameToken::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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FrameTimelineEvent_ActualSurfaceFrameStart>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_LayerName =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FrameTimelineEvent_ActualSurfaceFrameStart>;
+
+  static constexpr FieldMetadata_LayerName kLayerName{};
+  void set_layer_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_LayerName::kFieldId, data, size);
+  }
+  void set_layer_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_LayerName::kFieldId, chars.data, chars.size);
+  }
+  void set_layer_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_LayerName::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_PresentType =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      FrameTimelineEvent_PresentType,
+      FrameTimelineEvent_ActualSurfaceFrameStart>;
+
+  static constexpr FieldMetadata_PresentType kPresentType{};
+  void set_present_type(FrameTimelineEvent_PresentType value) {
+    static constexpr uint32_t field_id = FieldMetadata_PresentType::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_OnTimeFinish =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FrameTimelineEvent_ActualSurfaceFrameStart>;
+
+  static constexpr FieldMetadata_OnTimeFinish kOnTimeFinish{};
+  void set_on_time_finish(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_OnTimeFinish::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_GpuComposition =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FrameTimelineEvent_ActualSurfaceFrameStart>;
+
+  static constexpr FieldMetadata_GpuComposition kGpuComposition{};
+  void set_gpu_composition(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_GpuComposition::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_JankType =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FrameTimelineEvent_ActualSurfaceFrameStart>;
+
+  static constexpr FieldMetadata_JankType kJankType{};
+  void set_jank_type(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_JankType::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_PredictionType =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      FrameTimelineEvent_PredictionType,
+      FrameTimelineEvent_ActualSurfaceFrameStart>;
+
+  static constexpr FieldMetadata_PredictionType kPredictionType{};
+  void set_prediction_type(FrameTimelineEvent_PredictionType value) {
+    static constexpr uint32_t field_id = FieldMetadata_PredictionType::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_IsBuffer =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FrameTimelineEvent_ActualSurfaceFrameStart>;
+
+  static constexpr FieldMetadata_IsBuffer kIsBuffer{};
+  void set_is_buffer(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsBuffer::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_JankSeverityType =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      FrameTimelineEvent_JankSeverityType,
+      FrameTimelineEvent_ActualSurfaceFrameStart>;
+
+  static constexpr FieldMetadata_JankSeverityType kJankSeverityType{};
+  void set_jank_severity_type(FrameTimelineEvent_JankSeverityType value) {
+    static constexpr uint32_t field_id = FieldMetadata_JankSeverityType::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);
+  }
+};
+
+class FrameTimelineEvent_ExpectedSurfaceFrameStart_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FrameTimelineEvent_ExpectedSurfaceFrameStart_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FrameTimelineEvent_ExpectedSurfaceFrameStart_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FrameTimelineEvent_ExpectedSurfaceFrameStart_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cookie() const { return at<1>().valid(); }
+  int64_t cookie() const { return at<1>().as_int64(); }
+  bool has_token() const { return at<2>().valid(); }
+  int64_t token() const { return at<2>().as_int64(); }
+  bool has_display_frame_token() const { return at<3>().valid(); }
+  int64_t display_frame_token() const { return at<3>().as_int64(); }
+  bool has_pid() const { return at<4>().valid(); }
+  int32_t pid() const { return at<4>().as_int32(); }
+  bool has_layer_name() const { return at<5>().valid(); }
+  ::protozero::ConstChars layer_name() const { return at<5>().as_string(); }
+};
+
+class FrameTimelineEvent_ExpectedSurfaceFrameStart : public ::protozero::Message {
+ public:
+  using Decoder = FrameTimelineEvent_ExpectedSurfaceFrameStart_Decoder;
+  enum : int32_t {
+    kCookieFieldNumber = 1,
+    kTokenFieldNumber = 2,
+    kDisplayFrameTokenFieldNumber = 3,
+    kPidFieldNumber = 4,
+    kLayerNameFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FrameTimelineEvent.ExpectedSurfaceFrameStart"; }
+
+
+  using FieldMetadata_Cookie =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      FrameTimelineEvent_ExpectedSurfaceFrameStart>;
+
+  static constexpr FieldMetadata_Cookie kCookie{};
+  void set_cookie(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cookie::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_Token =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      FrameTimelineEvent_ExpectedSurfaceFrameStart>;
+
+  static constexpr FieldMetadata_Token kToken{};
+  void set_token(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Token::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_DisplayFrameToken =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      FrameTimelineEvent_ExpectedSurfaceFrameStart>;
+
+  static constexpr FieldMetadata_DisplayFrameToken kDisplayFrameToken{};
+  void set_display_frame_token(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DisplayFrameToken::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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FrameTimelineEvent_ExpectedSurfaceFrameStart>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_LayerName =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FrameTimelineEvent_ExpectedSurfaceFrameStart>;
+
+  static constexpr FieldMetadata_LayerName kLayerName{};
+  void set_layer_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_LayerName::kFieldId, data, size);
+  }
+  void set_layer_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_LayerName::kFieldId, chars.data, chars.size);
+  }
+  void set_layer_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_LayerName::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/android/gpu_mem_event.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_GPU_MEM_EVENT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_GPU_MEM_EVENT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class GpuMemTotalEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  GpuMemTotalEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GpuMemTotalEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GpuMemTotalEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_gpu_id() const { return at<1>().valid(); }
+  uint32_t gpu_id() const { return at<1>().as_uint32(); }
+  bool has_pid() const { return at<2>().valid(); }
+  uint32_t pid() const { return at<2>().as_uint32(); }
+  bool has_size() const { return at<3>().valid(); }
+  uint64_t size() const { return at<3>().as_uint64(); }
+};
+
+class GpuMemTotalEvent : public ::protozero::Message {
+ public:
+  using Decoder = GpuMemTotalEvent_Decoder;
+  enum : int32_t {
+    kGpuIdFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kSizeFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GpuMemTotalEvent"; }
+
+
+  using FieldMetadata_GpuId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GpuMemTotalEvent>;
+
+  static constexpr FieldMetadata_GpuId kGpuId{};
+  void set_gpu_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GpuId::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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GpuMemTotalEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuMemTotalEvent>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void set_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/android/graphics_frame_event.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_GRAPHICS_FRAME_EVENT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_GRAPHICS_FRAME_EVENT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class GraphicsFrameEvent_BufferEvent;
+namespace perfetto_pbzero_enum_GraphicsFrameEvent {
+enum BufferEventType : int32_t;
+}  // namespace perfetto_pbzero_enum_GraphicsFrameEvent
+using GraphicsFrameEvent_BufferEventType = perfetto_pbzero_enum_GraphicsFrameEvent::BufferEventType;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_GraphicsFrameEvent {
+enum BufferEventType : int32_t {
+  UNSPECIFIED = 0,
+  DEQUEUE = 1,
+  QUEUE = 2,
+  POST = 3,
+  ACQUIRE_FENCE = 4,
+  LATCH = 5,
+  HWC_COMPOSITION_QUEUED = 6,
+  FALLBACK_COMPOSITION = 7,
+  PRESENT_FENCE = 8,
+  RELEASE_FENCE = 9,
+  MODIFY = 10,
+  DETACH = 11,
+  ATTACH = 12,
+  CANCEL = 13,
+};
+} // namespace perfetto_pbzero_enum_GraphicsFrameEvent
+using GraphicsFrameEvent_BufferEventType = perfetto_pbzero_enum_GraphicsFrameEvent::BufferEventType;
+
+
+constexpr GraphicsFrameEvent_BufferEventType GraphicsFrameEvent_BufferEventType_MIN = GraphicsFrameEvent_BufferEventType::UNSPECIFIED;
+constexpr GraphicsFrameEvent_BufferEventType GraphicsFrameEvent_BufferEventType_MAX = GraphicsFrameEvent_BufferEventType::CANCEL;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* GraphicsFrameEvent_BufferEventType_Name(::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEventType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEventType::UNSPECIFIED:
+    return "UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEventType::DEQUEUE:
+    return "DEQUEUE";
+
+  case ::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEventType::QUEUE:
+    return "QUEUE";
+
+  case ::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEventType::POST:
+    return "POST";
+
+  case ::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEventType::ACQUIRE_FENCE:
+    return "ACQUIRE_FENCE";
+
+  case ::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEventType::LATCH:
+    return "LATCH";
+
+  case ::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEventType::HWC_COMPOSITION_QUEUED:
+    return "HWC_COMPOSITION_QUEUED";
+
+  case ::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEventType::FALLBACK_COMPOSITION:
+    return "FALLBACK_COMPOSITION";
+
+  case ::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEventType::PRESENT_FENCE:
+    return "PRESENT_FENCE";
+
+  case ::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEventType::RELEASE_FENCE:
+    return "RELEASE_FENCE";
+
+  case ::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEventType::MODIFY:
+    return "MODIFY";
+
+  case ::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEventType::DETACH:
+    return "DETACH";
+
+  case ::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEventType::ATTACH:
+    return "ATTACH";
+
+  case ::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEventType::CANCEL:
+    return "CANCEL";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class GraphicsFrameEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  GraphicsFrameEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GraphicsFrameEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GraphicsFrameEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_buffer_event() const { return at<1>().valid(); }
+  ::protozero::ConstBytes buffer_event() const { return at<1>().as_bytes(); }
+};
+
+class GraphicsFrameEvent : public ::protozero::Message {
+ public:
+  using Decoder = GraphicsFrameEvent_Decoder;
+  enum : int32_t {
+    kBufferEventFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GraphicsFrameEvent"; }
+
+  using BufferEvent = ::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEvent;
+
+  using BufferEventType = ::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEventType;
+  static inline const char* BufferEventType_Name(BufferEventType value) {
+    return ::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEventType_Name(value);
+  }
+  static inline const BufferEventType UNSPECIFIED = BufferEventType::UNSPECIFIED;
+  static inline const BufferEventType DEQUEUE = BufferEventType::DEQUEUE;
+  static inline const BufferEventType QUEUE = BufferEventType::QUEUE;
+  static inline const BufferEventType POST = BufferEventType::POST;
+  static inline const BufferEventType ACQUIRE_FENCE = BufferEventType::ACQUIRE_FENCE;
+  static inline const BufferEventType LATCH = BufferEventType::LATCH;
+  static inline const BufferEventType HWC_COMPOSITION_QUEUED = BufferEventType::HWC_COMPOSITION_QUEUED;
+  static inline const BufferEventType FALLBACK_COMPOSITION = BufferEventType::FALLBACK_COMPOSITION;
+  static inline const BufferEventType PRESENT_FENCE = BufferEventType::PRESENT_FENCE;
+  static inline const BufferEventType RELEASE_FENCE = BufferEventType::RELEASE_FENCE;
+  static inline const BufferEventType MODIFY = BufferEventType::MODIFY;
+  static inline const BufferEventType DETACH = BufferEventType::DETACH;
+  static inline const BufferEventType ATTACH = BufferEventType::ATTACH;
+  static inline const BufferEventType CANCEL = BufferEventType::CANCEL;
+
+  using FieldMetadata_BufferEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GraphicsFrameEvent_BufferEvent,
+      GraphicsFrameEvent>;
+
+  static constexpr FieldMetadata_BufferEvent kBufferEvent{};
+  template <typename T = GraphicsFrameEvent_BufferEvent> T* set_buffer_event() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+class GraphicsFrameEvent_BufferEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  GraphicsFrameEvent_BufferEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GraphicsFrameEvent_BufferEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GraphicsFrameEvent_BufferEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_frame_number() const { return at<1>().valid(); }
+  uint32_t frame_number() const { return at<1>().as_uint32(); }
+  bool has_type() const { return at<2>().valid(); }
+  int32_t type() const { return at<2>().as_int32(); }
+  bool has_layer_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars layer_name() const { return at<3>().as_string(); }
+  bool has_duration_ns() const { return at<4>().valid(); }
+  uint64_t duration_ns() const { return at<4>().as_uint64(); }
+  bool has_buffer_id() const { return at<5>().valid(); }
+  uint32_t buffer_id() const { return at<5>().as_uint32(); }
+};
+
+class GraphicsFrameEvent_BufferEvent : public ::protozero::Message {
+ public:
+  using Decoder = GraphicsFrameEvent_BufferEvent_Decoder;
+  enum : int32_t {
+    kFrameNumberFieldNumber = 1,
+    kTypeFieldNumber = 2,
+    kLayerNameFieldNumber = 3,
+    kDurationNsFieldNumber = 4,
+    kBufferIdFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GraphicsFrameEvent.BufferEvent"; }
+
+
+  using FieldMetadata_FrameNumber =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GraphicsFrameEvent_BufferEvent>;
+
+  static constexpr FieldMetadata_FrameNumber kFrameNumber{};
+  void set_frame_number(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FrameNumber::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_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      GraphicsFrameEvent_BufferEventType,
+      GraphicsFrameEvent_BufferEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(GraphicsFrameEvent_BufferEventType value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::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_LayerName =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      GraphicsFrameEvent_BufferEvent>;
+
+  static constexpr FieldMetadata_LayerName kLayerName{};
+  void set_layer_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_LayerName::kFieldId, data, size);
+  }
+  void set_layer_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_LayerName::kFieldId, chars.data, chars.size);
+  }
+  void set_layer_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_LayerName::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_DurationNs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GraphicsFrameEvent_BufferEvent>;
+
+  static constexpr FieldMetadata_DurationNs kDurationNs{};
+  void set_duration_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DurationNs::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_BufferId =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GraphicsFrameEvent_BufferEvent>;
+
+  static constexpr FieldMetadata_BufferId kBufferId{};
+  void set_buffer_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BufferId::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/android/initial_display_state.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_INITIAL_DISPLAY_STATE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_INITIAL_DISPLAY_STATE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class InitialDisplayState_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  InitialDisplayState_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit InitialDisplayState_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit InitialDisplayState_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_display_state() const { return at<1>().valid(); }
+  int32_t display_state() const { return at<1>().as_int32(); }
+  bool has_brightness() const { return at<2>().valid(); }
+  double brightness() const { return at<2>().as_double(); }
+};
+
+class InitialDisplayState : public ::protozero::Message {
+ public:
+  using Decoder = InitialDisplayState_Decoder;
+  enum : int32_t {
+    kDisplayStateFieldNumber = 1,
+    kBrightnessFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.InitialDisplayState"; }
+
+
+  using FieldMetadata_DisplayState =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      InitialDisplayState>;
+
+  static constexpr FieldMetadata_DisplayState kDisplayState{};
+  void set_display_state(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DisplayState::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_Brightness =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      InitialDisplayState>;
+
+  static constexpr FieldMetadata_Brightness kBrightness{};
+  void set_brightness(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_Brightness::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/android/network_trace.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_NETWORK_TRACE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_NETWORK_TRACE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class NetworkPacketEvent;
+enum TrafficDirection : int32_t;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+enum TrafficDirection : int32_t {
+  DIR_UNSPECIFIED = 0,
+  DIR_INGRESS = 1,
+  DIR_EGRESS = 2,
+};
+
+constexpr TrafficDirection TrafficDirection_MIN = TrafficDirection::DIR_UNSPECIFIED;
+constexpr TrafficDirection TrafficDirection_MAX = TrafficDirection::DIR_EGRESS;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* TrafficDirection_Name(::perfetto::protos::pbzero::TrafficDirection value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::TrafficDirection::DIR_UNSPECIFIED:
+    return "DIR_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::TrafficDirection::DIR_INGRESS:
+    return "DIR_INGRESS";
+
+  case ::perfetto::protos::pbzero::TrafficDirection::DIR_EGRESS:
+    return "DIR_EGRESS";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class NetworkPacketContext_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  NetworkPacketContext_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit NetworkPacketContext_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit NetworkPacketContext_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_ctx() const { return at<2>().valid(); }
+  ::protozero::ConstBytes ctx() const { return at<2>().as_bytes(); }
+};
+
+class NetworkPacketContext : public ::protozero::Message {
+ public:
+  using Decoder = NetworkPacketContext_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kCtxFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.NetworkPacketContext"; }
+
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      NetworkPacketContext>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::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_Ctx =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      NetworkPacketEvent,
+      NetworkPacketContext>;
+
+  static constexpr FieldMetadata_Ctx kCtx{};
+  template <typename T = NetworkPacketEvent> T* set_ctx() {
+    return BeginNestedMessage<T>(2);
+  }
+
+};
+
+class NetworkPacketBundle_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  NetworkPacketBundle_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit NetworkPacketBundle_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit NetworkPacketBundle_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_ctx() const { return at<2>().valid(); }
+  ::protozero::ConstBytes ctx() const { return at<2>().as_bytes(); }
+  bool has_packet_timestamps() const { return at<3>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, uint64_t> packet_timestamps(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, uint64_t>(3, parse_error_ptr); }
+  bool has_packet_lengths() const { return at<4>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, uint32_t> packet_lengths(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, uint32_t>(4, parse_error_ptr); }
+  bool has_total_packets() const { return at<5>().valid(); }
+  uint32_t total_packets() const { return at<5>().as_uint32(); }
+  bool has_total_duration() const { return at<6>().valid(); }
+  uint64_t total_duration() const { return at<6>().as_uint64(); }
+  bool has_total_length() const { return at<7>().valid(); }
+  uint64_t total_length() const { return at<7>().as_uint64(); }
+};
+
+class NetworkPacketBundle : public ::protozero::Message {
+ public:
+  using Decoder = NetworkPacketBundle_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kCtxFieldNumber = 2,
+    kPacketTimestampsFieldNumber = 3,
+    kPacketLengthsFieldNumber = 4,
+    kTotalPacketsFieldNumber = 5,
+    kTotalDurationFieldNumber = 6,
+    kTotalLengthFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.NetworkPacketBundle"; }
+
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      NetworkPacketBundle>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::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_Ctx =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      NetworkPacketEvent,
+      NetworkPacketBundle>;
+
+  static constexpr FieldMetadata_Ctx kCtx{};
+  template <typename T = NetworkPacketEvent> T* set_ctx() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_PacketTimestamps =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      NetworkPacketBundle>;
+
+  static constexpr FieldMetadata_PacketTimestamps kPacketTimestamps{};
+  void set_packet_timestamps(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_PacketTimestamps::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_PacketLengths =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NetworkPacketBundle>;
+
+  static constexpr FieldMetadata_PacketLengths kPacketLengths{};
+  void set_packet_lengths(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_PacketLengths::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_TotalPackets =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NetworkPacketBundle>;
+
+  static constexpr FieldMetadata_TotalPackets kTotalPackets{};
+  void set_total_packets(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TotalPackets::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_TotalDuration =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      NetworkPacketBundle>;
+
+  static constexpr FieldMetadata_TotalDuration kTotalDuration{};
+  void set_total_duration(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TotalDuration::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_TotalLength =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      NetworkPacketBundle>;
+
+  static constexpr FieldMetadata_TotalLength kTotalLength{};
+  void set_total_length(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TotalLength::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 NetworkPacketEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/11, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  NetworkPacketEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit NetworkPacketEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit NetworkPacketEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_direction() const { return at<1>().valid(); }
+  int32_t direction() const { return at<1>().as_int32(); }
+  bool has_interface() const { return at<2>().valid(); }
+  ::protozero::ConstChars interface() const { return at<2>().as_string(); }
+  bool has_length() const { return at<3>().valid(); }
+  uint32_t length() const { return at<3>().as_uint32(); }
+  bool has_uid() const { return at<4>().valid(); }
+  uint32_t uid() const { return at<4>().as_uint32(); }
+  bool has_tag() const { return at<5>().valid(); }
+  uint32_t tag() const { return at<5>().as_uint32(); }
+  bool has_ip_proto() const { return at<6>().valid(); }
+  uint32_t ip_proto() const { return at<6>().as_uint32(); }
+  bool has_tcp_flags() const { return at<7>().valid(); }
+  uint32_t tcp_flags() const { return at<7>().as_uint32(); }
+  bool has_local_port() const { return at<8>().valid(); }
+  uint32_t local_port() const { return at<8>().as_uint32(); }
+  bool has_remote_port() const { return at<9>().valid(); }
+  uint32_t remote_port() const { return at<9>().as_uint32(); }
+  bool has_icmp_type() const { return at<10>().valid(); }
+  uint32_t icmp_type() const { return at<10>().as_uint32(); }
+  bool has_icmp_code() const { return at<11>().valid(); }
+  uint32_t icmp_code() const { return at<11>().as_uint32(); }
+};
+
+class NetworkPacketEvent : public ::protozero::Message {
+ public:
+  using Decoder = NetworkPacketEvent_Decoder;
+  enum : int32_t {
+    kDirectionFieldNumber = 1,
+    kInterfaceFieldNumber = 2,
+    kLengthFieldNumber = 3,
+    kUidFieldNumber = 4,
+    kTagFieldNumber = 5,
+    kIpProtoFieldNumber = 6,
+    kTcpFlagsFieldNumber = 7,
+    kLocalPortFieldNumber = 8,
+    kRemotePortFieldNumber = 9,
+    kIcmpTypeFieldNumber = 10,
+    kIcmpCodeFieldNumber = 11,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.NetworkPacketEvent"; }
+
+
+  using FieldMetadata_Direction =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      TrafficDirection,
+      NetworkPacketEvent>;
+
+  static constexpr FieldMetadata_Direction kDirection{};
+  void set_direction(TrafficDirection value) {
+    static constexpr uint32_t field_id = FieldMetadata_Direction::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_Interface =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      NetworkPacketEvent>;
+
+  static constexpr FieldMetadata_Interface kInterface{};
+  void set_interface(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Interface::kFieldId, data, size);
+  }
+  void set_interface(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Interface::kFieldId, chars.data, chars.size);
+  }
+  void set_interface(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Interface::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_Length =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NetworkPacketEvent>;
+
+  static constexpr FieldMetadata_Length kLength{};
+  void set_length(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Length::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_Uid =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NetworkPacketEvent>;
+
+  static constexpr FieldMetadata_Uid kUid{};
+  void set_uid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Uid::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_Tag =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NetworkPacketEvent>;
+
+  static constexpr FieldMetadata_Tag kTag{};
+  void set_tag(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tag::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_IpProto =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NetworkPacketEvent>;
+
+  static constexpr FieldMetadata_IpProto kIpProto{};
+  void set_ip_proto(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IpProto::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_TcpFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NetworkPacketEvent>;
+
+  static constexpr FieldMetadata_TcpFlags kTcpFlags{};
+  void set_tcp_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TcpFlags::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_LocalPort =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NetworkPacketEvent>;
+
+  static constexpr FieldMetadata_LocalPort kLocalPort{};
+  void set_local_port(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LocalPort::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_RemotePort =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NetworkPacketEvent>;
+
+  static constexpr FieldMetadata_RemotePort kRemotePort{};
+  void set_remote_port(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RemotePort::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_IcmpType =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NetworkPacketEvent>;
+
+  static constexpr FieldMetadata_IcmpType kIcmpType{};
+  void set_icmp_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IcmpType::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_IcmpCode =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NetworkPacketEvent>;
+
+  static constexpr FieldMetadata_IcmpCode kIcmpCode{};
+  void set_icmp_code(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IcmpCode::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/android/packages_list.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_PACKAGES_LIST_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_PACKAGES_LIST_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class PackagesList_PackageInfo;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class PackagesList_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  PackagesList_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PackagesList_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PackagesList_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_packages() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> packages() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_parse_error() const { return at<2>().valid(); }
+  bool parse_error() const { return at<2>().as_bool(); }
+  bool has_read_error() const { return at<3>().valid(); }
+  bool read_error() const { return at<3>().as_bool(); }
+};
+
+class PackagesList : public ::protozero::Message {
+ public:
+  using Decoder = PackagesList_Decoder;
+  enum : int32_t {
+    kPackagesFieldNumber = 1,
+    kParseErrorFieldNumber = 2,
+    kReadErrorFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PackagesList"; }
+
+  using PackageInfo = ::perfetto::protos::pbzero::PackagesList_PackageInfo;
+
+  using FieldMetadata_Packages =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PackagesList_PackageInfo,
+      PackagesList>;
+
+  static constexpr FieldMetadata_Packages kPackages{};
+  template <typename T = PackagesList_PackageInfo> T* add_packages() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_ParseError =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      PackagesList>;
+
+  static constexpr FieldMetadata_ParseError kParseError{};
+  void set_parse_error(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ParseError::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_ReadError =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      PackagesList>;
+
+  static constexpr FieldMetadata_ReadError kReadError{};
+  void set_read_error(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReadError::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 PackagesList_PackageInfo_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  PackagesList_PackageInfo_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PackagesList_PackageInfo_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PackagesList_PackageInfo_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_uid() const { return at<2>().valid(); }
+  uint64_t uid() const { return at<2>().as_uint64(); }
+  bool has_debuggable() const { return at<3>().valid(); }
+  bool debuggable() const { return at<3>().as_bool(); }
+  bool has_profileable_from_shell() const { return at<4>().valid(); }
+  bool profileable_from_shell() const { return at<4>().as_bool(); }
+  bool has_version_code() const { return at<5>().valid(); }
+  int64_t version_code() const { return at<5>().as_int64(); }
+};
+
+class PackagesList_PackageInfo : public ::protozero::Message {
+ public:
+  using Decoder = PackagesList_PackageInfo_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kUidFieldNumber = 2,
+    kDebuggableFieldNumber = 3,
+    kProfileableFromShellFieldNumber = 4,
+    kVersionCodeFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PackagesList.PackageInfo"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PackagesList_PackageInfo>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Uid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PackagesList_PackageInfo>;
+
+  static constexpr FieldMetadata_Uid kUid{};
+  void set_uid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Uid::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_Debuggable =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      PackagesList_PackageInfo>;
+
+  static constexpr FieldMetadata_Debuggable kDebuggable{};
+  void set_debuggable(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_Debuggable::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_ProfileableFromShell =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      PackagesList_PackageInfo>;
+
+  static constexpr FieldMetadata_ProfileableFromShell kProfileableFromShell{};
+  void set_profileable_from_shell(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProfileableFromShell::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_VersionCode =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      PackagesList_PackageInfo>;
+
+  static constexpr FieldMetadata_VersionCode kVersionCode{};
+  void set_version_code(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VersionCode::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/android/pixel_modem_events.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_PIXEL_MODEM_EVENTS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_PIXEL_MODEM_EVENTS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class PixelModemTokenDatabase_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  PixelModemTokenDatabase_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PixelModemTokenDatabase_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PixelModemTokenDatabase_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_database() const { return at<1>().valid(); }
+  ::protozero::ConstBytes database() const { return at<1>().as_bytes(); }
+};
+
+class PixelModemTokenDatabase : public ::protozero::Message {
+ public:
+  using Decoder = PixelModemTokenDatabase_Decoder;
+  enum : int32_t {
+    kDatabaseFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PixelModemTokenDatabase"; }
+
+
+  using FieldMetadata_Database =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      PixelModemTokenDatabase>;
+
+  static constexpr FieldMetadata_Database kDatabase{};
+  void set_database(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_Database::kFieldId, data, size);
+  }
+  void set_database(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_Database::kFieldId, bytes.data, bytes.size);
+  }
+  void set_database(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Database::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 PixelModemEvents_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  PixelModemEvents_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PixelModemEvents_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PixelModemEvents_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_events() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> events() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_event_time_nanos() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> event_time_nanos() const { return GetRepeated<uint64_t>(2); }
+};
+
+class PixelModemEvents : public ::protozero::Message {
+ public:
+  using Decoder = PixelModemEvents_Decoder;
+  enum : int32_t {
+    kEventsFieldNumber = 1,
+    kEventTimeNanosFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PixelModemEvents"; }
+
+
+  using FieldMetadata_Events =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      PixelModemEvents>;
+
+  static constexpr FieldMetadata_Events kEvents{};
+  void add_events(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_Events::kFieldId, data, size);
+  }
+  void add_events(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_Events::kFieldId, bytes.data, bytes.size);
+  }
+  void add_events(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Events::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);
+  }
+
+  using FieldMetadata_EventTimeNanos =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PixelModemEvents>;
+
+  static constexpr FieldMetadata_EventTimeNanos kEventTimeNanos{};
+  void add_event_time_nanos(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EventTimeNanos::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/chrome/chrome_benchmark_metadata.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_CHROME_CHROME_BENCHMARK_METADATA_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_CHROME_CHROME_BENCHMARK_METADATA_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class ChromeBenchmarkMetadata_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ChromeBenchmarkMetadata_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeBenchmarkMetadata_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeBenchmarkMetadata_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_benchmark_start_time_us() const { return at<1>().valid(); }
+  int64_t benchmark_start_time_us() const { return at<1>().as_int64(); }
+  bool has_story_run_time_us() const { return at<2>().valid(); }
+  int64_t story_run_time_us() const { return at<2>().as_int64(); }
+  bool has_benchmark_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars benchmark_name() const { return at<3>().as_string(); }
+  bool has_benchmark_description() const { return at<4>().valid(); }
+  ::protozero::ConstChars benchmark_description() const { return at<4>().as_string(); }
+  bool has_label() const { return at<5>().valid(); }
+  ::protozero::ConstChars label() const { return at<5>().as_string(); }
+  bool has_story_name() const { return at<6>().valid(); }
+  ::protozero::ConstChars story_name() const { return at<6>().as_string(); }
+  bool has_story_tags() const { return at<7>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> story_tags() const { return GetRepeated<::protozero::ConstChars>(7); }
+  bool has_story_run_index() const { return at<8>().valid(); }
+  int32_t story_run_index() const { return at<8>().as_int32(); }
+  bool has_had_failures() const { return at<9>().valid(); }
+  bool had_failures() const { return at<9>().as_bool(); }
+};
+
+class ChromeBenchmarkMetadata : public ::protozero::Message {
+ public:
+  using Decoder = ChromeBenchmarkMetadata_Decoder;
+  enum : int32_t {
+    kBenchmarkStartTimeUsFieldNumber = 1,
+    kStoryRunTimeUsFieldNumber = 2,
+    kBenchmarkNameFieldNumber = 3,
+    kBenchmarkDescriptionFieldNumber = 4,
+    kLabelFieldNumber = 5,
+    kStoryNameFieldNumber = 6,
+    kStoryTagsFieldNumber = 7,
+    kStoryRunIndexFieldNumber = 8,
+    kHadFailuresFieldNumber = 9,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeBenchmarkMetadata"; }
+
+
+  using FieldMetadata_BenchmarkStartTimeUs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ChromeBenchmarkMetadata>;
+
+  static constexpr FieldMetadata_BenchmarkStartTimeUs kBenchmarkStartTimeUs{};
+  void set_benchmark_start_time_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BenchmarkStartTimeUs::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_StoryRunTimeUs =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ChromeBenchmarkMetadata>;
+
+  static constexpr FieldMetadata_StoryRunTimeUs kStoryRunTimeUs{};
+  void set_story_run_time_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StoryRunTimeUs::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_BenchmarkName =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeBenchmarkMetadata>;
+
+  static constexpr FieldMetadata_BenchmarkName kBenchmarkName{};
+  void set_benchmark_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_BenchmarkName::kFieldId, data, size);
+  }
+  void set_benchmark_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_BenchmarkName::kFieldId, chars.data, chars.size);
+  }
+  void set_benchmark_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_BenchmarkName::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_BenchmarkDescription =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeBenchmarkMetadata>;
+
+  static constexpr FieldMetadata_BenchmarkDescription kBenchmarkDescription{};
+  void set_benchmark_description(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_BenchmarkDescription::kFieldId, data, size);
+  }
+  void set_benchmark_description(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_BenchmarkDescription::kFieldId, chars.data, chars.size);
+  }
+  void set_benchmark_description(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_BenchmarkDescription::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_Label =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeBenchmarkMetadata>;
+
+  static constexpr FieldMetadata_Label kLabel{};
+  void set_label(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Label::kFieldId, data, size);
+  }
+  void set_label(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Label::kFieldId, chars.data, chars.size);
+  }
+  void set_label(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Label::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_StoryName =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeBenchmarkMetadata>;
+
+  static constexpr FieldMetadata_StoryName kStoryName{};
+  void set_story_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_StoryName::kFieldId, data, size);
+  }
+  void set_story_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_StoryName::kFieldId, chars.data, chars.size);
+  }
+  void set_story_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_StoryName::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_StoryTags =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeBenchmarkMetadata>;
+
+  static constexpr FieldMetadata_StoryTags kStoryTags{};
+  void add_story_tags(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_StoryTags::kFieldId, data, size);
+  }
+  void add_story_tags(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_StoryTags::kFieldId, chars.data, chars.size);
+  }
+  void add_story_tags(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_StoryTags::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_StoryRunIndex =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeBenchmarkMetadata>;
+
+  static constexpr FieldMetadata_StoryRunIndex kStoryRunIndex{};
+  void set_story_run_index(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StoryRunIndex::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_HadFailures =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeBenchmarkMetadata>;
+
+  static constexpr FieldMetadata_HadFailures kHadFailures{};
+  void set_had_failures(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_HadFailures::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/chrome/chrome_metadata.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_CHROME_CHROME_METADATA_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_CHROME_CHROME_METADATA_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class BackgroundTracingMetadata;
+class BackgroundTracingMetadata_TriggerRule;
+class BackgroundTracingMetadata_TriggerRule_HistogramRule;
+class BackgroundTracingMetadata_TriggerRule_NamedRule;
+class ChromeMetadataPacket_FinchHash;
+namespace perfetto_pbzero_enum_BackgroundTracingMetadata_TriggerRule_NamedRule {
+enum EventType : int32_t;
+}  // namespace perfetto_pbzero_enum_BackgroundTracingMetadata_TriggerRule_NamedRule
+using BackgroundTracingMetadata_TriggerRule_NamedRule_EventType = perfetto_pbzero_enum_BackgroundTracingMetadata_TriggerRule_NamedRule::EventType;
+namespace perfetto_pbzero_enum_BackgroundTracingMetadata_TriggerRule {
+enum TriggerType : int32_t;
+}  // namespace perfetto_pbzero_enum_BackgroundTracingMetadata_TriggerRule
+using BackgroundTracingMetadata_TriggerRule_TriggerType = perfetto_pbzero_enum_BackgroundTracingMetadata_TriggerRule::TriggerType;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_BackgroundTracingMetadata_TriggerRule {
+enum TriggerType : int32_t {
+  TRIGGER_UNSPECIFIED = 0,
+  MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE = 1,
+  MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED = 2,
+};
+} // namespace perfetto_pbzero_enum_BackgroundTracingMetadata_TriggerRule
+using BackgroundTracingMetadata_TriggerRule_TriggerType = perfetto_pbzero_enum_BackgroundTracingMetadata_TriggerRule::TriggerType;
+
+
+constexpr BackgroundTracingMetadata_TriggerRule_TriggerType BackgroundTracingMetadata_TriggerRule_TriggerType_MIN = BackgroundTracingMetadata_TriggerRule_TriggerType::TRIGGER_UNSPECIFIED;
+constexpr BackgroundTracingMetadata_TriggerRule_TriggerType BackgroundTracingMetadata_TriggerRule_TriggerType_MAX = BackgroundTracingMetadata_TriggerRule_TriggerType::MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* BackgroundTracingMetadata_TriggerRule_TriggerType_Name(::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_TriggerType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_TriggerType::TRIGGER_UNSPECIFIED:
+    return "TRIGGER_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_TriggerType::MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE:
+    return "MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE";
+
+  case ::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_TriggerType::MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED:
+    return "MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_BackgroundTracingMetadata_TriggerRule_NamedRule {
+enum EventType : int32_t {
+  UNSPECIFIED = 0,
+  SESSION_RESTORE = 1,
+  NAVIGATION = 2,
+  STARTUP = 3,
+  REACHED_CODE = 4,
+  CONTENT_TRIGGER = 5,
+  TEST_RULE = 1000,
+};
+} // namespace perfetto_pbzero_enum_BackgroundTracingMetadata_TriggerRule_NamedRule
+using BackgroundTracingMetadata_TriggerRule_NamedRule_EventType = perfetto_pbzero_enum_BackgroundTracingMetadata_TriggerRule_NamedRule::EventType;
+
+
+constexpr BackgroundTracingMetadata_TriggerRule_NamedRule_EventType BackgroundTracingMetadata_TriggerRule_NamedRule_EventType_MIN = BackgroundTracingMetadata_TriggerRule_NamedRule_EventType::UNSPECIFIED;
+constexpr BackgroundTracingMetadata_TriggerRule_NamedRule_EventType BackgroundTracingMetadata_TriggerRule_NamedRule_EventType_MAX = BackgroundTracingMetadata_TriggerRule_NamedRule_EventType::TEST_RULE;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* BackgroundTracingMetadata_TriggerRule_NamedRule_EventType_Name(::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_NamedRule_EventType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_NamedRule_EventType::UNSPECIFIED:
+    return "UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_NamedRule_EventType::SESSION_RESTORE:
+    return "SESSION_RESTORE";
+
+  case ::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_NamedRule_EventType::NAVIGATION:
+    return "NAVIGATION";
+
+  case ::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_NamedRule_EventType::STARTUP:
+    return "STARTUP";
+
+  case ::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_NamedRule_EventType::REACHED_CODE:
+    return "REACHED_CODE";
+
+  case ::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_NamedRule_EventType::CONTENT_TRIGGER:
+    return "CONTENT_TRIGGER";
+
+  case ::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_NamedRule_EventType::TEST_RULE:
+    return "TEST_RULE";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class BackgroundTracingMetadata_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  BackgroundTracingMetadata_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BackgroundTracingMetadata_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BackgroundTracingMetadata_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_triggered_rule() const { return at<1>().valid(); }
+  ::protozero::ConstBytes triggered_rule() const { return at<1>().as_bytes(); }
+  bool has_active_rules() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> active_rules() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_scenario_name_hash() const { return at<3>().valid(); }
+  uint32_t scenario_name_hash() const { return at<3>().as_uint32(); }
+};
+
+class BackgroundTracingMetadata : public ::protozero::Message {
+ public:
+  using Decoder = BackgroundTracingMetadata_Decoder;
+  enum : int32_t {
+    kTriggeredRuleFieldNumber = 1,
+    kActiveRulesFieldNumber = 2,
+    kScenarioNameHashFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BackgroundTracingMetadata"; }
+
+  using TriggerRule = ::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule;
+
+  using FieldMetadata_TriggeredRule =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BackgroundTracingMetadata_TriggerRule,
+      BackgroundTracingMetadata>;
+
+  static constexpr FieldMetadata_TriggeredRule kTriggeredRule{};
+  template <typename T = BackgroundTracingMetadata_TriggerRule> T* set_triggered_rule() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_ActiveRules =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BackgroundTracingMetadata_TriggerRule,
+      BackgroundTracingMetadata>;
+
+  static constexpr FieldMetadata_ActiveRules kActiveRules{};
+  template <typename T = BackgroundTracingMetadata_TriggerRule> T* add_active_rules() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_ScenarioNameHash =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed32,
+      uint32_t,
+      BackgroundTracingMetadata>;
+
+  static constexpr FieldMetadata_ScenarioNameHash kScenarioNameHash{};
+  void set_scenario_name_hash(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ScenarioNameHash::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class BackgroundTracingMetadata_TriggerRule_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BackgroundTracingMetadata_TriggerRule_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BackgroundTracingMetadata_TriggerRule_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BackgroundTracingMetadata_TriggerRule_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_trigger_type() const { return at<1>().valid(); }
+  int32_t trigger_type() const { return at<1>().as_int32(); }
+  bool has_histogram_rule() const { return at<2>().valid(); }
+  ::protozero::ConstBytes histogram_rule() const { return at<2>().as_bytes(); }
+  bool has_named_rule() const { return at<3>().valid(); }
+  ::protozero::ConstBytes named_rule() const { return at<3>().as_bytes(); }
+  bool has_name_hash() const { return at<4>().valid(); }
+  uint32_t name_hash() const { return at<4>().as_uint32(); }
+};
+
+class BackgroundTracingMetadata_TriggerRule : public ::protozero::Message {
+ public:
+  using Decoder = BackgroundTracingMetadata_TriggerRule_Decoder;
+  enum : int32_t {
+    kTriggerTypeFieldNumber = 1,
+    kHistogramRuleFieldNumber = 2,
+    kNamedRuleFieldNumber = 3,
+    kNameHashFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BackgroundTracingMetadata.TriggerRule"; }
+
+  using HistogramRule = ::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_HistogramRule;
+  using NamedRule = ::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_NamedRule;
+
+  using TriggerType = ::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_TriggerType;
+  static inline const char* TriggerType_Name(TriggerType value) {
+    return ::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_TriggerType_Name(value);
+  }
+  static inline const TriggerType TRIGGER_UNSPECIFIED = TriggerType::TRIGGER_UNSPECIFIED;
+  static inline const TriggerType MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE = TriggerType::MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE;
+  static inline const TriggerType MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED = TriggerType::MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED;
+
+  using FieldMetadata_TriggerType =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      BackgroundTracingMetadata_TriggerRule_TriggerType,
+      BackgroundTracingMetadata_TriggerRule>;
+
+  static constexpr FieldMetadata_TriggerType kTriggerType{};
+  void set_trigger_type(BackgroundTracingMetadata_TriggerRule_TriggerType value) {
+    static constexpr uint32_t field_id = FieldMetadata_TriggerType::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_HistogramRule =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BackgroundTracingMetadata_TriggerRule_HistogramRule,
+      BackgroundTracingMetadata_TriggerRule>;
+
+  static constexpr FieldMetadata_HistogramRule kHistogramRule{};
+  template <typename T = BackgroundTracingMetadata_TriggerRule_HistogramRule> T* set_histogram_rule() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_NamedRule =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BackgroundTracingMetadata_TriggerRule_NamedRule,
+      BackgroundTracingMetadata_TriggerRule>;
+
+  static constexpr FieldMetadata_NamedRule kNamedRule{};
+  template <typename T = BackgroundTracingMetadata_TriggerRule_NamedRule> T* set_named_rule() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_NameHash =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed32,
+      uint32_t,
+      BackgroundTracingMetadata_TriggerRule>;
+
+  static constexpr FieldMetadata_NameHash kNameHash{};
+  void set_name_hash(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NameHash::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class BackgroundTracingMetadata_TriggerRule_NamedRule_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BackgroundTracingMetadata_TriggerRule_NamedRule_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BackgroundTracingMetadata_TriggerRule_NamedRule_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BackgroundTracingMetadata_TriggerRule_NamedRule_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_event_type() const { return at<1>().valid(); }
+  int32_t event_type() const { return at<1>().as_int32(); }
+  bool has_content_trigger_name_hash() const { return at<2>().valid(); }
+  uint64_t content_trigger_name_hash() const { return at<2>().as_uint64(); }
+};
+
+class BackgroundTracingMetadata_TriggerRule_NamedRule : public ::protozero::Message {
+ public:
+  using Decoder = BackgroundTracingMetadata_TriggerRule_NamedRule_Decoder;
+  enum : int32_t {
+    kEventTypeFieldNumber = 1,
+    kContentTriggerNameHashFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BackgroundTracingMetadata.TriggerRule.NamedRule"; }
+
+
+  using EventType = ::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_NamedRule_EventType;
+  static inline const char* EventType_Name(EventType value) {
+    return ::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_NamedRule_EventType_Name(value);
+  }
+  static inline const EventType UNSPECIFIED = EventType::UNSPECIFIED;
+  static inline const EventType SESSION_RESTORE = EventType::SESSION_RESTORE;
+  static inline const EventType NAVIGATION = EventType::NAVIGATION;
+  static inline const EventType STARTUP = EventType::STARTUP;
+  static inline const EventType REACHED_CODE = EventType::REACHED_CODE;
+  static inline const EventType CONTENT_TRIGGER = EventType::CONTENT_TRIGGER;
+  static inline const EventType TEST_RULE = EventType::TEST_RULE;
+
+  using FieldMetadata_EventType =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      BackgroundTracingMetadata_TriggerRule_NamedRule_EventType,
+      BackgroundTracingMetadata_TriggerRule_NamedRule>;
+
+  static constexpr FieldMetadata_EventType kEventType{};
+  void set_event_type(BackgroundTracingMetadata_TriggerRule_NamedRule_EventType value) {
+    static constexpr uint32_t field_id = FieldMetadata_EventType::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_ContentTriggerNameHash =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64,
+      uint64_t,
+      BackgroundTracingMetadata_TriggerRule_NamedRule>;
+
+  static constexpr FieldMetadata_ContentTriggerNameHash kContentTriggerNameHash{};
+  void set_content_trigger_name_hash(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ContentTriggerNameHash::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class BackgroundTracingMetadata_TriggerRule_HistogramRule_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BackgroundTracingMetadata_TriggerRule_HistogramRule_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BackgroundTracingMetadata_TriggerRule_HistogramRule_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BackgroundTracingMetadata_TriggerRule_HistogramRule_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_histogram_name_hash() const { return at<1>().valid(); }
+  uint64_t histogram_name_hash() const { return at<1>().as_uint64(); }
+  bool has_histogram_min_trigger() const { return at<2>().valid(); }
+  int64_t histogram_min_trigger() const { return at<2>().as_int64(); }
+  bool has_histogram_max_trigger() const { return at<3>().valid(); }
+  int64_t histogram_max_trigger() const { return at<3>().as_int64(); }
+};
+
+class BackgroundTracingMetadata_TriggerRule_HistogramRule : public ::protozero::Message {
+ public:
+  using Decoder = BackgroundTracingMetadata_TriggerRule_HistogramRule_Decoder;
+  enum : int32_t {
+    kHistogramNameHashFieldNumber = 1,
+    kHistogramMinTriggerFieldNumber = 2,
+    kHistogramMaxTriggerFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BackgroundTracingMetadata.TriggerRule.HistogramRule"; }
+
+
+  using FieldMetadata_HistogramNameHash =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64,
+      uint64_t,
+      BackgroundTracingMetadata_TriggerRule_HistogramRule>;
+
+  static constexpr FieldMetadata_HistogramNameHash kHistogramNameHash{};
+  void set_histogram_name_hash(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_HistogramNameHash::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HistogramMinTrigger =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BackgroundTracingMetadata_TriggerRule_HistogramRule>;
+
+  static constexpr FieldMetadata_HistogramMinTrigger kHistogramMinTrigger{};
+  void set_histogram_min_trigger(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_HistogramMinTrigger::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_HistogramMaxTrigger =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BackgroundTracingMetadata_TriggerRule_HistogramRule>;
+
+  static constexpr FieldMetadata_HistogramMaxTrigger kHistogramMaxTrigger{};
+  void set_histogram_max_trigger(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_HistogramMaxTrigger::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 ChromeMetadataPacket_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ChromeMetadataPacket_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeMetadataPacket_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeMetadataPacket_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_background_tracing_metadata() const { return at<1>().valid(); }
+  ::protozero::ConstBytes background_tracing_metadata() const { return at<1>().as_bytes(); }
+  bool has_chrome_version_code() const { return at<2>().valid(); }
+  int32_t chrome_version_code() const { return at<2>().as_int32(); }
+  bool has_enabled_categories() const { return at<3>().valid(); }
+  ::protozero::ConstChars enabled_categories() const { return at<3>().as_string(); }
+  bool has_field_trial_hashes() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> field_trial_hashes() const { return GetRepeated<::protozero::ConstBytes>(4); }
+};
+
+class ChromeMetadataPacket : public ::protozero::Message {
+ public:
+  using Decoder = ChromeMetadataPacket_Decoder;
+  enum : int32_t {
+    kBackgroundTracingMetadataFieldNumber = 1,
+    kChromeVersionCodeFieldNumber = 2,
+    kEnabledCategoriesFieldNumber = 3,
+    kFieldTrialHashesFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeMetadataPacket"; }
+
+  using FinchHash = ::perfetto::protos::pbzero::ChromeMetadataPacket_FinchHash;
+
+  using FieldMetadata_BackgroundTracingMetadata =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BackgroundTracingMetadata,
+      ChromeMetadataPacket>;
+
+  static constexpr FieldMetadata_BackgroundTracingMetadata kBackgroundTracingMetadata{};
+  template <typename T = BackgroundTracingMetadata> T* set_background_tracing_metadata() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_ChromeVersionCode =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeMetadataPacket>;
+
+  static constexpr FieldMetadata_ChromeVersionCode kChromeVersionCode{};
+  void set_chrome_version_code(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChromeVersionCode::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_EnabledCategories =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeMetadataPacket>;
+
+  static constexpr FieldMetadata_EnabledCategories kEnabledCategories{};
+  void set_enabled_categories(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_EnabledCategories::kFieldId, data, size);
+  }
+  void set_enabled_categories(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_EnabledCategories::kFieldId, chars.data, chars.size);
+  }
+  void set_enabled_categories(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_EnabledCategories::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_FieldTrialHashes =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeMetadataPacket_FinchHash,
+      ChromeMetadataPacket>;
+
+  static constexpr FieldMetadata_FieldTrialHashes kFieldTrialHashes{};
+  template <typename T = ChromeMetadataPacket_FinchHash> T* add_field_trial_hashes() {
+    return BeginNestedMessage<T>(4);
+  }
+
+};
+
+class ChromeMetadataPacket_FinchHash_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeMetadataPacket_FinchHash_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeMetadataPacket_FinchHash_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeMetadataPacket_FinchHash_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  uint32_t name() const { return at<1>().as_uint32(); }
+  bool has_group() const { return at<2>().valid(); }
+  uint32_t group() const { return at<2>().as_uint32(); }
+};
+
+class ChromeMetadataPacket_FinchHash : public ::protozero::Message {
+ public:
+  using Decoder = ChromeMetadataPacket_FinchHash_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kGroupFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeMetadataPacket.FinchHash"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ChromeMetadataPacket_FinchHash>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(uint32_t 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::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Group =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ChromeMetadataPacket_FinchHash>;
+
+  static constexpr FieldMetadata_Group kGroup{};
+  void set_group(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Group::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/chrome/chrome_trace_event.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_CHROME_CHROME_TRACE_EVENT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_CHROME_CHROME_TRACE_EVENT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class ChromeLegacyJsonTrace;
+class ChromeMetadata;
+class ChromeStringTableEntry;
+class ChromeTraceEvent;
+class ChromeTraceEvent_Arg;
+class ChromeTracedValue;
+namespace perfetto_pbzero_enum_ChromeLegacyJsonTrace {
+enum TraceType : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeLegacyJsonTrace
+using ChromeLegacyJsonTrace_TraceType = perfetto_pbzero_enum_ChromeLegacyJsonTrace::TraceType;
+namespace perfetto_pbzero_enum_ChromeTracedValue {
+enum NestedType : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeTracedValue
+using ChromeTracedValue_NestedType = perfetto_pbzero_enum_ChromeTracedValue::NestedType;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_ChromeLegacyJsonTrace {
+enum TraceType : int32_t {
+  USER_TRACE = 0,
+  SYSTEM_TRACE = 1,
+};
+} // namespace perfetto_pbzero_enum_ChromeLegacyJsonTrace
+using ChromeLegacyJsonTrace_TraceType = perfetto_pbzero_enum_ChromeLegacyJsonTrace::TraceType;
+
+
+constexpr ChromeLegacyJsonTrace_TraceType ChromeLegacyJsonTrace_TraceType_MIN = ChromeLegacyJsonTrace_TraceType::USER_TRACE;
+constexpr ChromeLegacyJsonTrace_TraceType ChromeLegacyJsonTrace_TraceType_MAX = ChromeLegacyJsonTrace_TraceType::SYSTEM_TRACE;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeLegacyJsonTrace_TraceType_Name(::perfetto::protos::pbzero::ChromeLegacyJsonTrace_TraceType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeLegacyJsonTrace_TraceType::USER_TRACE:
+    return "USER_TRACE";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyJsonTrace_TraceType::SYSTEM_TRACE:
+    return "SYSTEM_TRACE";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_ChromeTracedValue {
+enum NestedType : int32_t {
+  DICT = 0,
+  ARRAY = 1,
+};
+} // namespace perfetto_pbzero_enum_ChromeTracedValue
+using ChromeTracedValue_NestedType = perfetto_pbzero_enum_ChromeTracedValue::NestedType;
+
+
+constexpr ChromeTracedValue_NestedType ChromeTracedValue_NestedType_MIN = ChromeTracedValue_NestedType::DICT;
+constexpr ChromeTracedValue_NestedType ChromeTracedValue_NestedType_MAX = ChromeTracedValue_NestedType::ARRAY;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeTracedValue_NestedType_Name(::perfetto::protos::pbzero::ChromeTracedValue_NestedType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeTracedValue_NestedType::DICT:
+    return "DICT";
+
+  case ::perfetto::protos::pbzero::ChromeTracedValue_NestedType::ARRAY:
+    return "ARRAY";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class ChromeEventBundle_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ChromeEventBundle_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeEventBundle_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeEventBundle_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_trace_events() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> trace_events() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_metadata() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> metadata() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_legacy_ftrace_output() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> legacy_ftrace_output() const { return GetRepeated<::protozero::ConstChars>(4); }
+  bool has_legacy_json_trace() const { return at<5>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> legacy_json_trace() const { return GetRepeated<::protozero::ConstBytes>(5); }
+  bool has_string_table() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> string_table() const { return GetRepeated<::protozero::ConstBytes>(3); }
+};
+
+class ChromeEventBundle : public ::protozero::Message {
+ public:
+  using Decoder = ChromeEventBundle_Decoder;
+  enum : int32_t {
+    kTraceEventsFieldNumber = 1,
+    kMetadataFieldNumber = 2,
+    kLegacyFtraceOutputFieldNumber = 4,
+    kLegacyJsonTraceFieldNumber = 5,
+    kStringTableFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeEventBundle"; }
+
+
+  using FieldMetadata_TraceEvents =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeTraceEvent,
+      ChromeEventBundle>;
+
+  static constexpr FieldMetadata_TraceEvents kTraceEvents{};
+  template <typename T = ChromeTraceEvent> T* add_trace_events() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_Metadata =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeMetadata,
+      ChromeEventBundle>;
+
+  static constexpr FieldMetadata_Metadata kMetadata{};
+  template <typename T = ChromeMetadata> T* add_metadata() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_LegacyFtraceOutput =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeEventBundle>;
+
+  static constexpr FieldMetadata_LegacyFtraceOutput kLegacyFtraceOutput{};
+  void add_legacy_ftrace_output(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_LegacyFtraceOutput::kFieldId, data, size);
+  }
+  void add_legacy_ftrace_output(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_LegacyFtraceOutput::kFieldId, chars.data, chars.size);
+  }
+  void add_legacy_ftrace_output(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_LegacyFtraceOutput::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_LegacyJsonTrace =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeLegacyJsonTrace,
+      ChromeEventBundle>;
+
+  static constexpr FieldMetadata_LegacyJsonTrace kLegacyJsonTrace{};
+  template <typename T = ChromeLegacyJsonTrace> T* add_legacy_json_trace() {
+    return BeginNestedMessage<T>(5);
+  }
+
+
+  using FieldMetadata_StringTable =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeStringTableEntry,
+      ChromeEventBundle>;
+
+  static constexpr FieldMetadata_StringTable kStringTable{};
+  template <typename T = ChromeStringTableEntry> T* add_string_table() {
+    return BeginNestedMessage<T>(3);
+  }
+
+};
+
+class ChromeLegacyJsonTrace_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeLegacyJsonTrace_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeLegacyJsonTrace_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeLegacyJsonTrace_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_type() const { return at<1>().valid(); }
+  int32_t type() const { return at<1>().as_int32(); }
+  bool has_data() const { return at<2>().valid(); }
+  ::protozero::ConstChars data() const { return at<2>().as_string(); }
+};
+
+class ChromeLegacyJsonTrace : public ::protozero::Message {
+ public:
+  using Decoder = ChromeLegacyJsonTrace_Decoder;
+  enum : int32_t {
+    kTypeFieldNumber = 1,
+    kDataFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeLegacyJsonTrace"; }
+
+
+  using TraceType = ::perfetto::protos::pbzero::ChromeLegacyJsonTrace_TraceType;
+  static inline const char* TraceType_Name(TraceType value) {
+    return ::perfetto::protos::pbzero::ChromeLegacyJsonTrace_TraceType_Name(value);
+  }
+  static inline const TraceType USER_TRACE = TraceType::USER_TRACE;
+  static inline const TraceType SYSTEM_TRACE = TraceType::SYSTEM_TRACE;
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ChromeLegacyJsonTrace_TraceType,
+      ChromeLegacyJsonTrace>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(ChromeLegacyJsonTrace_TraceType value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::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_Data =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeLegacyJsonTrace>;
+
+  static constexpr FieldMetadata_Data kData{};
+  void set_data(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Data::kFieldId, data, size);
+  }
+  void set_data(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Data::kFieldId, chars.data, chars.size);
+  }
+  void set_data(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Data::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 ChromeMetadata_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeMetadata_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeMetadata_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeMetadata_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_string_value() const { return at<2>().valid(); }
+  ::protozero::ConstChars string_value() const { return at<2>().as_string(); }
+  bool has_bool_value() const { return at<3>().valid(); }
+  bool bool_value() const { return at<3>().as_bool(); }
+  bool has_int_value() const { return at<4>().valid(); }
+  int64_t int_value() const { return at<4>().as_int64(); }
+  bool has_json_value() const { return at<5>().valid(); }
+  ::protozero::ConstChars json_value() const { return at<5>().as_string(); }
+};
+
+class ChromeMetadata : public ::protozero::Message {
+ public:
+  using Decoder = ChromeMetadata_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kStringValueFieldNumber = 2,
+    kBoolValueFieldNumber = 3,
+    kIntValueFieldNumber = 4,
+    kJsonValueFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeMetadata"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeMetadata>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_StringValue =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeMetadata>;
+
+  static constexpr FieldMetadata_StringValue kStringValue{};
+  void set_string_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_StringValue::kFieldId, data, size);
+  }
+  void set_string_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_StringValue::kFieldId, chars.data, chars.size);
+  }
+  void set_string_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_StringValue::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_BoolValue =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeMetadata>;
+
+  static constexpr FieldMetadata_BoolValue kBoolValue{};
+  void set_bool_value(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_BoolValue::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_IntValue =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ChromeMetadata>;
+
+  static constexpr FieldMetadata_IntValue kIntValue{};
+  void set_int_value(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IntValue::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_JsonValue =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeMetadata>;
+
+  static constexpr FieldMetadata_JsonValue kJsonValue{};
+  void set_json_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_JsonValue::kFieldId, data, size);
+  }
+  void set_json_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_JsonValue::kFieldId, chars.data, chars.size);
+  }
+  void set_json_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_JsonValue::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 ChromeTraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/16, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ChromeTraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeTraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeTraceEvent_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_timestamp() const { return at<2>().valid(); }
+  int64_t timestamp() const { return at<2>().as_int64(); }
+  bool has_phase() const { return at<3>().valid(); }
+  int32_t phase() const { return at<3>().as_int32(); }
+  bool has_thread_id() const { return at<4>().valid(); }
+  int32_t thread_id() const { return at<4>().as_int32(); }
+  bool has_duration() const { return at<5>().valid(); }
+  int64_t duration() const { return at<5>().as_int64(); }
+  bool has_thread_duration() const { return at<6>().valid(); }
+  int64_t thread_duration() const { return at<6>().as_int64(); }
+  bool has_scope() const { return at<7>().valid(); }
+  ::protozero::ConstChars scope() const { return at<7>().as_string(); }
+  bool has_id() const { return at<8>().valid(); }
+  uint64_t id() const { return at<8>().as_uint64(); }
+  bool has_flags() const { return at<9>().valid(); }
+  uint32_t flags() const { return at<9>().as_uint32(); }
+  bool has_category_group_name() const { return at<10>().valid(); }
+  ::protozero::ConstChars category_group_name() const { return at<10>().as_string(); }
+  bool has_process_id() const { return at<11>().valid(); }
+  int32_t process_id() const { return at<11>().as_int32(); }
+  bool has_thread_timestamp() const { return at<12>().valid(); }
+  int64_t thread_timestamp() const { return at<12>().as_int64(); }
+  bool has_bind_id() const { return at<13>().valid(); }
+  uint64_t bind_id() const { return at<13>().as_uint64(); }
+  bool has_args() const { return at<14>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> args() const { return GetRepeated<::protozero::ConstBytes>(14); }
+  bool has_name_index() const { return at<15>().valid(); }
+  uint32_t name_index() const { return at<15>().as_uint32(); }
+  bool has_category_group_name_index() const { return at<16>().valid(); }
+  uint32_t category_group_name_index() const { return at<16>().as_uint32(); }
+};
+
+class ChromeTraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = ChromeTraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kTimestampFieldNumber = 2,
+    kPhaseFieldNumber = 3,
+    kThreadIdFieldNumber = 4,
+    kDurationFieldNumber = 5,
+    kThreadDurationFieldNumber = 6,
+    kScopeFieldNumber = 7,
+    kIdFieldNumber = 8,
+    kFlagsFieldNumber = 9,
+    kCategoryGroupNameFieldNumber = 10,
+    kProcessIdFieldNumber = 11,
+    kThreadTimestampFieldNumber = 12,
+    kBindIdFieldNumber = 13,
+    kArgsFieldNumber = 14,
+    kNameIndexFieldNumber = 15,
+    kCategoryGroupNameIndexFieldNumber = 16,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeTraceEvent"; }
+
+  using Arg = ::perfetto::protos::pbzero::ChromeTraceEvent_Arg;
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeTraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ChromeTraceEvent>;
+
+  static constexpr FieldMetadata_Timestamp kTimestamp{};
+  void set_timestamp(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timestamp::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_Phase =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeTraceEvent>;
+
+  static constexpr FieldMetadata_Phase kPhase{};
+  void set_phase(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Phase::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_ThreadId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeTraceEvent>;
+
+  static constexpr FieldMetadata_ThreadId kThreadId{};
+  void set_thread_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ThreadId::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_Duration =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ChromeTraceEvent>;
+
+  static constexpr FieldMetadata_Duration kDuration{};
+  void set_duration(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Duration::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_ThreadDuration =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ChromeTraceEvent>;
+
+  static constexpr FieldMetadata_ThreadDuration kThreadDuration{};
+  void set_thread_duration(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ThreadDuration::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_Scope =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeTraceEvent>;
+
+  static constexpr FieldMetadata_Scope kScope{};
+  void set_scope(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Scope::kFieldId, data, size);
+  }
+  void set_scope(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Scope::kFieldId, chars.data, chars.size);
+  }
+  void set_scope(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Scope::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_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ChromeTraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ChromeTraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_CategoryGroupName =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeTraceEvent>;
+
+  static constexpr FieldMetadata_CategoryGroupName kCategoryGroupName{};
+  void set_category_group_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_CategoryGroupName::kFieldId, data, size);
+  }
+  void set_category_group_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_CategoryGroupName::kFieldId, chars.data, chars.size);
+  }
+  void set_category_group_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_CategoryGroupName::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_ProcessId =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeTraceEvent>;
+
+  static constexpr FieldMetadata_ProcessId kProcessId{};
+  void set_process_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProcessId::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_ThreadTimestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ChromeTraceEvent>;
+
+  static constexpr FieldMetadata_ThreadTimestamp kThreadTimestamp{};
+  void set_thread_timestamp(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ThreadTimestamp::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_BindId =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ChromeTraceEvent>;
+
+  static constexpr FieldMetadata_BindId kBindId{};
+  void set_bind_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BindId::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_Args =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeTraceEvent_Arg,
+      ChromeTraceEvent>;
+
+  static constexpr FieldMetadata_Args kArgs{};
+  template <typename T = ChromeTraceEvent_Arg> T* add_args() {
+    return BeginNestedMessage<T>(14);
+  }
+
+
+  using FieldMetadata_NameIndex =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ChromeTraceEvent>;
+
+  static constexpr FieldMetadata_NameIndex kNameIndex{};
+  void set_name_index(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NameIndex::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_CategoryGroupNameIndex =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ChromeTraceEvent>;
+
+  static constexpr FieldMetadata_CategoryGroupNameIndex kCategoryGroupNameIndex{};
+  void set_category_group_name_index(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CategoryGroupNameIndex::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 ChromeTraceEvent_Arg_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/10, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeTraceEvent_Arg_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeTraceEvent_Arg_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeTraceEvent_Arg_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_bool_value() const { return at<2>().valid(); }
+  bool bool_value() const { return at<2>().as_bool(); }
+  bool has_uint_value() const { return at<3>().valid(); }
+  uint64_t uint_value() const { return at<3>().as_uint64(); }
+  bool has_int_value() const { return at<4>().valid(); }
+  int64_t int_value() const { return at<4>().as_int64(); }
+  bool has_double_value() const { return at<5>().valid(); }
+  double double_value() const { return at<5>().as_double(); }
+  bool has_string_value() const { return at<6>().valid(); }
+  ::protozero::ConstChars string_value() const { return at<6>().as_string(); }
+  bool has_pointer_value() const { return at<7>().valid(); }
+  uint64_t pointer_value() const { return at<7>().as_uint64(); }
+  bool has_json_value() const { return at<8>().valid(); }
+  ::protozero::ConstChars json_value() const { return at<8>().as_string(); }
+  bool has_traced_value() const { return at<10>().valid(); }
+  ::protozero::ConstBytes traced_value() const { return at<10>().as_bytes(); }
+  bool has_name_index() const { return at<9>().valid(); }
+  uint32_t name_index() const { return at<9>().as_uint32(); }
+};
+
+class ChromeTraceEvent_Arg : public ::protozero::Message {
+ public:
+  using Decoder = ChromeTraceEvent_Arg_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kBoolValueFieldNumber = 2,
+    kUintValueFieldNumber = 3,
+    kIntValueFieldNumber = 4,
+    kDoubleValueFieldNumber = 5,
+    kStringValueFieldNumber = 6,
+    kPointerValueFieldNumber = 7,
+    kJsonValueFieldNumber = 8,
+    kTracedValueFieldNumber = 10,
+    kNameIndexFieldNumber = 9,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeTraceEvent.Arg"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeTraceEvent_Arg>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_BoolValue =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeTraceEvent_Arg>;
+
+  static constexpr FieldMetadata_BoolValue kBoolValue{};
+  void set_bool_value(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_BoolValue::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_UintValue =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ChromeTraceEvent_Arg>;
+
+  static constexpr FieldMetadata_UintValue kUintValue{};
+  void set_uint_value(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UintValue::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_IntValue =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ChromeTraceEvent_Arg>;
+
+  static constexpr FieldMetadata_IntValue kIntValue{};
+  void set_int_value(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IntValue::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_DoubleValue =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      ChromeTraceEvent_Arg>;
+
+  static constexpr FieldMetadata_DoubleValue kDoubleValue{};
+  void set_double_value(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_DoubleValue::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);
+  }
+
+  using FieldMetadata_StringValue =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeTraceEvent_Arg>;
+
+  static constexpr FieldMetadata_StringValue kStringValue{};
+  void set_string_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_StringValue::kFieldId, data, size);
+  }
+  void set_string_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_StringValue::kFieldId, chars.data, chars.size);
+  }
+  void set_string_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_StringValue::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_PointerValue =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ChromeTraceEvent_Arg>;
+
+  static constexpr FieldMetadata_PointerValue kPointerValue{};
+  void set_pointer_value(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PointerValue::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_JsonValue =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeTraceEvent_Arg>;
+
+  static constexpr FieldMetadata_JsonValue kJsonValue{};
+  void set_json_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_JsonValue::kFieldId, data, size);
+  }
+  void set_json_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_JsonValue::kFieldId, chars.data, chars.size);
+  }
+  void set_json_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_JsonValue::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_TracedValue =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeTracedValue,
+      ChromeTraceEvent_Arg>;
+
+  static constexpr FieldMetadata_TracedValue kTracedValue{};
+  template <typename T = ChromeTracedValue> T* set_traced_value() {
+    return BeginNestedMessage<T>(10);
+  }
+
+
+  using FieldMetadata_NameIndex =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ChromeTraceEvent_Arg>;
+
+  static constexpr FieldMetadata_NameIndex kNameIndex{};
+  void set_name_index(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NameIndex::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 ChromeStringTableEntry_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeStringTableEntry_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeStringTableEntry_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeStringTableEntry_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_value() const { return at<1>().valid(); }
+  ::protozero::ConstChars value() const { return at<1>().as_string(); }
+  bool has_index() const { return at<2>().valid(); }
+  int32_t index() const { return at<2>().as_int32(); }
+};
+
+class ChromeStringTableEntry : public ::protozero::Message {
+ public:
+  using Decoder = ChromeStringTableEntry_Decoder;
+  enum : int32_t {
+    kValueFieldNumber = 1,
+    kIndexFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeStringTableEntry"; }
+
+
+  using FieldMetadata_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeStringTableEntry>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Value::kFieldId, data, size);
+  }
+  void set_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Value::kFieldId, chars.data, chars.size);
+  }
+  void set_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::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_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeStringTableEntry>;
+
+  static constexpr FieldMetadata_Index kIndex{};
+  void set_index(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Index::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);
+  }
+};
+
+class ChromeTracedValue_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ChromeTracedValue_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeTracedValue_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeTracedValue_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_nested_type() const { return at<1>().valid(); }
+  int32_t nested_type() const { return at<1>().as_int32(); }
+  bool has_dict_keys() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> dict_keys() const { return GetRepeated<::protozero::ConstChars>(2); }
+  bool has_dict_values() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> dict_values() const { return GetRepeated<::protozero::ConstBytes>(3); }
+  bool has_array_values() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> array_values() const { return GetRepeated<::protozero::ConstBytes>(4); }
+  bool has_int_value() const { return at<5>().valid(); }
+  int32_t int_value() const { return at<5>().as_int32(); }
+  bool has_double_value() const { return at<6>().valid(); }
+  double double_value() const { return at<6>().as_double(); }
+  bool has_bool_value() const { return at<7>().valid(); }
+  bool bool_value() const { return at<7>().as_bool(); }
+  bool has_string_value() const { return at<8>().valid(); }
+  ::protozero::ConstChars string_value() const { return at<8>().as_string(); }
+};
+
+class ChromeTracedValue : public ::protozero::Message {
+ public:
+  using Decoder = ChromeTracedValue_Decoder;
+  enum : int32_t {
+    kNestedTypeFieldNumber = 1,
+    kDictKeysFieldNumber = 2,
+    kDictValuesFieldNumber = 3,
+    kArrayValuesFieldNumber = 4,
+    kIntValueFieldNumber = 5,
+    kDoubleValueFieldNumber = 6,
+    kBoolValueFieldNumber = 7,
+    kStringValueFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeTracedValue"; }
+
+
+  using NestedType = ::perfetto::protos::pbzero::ChromeTracedValue_NestedType;
+  static inline const char* NestedType_Name(NestedType value) {
+    return ::perfetto::protos::pbzero::ChromeTracedValue_NestedType_Name(value);
+  }
+  static inline const NestedType DICT = NestedType::DICT;
+  static inline const NestedType ARRAY = NestedType::ARRAY;
+
+  using FieldMetadata_NestedType =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ChromeTracedValue_NestedType,
+      ChromeTracedValue>;
+
+  static constexpr FieldMetadata_NestedType kNestedType{};
+  void set_nested_type(ChromeTracedValue_NestedType value) {
+    static constexpr uint32_t field_id = FieldMetadata_NestedType::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_DictKeys =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeTracedValue>;
+
+  static constexpr FieldMetadata_DictKeys kDictKeys{};
+  void add_dict_keys(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DictKeys::kFieldId, data, size);
+  }
+  void add_dict_keys(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_DictKeys::kFieldId, chars.data, chars.size);
+  }
+  void add_dict_keys(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_DictKeys::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_DictValues =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeTracedValue,
+      ChromeTracedValue>;
+
+  static constexpr FieldMetadata_DictValues kDictValues{};
+  template <typename T = ChromeTracedValue> T* add_dict_values() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_ArrayValues =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeTracedValue,
+      ChromeTracedValue>;
+
+  static constexpr FieldMetadata_ArrayValues kArrayValues{};
+  template <typename T = ChromeTracedValue> T* add_array_values() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_IntValue =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeTracedValue>;
+
+  static constexpr FieldMetadata_IntValue kIntValue{};
+  void set_int_value(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IntValue::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_DoubleValue =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      ChromeTracedValue>;
+
+  static constexpr FieldMetadata_DoubleValue kDoubleValue{};
+  void set_double_value(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_DoubleValue::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);
+  }
+
+  using FieldMetadata_BoolValue =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeTracedValue>;
+
+  static constexpr FieldMetadata_BoolValue kBoolValue{};
+  void set_bool_value(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_BoolValue::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_StringValue =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeTracedValue>;
+
+  static constexpr FieldMetadata_StringValue kStringValue{};
+  void set_string_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_StringValue::kFieldId, data, size);
+  }
+  void set_string_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_StringValue::kFieldId, chars.data, chars.size);
+  }
+  void set_string_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_StringValue::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/chrome/chrome_trigger.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_CHROME_CHROME_TRIGGER_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_CHROME_CHROME_TRIGGER_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class ChromeTrigger_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeTrigger_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeTrigger_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeTrigger_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_trigger_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars trigger_name() const { return at<1>().as_string(); }
+  bool has_trigger_name_hash() const { return at<2>().valid(); }
+  uint32_t trigger_name_hash() const { return at<2>().as_uint32(); }
+};
+
+class ChromeTrigger : public ::protozero::Message {
+ public:
+  using Decoder = ChromeTrigger_Decoder;
+  enum : int32_t {
+    kTriggerNameFieldNumber = 1,
+    kTriggerNameHashFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeTrigger"; }
+
+
+  using FieldMetadata_TriggerName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeTrigger>;
+
+  static constexpr FieldMetadata_TriggerName kTriggerName{};
+  void set_trigger_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TriggerName::kFieldId, data, size);
+  }
+  void set_trigger_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_TriggerName::kFieldId, chars.data, chars.size);
+  }
+  void set_trigger_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_TriggerName::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_TriggerNameHash =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed32,
+      uint32_t,
+      ChromeTrigger>;
+
+  static constexpr FieldMetadata_TriggerNameHash kTriggerNameHash{};
+  void set_trigger_name_hash(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TriggerNameHash::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/chrome/v8.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_CHROME_V8_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_CHROME_V8_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class InternedV8Isolate_CodeRange;
+class V8String;
+namespace perfetto_pbzero_enum_InternedV8JsFunction {
+enum Kind : int32_t;
+}  // namespace perfetto_pbzero_enum_InternedV8JsFunction
+using InternedV8JsFunction_Kind = perfetto_pbzero_enum_InternedV8JsFunction::Kind;
+namespace perfetto_pbzero_enum_InternedV8JsScript {
+enum Type : int32_t;
+}  // namespace perfetto_pbzero_enum_InternedV8JsScript
+using InternedV8JsScript_Type = perfetto_pbzero_enum_InternedV8JsScript::Type;
+namespace perfetto_pbzero_enum_V8InternalCode {
+enum Type : int32_t;
+}  // namespace perfetto_pbzero_enum_V8InternalCode
+using V8InternalCode_Type = perfetto_pbzero_enum_V8InternalCode::Type;
+namespace perfetto_pbzero_enum_V8JsCode {
+enum Tier : int32_t;
+}  // namespace perfetto_pbzero_enum_V8JsCode
+using V8JsCode_Tier = perfetto_pbzero_enum_V8JsCode::Tier;
+namespace perfetto_pbzero_enum_V8WasmCode {
+enum Tier : int32_t;
+}  // namespace perfetto_pbzero_enum_V8WasmCode
+using V8WasmCode_Tier = perfetto_pbzero_enum_V8WasmCode::Tier;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_V8WasmCode {
+enum Tier : int32_t {
+  TIER_UNKNOWN = 0,
+  TIER_LIFTOFF = 1,
+  TIER_TURBOFAN = 2,
+};
+} // namespace perfetto_pbzero_enum_V8WasmCode
+using V8WasmCode_Tier = perfetto_pbzero_enum_V8WasmCode::Tier;
+
+
+constexpr V8WasmCode_Tier V8WasmCode_Tier_MIN = V8WasmCode_Tier::TIER_UNKNOWN;
+constexpr V8WasmCode_Tier V8WasmCode_Tier_MAX = V8WasmCode_Tier::TIER_TURBOFAN;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* V8WasmCode_Tier_Name(::perfetto::protos::pbzero::V8WasmCode_Tier value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::V8WasmCode_Tier::TIER_UNKNOWN:
+    return "TIER_UNKNOWN";
+
+  case ::perfetto::protos::pbzero::V8WasmCode_Tier::TIER_LIFTOFF:
+    return "TIER_LIFTOFF";
+
+  case ::perfetto::protos::pbzero::V8WasmCode_Tier::TIER_TURBOFAN:
+    return "TIER_TURBOFAN";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_V8InternalCode {
+enum Type : int32_t {
+  TYPE_UNKNOWN = 0,
+  TYPE_BYTECODE_HANDLER = 1,
+  TYPE_FOR_TESTING = 2,
+  TYPE_BUILTIN = 3,
+  TYPE_WASM_FUNCTION = 4,
+  TYPE_WASM_TO_CAPI_FUNCTION = 5,
+  TYPE_WASM_TO_JS_FUNCTION = 6,
+  TYPE_JS_TO_WASM_FUNCTION = 7,
+  TYPE_JS_TO_JS_FUNCTION = 8,
+  TYPE_C_WASM_ENTRY = 9,
+};
+} // namespace perfetto_pbzero_enum_V8InternalCode
+using V8InternalCode_Type = perfetto_pbzero_enum_V8InternalCode::Type;
+
+
+constexpr V8InternalCode_Type V8InternalCode_Type_MIN = V8InternalCode_Type::TYPE_UNKNOWN;
+constexpr V8InternalCode_Type V8InternalCode_Type_MAX = V8InternalCode_Type::TYPE_C_WASM_ENTRY;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* V8InternalCode_Type_Name(::perfetto::protos::pbzero::V8InternalCode_Type value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::V8InternalCode_Type::TYPE_UNKNOWN:
+    return "TYPE_UNKNOWN";
+
+  case ::perfetto::protos::pbzero::V8InternalCode_Type::TYPE_BYTECODE_HANDLER:
+    return "TYPE_BYTECODE_HANDLER";
+
+  case ::perfetto::protos::pbzero::V8InternalCode_Type::TYPE_FOR_TESTING:
+    return "TYPE_FOR_TESTING";
+
+  case ::perfetto::protos::pbzero::V8InternalCode_Type::TYPE_BUILTIN:
+    return "TYPE_BUILTIN";
+
+  case ::perfetto::protos::pbzero::V8InternalCode_Type::TYPE_WASM_FUNCTION:
+    return "TYPE_WASM_FUNCTION";
+
+  case ::perfetto::protos::pbzero::V8InternalCode_Type::TYPE_WASM_TO_CAPI_FUNCTION:
+    return "TYPE_WASM_TO_CAPI_FUNCTION";
+
+  case ::perfetto::protos::pbzero::V8InternalCode_Type::TYPE_WASM_TO_JS_FUNCTION:
+    return "TYPE_WASM_TO_JS_FUNCTION";
+
+  case ::perfetto::protos::pbzero::V8InternalCode_Type::TYPE_JS_TO_WASM_FUNCTION:
+    return "TYPE_JS_TO_WASM_FUNCTION";
+
+  case ::perfetto::protos::pbzero::V8InternalCode_Type::TYPE_JS_TO_JS_FUNCTION:
+    return "TYPE_JS_TO_JS_FUNCTION";
+
+  case ::perfetto::protos::pbzero::V8InternalCode_Type::TYPE_C_WASM_ENTRY:
+    return "TYPE_C_WASM_ENTRY";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_V8JsCode {
+enum Tier : int32_t {
+  TIER_UNKNOWN = 0,
+  TIER_IGNITION = 1,
+  TIER_SPARKPLUG = 2,
+  TIER_MAGLEV = 3,
+  TIER_TURBOSHAFT = 4,
+  TIER_TURBOFAN = 5,
+};
+} // namespace perfetto_pbzero_enum_V8JsCode
+using V8JsCode_Tier = perfetto_pbzero_enum_V8JsCode::Tier;
+
+
+constexpr V8JsCode_Tier V8JsCode_Tier_MIN = V8JsCode_Tier::TIER_UNKNOWN;
+constexpr V8JsCode_Tier V8JsCode_Tier_MAX = V8JsCode_Tier::TIER_TURBOFAN;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* V8JsCode_Tier_Name(::perfetto::protos::pbzero::V8JsCode_Tier value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::V8JsCode_Tier::TIER_UNKNOWN:
+    return "TIER_UNKNOWN";
+
+  case ::perfetto::protos::pbzero::V8JsCode_Tier::TIER_IGNITION:
+    return "TIER_IGNITION";
+
+  case ::perfetto::protos::pbzero::V8JsCode_Tier::TIER_SPARKPLUG:
+    return "TIER_SPARKPLUG";
+
+  case ::perfetto::protos::pbzero::V8JsCode_Tier::TIER_MAGLEV:
+    return "TIER_MAGLEV";
+
+  case ::perfetto::protos::pbzero::V8JsCode_Tier::TIER_TURBOSHAFT:
+    return "TIER_TURBOSHAFT";
+
+  case ::perfetto::protos::pbzero::V8JsCode_Tier::TIER_TURBOFAN:
+    return "TIER_TURBOFAN";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_InternedV8JsFunction {
+enum Kind : int32_t {
+  KIND_UNKNOWN = 0,
+  KIND_NORMAL_FUNCTION = 1,
+  KIND_MODULE = 2,
+  KIND_ASYNC_MODULE = 3,
+  KIND_BASE_CONSTRUCTOR = 4,
+  KIND_DEFAULT_BASE_CONSTRUCTOR = 5,
+  KIND_DEFAULT_DERIVED_CONSTRUCTOR = 6,
+  KIND_DERIVED_CONSTRUCTOR = 7,
+  KIND_GETTER_FUNCTION = 8,
+  KIND_STATIC_GETTER_FUNCTION = 9,
+  KIND_SETTER_FUNCTION = 10,
+  KIND_STATIC_SETTER_FUNCTION = 11,
+  KIND_ARROW_FUNCTION = 12,
+  KIND_ASYNC_ARROW_FUNCTION = 13,
+  KIND_ASYNC_FUNCTION = 14,
+  KIND_ASYNC_CONCISE_METHOD = 15,
+  KIND_STATIC_ASYNC_CONCISE_METHOD = 16,
+  KIND_ASYNC_CONCISE_GENERATOR_METHOD = 17,
+  KIND_STATIC_ASYNC_CONCISE_GENERATOR_METHOD = 18,
+  KIND_ASYNC_GENERATOR_FUNCTION = 19,
+  KIND_GENERATOR_FUNCTION = 20,
+  KIND_CONCISE_GENERATOR_METHOD = 21,
+  KIND_STATIC_CONCISE_GENERATOR_METHOD = 22,
+  KIND_CONCISE_METHOD = 23,
+  KIND_STATIC_CONCISE_METHOD = 24,
+  KIND_CLASS_MEMBERS_INITIALIZER_FUNCTION = 25,
+  KIND_CLASS_STATIC_INITIALIZER_FUNCTION = 26,
+  KIND_INVALID = 27,
+};
+} // namespace perfetto_pbzero_enum_InternedV8JsFunction
+using InternedV8JsFunction_Kind = perfetto_pbzero_enum_InternedV8JsFunction::Kind;
+
+
+constexpr InternedV8JsFunction_Kind InternedV8JsFunction_Kind_MIN = InternedV8JsFunction_Kind::KIND_UNKNOWN;
+constexpr InternedV8JsFunction_Kind InternedV8JsFunction_Kind_MAX = InternedV8JsFunction_Kind::KIND_INVALID;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* InternedV8JsFunction_Kind_Name(::perfetto::protos::pbzero::InternedV8JsFunction_Kind value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::InternedV8JsFunction_Kind::KIND_UNKNOWN:
+    return "KIND_UNKNOWN";
+
+  case ::perfetto::protos::pbzero::InternedV8JsFunction_Kind::KIND_NORMAL_FUNCTION:
+    return "KIND_NORMAL_FUNCTION";
+
+  case ::perfetto::protos::pbzero::InternedV8JsFunction_Kind::KIND_MODULE:
+    return "KIND_MODULE";
+
+  case ::perfetto::protos::pbzero::InternedV8JsFunction_Kind::KIND_ASYNC_MODULE:
+    return "KIND_ASYNC_MODULE";
+
+  case ::perfetto::protos::pbzero::InternedV8JsFunction_Kind::KIND_BASE_CONSTRUCTOR:
+    return "KIND_BASE_CONSTRUCTOR";
+
+  case ::perfetto::protos::pbzero::InternedV8JsFunction_Kind::KIND_DEFAULT_BASE_CONSTRUCTOR:
+    return "KIND_DEFAULT_BASE_CONSTRUCTOR";
+
+  case ::perfetto::protos::pbzero::InternedV8JsFunction_Kind::KIND_DEFAULT_DERIVED_CONSTRUCTOR:
+    return "KIND_DEFAULT_DERIVED_CONSTRUCTOR";
+
+  case ::perfetto::protos::pbzero::InternedV8JsFunction_Kind::KIND_DERIVED_CONSTRUCTOR:
+    return "KIND_DERIVED_CONSTRUCTOR";
+
+  case ::perfetto::protos::pbzero::InternedV8JsFunction_Kind::KIND_GETTER_FUNCTION:
+    return "KIND_GETTER_FUNCTION";
+
+  case ::perfetto::protos::pbzero::InternedV8JsFunction_Kind::KIND_STATIC_GETTER_FUNCTION:
+    return "KIND_STATIC_GETTER_FUNCTION";
+
+  case ::perfetto::protos::pbzero::InternedV8JsFunction_Kind::KIND_SETTER_FUNCTION:
+    return "KIND_SETTER_FUNCTION";
+
+  case ::perfetto::protos::pbzero::InternedV8JsFunction_Kind::KIND_STATIC_SETTER_FUNCTION:
+    return "KIND_STATIC_SETTER_FUNCTION";
+
+  case ::perfetto::protos::pbzero::InternedV8JsFunction_Kind::KIND_ARROW_FUNCTION:
+    return "KIND_ARROW_FUNCTION";
+
+  case ::perfetto::protos::pbzero::InternedV8JsFunction_Kind::KIND_ASYNC_ARROW_FUNCTION:
+    return "KIND_ASYNC_ARROW_FUNCTION";
+
+  case ::perfetto::protos::pbzero::InternedV8JsFunction_Kind::KIND_ASYNC_FUNCTION:
+    return "KIND_ASYNC_FUNCTION";
+
+  case ::perfetto::protos::pbzero::InternedV8JsFunction_Kind::KIND_ASYNC_CONCISE_METHOD:
+    return "KIND_ASYNC_CONCISE_METHOD";
+
+  case ::perfetto::protos::pbzero::InternedV8JsFunction_Kind::KIND_STATIC_ASYNC_CONCISE_METHOD:
+    return "KIND_STATIC_ASYNC_CONCISE_METHOD";
+
+  case ::perfetto::protos::pbzero::InternedV8JsFunction_Kind::KIND_ASYNC_CONCISE_GENERATOR_METHOD:
+    return "KIND_ASYNC_CONCISE_GENERATOR_METHOD";
+
+  case ::perfetto::protos::pbzero::InternedV8JsFunction_Kind::KIND_STATIC_ASYNC_CONCISE_GENERATOR_METHOD:
+    return "KIND_STATIC_ASYNC_CONCISE_GENERATOR_METHOD";
+
+  case ::perfetto::protos::pbzero::InternedV8JsFunction_Kind::KIND_ASYNC_GENERATOR_FUNCTION:
+    return "KIND_ASYNC_GENERATOR_FUNCTION";
+
+  case ::perfetto::protos::pbzero::InternedV8JsFunction_Kind::KIND_GENERATOR_FUNCTION:
+    return "KIND_GENERATOR_FUNCTION";
+
+  case ::perfetto::protos::pbzero::InternedV8JsFunction_Kind::KIND_CONCISE_GENERATOR_METHOD:
+    return "KIND_CONCISE_GENERATOR_METHOD";
+
+  case ::perfetto::protos::pbzero::InternedV8JsFunction_Kind::KIND_STATIC_CONCISE_GENERATOR_METHOD:
+    return "KIND_STATIC_CONCISE_GENERATOR_METHOD";
+
+  case ::perfetto::protos::pbzero::InternedV8JsFunction_Kind::KIND_CONCISE_METHOD:
+    return "KIND_CONCISE_METHOD";
+
+  case ::perfetto::protos::pbzero::InternedV8JsFunction_Kind::KIND_STATIC_CONCISE_METHOD:
+    return "KIND_STATIC_CONCISE_METHOD";
+
+  case ::perfetto::protos::pbzero::InternedV8JsFunction_Kind::KIND_CLASS_MEMBERS_INITIALIZER_FUNCTION:
+    return "KIND_CLASS_MEMBERS_INITIALIZER_FUNCTION";
+
+  case ::perfetto::protos::pbzero::InternedV8JsFunction_Kind::KIND_CLASS_STATIC_INITIALIZER_FUNCTION:
+    return "KIND_CLASS_STATIC_INITIALIZER_FUNCTION";
+
+  case ::perfetto::protos::pbzero::InternedV8JsFunction_Kind::KIND_INVALID:
+    return "KIND_INVALID";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_InternedV8JsScript {
+enum Type : int32_t {
+  TYPE_UNKNOWN = 0,
+  TYPE_NORMAL = 1,
+  TYPE_EVAL = 2,
+  TYPE_MODULE = 3,
+  TYPE_NATIVE = 4,
+  TYPE_EXTENSION = 5,
+  TYPE_INSPECTOR = 6,
+};
+} // namespace perfetto_pbzero_enum_InternedV8JsScript
+using InternedV8JsScript_Type = perfetto_pbzero_enum_InternedV8JsScript::Type;
+
+
+constexpr InternedV8JsScript_Type InternedV8JsScript_Type_MIN = InternedV8JsScript_Type::TYPE_UNKNOWN;
+constexpr InternedV8JsScript_Type InternedV8JsScript_Type_MAX = InternedV8JsScript_Type::TYPE_INSPECTOR;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* InternedV8JsScript_Type_Name(::perfetto::protos::pbzero::InternedV8JsScript_Type value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::InternedV8JsScript_Type::TYPE_UNKNOWN:
+    return "TYPE_UNKNOWN";
+
+  case ::perfetto::protos::pbzero::InternedV8JsScript_Type::TYPE_NORMAL:
+    return "TYPE_NORMAL";
+
+  case ::perfetto::protos::pbzero::InternedV8JsScript_Type::TYPE_EVAL:
+    return "TYPE_EVAL";
+
+  case ::perfetto::protos::pbzero::InternedV8JsScript_Type::TYPE_MODULE:
+    return "TYPE_MODULE";
+
+  case ::perfetto::protos::pbzero::InternedV8JsScript_Type::TYPE_NATIVE:
+    return "TYPE_NATIVE";
+
+  case ::perfetto::protos::pbzero::InternedV8JsScript_Type::TYPE_EXTENSION:
+    return "TYPE_EXTENSION";
+
+  case ::perfetto::protos::pbzero::InternedV8JsScript_Type::TYPE_INSPECTOR:
+    return "TYPE_INSPECTOR";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class V8CodeDefaults_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  V8CodeDefaults_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit V8CodeDefaults_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit V8CodeDefaults_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_tid() const { return at<1>().valid(); }
+  uint32_t tid() const { return at<1>().as_uint32(); }
+};
+
+class V8CodeDefaults : public ::protozero::Message {
+ public:
+  using Decoder = V8CodeDefaults_Decoder;
+  enum : int32_t {
+    kTidFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.V8CodeDefaults"; }
+
+
+  using FieldMetadata_Tid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V8CodeDefaults>;
+
+  static constexpr FieldMetadata_Tid kTid{};
+  void set_tid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tid::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 V8CodeMove_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  V8CodeMove_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit V8CodeMove_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit V8CodeMove_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_isolate_iid() const { return at<1>().valid(); }
+  uint64_t isolate_iid() const { return at<1>().as_uint64(); }
+  bool has_tid() const { return at<2>().valid(); }
+  uint32_t tid() const { return at<2>().as_uint32(); }
+  bool has_from_instruction_start_address() const { return at<3>().valid(); }
+  uint64_t from_instruction_start_address() const { return at<3>().as_uint64(); }
+  bool has_to_instruction_start_address() const { return at<4>().valid(); }
+  uint64_t to_instruction_start_address() const { return at<4>().as_uint64(); }
+  bool has_instruction_size_bytes() const { return at<5>().valid(); }
+  uint64_t instruction_size_bytes() const { return at<5>().as_uint64(); }
+  bool has_to_machine_code() const { return at<6>().valid(); }
+  ::protozero::ConstBytes to_machine_code() const { return at<6>().as_bytes(); }
+  bool has_to_bytecode() const { return at<7>().valid(); }
+  ::protozero::ConstBytes to_bytecode() const { return at<7>().as_bytes(); }
+};
+
+class V8CodeMove : public ::protozero::Message {
+ public:
+  using Decoder = V8CodeMove_Decoder;
+  enum : int32_t {
+    kIsolateIidFieldNumber = 1,
+    kTidFieldNumber = 2,
+    kFromInstructionStartAddressFieldNumber = 3,
+    kToInstructionStartAddressFieldNumber = 4,
+    kInstructionSizeBytesFieldNumber = 5,
+    kToMachineCodeFieldNumber = 6,
+    kToBytecodeFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.V8CodeMove"; }
+
+
+  using FieldMetadata_IsolateIid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      V8CodeMove>;
+
+  static constexpr FieldMetadata_IsolateIid kIsolateIid{};
+  void set_isolate_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsolateIid::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_Tid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V8CodeMove>;
+
+  static constexpr FieldMetadata_Tid kTid{};
+  void set_tid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tid::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_FromInstructionStartAddress =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      V8CodeMove>;
+
+  static constexpr FieldMetadata_FromInstructionStartAddress kFromInstructionStartAddress{};
+  void set_from_instruction_start_address(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FromInstructionStartAddress::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_ToInstructionStartAddress =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      V8CodeMove>;
+
+  static constexpr FieldMetadata_ToInstructionStartAddress kToInstructionStartAddress{};
+  void set_to_instruction_start_address(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ToInstructionStartAddress::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_InstructionSizeBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      V8CodeMove>;
+
+  static constexpr FieldMetadata_InstructionSizeBytes kInstructionSizeBytes{};
+  void set_instruction_size_bytes(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InstructionSizeBytes::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_ToMachineCode =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      V8CodeMove>;
+
+  static constexpr FieldMetadata_ToMachineCode kToMachineCode{};
+  void set_to_machine_code(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_ToMachineCode::kFieldId, data, size);
+  }
+  void set_to_machine_code(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_ToMachineCode::kFieldId, bytes.data, bytes.size);
+  }
+  void set_to_machine_code(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ToMachineCode::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);
+  }
+
+  using FieldMetadata_ToBytecode =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      V8CodeMove>;
+
+  static constexpr FieldMetadata_ToBytecode kToBytecode{};
+  void set_to_bytecode(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_ToBytecode::kFieldId, data, size);
+  }
+  void set_to_bytecode(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_ToBytecode::kFieldId, bytes.data, bytes.size);
+  }
+  void set_to_bytecode(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ToBytecode::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 V8RegExpCode_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  V8RegExpCode_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit V8RegExpCode_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit V8RegExpCode_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_v8_isolate_iid() const { return at<1>().valid(); }
+  uint64_t v8_isolate_iid() const { return at<1>().as_uint64(); }
+  bool has_tid() const { return at<2>().valid(); }
+  uint32_t tid() const { return at<2>().as_uint32(); }
+  bool has_pattern() const { return at<3>().valid(); }
+  ::protozero::ConstBytes pattern() const { return at<3>().as_bytes(); }
+  bool has_instruction_start() const { return at<4>().valid(); }
+  uint64_t instruction_start() const { return at<4>().as_uint64(); }
+  bool has_instruction_size_bytes() const { return at<5>().valid(); }
+  uint64_t instruction_size_bytes() const { return at<5>().as_uint64(); }
+  bool has_machine_code() const { return at<6>().valid(); }
+  ::protozero::ConstBytes machine_code() const { return at<6>().as_bytes(); }
+};
+
+class V8RegExpCode : public ::protozero::Message {
+ public:
+  using Decoder = V8RegExpCode_Decoder;
+  enum : int32_t {
+    kV8IsolateIidFieldNumber = 1,
+    kTidFieldNumber = 2,
+    kPatternFieldNumber = 3,
+    kInstructionStartFieldNumber = 4,
+    kInstructionSizeBytesFieldNumber = 5,
+    kMachineCodeFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.V8RegExpCode"; }
+
+
+  using FieldMetadata_V8IsolateIid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      V8RegExpCode>;
+
+  static constexpr FieldMetadata_V8IsolateIid kV8IsolateIid{};
+  void set_v8_isolate_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_V8IsolateIid::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_Tid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V8RegExpCode>;
+
+  static constexpr FieldMetadata_Tid kTid{};
+  void set_tid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tid::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_Pattern =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      V8String,
+      V8RegExpCode>;
+
+  static constexpr FieldMetadata_Pattern kPattern{};
+  template <typename T = V8String> T* set_pattern() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_InstructionStart =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      V8RegExpCode>;
+
+  static constexpr FieldMetadata_InstructionStart kInstructionStart{};
+  void set_instruction_start(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InstructionStart::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_InstructionSizeBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      V8RegExpCode>;
+
+  static constexpr FieldMetadata_InstructionSizeBytes kInstructionSizeBytes{};
+  void set_instruction_size_bytes(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InstructionSizeBytes::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_MachineCode =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      V8RegExpCode>;
+
+  static constexpr FieldMetadata_MachineCode kMachineCode{};
+  void set_machine_code(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_MachineCode::kFieldId, data, size);
+  }
+  void set_machine_code(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_MachineCode::kFieldId, bytes.data, bytes.size);
+  }
+  void set_machine_code(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_MachineCode::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 V8WasmCode_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  V8WasmCode_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit V8WasmCode_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit V8WasmCode_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_v8_isolate_iid() const { return at<1>().valid(); }
+  uint64_t v8_isolate_iid() const { return at<1>().as_uint64(); }
+  bool has_tid() const { return at<2>().valid(); }
+  uint32_t tid() const { return at<2>().as_uint32(); }
+  bool has_v8_wasm_script_iid() const { return at<3>().valid(); }
+  uint64_t v8_wasm_script_iid() const { return at<3>().as_uint64(); }
+  bool has_function_name() const { return at<4>().valid(); }
+  ::protozero::ConstChars function_name() const { return at<4>().as_string(); }
+  bool has_tier() const { return at<5>().valid(); }
+  int32_t tier() const { return at<5>().as_int32(); }
+  bool has_code_offset_in_module() const { return at<6>().valid(); }
+  int32_t code_offset_in_module() const { return at<6>().as_int32(); }
+  bool has_instruction_start() const { return at<7>().valid(); }
+  uint64_t instruction_start() const { return at<7>().as_uint64(); }
+  bool has_instruction_size_bytes() const { return at<8>().valid(); }
+  uint64_t instruction_size_bytes() const { return at<8>().as_uint64(); }
+  bool has_machine_code() const { return at<9>().valid(); }
+  ::protozero::ConstBytes machine_code() const { return at<9>().as_bytes(); }
+};
+
+class V8WasmCode : public ::protozero::Message {
+ public:
+  using Decoder = V8WasmCode_Decoder;
+  enum : int32_t {
+    kV8IsolateIidFieldNumber = 1,
+    kTidFieldNumber = 2,
+    kV8WasmScriptIidFieldNumber = 3,
+    kFunctionNameFieldNumber = 4,
+    kTierFieldNumber = 5,
+    kCodeOffsetInModuleFieldNumber = 6,
+    kInstructionStartFieldNumber = 7,
+    kInstructionSizeBytesFieldNumber = 8,
+    kMachineCodeFieldNumber = 9,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.V8WasmCode"; }
+
+
+  using Tier = ::perfetto::protos::pbzero::V8WasmCode_Tier;
+  static inline const char* Tier_Name(Tier value) {
+    return ::perfetto::protos::pbzero::V8WasmCode_Tier_Name(value);
+  }
+  static inline const Tier TIER_UNKNOWN = Tier::TIER_UNKNOWN;
+  static inline const Tier TIER_LIFTOFF = Tier::TIER_LIFTOFF;
+  static inline const Tier TIER_TURBOFAN = Tier::TIER_TURBOFAN;
+
+  using FieldMetadata_V8IsolateIid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      V8WasmCode>;
+
+  static constexpr FieldMetadata_V8IsolateIid kV8IsolateIid{};
+  void set_v8_isolate_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_V8IsolateIid::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_Tid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V8WasmCode>;
+
+  static constexpr FieldMetadata_Tid kTid{};
+  void set_tid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tid::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_V8WasmScriptIid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      V8WasmCode>;
+
+  static constexpr FieldMetadata_V8WasmScriptIid kV8WasmScriptIid{};
+  void set_v8_wasm_script_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_V8WasmScriptIid::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_FunctionName =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      V8WasmCode>;
+
+  static constexpr FieldMetadata_FunctionName kFunctionName{};
+  void set_function_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_FunctionName::kFieldId, data, size);
+  }
+  void set_function_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_FunctionName::kFieldId, chars.data, chars.size);
+  }
+  void set_function_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_FunctionName::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_Tier =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      V8WasmCode_Tier,
+      V8WasmCode>;
+
+  static constexpr FieldMetadata_Tier kTier{};
+  void set_tier(V8WasmCode_Tier value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tier::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_CodeOffsetInModule =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      V8WasmCode>;
+
+  static constexpr FieldMetadata_CodeOffsetInModule kCodeOffsetInModule{};
+  void set_code_offset_in_module(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CodeOffsetInModule::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_InstructionStart =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      V8WasmCode>;
+
+  static constexpr FieldMetadata_InstructionStart kInstructionStart{};
+  void set_instruction_start(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InstructionStart::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_InstructionSizeBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      V8WasmCode>;
+
+  static constexpr FieldMetadata_InstructionSizeBytes kInstructionSizeBytes{};
+  void set_instruction_size_bytes(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InstructionSizeBytes::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_MachineCode =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      V8WasmCode>;
+
+  static constexpr FieldMetadata_MachineCode kMachineCode{};
+  void set_machine_code(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_MachineCode::kFieldId, data, size);
+  }
+  void set_machine_code(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_MachineCode::kFieldId, bytes.data, bytes.size);
+  }
+  void set_machine_code(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_MachineCode::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 V8InternalCode_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  V8InternalCode_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit V8InternalCode_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit V8InternalCode_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_v8_isolate_iid() const { return at<1>().valid(); }
+  uint64_t v8_isolate_iid() const { return at<1>().as_uint64(); }
+  bool has_tid() const { return at<2>().valid(); }
+  uint32_t tid() const { return at<2>().as_uint32(); }
+  bool has_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars name() const { return at<3>().as_string(); }
+  bool has_type() const { return at<4>().valid(); }
+  int32_t type() const { return at<4>().as_int32(); }
+  bool has_builtin_id() const { return at<5>().valid(); }
+  int32_t builtin_id() const { return at<5>().as_int32(); }
+  bool has_instruction_start() const { return at<6>().valid(); }
+  uint64_t instruction_start() const { return at<6>().as_uint64(); }
+  bool has_instruction_size_bytes() const { return at<7>().valid(); }
+  uint64_t instruction_size_bytes() const { return at<7>().as_uint64(); }
+  bool has_machine_code() const { return at<8>().valid(); }
+  ::protozero::ConstBytes machine_code() const { return at<8>().as_bytes(); }
+};
+
+class V8InternalCode : public ::protozero::Message {
+ public:
+  using Decoder = V8InternalCode_Decoder;
+  enum : int32_t {
+    kV8IsolateIidFieldNumber = 1,
+    kTidFieldNumber = 2,
+    kNameFieldNumber = 3,
+    kTypeFieldNumber = 4,
+    kBuiltinIdFieldNumber = 5,
+    kInstructionStartFieldNumber = 6,
+    kInstructionSizeBytesFieldNumber = 7,
+    kMachineCodeFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.V8InternalCode"; }
+
+
+  using Type = ::perfetto::protos::pbzero::V8InternalCode_Type;
+  static inline const char* Type_Name(Type value) {
+    return ::perfetto::protos::pbzero::V8InternalCode_Type_Name(value);
+  }
+  static inline const Type TYPE_UNKNOWN = Type::TYPE_UNKNOWN;
+  static inline const Type TYPE_BYTECODE_HANDLER = Type::TYPE_BYTECODE_HANDLER;
+  static inline const Type TYPE_FOR_TESTING = Type::TYPE_FOR_TESTING;
+  static inline const Type TYPE_BUILTIN = Type::TYPE_BUILTIN;
+  static inline const Type TYPE_WASM_FUNCTION = Type::TYPE_WASM_FUNCTION;
+  static inline const Type TYPE_WASM_TO_CAPI_FUNCTION = Type::TYPE_WASM_TO_CAPI_FUNCTION;
+  static inline const Type TYPE_WASM_TO_JS_FUNCTION = Type::TYPE_WASM_TO_JS_FUNCTION;
+  static inline const Type TYPE_JS_TO_WASM_FUNCTION = Type::TYPE_JS_TO_WASM_FUNCTION;
+  static inline const Type TYPE_JS_TO_JS_FUNCTION = Type::TYPE_JS_TO_JS_FUNCTION;
+  static inline const Type TYPE_C_WASM_ENTRY = Type::TYPE_C_WASM_ENTRY;
+
+  using FieldMetadata_V8IsolateIid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      V8InternalCode>;
+
+  static constexpr FieldMetadata_V8IsolateIid kV8IsolateIid{};
+  void set_v8_isolate_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_V8IsolateIid::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_Tid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V8InternalCode>;
+
+  static constexpr FieldMetadata_Tid kTid{};
+  void set_tid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tid::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      V8InternalCode>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      V8InternalCode_Type,
+      V8InternalCode>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(V8InternalCode_Type value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::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_BuiltinId =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      V8InternalCode>;
+
+  static constexpr FieldMetadata_BuiltinId kBuiltinId{};
+  void set_builtin_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BuiltinId::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_InstructionStart =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      V8InternalCode>;
+
+  static constexpr FieldMetadata_InstructionStart kInstructionStart{};
+  void set_instruction_start(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InstructionStart::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_InstructionSizeBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      V8InternalCode>;
+
+  static constexpr FieldMetadata_InstructionSizeBytes kInstructionSizeBytes{};
+  void set_instruction_size_bytes(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InstructionSizeBytes::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_MachineCode =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      V8InternalCode>;
+
+  static constexpr FieldMetadata_MachineCode kMachineCode{};
+  void set_machine_code(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_MachineCode::kFieldId, data, size);
+  }
+  void set_machine_code(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_MachineCode::kFieldId, bytes.data, bytes.size);
+  }
+  void set_machine_code(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_MachineCode::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 V8JsCode_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  V8JsCode_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit V8JsCode_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit V8JsCode_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_v8_isolate_iid() const { return at<1>().valid(); }
+  uint64_t v8_isolate_iid() const { return at<1>().as_uint64(); }
+  bool has_tid() const { return at<2>().valid(); }
+  uint32_t tid() const { return at<2>().as_uint32(); }
+  bool has_v8_js_function_iid() const { return at<3>().valid(); }
+  uint64_t v8_js_function_iid() const { return at<3>().as_uint64(); }
+  bool has_tier() const { return at<4>().valid(); }
+  int32_t tier() const { return at<4>().as_int32(); }
+  bool has_instruction_start() const { return at<5>().valid(); }
+  uint64_t instruction_start() const { return at<5>().as_uint64(); }
+  bool has_instruction_size_bytes() const { return at<6>().valid(); }
+  uint64_t instruction_size_bytes() const { return at<6>().as_uint64(); }
+  bool has_machine_code() const { return at<7>().valid(); }
+  ::protozero::ConstBytes machine_code() const { return at<7>().as_bytes(); }
+  bool has_bytecode() const { return at<8>().valid(); }
+  ::protozero::ConstBytes bytecode() const { return at<8>().as_bytes(); }
+};
+
+class V8JsCode : public ::protozero::Message {
+ public:
+  using Decoder = V8JsCode_Decoder;
+  enum : int32_t {
+    kV8IsolateIidFieldNumber = 1,
+    kTidFieldNumber = 2,
+    kV8JsFunctionIidFieldNumber = 3,
+    kTierFieldNumber = 4,
+    kInstructionStartFieldNumber = 5,
+    kInstructionSizeBytesFieldNumber = 6,
+    kMachineCodeFieldNumber = 7,
+    kBytecodeFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.V8JsCode"; }
+
+
+  using Tier = ::perfetto::protos::pbzero::V8JsCode_Tier;
+  static inline const char* Tier_Name(Tier value) {
+    return ::perfetto::protos::pbzero::V8JsCode_Tier_Name(value);
+  }
+  static inline const Tier TIER_UNKNOWN = Tier::TIER_UNKNOWN;
+  static inline const Tier TIER_IGNITION = Tier::TIER_IGNITION;
+  static inline const Tier TIER_SPARKPLUG = Tier::TIER_SPARKPLUG;
+  static inline const Tier TIER_MAGLEV = Tier::TIER_MAGLEV;
+  static inline const Tier TIER_TURBOSHAFT = Tier::TIER_TURBOSHAFT;
+  static inline const Tier TIER_TURBOFAN = Tier::TIER_TURBOFAN;
+
+  using FieldMetadata_V8IsolateIid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      V8JsCode>;
+
+  static constexpr FieldMetadata_V8IsolateIid kV8IsolateIid{};
+  void set_v8_isolate_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_V8IsolateIid::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_Tid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V8JsCode>;
+
+  static constexpr FieldMetadata_Tid kTid{};
+  void set_tid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tid::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_V8JsFunctionIid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      V8JsCode>;
+
+  static constexpr FieldMetadata_V8JsFunctionIid kV8JsFunctionIid{};
+  void set_v8_js_function_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_V8JsFunctionIid::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_Tier =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      V8JsCode_Tier,
+      V8JsCode>;
+
+  static constexpr FieldMetadata_Tier kTier{};
+  void set_tier(V8JsCode_Tier value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tier::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_InstructionStart =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      V8JsCode>;
+
+  static constexpr FieldMetadata_InstructionStart kInstructionStart{};
+  void set_instruction_start(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InstructionStart::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_InstructionSizeBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      V8JsCode>;
+
+  static constexpr FieldMetadata_InstructionSizeBytes kInstructionSizeBytes{};
+  void set_instruction_size_bytes(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InstructionSizeBytes::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_MachineCode =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      V8JsCode>;
+
+  static constexpr FieldMetadata_MachineCode kMachineCode{};
+  void set_machine_code(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_MachineCode::kFieldId, data, size);
+  }
+  void set_machine_code(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_MachineCode::kFieldId, bytes.data, bytes.size);
+  }
+  void set_machine_code(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_MachineCode::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);
+  }
+
+  using FieldMetadata_Bytecode =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      V8JsCode>;
+
+  static constexpr FieldMetadata_Bytecode kBytecode{};
+  void set_bytecode(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_Bytecode::kFieldId, data, size);
+  }
+  void set_bytecode(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_Bytecode::kFieldId, bytes.data, bytes.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 InternedV8Isolate_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  InternedV8Isolate_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit InternedV8Isolate_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit InternedV8Isolate_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_pid() const { return at<2>().valid(); }
+  uint32_t pid() const { return at<2>().as_uint32(); }
+  bool has_isolate_id() const { return at<3>().valid(); }
+  int32_t isolate_id() const { return at<3>().as_int32(); }
+  bool has_code_range() const { return at<4>().valid(); }
+  ::protozero::ConstBytes code_range() const { return at<4>().as_bytes(); }
+  bool has_embedded_blob_code_start_address() const { return at<5>().valid(); }
+  uint64_t embedded_blob_code_start_address() const { return at<5>().as_uint64(); }
+  bool has_embedded_blob_code_size() const { return at<6>().valid(); }
+  uint64_t embedded_blob_code_size() const { return at<6>().as_uint64(); }
+};
+
+class InternedV8Isolate : public ::protozero::Message {
+ public:
+  using Decoder = InternedV8Isolate_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kIsolateIdFieldNumber = 3,
+    kCodeRangeFieldNumber = 4,
+    kEmbeddedBlobCodeStartAddressFieldNumber = 5,
+    kEmbeddedBlobCodeSizeFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.InternedV8Isolate"; }
+
+  using CodeRange = ::perfetto::protos::pbzero::InternedV8Isolate_CodeRange;
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      InternedV8Isolate>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      InternedV8Isolate>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_IsolateId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      InternedV8Isolate>;
+
+  static constexpr FieldMetadata_IsolateId kIsolateId{};
+  void set_isolate_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsolateId::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_CodeRange =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InternedV8Isolate_CodeRange,
+      InternedV8Isolate>;
+
+  static constexpr FieldMetadata_CodeRange kCodeRange{};
+  template <typename T = InternedV8Isolate_CodeRange> T* set_code_range() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_EmbeddedBlobCodeStartAddress =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      InternedV8Isolate>;
+
+  static constexpr FieldMetadata_EmbeddedBlobCodeStartAddress kEmbeddedBlobCodeStartAddress{};
+  void set_embedded_blob_code_start_address(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EmbeddedBlobCodeStartAddress::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_EmbeddedBlobCodeSize =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      InternedV8Isolate>;
+
+  static constexpr FieldMetadata_EmbeddedBlobCodeSize kEmbeddedBlobCodeSize{};
+  void set_embedded_blob_code_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EmbeddedBlobCodeSize::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 InternedV8Isolate_CodeRange_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  InternedV8Isolate_CodeRange_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit InternedV8Isolate_CodeRange_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit InternedV8Isolate_CodeRange_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_base_address() const { return at<1>().valid(); }
+  uint64_t base_address() const { return at<1>().as_uint64(); }
+  bool has_size() const { return at<2>().valid(); }
+  uint64_t size() const { return at<2>().as_uint64(); }
+  bool has_embedded_blob_code_copy_start_address() const { return at<3>().valid(); }
+  uint64_t embedded_blob_code_copy_start_address() const { return at<3>().as_uint64(); }
+  bool has_is_process_wide() const { return at<4>().valid(); }
+  bool is_process_wide() const { return at<4>().as_bool(); }
+};
+
+class InternedV8Isolate_CodeRange : public ::protozero::Message {
+ public:
+  using Decoder = InternedV8Isolate_CodeRange_Decoder;
+  enum : int32_t {
+    kBaseAddressFieldNumber = 1,
+    kSizeFieldNumber = 2,
+    kEmbeddedBlobCodeCopyStartAddressFieldNumber = 3,
+    kIsProcessWideFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.InternedV8Isolate.CodeRange"; }
+
+
+  using FieldMetadata_BaseAddress =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      InternedV8Isolate_CodeRange>;
+
+  static constexpr FieldMetadata_BaseAddress kBaseAddress{};
+  void set_base_address(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BaseAddress::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_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      InternedV8Isolate_CodeRange>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void set_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::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_EmbeddedBlobCodeCopyStartAddress =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      InternedV8Isolate_CodeRange>;
+
+  static constexpr FieldMetadata_EmbeddedBlobCodeCopyStartAddress kEmbeddedBlobCodeCopyStartAddress{};
+  void set_embedded_blob_code_copy_start_address(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EmbeddedBlobCodeCopyStartAddress::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_IsProcessWide =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      InternedV8Isolate_CodeRange>;
+
+  static constexpr FieldMetadata_IsProcessWide kIsProcessWide{};
+  void set_is_process_wide(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsProcessWide::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 InternedV8JsFunction_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  InternedV8JsFunction_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit InternedV8JsFunction_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit InternedV8JsFunction_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_v8_js_function_name_iid() const { return at<2>().valid(); }
+  uint64_t v8_js_function_name_iid() const { return at<2>().as_uint64(); }
+  bool has_v8_js_script_iid() const { return at<3>().valid(); }
+  uint64_t v8_js_script_iid() const { return at<3>().as_uint64(); }
+  bool has_is_toplevel() const { return at<4>().valid(); }
+  bool is_toplevel() const { return at<4>().as_bool(); }
+  bool has_kind() const { return at<5>().valid(); }
+  int32_t kind() const { return at<5>().as_int32(); }
+  bool has_byte_offset() const { return at<6>().valid(); }
+  uint32_t byte_offset() const { return at<6>().as_uint32(); }
+};
+
+class InternedV8JsFunction : public ::protozero::Message {
+ public:
+  using Decoder = InternedV8JsFunction_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kV8JsFunctionNameIidFieldNumber = 2,
+    kV8JsScriptIidFieldNumber = 3,
+    kIsToplevelFieldNumber = 4,
+    kKindFieldNumber = 5,
+    kByteOffsetFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.InternedV8JsFunction"; }
+
+
+  using Kind = ::perfetto::protos::pbzero::InternedV8JsFunction_Kind;
+  static inline const char* Kind_Name(Kind value) {
+    return ::perfetto::protos::pbzero::InternedV8JsFunction_Kind_Name(value);
+  }
+  static inline const Kind KIND_UNKNOWN = Kind::KIND_UNKNOWN;
+  static inline const Kind KIND_NORMAL_FUNCTION = Kind::KIND_NORMAL_FUNCTION;
+  static inline const Kind KIND_MODULE = Kind::KIND_MODULE;
+  static inline const Kind KIND_ASYNC_MODULE = Kind::KIND_ASYNC_MODULE;
+  static inline const Kind KIND_BASE_CONSTRUCTOR = Kind::KIND_BASE_CONSTRUCTOR;
+  static inline const Kind KIND_DEFAULT_BASE_CONSTRUCTOR = Kind::KIND_DEFAULT_BASE_CONSTRUCTOR;
+  static inline const Kind KIND_DEFAULT_DERIVED_CONSTRUCTOR = Kind::KIND_DEFAULT_DERIVED_CONSTRUCTOR;
+  static inline const Kind KIND_DERIVED_CONSTRUCTOR = Kind::KIND_DERIVED_CONSTRUCTOR;
+  static inline const Kind KIND_GETTER_FUNCTION = Kind::KIND_GETTER_FUNCTION;
+  static inline const Kind KIND_STATIC_GETTER_FUNCTION = Kind::KIND_STATIC_GETTER_FUNCTION;
+  static inline const Kind KIND_SETTER_FUNCTION = Kind::KIND_SETTER_FUNCTION;
+  static inline const Kind KIND_STATIC_SETTER_FUNCTION = Kind::KIND_STATIC_SETTER_FUNCTION;
+  static inline const Kind KIND_ARROW_FUNCTION = Kind::KIND_ARROW_FUNCTION;
+  static inline const Kind KIND_ASYNC_ARROW_FUNCTION = Kind::KIND_ASYNC_ARROW_FUNCTION;
+  static inline const Kind KIND_ASYNC_FUNCTION = Kind::KIND_ASYNC_FUNCTION;
+  static inline const Kind KIND_ASYNC_CONCISE_METHOD = Kind::KIND_ASYNC_CONCISE_METHOD;
+  static inline const Kind KIND_STATIC_ASYNC_CONCISE_METHOD = Kind::KIND_STATIC_ASYNC_CONCISE_METHOD;
+  static inline const Kind KIND_ASYNC_CONCISE_GENERATOR_METHOD = Kind::KIND_ASYNC_CONCISE_GENERATOR_METHOD;
+  static inline const Kind KIND_STATIC_ASYNC_CONCISE_GENERATOR_METHOD = Kind::KIND_STATIC_ASYNC_CONCISE_GENERATOR_METHOD;
+  static inline const Kind KIND_ASYNC_GENERATOR_FUNCTION = Kind::KIND_ASYNC_GENERATOR_FUNCTION;
+  static inline const Kind KIND_GENERATOR_FUNCTION = Kind::KIND_GENERATOR_FUNCTION;
+  static inline const Kind KIND_CONCISE_GENERATOR_METHOD = Kind::KIND_CONCISE_GENERATOR_METHOD;
+  static inline const Kind KIND_STATIC_CONCISE_GENERATOR_METHOD = Kind::KIND_STATIC_CONCISE_GENERATOR_METHOD;
+  static inline const Kind KIND_CONCISE_METHOD = Kind::KIND_CONCISE_METHOD;
+  static inline const Kind KIND_STATIC_CONCISE_METHOD = Kind::KIND_STATIC_CONCISE_METHOD;
+  static inline const Kind KIND_CLASS_MEMBERS_INITIALIZER_FUNCTION = Kind::KIND_CLASS_MEMBERS_INITIALIZER_FUNCTION;
+  static inline const Kind KIND_CLASS_STATIC_INITIALIZER_FUNCTION = Kind::KIND_CLASS_STATIC_INITIALIZER_FUNCTION;
+  static inline const Kind KIND_INVALID = Kind::KIND_INVALID;
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      InternedV8JsFunction>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::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_V8JsFunctionNameIid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      InternedV8JsFunction>;
+
+  static constexpr FieldMetadata_V8JsFunctionNameIid kV8JsFunctionNameIid{};
+  void set_v8_js_function_name_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_V8JsFunctionNameIid::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_V8JsScriptIid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      InternedV8JsFunction>;
+
+  static constexpr FieldMetadata_V8JsScriptIid kV8JsScriptIid{};
+  void set_v8_js_script_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_V8JsScriptIid::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_IsToplevel =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      InternedV8JsFunction>;
+
+  static constexpr FieldMetadata_IsToplevel kIsToplevel{};
+  void set_is_toplevel(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsToplevel::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_Kind =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      InternedV8JsFunction_Kind,
+      InternedV8JsFunction>;
+
+  static constexpr FieldMetadata_Kind kKind{};
+  void set_kind(InternedV8JsFunction_Kind value) {
+    static constexpr uint32_t field_id = FieldMetadata_Kind::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_ByteOffset =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      InternedV8JsFunction>;
+
+  static constexpr FieldMetadata_ByteOffset kByteOffset{};
+  void set_byte_offset(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ByteOffset::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 InternedV8WasmScript_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  InternedV8WasmScript_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit InternedV8WasmScript_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit InternedV8WasmScript_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_script_id() const { return at<2>().valid(); }
+  int32_t script_id() const { return at<2>().as_int32(); }
+  bool has_url() const { return at<3>().valid(); }
+  ::protozero::ConstChars url() const { return at<3>().as_string(); }
+};
+
+class InternedV8WasmScript : public ::protozero::Message {
+ public:
+  using Decoder = InternedV8WasmScript_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kScriptIdFieldNumber = 2,
+    kUrlFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.InternedV8WasmScript"; }
+
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      InternedV8WasmScript>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::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_ScriptId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      InternedV8WasmScript>;
+
+  static constexpr FieldMetadata_ScriptId kScriptId{};
+  void set_script_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ScriptId::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_Url =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      InternedV8WasmScript>;
+
+  static constexpr FieldMetadata_Url kUrl{};
+  void set_url(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Url::kFieldId, data, size);
+  }
+  void set_url(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Url::kFieldId, chars.data, chars.size);
+  }
+  void set_url(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Url::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 InternedV8JsScript_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  InternedV8JsScript_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit InternedV8JsScript_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit InternedV8JsScript_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_script_id() const { return at<2>().valid(); }
+  int32_t script_id() const { return at<2>().as_int32(); }
+  bool has_type() const { return at<3>().valid(); }
+  int32_t type() const { return at<3>().as_int32(); }
+  bool has_name() const { return at<4>().valid(); }
+  ::protozero::ConstBytes name() const { return at<4>().as_bytes(); }
+  bool has_source() const { return at<5>().valid(); }
+  ::protozero::ConstBytes source() const { return at<5>().as_bytes(); }
+};
+
+class InternedV8JsScript : public ::protozero::Message {
+ public:
+  using Decoder = InternedV8JsScript_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kScriptIdFieldNumber = 2,
+    kTypeFieldNumber = 3,
+    kNameFieldNumber = 4,
+    kSourceFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.InternedV8JsScript"; }
+
+
+  using Type = ::perfetto::protos::pbzero::InternedV8JsScript_Type;
+  static inline const char* Type_Name(Type value) {
+    return ::perfetto::protos::pbzero::InternedV8JsScript_Type_Name(value);
+  }
+  static inline const Type TYPE_UNKNOWN = Type::TYPE_UNKNOWN;
+  static inline const Type TYPE_NORMAL = Type::TYPE_NORMAL;
+  static inline const Type TYPE_EVAL = Type::TYPE_EVAL;
+  static inline const Type TYPE_MODULE = Type::TYPE_MODULE;
+  static inline const Type TYPE_NATIVE = Type::TYPE_NATIVE;
+  static inline const Type TYPE_EXTENSION = Type::TYPE_EXTENSION;
+  static inline const Type TYPE_INSPECTOR = Type::TYPE_INSPECTOR;
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      InternedV8JsScript>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::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_ScriptId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      InternedV8JsScript>;
+
+  static constexpr FieldMetadata_ScriptId kScriptId{};
+  void set_script_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ScriptId::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_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      InternedV8JsScript_Type,
+      InternedV8JsScript>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(InternedV8JsScript_Type value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      V8String,
+      InternedV8JsScript>;
+
+  static constexpr FieldMetadata_Name kName{};
+  template <typename T = V8String> T* set_name() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_Source =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      V8String,
+      InternedV8JsScript>;
+
+  static constexpr FieldMetadata_Source kSource{};
+  template <typename T = V8String> T* set_source() {
+    return BeginNestedMessage<T>(5);
+  }
+
+};
+
+class InternedV8String_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  InternedV8String_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit InternedV8String_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit InternedV8String_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_latin1() const { return at<2>().valid(); }
+  ::protozero::ConstBytes latin1() const { return at<2>().as_bytes(); }
+  bool has_utf16_le() const { return at<3>().valid(); }
+  ::protozero::ConstBytes utf16_le() const { return at<3>().as_bytes(); }
+  bool has_utf16_be() const { return at<4>().valid(); }
+  ::protozero::ConstBytes utf16_be() const { return at<4>().as_bytes(); }
+};
+
+class InternedV8String : public ::protozero::Message {
+ public:
+  using Decoder = InternedV8String_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kLatin1FieldNumber = 2,
+    kUtf16LeFieldNumber = 3,
+    kUtf16BeFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.InternedV8String"; }
+
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      InternedV8String>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::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_Latin1 =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      InternedV8String>;
+
+  static constexpr FieldMetadata_Latin1 kLatin1{};
+  void set_latin1(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_Latin1::kFieldId, data, size);
+  }
+  void set_latin1(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_Latin1::kFieldId, bytes.data, bytes.size);
+  }
+  void set_latin1(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Latin1::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);
+  }
+
+  using FieldMetadata_Utf16Le =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      InternedV8String>;
+
+  static constexpr FieldMetadata_Utf16Le kUtf16Le{};
+  void set_utf16_le(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_Utf16Le::kFieldId, data, size);
+  }
+  void set_utf16_le(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_Utf16Le::kFieldId, bytes.data, bytes.size);
+  }
+  void set_utf16_le(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Utf16Le::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);
+  }
+
+  using FieldMetadata_Utf16Be =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      InternedV8String>;
+
+  static constexpr FieldMetadata_Utf16Be kUtf16Be{};
+  void set_utf16_be(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_Utf16Be::kFieldId, data, size);
+  }
+  void set_utf16_be(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_Utf16Be::kFieldId, bytes.data, bytes.size);
+  }
+  void set_utf16_be(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Utf16Be::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 V8String_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  V8String_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit V8String_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit V8String_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_latin1() const { return at<1>().valid(); }
+  ::protozero::ConstBytes latin1() const { return at<1>().as_bytes(); }
+  bool has_utf16_le() const { return at<2>().valid(); }
+  ::protozero::ConstBytes utf16_le() const { return at<2>().as_bytes(); }
+  bool has_utf16_be() const { return at<3>().valid(); }
+  ::protozero::ConstBytes utf16_be() const { return at<3>().as_bytes(); }
+};
+
+class V8String : public ::protozero::Message {
+ public:
+  using Decoder = V8String_Decoder;
+  enum : int32_t {
+    kLatin1FieldNumber = 1,
+    kUtf16LeFieldNumber = 2,
+    kUtf16BeFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.V8String"; }
+
+
+  using FieldMetadata_Latin1 =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      V8String>;
+
+  static constexpr FieldMetadata_Latin1 kLatin1{};
+  void set_latin1(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_Latin1::kFieldId, data, size);
+  }
+  void set_latin1(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_Latin1::kFieldId, bytes.data, bytes.size);
+  }
+  void set_latin1(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Latin1::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);
+  }
+
+  using FieldMetadata_Utf16Le =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      V8String>;
+
+  static constexpr FieldMetadata_Utf16Le kUtf16Le{};
+  void set_utf16_le(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_Utf16Le::kFieldId, data, size);
+  }
+  void set_utf16_le(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_Utf16Le::kFieldId, bytes.data, bytes.size);
+  }
+  void set_utf16_le(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Utf16Le::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);
+  }
+
+  using FieldMetadata_Utf16Be =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      V8String>;
+
+  static constexpr FieldMetadata_Utf16Be kUtf16Be{};
+  void set_utf16_be(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_Utf16Be::kFieldId, data, size);
+  }
+  void set_utf16_be(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_Utf16Be::kFieldId, bytes.data, bytes.size);
+  }
+  void set_utf16_be(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Utf16Be::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/etw/etw.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ETW_ETW_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ETW_ETW_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+namespace perfetto_pbzero_enum_CSwitchEtwEvent {
+enum OldThreadState : int32_t;
+}  // namespace perfetto_pbzero_enum_CSwitchEtwEvent
+using CSwitchEtwEvent_OldThreadState = perfetto_pbzero_enum_CSwitchEtwEvent::OldThreadState;
+namespace perfetto_pbzero_enum_CSwitchEtwEvent {
+enum OldThreadWaitMode : int32_t;
+}  // namespace perfetto_pbzero_enum_CSwitchEtwEvent
+using CSwitchEtwEvent_OldThreadWaitMode = perfetto_pbzero_enum_CSwitchEtwEvent::OldThreadWaitMode;
+namespace perfetto_pbzero_enum_CSwitchEtwEvent {
+enum OldThreadWaitReason : int32_t;
+}  // namespace perfetto_pbzero_enum_CSwitchEtwEvent
+using CSwitchEtwEvent_OldThreadWaitReason = perfetto_pbzero_enum_CSwitchEtwEvent::OldThreadWaitReason;
+namespace perfetto_pbzero_enum_ReadyThreadEtwEvent {
+enum AdjustReason : int32_t;
+}  // namespace perfetto_pbzero_enum_ReadyThreadEtwEvent
+using ReadyThreadEtwEvent_AdjustReason = perfetto_pbzero_enum_ReadyThreadEtwEvent::AdjustReason;
+namespace perfetto_pbzero_enum_ReadyThreadEtwEvent {
+enum TraceFlag : int32_t;
+}  // namespace perfetto_pbzero_enum_ReadyThreadEtwEvent
+using ReadyThreadEtwEvent_TraceFlag = perfetto_pbzero_enum_ReadyThreadEtwEvent::TraceFlag;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_ReadyThreadEtwEvent {
+enum AdjustReason : int32_t {
+  IGNORE_THE_INCREMENT = 0,
+  APPLY_INCREMENT = 1,
+  APPLY_INCREMENT_BOOST = 2,
+};
+} // namespace perfetto_pbzero_enum_ReadyThreadEtwEvent
+using ReadyThreadEtwEvent_AdjustReason = perfetto_pbzero_enum_ReadyThreadEtwEvent::AdjustReason;
+
+
+constexpr ReadyThreadEtwEvent_AdjustReason ReadyThreadEtwEvent_AdjustReason_MIN = ReadyThreadEtwEvent_AdjustReason::IGNORE_THE_INCREMENT;
+constexpr ReadyThreadEtwEvent_AdjustReason ReadyThreadEtwEvent_AdjustReason_MAX = ReadyThreadEtwEvent_AdjustReason::APPLY_INCREMENT_BOOST;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ReadyThreadEtwEvent_AdjustReason_Name(::perfetto::protos::pbzero::ReadyThreadEtwEvent_AdjustReason value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ReadyThreadEtwEvent_AdjustReason::IGNORE_THE_INCREMENT:
+    return "IGNORE_THE_INCREMENT";
+
+  case ::perfetto::protos::pbzero::ReadyThreadEtwEvent_AdjustReason::APPLY_INCREMENT:
+    return "APPLY_INCREMENT";
+
+  case ::perfetto::protos::pbzero::ReadyThreadEtwEvent_AdjustReason::APPLY_INCREMENT_BOOST:
+    return "APPLY_INCREMENT_BOOST";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_ReadyThreadEtwEvent {
+enum TraceFlag : int32_t {
+  TRACE_FLAG_UNSPECIFIED = 0,
+  THREAD_READIED = 1,
+  KERNEL_STACK_SWAPPED_OUT = 2,
+  PROCESS_ADDRESS_SWAPPED_OUT = 4,
+};
+} // namespace perfetto_pbzero_enum_ReadyThreadEtwEvent
+using ReadyThreadEtwEvent_TraceFlag = perfetto_pbzero_enum_ReadyThreadEtwEvent::TraceFlag;
+
+
+constexpr ReadyThreadEtwEvent_TraceFlag ReadyThreadEtwEvent_TraceFlag_MIN = ReadyThreadEtwEvent_TraceFlag::TRACE_FLAG_UNSPECIFIED;
+constexpr ReadyThreadEtwEvent_TraceFlag ReadyThreadEtwEvent_TraceFlag_MAX = ReadyThreadEtwEvent_TraceFlag::PROCESS_ADDRESS_SWAPPED_OUT;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ReadyThreadEtwEvent_TraceFlag_Name(::perfetto::protos::pbzero::ReadyThreadEtwEvent_TraceFlag value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ReadyThreadEtwEvent_TraceFlag::TRACE_FLAG_UNSPECIFIED:
+    return "TRACE_FLAG_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ReadyThreadEtwEvent_TraceFlag::THREAD_READIED:
+    return "THREAD_READIED";
+
+  case ::perfetto::protos::pbzero::ReadyThreadEtwEvent_TraceFlag::KERNEL_STACK_SWAPPED_OUT:
+    return "KERNEL_STACK_SWAPPED_OUT";
+
+  case ::perfetto::protos::pbzero::ReadyThreadEtwEvent_TraceFlag::PROCESS_ADDRESS_SWAPPED_OUT:
+    return "PROCESS_ADDRESS_SWAPPED_OUT";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_CSwitchEtwEvent {
+enum OldThreadWaitReason : int32_t {
+  EXECUTIVE = 0,
+  FREE_PAGE = 1,
+  PAGE_IN = 2,
+  POOL_ALLOCATION = 3,
+  DELAY_EXECUTION = 4,
+  SUSPEND = 5,
+  USER_REQUEST = 6,
+  WR_EXECUTIVE = 7,
+  WR_FREE_PAGE = 8,
+  WR_PAGE_IN = 9,
+  WR_POOL_ALLOCATION = 10,
+  WR_DELAY_EXECUTION = 11,
+  WR_SUSPENDED = 12,
+  WR_USER_REQUEST = 13,
+  WR_EVENT_PAIR = 14,
+  WR_QUEUE = 15,
+  WR_LPC_RECEIVER = 16,
+  WR_LPC_REPLY = 17,
+  WR_VIRTUAL_MEMORY = 18,
+  WR_PAGE_OUT = 19,
+  WR_RENDEZ_VOUS = 20,
+  WR_KEYED_EVENT = 21,
+  WR_TERMINATED = 22,
+  WR_PROCESS_IN_SWAP = 23,
+  WR_CPU_RATE_CONTROL = 24,
+  WR_CALLOUT_STACK = 25,
+  WR_KERNEL = 26,
+  WR_RESOURCE = 27,
+  WR_PUSH_LOCK = 28,
+  WR_MUTEX = 29,
+  WR_QUANTUM_END = 30,
+  WR_DISPATCH_INT = 31,
+  WR_PREEMPTED = 32,
+  WR_YIELD_EXECUTION = 33,
+  WR_FAST_MUTEX = 34,
+  WR_GUARD_MUTEX = 35,
+  WR_RUNDOWN = 36,
+  MAXIMUM_WAIT_REASON = 37,
+};
+} // namespace perfetto_pbzero_enum_CSwitchEtwEvent
+using CSwitchEtwEvent_OldThreadWaitReason = perfetto_pbzero_enum_CSwitchEtwEvent::OldThreadWaitReason;
+
+
+constexpr CSwitchEtwEvent_OldThreadWaitReason CSwitchEtwEvent_OldThreadWaitReason_MIN = CSwitchEtwEvent_OldThreadWaitReason::EXECUTIVE;
+constexpr CSwitchEtwEvent_OldThreadWaitReason CSwitchEtwEvent_OldThreadWaitReason_MAX = CSwitchEtwEvent_OldThreadWaitReason::MAXIMUM_WAIT_REASON;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* CSwitchEtwEvent_OldThreadWaitReason_Name(::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::EXECUTIVE:
+    return "EXECUTIVE";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::FREE_PAGE:
+    return "FREE_PAGE";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::PAGE_IN:
+    return "PAGE_IN";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::POOL_ALLOCATION:
+    return "POOL_ALLOCATION";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::DELAY_EXECUTION:
+    return "DELAY_EXECUTION";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::SUSPEND:
+    return "SUSPEND";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::USER_REQUEST:
+    return "USER_REQUEST";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_EXECUTIVE:
+    return "WR_EXECUTIVE";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_FREE_PAGE:
+    return "WR_FREE_PAGE";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_PAGE_IN:
+    return "WR_PAGE_IN";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_POOL_ALLOCATION:
+    return "WR_POOL_ALLOCATION";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_DELAY_EXECUTION:
+    return "WR_DELAY_EXECUTION";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_SUSPENDED:
+    return "WR_SUSPENDED";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_USER_REQUEST:
+    return "WR_USER_REQUEST";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_EVENT_PAIR:
+    return "WR_EVENT_PAIR";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_QUEUE:
+    return "WR_QUEUE";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_LPC_RECEIVER:
+    return "WR_LPC_RECEIVER";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_LPC_REPLY:
+    return "WR_LPC_REPLY";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_VIRTUAL_MEMORY:
+    return "WR_VIRTUAL_MEMORY";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_PAGE_OUT:
+    return "WR_PAGE_OUT";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_RENDEZ_VOUS:
+    return "WR_RENDEZ_VOUS";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_KEYED_EVENT:
+    return "WR_KEYED_EVENT";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_TERMINATED:
+    return "WR_TERMINATED";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_PROCESS_IN_SWAP:
+    return "WR_PROCESS_IN_SWAP";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_CPU_RATE_CONTROL:
+    return "WR_CPU_RATE_CONTROL";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_CALLOUT_STACK:
+    return "WR_CALLOUT_STACK";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_KERNEL:
+    return "WR_KERNEL";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_RESOURCE:
+    return "WR_RESOURCE";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_PUSH_LOCK:
+    return "WR_PUSH_LOCK";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_MUTEX:
+    return "WR_MUTEX";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_QUANTUM_END:
+    return "WR_QUANTUM_END";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_DISPATCH_INT:
+    return "WR_DISPATCH_INT";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_PREEMPTED:
+    return "WR_PREEMPTED";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_YIELD_EXECUTION:
+    return "WR_YIELD_EXECUTION";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_FAST_MUTEX:
+    return "WR_FAST_MUTEX";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_GUARD_MUTEX:
+    return "WR_GUARD_MUTEX";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_RUNDOWN:
+    return "WR_RUNDOWN";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::MAXIMUM_WAIT_REASON:
+    return "MAXIMUM_WAIT_REASON";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_CSwitchEtwEvent {
+enum OldThreadWaitMode : int32_t {
+  KERNEL_MODE = 0,
+  USER_MODE = 1,
+};
+} // namespace perfetto_pbzero_enum_CSwitchEtwEvent
+using CSwitchEtwEvent_OldThreadWaitMode = perfetto_pbzero_enum_CSwitchEtwEvent::OldThreadWaitMode;
+
+
+constexpr CSwitchEtwEvent_OldThreadWaitMode CSwitchEtwEvent_OldThreadWaitMode_MIN = CSwitchEtwEvent_OldThreadWaitMode::KERNEL_MODE;
+constexpr CSwitchEtwEvent_OldThreadWaitMode CSwitchEtwEvent_OldThreadWaitMode_MAX = CSwitchEtwEvent_OldThreadWaitMode::USER_MODE;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* CSwitchEtwEvent_OldThreadWaitMode_Name(::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitMode value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitMode::KERNEL_MODE:
+    return "KERNEL_MODE";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitMode::USER_MODE:
+    return "USER_MODE";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_CSwitchEtwEvent {
+enum OldThreadState : int32_t {
+  INITIALIZED = 0,
+  READY = 1,
+  RUNNING = 2,
+  STANDBY = 3,
+  TERMINATED = 4,
+  WAITING = 5,
+  TRANSITION = 6,
+  DEFERRED_READY = 7,
+};
+} // namespace perfetto_pbzero_enum_CSwitchEtwEvent
+using CSwitchEtwEvent_OldThreadState = perfetto_pbzero_enum_CSwitchEtwEvent::OldThreadState;
+
+
+constexpr CSwitchEtwEvent_OldThreadState CSwitchEtwEvent_OldThreadState_MIN = CSwitchEtwEvent_OldThreadState::INITIALIZED;
+constexpr CSwitchEtwEvent_OldThreadState CSwitchEtwEvent_OldThreadState_MAX = CSwitchEtwEvent_OldThreadState::DEFERRED_READY;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* CSwitchEtwEvent_OldThreadState_Name(::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadState value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadState::INITIALIZED:
+    return "INITIALIZED";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadState::READY:
+    return "READY";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadState::RUNNING:
+    return "RUNNING";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadState::STANDBY:
+    return "STANDBY";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadState::TERMINATED:
+    return "TERMINATED";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadState::WAITING:
+    return "WAITING";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadState::TRANSITION:
+    return "TRANSITION";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadState::DEFERRED_READY:
+    return "DEFERRED_READY";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class ReadyThreadEtwEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ReadyThreadEtwEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ReadyThreadEtwEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ReadyThreadEtwEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_t_thread_id() const { return at<1>().valid(); }
+  uint32_t t_thread_id() const { return at<1>().as_uint32(); }
+  bool has_adjust_reason() const { return at<2>().valid(); }
+  int32_t adjust_reason() const { return at<2>().as_int32(); }
+  bool has_adjust_increment() const { return at<3>().valid(); }
+  int32_t adjust_increment() const { return at<3>().as_sint32(); }
+  bool has_flag() const { return at<4>().valid(); }
+  int32_t flag() const { return at<4>().as_int32(); }
+};
+
+class ReadyThreadEtwEvent : public ::protozero::Message {
+ public:
+  using Decoder = ReadyThreadEtwEvent_Decoder;
+  enum : int32_t {
+    kTThreadIdFieldNumber = 1,
+    kAdjustReasonFieldNumber = 2,
+    kAdjustIncrementFieldNumber = 3,
+    kFlagFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ReadyThreadEtwEvent"; }
+
+
+  using AdjustReason = ::perfetto::protos::pbzero::ReadyThreadEtwEvent_AdjustReason;
+  static inline const char* AdjustReason_Name(AdjustReason value) {
+    return ::perfetto::protos::pbzero::ReadyThreadEtwEvent_AdjustReason_Name(value);
+  }
+
+  using TraceFlag = ::perfetto::protos::pbzero::ReadyThreadEtwEvent_TraceFlag;
+  static inline const char* TraceFlag_Name(TraceFlag value) {
+    return ::perfetto::protos::pbzero::ReadyThreadEtwEvent_TraceFlag_Name(value);
+  }
+  static inline const AdjustReason IGNORE_THE_INCREMENT = AdjustReason::IGNORE_THE_INCREMENT;
+  static inline const AdjustReason APPLY_INCREMENT = AdjustReason::APPLY_INCREMENT;
+  static inline const AdjustReason APPLY_INCREMENT_BOOST = AdjustReason::APPLY_INCREMENT_BOOST;
+  static inline const TraceFlag TRACE_FLAG_UNSPECIFIED = TraceFlag::TRACE_FLAG_UNSPECIFIED;
+  static inline const TraceFlag THREAD_READIED = TraceFlag::THREAD_READIED;
+  static inline const TraceFlag KERNEL_STACK_SWAPPED_OUT = TraceFlag::KERNEL_STACK_SWAPPED_OUT;
+  static inline const TraceFlag PROCESS_ADDRESS_SWAPPED_OUT = TraceFlag::PROCESS_ADDRESS_SWAPPED_OUT;
+
+  using FieldMetadata_TThreadId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ReadyThreadEtwEvent>;
+
+  static constexpr FieldMetadata_TThreadId kTThreadId{};
+  void set_t_thread_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TThreadId::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_AdjustReason =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ReadyThreadEtwEvent_AdjustReason,
+      ReadyThreadEtwEvent>;
+
+  static constexpr FieldMetadata_AdjustReason kAdjustReason{};
+  void set_adjust_reason(ReadyThreadEtwEvent_AdjustReason value) {
+    static constexpr uint32_t field_id = FieldMetadata_AdjustReason::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_AdjustIncrement =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kSint32,
+      int32_t,
+      ReadyThreadEtwEvent>;
+
+  static constexpr FieldMetadata_AdjustIncrement kAdjustIncrement{};
+  void set_adjust_increment(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AdjustIncrement::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kSint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flag =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ReadyThreadEtwEvent_TraceFlag,
+      ReadyThreadEtwEvent>;
+
+  static constexpr FieldMetadata_Flag kFlag{};
+  void set_flag(ReadyThreadEtwEvent_TraceFlag value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flag::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);
+  }
+};
+
+class CSwitchEtwEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/10, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CSwitchEtwEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CSwitchEtwEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CSwitchEtwEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_new_thread_id() const { return at<1>().valid(); }
+  uint32_t new_thread_id() const { return at<1>().as_uint32(); }
+  bool has_old_thread_id() const { return at<2>().valid(); }
+  uint32_t old_thread_id() const { return at<2>().as_uint32(); }
+  bool has_new_thread_priority() const { return at<3>().valid(); }
+  int32_t new_thread_priority() const { return at<3>().as_sint32(); }
+  bool has_old_thread_priority() const { return at<4>().valid(); }
+  int32_t old_thread_priority() const { return at<4>().as_sint32(); }
+  bool has_previous_c_state() const { return at<5>().valid(); }
+  uint32_t previous_c_state() const { return at<5>().as_uint32(); }
+  bool has_old_thread_wait_reason() const { return at<6>().valid(); }
+  int32_t old_thread_wait_reason() const { return at<6>().as_int32(); }
+  bool has_old_thread_wait_mode() const { return at<7>().valid(); }
+  int32_t old_thread_wait_mode() const { return at<7>().as_int32(); }
+  bool has_old_thread_state() const { return at<8>().valid(); }
+  int32_t old_thread_state() const { return at<8>().as_int32(); }
+  bool has_old_thread_wait_ideal_processor() const { return at<9>().valid(); }
+  int32_t old_thread_wait_ideal_processor() const { return at<9>().as_sint32(); }
+  bool has_new_thread_wait_time() const { return at<10>().valid(); }
+  uint32_t new_thread_wait_time() const { return at<10>().as_uint32(); }
+};
+
+class CSwitchEtwEvent : public ::protozero::Message {
+ public:
+  using Decoder = CSwitchEtwEvent_Decoder;
+  enum : int32_t {
+    kNewThreadIdFieldNumber = 1,
+    kOldThreadIdFieldNumber = 2,
+    kNewThreadPriorityFieldNumber = 3,
+    kOldThreadPriorityFieldNumber = 4,
+    kPreviousCStateFieldNumber = 5,
+    kOldThreadWaitReasonFieldNumber = 6,
+    kOldThreadWaitModeFieldNumber = 7,
+    kOldThreadStateFieldNumber = 8,
+    kOldThreadWaitIdealProcessorFieldNumber = 9,
+    kNewThreadWaitTimeFieldNumber = 10,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CSwitchEtwEvent"; }
+
+
+  using OldThreadWaitReason = ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason;
+  static inline const char* OldThreadWaitReason_Name(OldThreadWaitReason value) {
+    return ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason_Name(value);
+  }
+
+  using OldThreadWaitMode = ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitMode;
+  static inline const char* OldThreadWaitMode_Name(OldThreadWaitMode value) {
+    return ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitMode_Name(value);
+  }
+
+  using OldThreadState = ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadState;
+  static inline const char* OldThreadState_Name(OldThreadState value) {
+    return ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadState_Name(value);
+  }
+  static inline const OldThreadWaitReason EXECUTIVE = OldThreadWaitReason::EXECUTIVE;
+  static inline const OldThreadWaitReason FREE_PAGE = OldThreadWaitReason::FREE_PAGE;
+  static inline const OldThreadWaitReason PAGE_IN = OldThreadWaitReason::PAGE_IN;
+  static inline const OldThreadWaitReason POOL_ALLOCATION = OldThreadWaitReason::POOL_ALLOCATION;
+  static inline const OldThreadWaitReason DELAY_EXECUTION = OldThreadWaitReason::DELAY_EXECUTION;
+  static inline const OldThreadWaitReason SUSPEND = OldThreadWaitReason::SUSPEND;
+  static inline const OldThreadWaitReason USER_REQUEST = OldThreadWaitReason::USER_REQUEST;
+  static inline const OldThreadWaitReason WR_EXECUTIVE = OldThreadWaitReason::WR_EXECUTIVE;
+  static inline const OldThreadWaitReason WR_FREE_PAGE = OldThreadWaitReason::WR_FREE_PAGE;
+  static inline const OldThreadWaitReason WR_PAGE_IN = OldThreadWaitReason::WR_PAGE_IN;
+  static inline const OldThreadWaitReason WR_POOL_ALLOCATION = OldThreadWaitReason::WR_POOL_ALLOCATION;
+  static inline const OldThreadWaitReason WR_DELAY_EXECUTION = OldThreadWaitReason::WR_DELAY_EXECUTION;
+  static inline const OldThreadWaitReason WR_SUSPENDED = OldThreadWaitReason::WR_SUSPENDED;
+  static inline const OldThreadWaitReason WR_USER_REQUEST = OldThreadWaitReason::WR_USER_REQUEST;
+  static inline const OldThreadWaitReason WR_EVENT_PAIR = OldThreadWaitReason::WR_EVENT_PAIR;
+  static inline const OldThreadWaitReason WR_QUEUE = OldThreadWaitReason::WR_QUEUE;
+  static inline const OldThreadWaitReason WR_LPC_RECEIVER = OldThreadWaitReason::WR_LPC_RECEIVER;
+  static inline const OldThreadWaitReason WR_LPC_REPLY = OldThreadWaitReason::WR_LPC_REPLY;
+  static inline const OldThreadWaitReason WR_VIRTUAL_MEMORY = OldThreadWaitReason::WR_VIRTUAL_MEMORY;
+  static inline const OldThreadWaitReason WR_PAGE_OUT = OldThreadWaitReason::WR_PAGE_OUT;
+  static inline const OldThreadWaitReason WR_RENDEZ_VOUS = OldThreadWaitReason::WR_RENDEZ_VOUS;
+  static inline const OldThreadWaitReason WR_KEYED_EVENT = OldThreadWaitReason::WR_KEYED_EVENT;
+  static inline const OldThreadWaitReason WR_TERMINATED = OldThreadWaitReason::WR_TERMINATED;
+  static inline const OldThreadWaitReason WR_PROCESS_IN_SWAP = OldThreadWaitReason::WR_PROCESS_IN_SWAP;
+  static inline const OldThreadWaitReason WR_CPU_RATE_CONTROL = OldThreadWaitReason::WR_CPU_RATE_CONTROL;
+  static inline const OldThreadWaitReason WR_CALLOUT_STACK = OldThreadWaitReason::WR_CALLOUT_STACK;
+  static inline const OldThreadWaitReason WR_KERNEL = OldThreadWaitReason::WR_KERNEL;
+  static inline const OldThreadWaitReason WR_RESOURCE = OldThreadWaitReason::WR_RESOURCE;
+  static inline const OldThreadWaitReason WR_PUSH_LOCK = OldThreadWaitReason::WR_PUSH_LOCK;
+  static inline const OldThreadWaitReason WR_MUTEX = OldThreadWaitReason::WR_MUTEX;
+  static inline const OldThreadWaitReason WR_QUANTUM_END = OldThreadWaitReason::WR_QUANTUM_END;
+  static inline const OldThreadWaitReason WR_DISPATCH_INT = OldThreadWaitReason::WR_DISPATCH_INT;
+  static inline const OldThreadWaitReason WR_PREEMPTED = OldThreadWaitReason::WR_PREEMPTED;
+  static inline const OldThreadWaitReason WR_YIELD_EXECUTION = OldThreadWaitReason::WR_YIELD_EXECUTION;
+  static inline const OldThreadWaitReason WR_FAST_MUTEX = OldThreadWaitReason::WR_FAST_MUTEX;
+  static inline const OldThreadWaitReason WR_GUARD_MUTEX = OldThreadWaitReason::WR_GUARD_MUTEX;
+  static inline const OldThreadWaitReason WR_RUNDOWN = OldThreadWaitReason::WR_RUNDOWN;
+  static inline const OldThreadWaitReason MAXIMUM_WAIT_REASON = OldThreadWaitReason::MAXIMUM_WAIT_REASON;
+  static inline const OldThreadWaitMode KERNEL_MODE = OldThreadWaitMode::KERNEL_MODE;
+  static inline const OldThreadWaitMode USER_MODE = OldThreadWaitMode::USER_MODE;
+  static inline const OldThreadState INITIALIZED = OldThreadState::INITIALIZED;
+  static inline const OldThreadState READY = OldThreadState::READY;
+  static inline const OldThreadState RUNNING = OldThreadState::RUNNING;
+  static inline const OldThreadState STANDBY = OldThreadState::STANDBY;
+  static inline const OldThreadState TERMINATED = OldThreadState::TERMINATED;
+  static inline const OldThreadState WAITING = OldThreadState::WAITING;
+  static inline const OldThreadState TRANSITION = OldThreadState::TRANSITION;
+  static inline const OldThreadState DEFERRED_READY = OldThreadState::DEFERRED_READY;
+
+  using FieldMetadata_NewThreadId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CSwitchEtwEvent>;
+
+  static constexpr FieldMetadata_NewThreadId kNewThreadId{};
+  void set_new_thread_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NewThreadId::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_OldThreadId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CSwitchEtwEvent>;
+
+  static constexpr FieldMetadata_OldThreadId kOldThreadId{};
+  void set_old_thread_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OldThreadId::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_NewThreadPriority =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kSint32,
+      int32_t,
+      CSwitchEtwEvent>;
+
+  static constexpr FieldMetadata_NewThreadPriority kNewThreadPriority{};
+  void set_new_thread_priority(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NewThreadPriority::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kSint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OldThreadPriority =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kSint32,
+      int32_t,
+      CSwitchEtwEvent>;
+
+  static constexpr FieldMetadata_OldThreadPriority kOldThreadPriority{};
+  void set_old_thread_priority(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OldThreadPriority::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kSint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PreviousCState =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CSwitchEtwEvent>;
+
+  static constexpr FieldMetadata_PreviousCState kPreviousCState{};
+  void set_previous_c_state(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PreviousCState::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_OldThreadWaitReason =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      CSwitchEtwEvent_OldThreadWaitReason,
+      CSwitchEtwEvent>;
+
+  static constexpr FieldMetadata_OldThreadWaitReason kOldThreadWaitReason{};
+  void set_old_thread_wait_reason(CSwitchEtwEvent_OldThreadWaitReason value) {
+    static constexpr uint32_t field_id = FieldMetadata_OldThreadWaitReason::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_OldThreadWaitMode =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      CSwitchEtwEvent_OldThreadWaitMode,
+      CSwitchEtwEvent>;
+
+  static constexpr FieldMetadata_OldThreadWaitMode kOldThreadWaitMode{};
+  void set_old_thread_wait_mode(CSwitchEtwEvent_OldThreadWaitMode value) {
+    static constexpr uint32_t field_id = FieldMetadata_OldThreadWaitMode::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_OldThreadState =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      CSwitchEtwEvent_OldThreadState,
+      CSwitchEtwEvent>;
+
+  static constexpr FieldMetadata_OldThreadState kOldThreadState{};
+  void set_old_thread_state(CSwitchEtwEvent_OldThreadState value) {
+    static constexpr uint32_t field_id = FieldMetadata_OldThreadState::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_OldThreadWaitIdealProcessor =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kSint32,
+      int32_t,
+      CSwitchEtwEvent>;
+
+  static constexpr FieldMetadata_OldThreadWaitIdealProcessor kOldThreadWaitIdealProcessor{};
+  void set_old_thread_wait_ideal_processor(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OldThreadWaitIdealProcessor::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kSint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NewThreadWaitTime =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CSwitchEtwEvent>;
+
+  static constexpr FieldMetadata_NewThreadWaitTime kNewThreadWaitTime{};
+  void set_new_thread_wait_time(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NewThreadWaitTime::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/etw/etw_event.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ETW_ETW_EVENT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ETW_ETW_EVENT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class CSwitchEtwEvent;
+class ReadyThreadEtwEvent;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class EtwTraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  EtwTraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit EtwTraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit EtwTraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_timestamp() const { return at<1>().valid(); }
+  uint64_t timestamp() const { return at<1>().as_uint64(); }
+  bool has_cpu() const { return at<4>().valid(); }
+  uint32_t cpu() const { return at<4>().as_uint32(); }
+  bool has_c_switch() const { return at<2>().valid(); }
+  ::protozero::ConstBytes c_switch() const { return at<2>().as_bytes(); }
+  bool has_ready_thread() const { return at<3>().valid(); }
+  ::protozero::ConstBytes ready_thread() const { return at<3>().as_bytes(); }
+};
+
+class EtwTraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = EtwTraceEvent_Decoder;
+  enum : int32_t {
+    kTimestampFieldNumber = 1,
+    kCpuFieldNumber = 4,
+    kCSwitchFieldNumber = 2,
+    kReadyThreadFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.EtwTraceEvent"; }
+
+
+  using FieldMetadata_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      EtwTraceEvent>;
+
+  static constexpr FieldMetadata_Timestamp kTimestamp{};
+  void set_timestamp(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timestamp::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_Cpu =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      EtwTraceEvent>;
+
+  static constexpr FieldMetadata_Cpu kCpu{};
+  void set_cpu(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cpu::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_CSwitch =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CSwitchEtwEvent,
+      EtwTraceEvent>;
+
+  static constexpr FieldMetadata_CSwitch kCSwitch{};
+  template <typename T = CSwitchEtwEvent> T* set_c_switch() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_ReadyThread =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ReadyThreadEtwEvent,
+      EtwTraceEvent>;
+
+  static constexpr FieldMetadata_ReadyThread kReadyThread{};
+  template <typename T = ReadyThreadEtwEvent> T* set_ready_thread() {
+    return BeginNestedMessage<T>(3);
+  }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/etw/etw_event_bundle.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ETW_ETW_EVENT_BUNDLE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ETW_ETW_EVENT_BUNDLE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class EtwTraceEvent;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class EtwTraceEventBundle_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  EtwTraceEventBundle_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit EtwTraceEventBundle_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit EtwTraceEventBundle_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cpu() const { return at<1>().valid(); }
+  uint32_t cpu() const { return at<1>().as_uint32(); }
+  bool has_event() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> event() const { return GetRepeated<::protozero::ConstBytes>(2); }
+};
+
+class EtwTraceEventBundle : public ::protozero::Message {
+ public:
+  using Decoder = EtwTraceEventBundle_Decoder;
+  enum : int32_t {
+    kCpuFieldNumber = 1,
+    kEventFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.EtwTraceEventBundle"; }
+
+
+  using FieldMetadata_Cpu =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      EtwTraceEventBundle>;
+
+  static constexpr FieldMetadata_Cpu kCpu{};
+  void set_cpu(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cpu::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_Event =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      EtwTraceEvent,
+      EtwTraceEventBundle>;
+
+  static constexpr FieldMetadata_Event kEvent{};
+  template <typename T = EtwTraceEvent> T* add_event() {
+    return BeginNestedMessage<T>(2);
+  }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/filesystem/inode_file_map.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FILESYSTEM_INODE_FILE_MAP_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FILESYSTEM_INODE_FILE_MAP_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class InodeFileMap_Entry;
+namespace perfetto_pbzero_enum_InodeFileMap_Entry {
+enum Type : int32_t;
+}  // namespace perfetto_pbzero_enum_InodeFileMap_Entry
+using InodeFileMap_Entry_Type = perfetto_pbzero_enum_InodeFileMap_Entry::Type;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_InodeFileMap_Entry {
+enum Type : int32_t {
+  UNKNOWN = 0,
+  FILE = 1,
+  DIRECTORY = 2,
+};
+} // namespace perfetto_pbzero_enum_InodeFileMap_Entry
+using InodeFileMap_Entry_Type = perfetto_pbzero_enum_InodeFileMap_Entry::Type;
+
+
+constexpr InodeFileMap_Entry_Type InodeFileMap_Entry_Type_MIN = InodeFileMap_Entry_Type::UNKNOWN;
+constexpr InodeFileMap_Entry_Type InodeFileMap_Entry_Type_MAX = InodeFileMap_Entry_Type::DIRECTORY;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* InodeFileMap_Entry_Type_Name(::perfetto::protos::pbzero::InodeFileMap_Entry_Type value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::InodeFileMap_Entry_Type::UNKNOWN:
+    return "UNKNOWN";
+
+  case ::perfetto::protos::pbzero::InodeFileMap_Entry_Type::FILE:
+    return "FILE";
+
+  case ::perfetto::protos::pbzero::InodeFileMap_Entry_Type::DIRECTORY:
+    return "DIRECTORY";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class InodeFileMap_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  InodeFileMap_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit InodeFileMap_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit InodeFileMap_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_block_device_id() const { return at<1>().valid(); }
+  uint64_t block_device_id() const { return at<1>().as_uint64(); }
+  bool has_mount_points() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> mount_points() const { return GetRepeated<::protozero::ConstChars>(2); }
+  bool has_entries() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> entries() const { return GetRepeated<::protozero::ConstBytes>(3); }
+};
+
+class InodeFileMap : public ::protozero::Message {
+ public:
+  using Decoder = InodeFileMap_Decoder;
+  enum : int32_t {
+    kBlockDeviceIdFieldNumber = 1,
+    kMountPointsFieldNumber = 2,
+    kEntriesFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.InodeFileMap"; }
+
+  using Entry = ::perfetto::protos::pbzero::InodeFileMap_Entry;
+
+  using FieldMetadata_BlockDeviceId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      InodeFileMap>;
+
+  static constexpr FieldMetadata_BlockDeviceId kBlockDeviceId{};
+  void set_block_device_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BlockDeviceId::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_MountPoints =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      InodeFileMap>;
+
+  static constexpr FieldMetadata_MountPoints kMountPoints{};
+  void add_mount_points(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_MountPoints::kFieldId, data, size);
+  }
+  void add_mount_points(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_MountPoints::kFieldId, chars.data, chars.size);
+  }
+  void add_mount_points(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_MountPoints::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_Entries =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InodeFileMap_Entry,
+      InodeFileMap>;
+
+  static constexpr FieldMetadata_Entries kEntries{};
+  template <typename T = InodeFileMap_Entry> T* add_entries() {
+    return BeginNestedMessage<T>(3);
+  }
+
+};
+
+class InodeFileMap_Entry_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  InodeFileMap_Entry_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit InodeFileMap_Entry_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit InodeFileMap_Entry_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_inode_number() const { return at<1>().valid(); }
+  uint64_t inode_number() const { return at<1>().as_uint64(); }
+  bool has_paths() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> paths() const { return GetRepeated<::protozero::ConstChars>(2); }
+  bool has_type() const { return at<3>().valid(); }
+  int32_t type() const { return at<3>().as_int32(); }
+};
+
+class InodeFileMap_Entry : public ::protozero::Message {
+ public:
+  using Decoder = InodeFileMap_Entry_Decoder;
+  enum : int32_t {
+    kInodeNumberFieldNumber = 1,
+    kPathsFieldNumber = 2,
+    kTypeFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.InodeFileMap.Entry"; }
+
+
+  using Type = ::perfetto::protos::pbzero::InodeFileMap_Entry_Type;
+  static inline const char* Type_Name(Type value) {
+    return ::perfetto::protos::pbzero::InodeFileMap_Entry_Type_Name(value);
+  }
+  static inline const Type UNKNOWN = Type::UNKNOWN;
+  static inline const Type FILE = Type::FILE;
+  static inline const Type DIRECTORY = Type::DIRECTORY;
+
+  using FieldMetadata_InodeNumber =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      InodeFileMap_Entry>;
+
+  static constexpr FieldMetadata_InodeNumber kInodeNumber{};
+  void set_inode_number(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InodeNumber::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_Paths =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      InodeFileMap_Entry>;
+
+  static constexpr FieldMetadata_Paths kPaths{};
+  void add_paths(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Paths::kFieldId, data, size);
+  }
+  void add_paths(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Paths::kFieldId, chars.data, chars.size);
+  }
+  void add_paths(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Paths::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_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      InodeFileMap_Entry_Type,
+      InodeFileMap_Entry>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(InodeFileMap_Entry_Type value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::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.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/ftrace_event.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_FTRACE_EVENT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_FTRACE_EVENT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class AllocPagesIommuEndFtraceEvent;
+class AllocPagesIommuFailFtraceEvent;
+class AllocPagesIommuStartFtraceEvent;
+class AllocPagesSysEndFtraceEvent;
+class AllocPagesSysFailFtraceEvent;
+class AllocPagesSysStartFtraceEvent;
+class AndroidFsDatareadEndFtraceEvent;
+class AndroidFsDatareadStartFtraceEvent;
+class AndroidFsDatawriteEndFtraceEvent;
+class AndroidFsDatawriteStartFtraceEvent;
+class AndroidFsFsyncEndFtraceEvent;
+class AndroidFsFsyncStartFtraceEvent;
+class BinderCommandFtraceEvent;
+class BinderLockFtraceEvent;
+class BinderLockedFtraceEvent;
+class BinderReturnFtraceEvent;
+class BinderSetPriorityFtraceEvent;
+class BinderTransactionAllocBufFtraceEvent;
+class BinderTransactionFtraceEvent;
+class BinderTransactionReceivedFtraceEvent;
+class BinderUnlockFtraceEvent;
+class BlockBioBackmergeFtraceEvent;
+class BlockBioBounceFtraceEvent;
+class BlockBioCompleteFtraceEvent;
+class BlockBioFrontmergeFtraceEvent;
+class BlockBioQueueFtraceEvent;
+class BlockBioRemapFtraceEvent;
+class BlockDirtyBufferFtraceEvent;
+class BlockGetrqFtraceEvent;
+class BlockPlugFtraceEvent;
+class BlockRqAbortFtraceEvent;
+class BlockRqCompleteFtraceEvent;
+class BlockRqInsertFtraceEvent;
+class BlockRqIssueFtraceEvent;
+class BlockRqRemapFtraceEvent;
+class BlockRqRequeueFtraceEvent;
+class BlockSleeprqFtraceEvent;
+class BlockSplitFtraceEvent;
+class BlockTouchBufferFtraceEvent;
+class BlockUnplugFtraceEvent;
+class CdevUpdateFtraceEvent;
+class CgroupAttachTaskFtraceEvent;
+class CgroupDestroyRootFtraceEvent;
+class CgroupMkdirFtraceEvent;
+class CgroupReleaseFtraceEvent;
+class CgroupRemountFtraceEvent;
+class CgroupRenameFtraceEvent;
+class CgroupRmdirFtraceEvent;
+class CgroupSetupRootFtraceEvent;
+class CgroupTransferTasksFtraceEvent;
+class ClkDisableFtraceEvent;
+class ClkEnableFtraceEvent;
+class ClkSetRateFtraceEvent;
+class ClockDisableFtraceEvent;
+class ClockEnableFtraceEvent;
+class ClockSetRateFtraceEvent;
+class CmaAllocInfoFtraceEvent;
+class CmaAllocStartFtraceEvent;
+class ConsoleFtraceEvent;
+class CpuFrequencyFtraceEvent;
+class CpuFrequencyLimitsFtraceEvent;
+class CpuIdleFtraceEvent;
+class CpuhpEnterFtraceEvent;
+class CpuhpExitFtraceEvent;
+class CpuhpLatencyFtraceEvent;
+class CpuhpMultiEnterFtraceEvent;
+class CpuhpPauseFtraceEvent;
+class CrosEcSensorhubDataFtraceEvent;
+class DevicePmCallbackEndFtraceEvent;
+class DevicePmCallbackStartFtraceEvent;
+class DmaAllocContiguousRetryFtraceEvent;
+class DmaFenceEmitFtraceEvent;
+class DmaFenceInitFtraceEvent;
+class DmaFenceSignaledFtraceEvent;
+class DmaFenceWaitEndFtraceEvent;
+class DmaFenceWaitStartFtraceEvent;
+class DmaHeapStatFtraceEvent;
+class DpuDsiCmdFifoStatusFtraceEvent;
+class DpuDsiRxFtraceEvent;
+class DpuDsiTxFtraceEvent;
+class DpuTracingMarkWriteFtraceEvent;
+class DrmRunJobFtraceEvent;
+class DrmSchedJobFtraceEvent;
+class DrmSchedProcessJobFtraceEvent;
+class DrmVblankEventDeliveredFtraceEvent;
+class DrmVblankEventFtraceEvent;
+class DsiCmdFifoStatusFtraceEvent;
+class DsiRxFtraceEvent;
+class DsiTxFtraceEvent;
+class Ext4AllocDaBlocksFtraceEvent;
+class Ext4AllocateBlocksFtraceEvent;
+class Ext4AllocateInodeFtraceEvent;
+class Ext4BeginOrderedTruncateFtraceEvent;
+class Ext4CollapseRangeFtraceEvent;
+class Ext4DaReleaseSpaceFtraceEvent;
+class Ext4DaReserveSpaceFtraceEvent;
+class Ext4DaUpdateReserveSpaceFtraceEvent;
+class Ext4DaWriteBeginFtraceEvent;
+class Ext4DaWriteEndFtraceEvent;
+class Ext4DaWritePagesExtentFtraceEvent;
+class Ext4DaWritePagesFtraceEvent;
+class Ext4DirectIOEnterFtraceEvent;
+class Ext4DirectIOExitFtraceEvent;
+class Ext4DiscardBlocksFtraceEvent;
+class Ext4DiscardPreallocationsFtraceEvent;
+class Ext4DropInodeFtraceEvent;
+class Ext4EsCacheExtentFtraceEvent;
+class Ext4EsFindDelayedExtentRangeEnterFtraceEvent;
+class Ext4EsFindDelayedExtentRangeExitFtraceEvent;
+class Ext4EsInsertExtentFtraceEvent;
+class Ext4EsLookupExtentEnterFtraceEvent;
+class Ext4EsLookupExtentExitFtraceEvent;
+class Ext4EsRemoveExtentFtraceEvent;
+class Ext4EsShrinkCountFtraceEvent;
+class Ext4EsShrinkFtraceEvent;
+class Ext4EsShrinkScanEnterFtraceEvent;
+class Ext4EsShrinkScanExitFtraceEvent;
+class Ext4EvictInodeFtraceEvent;
+class Ext4ExtConvertToInitializedEnterFtraceEvent;
+class Ext4ExtConvertToInitializedFastpathFtraceEvent;
+class Ext4ExtHandleUnwrittenExtentsFtraceEvent;
+class Ext4ExtInCacheFtraceEvent;
+class Ext4ExtLoadExtentFtraceEvent;
+class Ext4ExtMapBlocksEnterFtraceEvent;
+class Ext4ExtMapBlocksExitFtraceEvent;
+class Ext4ExtPutInCacheFtraceEvent;
+class Ext4ExtRemoveSpaceDoneFtraceEvent;
+class Ext4ExtRemoveSpaceFtraceEvent;
+class Ext4ExtRmIdxFtraceEvent;
+class Ext4ExtRmLeafFtraceEvent;
+class Ext4ExtShowExtentFtraceEvent;
+class Ext4FallocateEnterFtraceEvent;
+class Ext4FallocateExitFtraceEvent;
+class Ext4FindDelallocRangeFtraceEvent;
+class Ext4ForgetFtraceEvent;
+class Ext4FreeBlocksFtraceEvent;
+class Ext4FreeInodeFtraceEvent;
+class Ext4GetImpliedClusterAllocExitFtraceEvent;
+class Ext4GetReservedClusterAllocFtraceEvent;
+class Ext4IndMapBlocksEnterFtraceEvent;
+class Ext4IndMapBlocksExitFtraceEvent;
+class Ext4InsertRangeFtraceEvent;
+class Ext4InvalidatepageFtraceEvent;
+class Ext4JournalStartFtraceEvent;
+class Ext4JournalStartReservedFtraceEvent;
+class Ext4JournalledInvalidatepageFtraceEvent;
+class Ext4JournalledWriteEndFtraceEvent;
+class Ext4LoadInodeBitmapFtraceEvent;
+class Ext4LoadInodeFtraceEvent;
+class Ext4MarkInodeDirtyFtraceEvent;
+class Ext4MbBitmapLoadFtraceEvent;
+class Ext4MbBuddyBitmapLoadFtraceEvent;
+class Ext4MbDiscardPreallocationsFtraceEvent;
+class Ext4MbNewGroupPaFtraceEvent;
+class Ext4MbNewInodePaFtraceEvent;
+class Ext4MbReleaseGroupPaFtraceEvent;
+class Ext4MbReleaseInodePaFtraceEvent;
+class Ext4MballocAllocFtraceEvent;
+class Ext4MballocDiscardFtraceEvent;
+class Ext4MballocFreeFtraceEvent;
+class Ext4MballocPreallocFtraceEvent;
+class Ext4OtherInodeUpdateTimeFtraceEvent;
+class Ext4PunchHoleFtraceEvent;
+class Ext4ReadBlockBitmapLoadFtraceEvent;
+class Ext4ReadpageFtraceEvent;
+class Ext4ReleasepageFtraceEvent;
+class Ext4RemoveBlocksFtraceEvent;
+class Ext4RequestBlocksFtraceEvent;
+class Ext4RequestInodeFtraceEvent;
+class Ext4SyncFileEnterFtraceEvent;
+class Ext4SyncFileExitFtraceEvent;
+class Ext4SyncFsFtraceEvent;
+class Ext4TrimAllFreeFtraceEvent;
+class Ext4TrimExtentFtraceEvent;
+class Ext4TruncateEnterFtraceEvent;
+class Ext4TruncateExitFtraceEvent;
+class Ext4UnlinkEnterFtraceEvent;
+class Ext4UnlinkExitFtraceEvent;
+class Ext4WriteBeginFtraceEvent;
+class Ext4WriteEndFtraceEvent;
+class Ext4WritepageFtraceEvent;
+class Ext4WritepagesFtraceEvent;
+class Ext4WritepagesResultFtraceEvent;
+class Ext4ZeroRangeFtraceEvent;
+class F2fsBackgroundGcFtraceEvent;
+class F2fsDoSubmitBioFtraceEvent;
+class F2fsEvictInodeFtraceEvent;
+class F2fsFallocateFtraceEvent;
+class F2fsGcBeginFtraceEvent;
+class F2fsGcEndFtraceEvent;
+class F2fsGetDataBlockFtraceEvent;
+class F2fsGetVictimFtraceEvent;
+class F2fsIgetExitFtraceEvent;
+class F2fsIgetFtraceEvent;
+class F2fsIostatFtraceEvent;
+class F2fsIostatLatencyFtraceEvent;
+class F2fsNewInodeFtraceEvent;
+class F2fsReadpageFtraceEvent;
+class F2fsReserveNewBlockFtraceEvent;
+class F2fsSetPageDirtyFtraceEvent;
+class F2fsSubmitWritePageFtraceEvent;
+class F2fsSyncFileEnterFtraceEvent;
+class F2fsSyncFileExitFtraceEvent;
+class F2fsSyncFsFtraceEvent;
+class F2fsTruncateBlocksEnterFtraceEvent;
+class F2fsTruncateBlocksExitFtraceEvent;
+class F2fsTruncateDataBlocksRangeFtraceEvent;
+class F2fsTruncateFtraceEvent;
+class F2fsTruncateInodeBlocksEnterFtraceEvent;
+class F2fsTruncateInodeBlocksExitFtraceEvent;
+class F2fsTruncateNodeFtraceEvent;
+class F2fsTruncateNodesEnterFtraceEvent;
+class F2fsTruncateNodesExitFtraceEvent;
+class F2fsTruncatePartialNodesFtraceEvent;
+class F2fsUnlinkEnterFtraceEvent;
+class F2fsUnlinkExitFtraceEvent;
+class F2fsVmPageMkwriteFtraceEvent;
+class F2fsWriteBeginFtraceEvent;
+class F2fsWriteCheckpointFtraceEvent;
+class F2fsWriteEndFtraceEvent;
+class FastrpcDmaAllocFtraceEvent;
+class FastrpcDmaFreeFtraceEvent;
+class FastrpcDmaMapFtraceEvent;
+class FastrpcDmaStatFtraceEvent;
+class FastrpcDmaUnmapFtraceEvent;
+class FenceDestroyFtraceEvent;
+class FenceEnableSignalFtraceEvent;
+class FenceInitFtraceEvent;
+class FenceSignaledFtraceEvent;
+class FuncgraphEntryFtraceEvent;
+class FuncgraphExitFtraceEvent;
+class G2dTracingMarkWriteFtraceEvent;
+class GenericFtraceEvent;
+class GoogleIccEventFtraceEvent;
+class GoogleIrmEventFtraceEvent;
+class GpuFrequencyFtraceEvent;
+class GpuMemTotalFtraceEvent;
+class GpuWorkPeriodFtraceEvent;
+class HostHcallFtraceEvent;
+class HostMemAbortFtraceEvent;
+class HostSmcFtraceEvent;
+class HypEnterFtraceEvent;
+class HypExitFtraceEvent;
+class I2cReadFtraceEvent;
+class I2cReplyFtraceEvent;
+class I2cResultFtraceEvent;
+class I2cWriteFtraceEvent;
+class InetSockSetStateFtraceEvent;
+class IommuMapRangeFtraceEvent;
+class IommuSecPtblMapRangeEndFtraceEvent;
+class IommuSecPtblMapRangeStartFtraceEvent;
+class IonAllocBufferEndFtraceEvent;
+class IonAllocBufferFailFtraceEvent;
+class IonAllocBufferFallbackFtraceEvent;
+class IonAllocBufferStartFtraceEvent;
+class IonBufferCreateFtraceEvent;
+class IonBufferDestroyFtraceEvent;
+class IonCpAllocRetryFtraceEvent;
+class IonCpSecureBufferEndFtraceEvent;
+class IonCpSecureBufferStartFtraceEvent;
+class IonHeapGrowFtraceEvent;
+class IonHeapShrinkFtraceEvent;
+class IonPrefetchingFtraceEvent;
+class IonSecureCmaAddToPoolEndFtraceEvent;
+class IonSecureCmaAddToPoolStartFtraceEvent;
+class IonSecureCmaAllocateEndFtraceEvent;
+class IonSecureCmaAllocateStartFtraceEvent;
+class IonSecureCmaShrinkPoolEndFtraceEvent;
+class IonSecureCmaShrinkPoolStartFtraceEvent;
+class IonStatFtraceEvent;
+class IpiEntryFtraceEvent;
+class IpiExitFtraceEvent;
+class IpiRaiseFtraceEvent;
+class IrqHandlerEntryFtraceEvent;
+class IrqHandlerExitFtraceEvent;
+class KfreeFtraceEvent;
+class KfreeSkbFtraceEvent;
+class KmallocFtraceEvent;
+class KmallocNodeFtraceEvent;
+class KmemCacheAllocFtraceEvent;
+class KmemCacheAllocNodeFtraceEvent;
+class KmemCacheFreeFtraceEvent;
+class KvmAccessFaultFtraceEvent;
+class KvmAckIrqFtraceEvent;
+class KvmAgeHvaFtraceEvent;
+class KvmAgePageFtraceEvent;
+class KvmArmClearDebugFtraceEvent;
+class KvmArmSetDreg32FtraceEvent;
+class KvmArmSetRegsetFtraceEvent;
+class KvmArmSetupDebugFtraceEvent;
+class KvmEntryFtraceEvent;
+class KvmExitFtraceEvent;
+class KvmFpuFtraceEvent;
+class KvmGetTimerMapFtraceEvent;
+class KvmGuestFaultFtraceEvent;
+class KvmHandleSysRegFtraceEvent;
+class KvmHvcArm64FtraceEvent;
+class KvmIrqLineFtraceEvent;
+class KvmMmioEmulateFtraceEvent;
+class KvmMmioFtraceEvent;
+class KvmSetGuestDebugFtraceEvent;
+class KvmSetIrqFtraceEvent;
+class KvmSetSpteHvaFtraceEvent;
+class KvmSetWayFlushFtraceEvent;
+class KvmSysAccessFtraceEvent;
+class KvmTestAgeHvaFtraceEvent;
+class KvmTimerEmulateFtraceEvent;
+class KvmTimerHrtimerExpireFtraceEvent;
+class KvmTimerRestoreStateFtraceEvent;
+class KvmTimerSaveStateFtraceEvent;
+class KvmTimerUpdateIrqFtraceEvent;
+class KvmToggleCacheFtraceEvent;
+class KvmUnmapHvaRangeFtraceEvent;
+class KvmUserspaceExitFtraceEvent;
+class KvmVcpuWakeupFtraceEvent;
+class KvmWfxArm64FtraceEvent;
+class LowmemoryKillFtraceEvent;
+class LwisTracingMarkWriteFtraceEvent;
+class MaliMaliCSFINTERRUPTENDFtraceEvent;
+class MaliMaliCSFINTERRUPTSTARTFtraceEvent;
+class MaliMaliKCPUCQSSETFtraceEvent;
+class MaliMaliKCPUCQSWAITENDFtraceEvent;
+class MaliMaliKCPUCQSWAITSTARTFtraceEvent;
+class MaliMaliKCPUFENCESIGNALFtraceEvent;
+class MaliMaliKCPUFENCEWAITENDFtraceEvent;
+class MaliMaliKCPUFENCEWAITSTARTFtraceEvent;
+class MaliTracingMarkWriteFtraceEvent;
+class MarkVictimFtraceEvent;
+class MdpCmdKickoffFtraceEvent;
+class MdpCmdPingpongDoneFtraceEvent;
+class MdpCmdReadptrDoneFtraceEvent;
+class MdpCmdReleaseBwFtraceEvent;
+class MdpCmdWaitPingpongFtraceEvent;
+class MdpCommitFtraceEvent;
+class MdpCompareBwFtraceEvent;
+class MdpMisrCrcFtraceEvent;
+class MdpMixerUpdateFtraceEvent;
+class MdpPerfPrefillCalcFtraceEvent;
+class MdpPerfSetOtFtraceEvent;
+class MdpPerfSetPanicLutsFtraceEvent;
+class MdpPerfSetQosLutsFtraceEvent;
+class MdpPerfSetWmLevelsFtraceEvent;
+class MdpPerfUpdateBusFtraceEvent;
+class MdpSsppChangeFtraceEvent;
+class MdpSsppSetFtraceEvent;
+class MdpTraceCounterFtraceEvent;
+class MdpVideoUnderrunDoneFtraceEvent;
+class MigratePagesEndFtraceEvent;
+class MigratePagesStartFtraceEvent;
+class MigrateRetryFtraceEvent;
+class MmCompactionBeginFtraceEvent;
+class MmCompactionDeferCompactionFtraceEvent;
+class MmCompactionDeferResetFtraceEvent;
+class MmCompactionDeferredFtraceEvent;
+class MmCompactionEndFtraceEvent;
+class MmCompactionFinishedFtraceEvent;
+class MmCompactionIsolateFreepagesFtraceEvent;
+class MmCompactionIsolateMigratepagesFtraceEvent;
+class MmCompactionKcompactdSleepFtraceEvent;
+class MmCompactionKcompactdWakeFtraceEvent;
+class MmCompactionMigratepagesFtraceEvent;
+class MmCompactionSuitableFtraceEvent;
+class MmCompactionTryToCompactPagesFtraceEvent;
+class MmCompactionWakeupKcompactdFtraceEvent;
+class MmEventRecordFtraceEvent;
+class MmFilemapAddToPageCacheFtraceEvent;
+class MmFilemapDeleteFromPageCacheFtraceEvent;
+class MmPageAllocExtfragFtraceEvent;
+class MmPageAllocFtraceEvent;
+class MmPageAllocZoneLockedFtraceEvent;
+class MmPageFreeBatchedFtraceEvent;
+class MmPageFreeFtraceEvent;
+class MmPagePcpuDrainFtraceEvent;
+class MmShrinkSlabEndFtraceEvent;
+class MmShrinkSlabStartFtraceEvent;
+class MmVmscanDirectReclaimBeginFtraceEvent;
+class MmVmscanDirectReclaimEndFtraceEvent;
+class MmVmscanKswapdSleepFtraceEvent;
+class MmVmscanKswapdWakeFtraceEvent;
+class NapiGroReceiveEntryFtraceEvent;
+class NapiGroReceiveExitFtraceEvent;
+class NetDevXmitFtraceEvent;
+class NetifReceiveSkbFtraceEvent;
+class OomScoreAdjUpdateFtraceEvent;
+class PanelWriteGenericFtraceEvent;
+class PrintFtraceEvent;
+class RegulatorDisableCompleteFtraceEvent;
+class RegulatorDisableFtraceEvent;
+class RegulatorEnableCompleteFtraceEvent;
+class RegulatorEnableDelayFtraceEvent;
+class RegulatorEnableFtraceEvent;
+class RegulatorSetVoltageCompleteFtraceEvent;
+class RegulatorSetVoltageFtraceEvent;
+class RotatorBwAoAsContextFtraceEvent;
+class RpmStatusFtraceEvent;
+class RssStatFtraceEvent;
+class RssStatThrottledFtraceEvent;
+class SamsungTracingMarkWriteFtraceEvent;
+class SchedBlockedReasonFtraceEvent;
+class SchedCpuHotplugFtraceEvent;
+class SchedCpuUtilCfsFtraceEvent;
+class SchedMigrateTaskFtraceEvent;
+class SchedPiSetprioFtraceEvent;
+class SchedProcessExecFtraceEvent;
+class SchedProcessExitFtraceEvent;
+class SchedProcessForkFtraceEvent;
+class SchedProcessFreeFtraceEvent;
+class SchedProcessHangFtraceEvent;
+class SchedProcessWaitFtraceEvent;
+class SchedSwitchFtraceEvent;
+class SchedSwitchWithCtrsFtraceEvent;
+class SchedWakeupFtraceEvent;
+class SchedWakeupNewFtraceEvent;
+class SchedWakingFtraceEvent;
+class ScmCallEndFtraceEvent;
+class ScmCallStartFtraceEvent;
+class SdeSdeEvtlogFtraceEvent;
+class SdeSdePerfCalcCrtcFtraceEvent;
+class SdeSdePerfCrtcUpdateFtraceEvent;
+class SdeSdePerfSetQosLutsFtraceEvent;
+class SdeSdePerfUpdateBusFtraceEvent;
+class SdeTracingMarkWriteFtraceEvent;
+class SignalDeliverFtraceEvent;
+class SignalGenerateFtraceEvent;
+class SmbusReadFtraceEvent;
+class SmbusReplyFtraceEvent;
+class SmbusResultFtraceEvent;
+class SmbusWriteFtraceEvent;
+class SoftirqEntryFtraceEvent;
+class SoftirqExitFtraceEvent;
+class SoftirqRaiseFtraceEvent;
+class SuspendResumeFtraceEvent;
+class SuspendResumeMinimalFtraceEvent;
+class SyncPtFtraceEvent;
+class SyncTimelineFtraceEvent;
+class SyncWaitFtraceEvent;
+class SysEnterFtraceEvent;
+class SysExitFtraceEvent;
+class TaskNewtaskFtraceEvent;
+class TaskRenameFtraceEvent;
+class TcpRetransmitSkbFtraceEvent;
+class ThermalTemperatureFtraceEvent;
+class TracingMarkWriteFtraceEvent;
+class TrapRegFtraceEvent;
+class TrustyEnqueueNopFtraceEvent;
+class TrustyIpcConnectEndFtraceEvent;
+class TrustyIpcConnectFtraceEvent;
+class TrustyIpcHandleEventFtraceEvent;
+class TrustyIpcPollFtraceEvent;
+class TrustyIpcReadEndFtraceEvent;
+class TrustyIpcReadFtraceEvent;
+class TrustyIpcRxFtraceEvent;
+class TrustyIpcWriteFtraceEvent;
+class TrustyIrqFtraceEvent;
+class TrustyReclaimMemoryDoneFtraceEvent;
+class TrustyReclaimMemoryFtraceEvent;
+class TrustyShareMemoryDoneFtraceEvent;
+class TrustyShareMemoryFtraceEvent;
+class TrustySmcDoneFtraceEvent;
+class TrustySmcFtraceEvent;
+class TrustyStdCall32DoneFtraceEvent;
+class TrustyStdCall32FtraceEvent;
+class UfshcdClkGatingFtraceEvent;
+class UfshcdCommandFtraceEvent;
+class V4l2DqbufFtraceEvent;
+class V4l2QbufFtraceEvent;
+class Vb2V4l2BufDoneFtraceEvent;
+class Vb2V4l2BufQueueFtraceEvent;
+class Vb2V4l2DqbufFtraceEvent;
+class Vb2V4l2QbufFtraceEvent;
+class VgicUpdateIrqPendingFtraceEvent;
+class VirtioGpuCmdQueueFtraceEvent;
+class VirtioGpuCmdResponseFtraceEvent;
+class VirtioVideoCmdDoneFtraceEvent;
+class VirtioVideoCmdFtraceEvent;
+class VirtioVideoResourceQueueDoneFtraceEvent;
+class VirtioVideoResourceQueueFtraceEvent;
+class WakeupSourceActivateFtraceEvent;
+class WakeupSourceDeactivateFtraceEvent;
+class WorkqueueActivateWorkFtraceEvent;
+class WorkqueueExecuteEndFtraceEvent;
+class WorkqueueExecuteStartFtraceEvent;
+class WorkqueueQueueWorkFtraceEvent;
+class ZeroFtraceEvent;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class FtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/505, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_timestamp() const { return at<1>().valid(); }
+  uint64_t timestamp() const { return at<1>().as_uint64(); }
+  bool has_pid() const { return at<2>().valid(); }
+  uint32_t pid() const { return at<2>().as_uint32(); }
+  bool has_common_flags() const { return at<5>().valid(); }
+  uint32_t common_flags() const { return at<5>().as_uint32(); }
+  bool has_print() const { return at<3>().valid(); }
+  ::protozero::ConstBytes print() const { return at<3>().as_bytes(); }
+  bool has_sched_switch() const { return at<4>().valid(); }
+  ::protozero::ConstBytes sched_switch() const { return at<4>().as_bytes(); }
+  bool has_cpu_frequency() const { return at<11>().valid(); }
+  ::protozero::ConstBytes cpu_frequency() const { return at<11>().as_bytes(); }
+  bool has_cpu_frequency_limits() const { return at<12>().valid(); }
+  ::protozero::ConstBytes cpu_frequency_limits() const { return at<12>().as_bytes(); }
+  bool has_cpu_idle() const { return at<13>().valid(); }
+  ::protozero::ConstBytes cpu_idle() const { return at<13>().as_bytes(); }
+  bool has_clock_enable() const { return at<14>().valid(); }
+  ::protozero::ConstBytes clock_enable() const { return at<14>().as_bytes(); }
+  bool has_clock_disable() const { return at<15>().valid(); }
+  ::protozero::ConstBytes clock_disable() const { return at<15>().as_bytes(); }
+  bool has_clock_set_rate() const { return at<16>().valid(); }
+  ::protozero::ConstBytes clock_set_rate() const { return at<16>().as_bytes(); }
+  bool has_sched_wakeup() const { return at<17>().valid(); }
+  ::protozero::ConstBytes sched_wakeup() const { return at<17>().as_bytes(); }
+  bool has_sched_blocked_reason() const { return at<18>().valid(); }
+  ::protozero::ConstBytes sched_blocked_reason() const { return at<18>().as_bytes(); }
+  bool has_sched_cpu_hotplug() const { return at<19>().valid(); }
+  ::protozero::ConstBytes sched_cpu_hotplug() const { return at<19>().as_bytes(); }
+  bool has_sched_waking() const { return at<20>().valid(); }
+  ::protozero::ConstBytes sched_waking() const { return at<20>().as_bytes(); }
+  bool has_ipi_entry() const { return at<21>().valid(); }
+  ::protozero::ConstBytes ipi_entry() const { return at<21>().as_bytes(); }
+  bool has_ipi_exit() const { return at<22>().valid(); }
+  ::protozero::ConstBytes ipi_exit() const { return at<22>().as_bytes(); }
+  bool has_ipi_raise() const { return at<23>().valid(); }
+  ::protozero::ConstBytes ipi_raise() const { return at<23>().as_bytes(); }
+  bool has_softirq_entry() const { return at<24>().valid(); }
+  ::protozero::ConstBytes softirq_entry() const { return at<24>().as_bytes(); }
+  bool has_softirq_exit() const { return at<25>().valid(); }
+  ::protozero::ConstBytes softirq_exit() const { return at<25>().as_bytes(); }
+  bool has_softirq_raise() const { return at<26>().valid(); }
+  ::protozero::ConstBytes softirq_raise() const { return at<26>().as_bytes(); }
+  bool has_i2c_read() const { return at<27>().valid(); }
+  ::protozero::ConstBytes i2c_read() const { return at<27>().as_bytes(); }
+  bool has_i2c_write() const { return at<28>().valid(); }
+  ::protozero::ConstBytes i2c_write() const { return at<28>().as_bytes(); }
+  bool has_i2c_result() const { return at<29>().valid(); }
+  ::protozero::ConstBytes i2c_result() const { return at<29>().as_bytes(); }
+  bool has_i2c_reply() const { return at<30>().valid(); }
+  ::protozero::ConstBytes i2c_reply() const { return at<30>().as_bytes(); }
+  bool has_smbus_read() const { return at<31>().valid(); }
+  ::protozero::ConstBytes smbus_read() const { return at<31>().as_bytes(); }
+  bool has_smbus_write() const { return at<32>().valid(); }
+  ::protozero::ConstBytes smbus_write() const { return at<32>().as_bytes(); }
+  bool has_smbus_result() const { return at<33>().valid(); }
+  ::protozero::ConstBytes smbus_result() const { return at<33>().as_bytes(); }
+  bool has_smbus_reply() const { return at<34>().valid(); }
+  ::protozero::ConstBytes smbus_reply() const { return at<34>().as_bytes(); }
+  bool has_lowmemory_kill() const { return at<35>().valid(); }
+  ::protozero::ConstBytes lowmemory_kill() const { return at<35>().as_bytes(); }
+  bool has_irq_handler_entry() const { return at<36>().valid(); }
+  ::protozero::ConstBytes irq_handler_entry() const { return at<36>().as_bytes(); }
+  bool has_irq_handler_exit() const { return at<37>().valid(); }
+  ::protozero::ConstBytes irq_handler_exit() const { return at<37>().as_bytes(); }
+  bool has_sync_pt() const { return at<38>().valid(); }
+  ::protozero::ConstBytes sync_pt() const { return at<38>().as_bytes(); }
+  bool has_sync_timeline() const { return at<39>().valid(); }
+  ::protozero::ConstBytes sync_timeline() const { return at<39>().as_bytes(); }
+  bool has_sync_wait() const { return at<40>().valid(); }
+  ::protozero::ConstBytes sync_wait() const { return at<40>().as_bytes(); }
+  bool has_ext4_da_write_begin() const { return at<41>().valid(); }
+  ::protozero::ConstBytes ext4_da_write_begin() const { return at<41>().as_bytes(); }
+  bool has_ext4_da_write_end() const { return at<42>().valid(); }
+  ::protozero::ConstBytes ext4_da_write_end() const { return at<42>().as_bytes(); }
+  bool has_ext4_sync_file_enter() const { return at<43>().valid(); }
+  ::protozero::ConstBytes ext4_sync_file_enter() const { return at<43>().as_bytes(); }
+  bool has_ext4_sync_file_exit() const { return at<44>().valid(); }
+  ::protozero::ConstBytes ext4_sync_file_exit() const { return at<44>().as_bytes(); }
+  bool has_block_rq_issue() const { return at<45>().valid(); }
+  ::protozero::ConstBytes block_rq_issue() const { return at<45>().as_bytes(); }
+  bool has_mm_vmscan_direct_reclaim_begin() const { return at<46>().valid(); }
+  ::protozero::ConstBytes mm_vmscan_direct_reclaim_begin() const { return at<46>().as_bytes(); }
+  bool has_mm_vmscan_direct_reclaim_end() const { return at<47>().valid(); }
+  ::protozero::ConstBytes mm_vmscan_direct_reclaim_end() const { return at<47>().as_bytes(); }
+  bool has_mm_vmscan_kswapd_wake() const { return at<48>().valid(); }
+  ::protozero::ConstBytes mm_vmscan_kswapd_wake() const { return at<48>().as_bytes(); }
+  bool has_mm_vmscan_kswapd_sleep() const { return at<49>().valid(); }
+  ::protozero::ConstBytes mm_vmscan_kswapd_sleep() const { return at<49>().as_bytes(); }
+  bool has_binder_transaction() const { return at<50>().valid(); }
+  ::protozero::ConstBytes binder_transaction() const { return at<50>().as_bytes(); }
+  bool has_binder_transaction_received() const { return at<51>().valid(); }
+  ::protozero::ConstBytes binder_transaction_received() const { return at<51>().as_bytes(); }
+  bool has_binder_set_priority() const { return at<52>().valid(); }
+  ::protozero::ConstBytes binder_set_priority() const { return at<52>().as_bytes(); }
+  bool has_binder_lock() const { return at<53>().valid(); }
+  ::protozero::ConstBytes binder_lock() const { return at<53>().as_bytes(); }
+  bool has_binder_locked() const { return at<54>().valid(); }
+  ::protozero::ConstBytes binder_locked() const { return at<54>().as_bytes(); }
+  bool has_binder_unlock() const { return at<55>().valid(); }
+  ::protozero::ConstBytes binder_unlock() const { return at<55>().as_bytes(); }
+  bool has_workqueue_activate_work() const { return at<56>().valid(); }
+  ::protozero::ConstBytes workqueue_activate_work() const { return at<56>().as_bytes(); }
+  bool has_workqueue_execute_end() const { return at<57>().valid(); }
+  ::protozero::ConstBytes workqueue_execute_end() const { return at<57>().as_bytes(); }
+  bool has_workqueue_execute_start() const { return at<58>().valid(); }
+  ::protozero::ConstBytes workqueue_execute_start() const { return at<58>().as_bytes(); }
+  bool has_workqueue_queue_work() const { return at<59>().valid(); }
+  ::protozero::ConstBytes workqueue_queue_work() const { return at<59>().as_bytes(); }
+  bool has_regulator_disable() const { return at<60>().valid(); }
+  ::protozero::ConstBytes regulator_disable() const { return at<60>().as_bytes(); }
+  bool has_regulator_disable_complete() const { return at<61>().valid(); }
+  ::protozero::ConstBytes regulator_disable_complete() const { return at<61>().as_bytes(); }
+  bool has_regulator_enable() const { return at<62>().valid(); }
+  ::protozero::ConstBytes regulator_enable() const { return at<62>().as_bytes(); }
+  bool has_regulator_enable_complete() const { return at<63>().valid(); }
+  ::protozero::ConstBytes regulator_enable_complete() const { return at<63>().as_bytes(); }
+  bool has_regulator_enable_delay() const { return at<64>().valid(); }
+  ::protozero::ConstBytes regulator_enable_delay() const { return at<64>().as_bytes(); }
+  bool has_regulator_set_voltage() const { return at<65>().valid(); }
+  ::protozero::ConstBytes regulator_set_voltage() const { return at<65>().as_bytes(); }
+  bool has_regulator_set_voltage_complete() const { return at<66>().valid(); }
+  ::protozero::ConstBytes regulator_set_voltage_complete() const { return at<66>().as_bytes(); }
+  bool has_cgroup_attach_task() const { return at<67>().valid(); }
+  ::protozero::ConstBytes cgroup_attach_task() const { return at<67>().as_bytes(); }
+  bool has_cgroup_mkdir() const { return at<68>().valid(); }
+  ::protozero::ConstBytes cgroup_mkdir() const { return at<68>().as_bytes(); }
+  bool has_cgroup_remount() const { return at<69>().valid(); }
+  ::protozero::ConstBytes cgroup_remount() const { return at<69>().as_bytes(); }
+  bool has_cgroup_rmdir() const { return at<70>().valid(); }
+  ::protozero::ConstBytes cgroup_rmdir() const { return at<70>().as_bytes(); }
+  bool has_cgroup_transfer_tasks() const { return at<71>().valid(); }
+  ::protozero::ConstBytes cgroup_transfer_tasks() const { return at<71>().as_bytes(); }
+  bool has_cgroup_destroy_root() const { return at<72>().valid(); }
+  ::protozero::ConstBytes cgroup_destroy_root() const { return at<72>().as_bytes(); }
+  bool has_cgroup_release() const { return at<73>().valid(); }
+  ::protozero::ConstBytes cgroup_release() const { return at<73>().as_bytes(); }
+  bool has_cgroup_rename() const { return at<74>().valid(); }
+  ::protozero::ConstBytes cgroup_rename() const { return at<74>().as_bytes(); }
+  bool has_cgroup_setup_root() const { return at<75>().valid(); }
+  ::protozero::ConstBytes cgroup_setup_root() const { return at<75>().as_bytes(); }
+  bool has_mdp_cmd_kickoff() const { return at<76>().valid(); }
+  ::protozero::ConstBytes mdp_cmd_kickoff() const { return at<76>().as_bytes(); }
+  bool has_mdp_commit() const { return at<77>().valid(); }
+  ::protozero::ConstBytes mdp_commit() const { return at<77>().as_bytes(); }
+  bool has_mdp_perf_set_ot() const { return at<78>().valid(); }
+  ::protozero::ConstBytes mdp_perf_set_ot() const { return at<78>().as_bytes(); }
+  bool has_mdp_sspp_change() const { return at<79>().valid(); }
+  ::protozero::ConstBytes mdp_sspp_change() const { return at<79>().as_bytes(); }
+  bool has_tracing_mark_write() const { return at<80>().valid(); }
+  ::protozero::ConstBytes tracing_mark_write() const { return at<80>().as_bytes(); }
+  bool has_mdp_cmd_pingpong_done() const { return at<81>().valid(); }
+  ::protozero::ConstBytes mdp_cmd_pingpong_done() const { return at<81>().as_bytes(); }
+  bool has_mdp_compare_bw() const { return at<82>().valid(); }
+  ::protozero::ConstBytes mdp_compare_bw() const { return at<82>().as_bytes(); }
+  bool has_mdp_perf_set_panic_luts() const { return at<83>().valid(); }
+  ::protozero::ConstBytes mdp_perf_set_panic_luts() const { return at<83>().as_bytes(); }
+  bool has_mdp_sspp_set() const { return at<84>().valid(); }
+  ::protozero::ConstBytes mdp_sspp_set() const { return at<84>().as_bytes(); }
+  bool has_mdp_cmd_readptr_done() const { return at<85>().valid(); }
+  ::protozero::ConstBytes mdp_cmd_readptr_done() const { return at<85>().as_bytes(); }
+  bool has_mdp_misr_crc() const { return at<86>().valid(); }
+  ::protozero::ConstBytes mdp_misr_crc() const { return at<86>().as_bytes(); }
+  bool has_mdp_perf_set_qos_luts() const { return at<87>().valid(); }
+  ::protozero::ConstBytes mdp_perf_set_qos_luts() const { return at<87>().as_bytes(); }
+  bool has_mdp_trace_counter() const { return at<88>().valid(); }
+  ::protozero::ConstBytes mdp_trace_counter() const { return at<88>().as_bytes(); }
+  bool has_mdp_cmd_release_bw() const { return at<89>().valid(); }
+  ::protozero::ConstBytes mdp_cmd_release_bw() const { return at<89>().as_bytes(); }
+  bool has_mdp_mixer_update() const { return at<90>().valid(); }
+  ::protozero::ConstBytes mdp_mixer_update() const { return at<90>().as_bytes(); }
+  bool has_mdp_perf_set_wm_levels() const { return at<91>().valid(); }
+  ::protozero::ConstBytes mdp_perf_set_wm_levels() const { return at<91>().as_bytes(); }
+  bool has_mdp_video_underrun_done() const { return at<92>().valid(); }
+  ::protozero::ConstBytes mdp_video_underrun_done() const { return at<92>().as_bytes(); }
+  bool has_mdp_cmd_wait_pingpong() const { return at<93>().valid(); }
+  ::protozero::ConstBytes mdp_cmd_wait_pingpong() const { return at<93>().as_bytes(); }
+  bool has_mdp_perf_prefill_calc() const { return at<94>().valid(); }
+  ::protozero::ConstBytes mdp_perf_prefill_calc() const { return at<94>().as_bytes(); }
+  bool has_mdp_perf_update_bus() const { return at<95>().valid(); }
+  ::protozero::ConstBytes mdp_perf_update_bus() const { return at<95>().as_bytes(); }
+  bool has_rotator_bw_ao_as_context() const { return at<96>().valid(); }
+  ::protozero::ConstBytes rotator_bw_ao_as_context() const { return at<96>().as_bytes(); }
+  bool has_mm_filemap_add_to_page_cache() const { return at<97>().valid(); }
+  ::protozero::ConstBytes mm_filemap_add_to_page_cache() const { return at<97>().as_bytes(); }
+  bool has_mm_filemap_delete_from_page_cache() const { return at<98>().valid(); }
+  ::protozero::ConstBytes mm_filemap_delete_from_page_cache() const { return at<98>().as_bytes(); }
+  bool has_mm_compaction_begin() const { return at<99>().valid(); }
+  ::protozero::ConstBytes mm_compaction_begin() const { return at<99>().as_bytes(); }
+  bool has_mm_compaction_defer_compaction() const { return at<100>().valid(); }
+  ::protozero::ConstBytes mm_compaction_defer_compaction() const { return at<100>().as_bytes(); }
+  bool has_mm_compaction_deferred() const { return at<101>().valid(); }
+  ::protozero::ConstBytes mm_compaction_deferred() const { return at<101>().as_bytes(); }
+  bool has_mm_compaction_defer_reset() const { return at<102>().valid(); }
+  ::protozero::ConstBytes mm_compaction_defer_reset() const { return at<102>().as_bytes(); }
+  bool has_mm_compaction_end() const { return at<103>().valid(); }
+  ::protozero::ConstBytes mm_compaction_end() const { return at<103>().as_bytes(); }
+  bool has_mm_compaction_finished() const { return at<104>().valid(); }
+  ::protozero::ConstBytes mm_compaction_finished() const { return at<104>().as_bytes(); }
+  bool has_mm_compaction_isolate_freepages() const { return at<105>().valid(); }
+  ::protozero::ConstBytes mm_compaction_isolate_freepages() const { return at<105>().as_bytes(); }
+  bool has_mm_compaction_isolate_migratepages() const { return at<106>().valid(); }
+  ::protozero::ConstBytes mm_compaction_isolate_migratepages() const { return at<106>().as_bytes(); }
+  bool has_mm_compaction_kcompactd_sleep() const { return at<107>().valid(); }
+  ::protozero::ConstBytes mm_compaction_kcompactd_sleep() const { return at<107>().as_bytes(); }
+  bool has_mm_compaction_kcompactd_wake() const { return at<108>().valid(); }
+  ::protozero::ConstBytes mm_compaction_kcompactd_wake() const { return at<108>().as_bytes(); }
+  bool has_mm_compaction_migratepages() const { return at<109>().valid(); }
+  ::protozero::ConstBytes mm_compaction_migratepages() const { return at<109>().as_bytes(); }
+  bool has_mm_compaction_suitable() const { return at<110>().valid(); }
+  ::protozero::ConstBytes mm_compaction_suitable() const { return at<110>().as_bytes(); }
+  bool has_mm_compaction_try_to_compact_pages() const { return at<111>().valid(); }
+  ::protozero::ConstBytes mm_compaction_try_to_compact_pages() const { return at<111>().as_bytes(); }
+  bool has_mm_compaction_wakeup_kcompactd() const { return at<112>().valid(); }
+  ::protozero::ConstBytes mm_compaction_wakeup_kcompactd() const { return at<112>().as_bytes(); }
+  bool has_suspend_resume() const { return at<113>().valid(); }
+  ::protozero::ConstBytes suspend_resume() const { return at<113>().as_bytes(); }
+  bool has_sched_wakeup_new() const { return at<114>().valid(); }
+  ::protozero::ConstBytes sched_wakeup_new() const { return at<114>().as_bytes(); }
+  bool has_block_bio_backmerge() const { return at<115>().valid(); }
+  ::protozero::ConstBytes block_bio_backmerge() const { return at<115>().as_bytes(); }
+  bool has_block_bio_bounce() const { return at<116>().valid(); }
+  ::protozero::ConstBytes block_bio_bounce() const { return at<116>().as_bytes(); }
+  bool has_block_bio_complete() const { return at<117>().valid(); }
+  ::protozero::ConstBytes block_bio_complete() const { return at<117>().as_bytes(); }
+  bool has_block_bio_frontmerge() const { return at<118>().valid(); }
+  ::protozero::ConstBytes block_bio_frontmerge() const { return at<118>().as_bytes(); }
+  bool has_block_bio_queue() const { return at<119>().valid(); }
+  ::protozero::ConstBytes block_bio_queue() const { return at<119>().as_bytes(); }
+  bool has_block_bio_remap() const { return at<120>().valid(); }
+  ::protozero::ConstBytes block_bio_remap() const { return at<120>().as_bytes(); }
+  bool has_block_dirty_buffer() const { return at<121>().valid(); }
+  ::protozero::ConstBytes block_dirty_buffer() const { return at<121>().as_bytes(); }
+  bool has_block_getrq() const { return at<122>().valid(); }
+  ::protozero::ConstBytes block_getrq() const { return at<122>().as_bytes(); }
+  bool has_block_plug() const { return at<123>().valid(); }
+  ::protozero::ConstBytes block_plug() const { return at<123>().as_bytes(); }
+  bool has_block_rq_abort() const { return at<124>().valid(); }
+  ::protozero::ConstBytes block_rq_abort() const { return at<124>().as_bytes(); }
+  bool has_block_rq_complete() const { return at<125>().valid(); }
+  ::protozero::ConstBytes block_rq_complete() const { return at<125>().as_bytes(); }
+  bool has_block_rq_insert() const { return at<126>().valid(); }
+  ::protozero::ConstBytes block_rq_insert() const { return at<126>().as_bytes(); }
+  bool has_block_rq_remap() const { return at<128>().valid(); }
+  ::protozero::ConstBytes block_rq_remap() const { return at<128>().as_bytes(); }
+  bool has_block_rq_requeue() const { return at<129>().valid(); }
+  ::protozero::ConstBytes block_rq_requeue() const { return at<129>().as_bytes(); }
+  bool has_block_sleeprq() const { return at<130>().valid(); }
+  ::protozero::ConstBytes block_sleeprq() const { return at<130>().as_bytes(); }
+  bool has_block_split() const { return at<131>().valid(); }
+  ::protozero::ConstBytes block_split() const { return at<131>().as_bytes(); }
+  bool has_block_touch_buffer() const { return at<132>().valid(); }
+  ::protozero::ConstBytes block_touch_buffer() const { return at<132>().as_bytes(); }
+  bool has_block_unplug() const { return at<133>().valid(); }
+  ::protozero::ConstBytes block_unplug() const { return at<133>().as_bytes(); }
+  bool has_ext4_alloc_da_blocks() const { return at<134>().valid(); }
+  ::protozero::ConstBytes ext4_alloc_da_blocks() const { return at<134>().as_bytes(); }
+  bool has_ext4_allocate_blocks() const { return at<135>().valid(); }
+  ::protozero::ConstBytes ext4_allocate_blocks() const { return at<135>().as_bytes(); }
+  bool has_ext4_allocate_inode() const { return at<136>().valid(); }
+  ::protozero::ConstBytes ext4_allocate_inode() const { return at<136>().as_bytes(); }
+  bool has_ext4_begin_ordered_truncate() const { return at<137>().valid(); }
+  ::protozero::ConstBytes ext4_begin_ordered_truncate() const { return at<137>().as_bytes(); }
+  bool has_ext4_collapse_range() const { return at<138>().valid(); }
+  ::protozero::ConstBytes ext4_collapse_range() const { return at<138>().as_bytes(); }
+  bool has_ext4_da_release_space() const { return at<139>().valid(); }
+  ::protozero::ConstBytes ext4_da_release_space() const { return at<139>().as_bytes(); }
+  bool has_ext4_da_reserve_space() const { return at<140>().valid(); }
+  ::protozero::ConstBytes ext4_da_reserve_space() const { return at<140>().as_bytes(); }
+  bool has_ext4_da_update_reserve_space() const { return at<141>().valid(); }
+  ::protozero::ConstBytes ext4_da_update_reserve_space() const { return at<141>().as_bytes(); }
+  bool has_ext4_da_write_pages() const { return at<142>().valid(); }
+  ::protozero::ConstBytes ext4_da_write_pages() const { return at<142>().as_bytes(); }
+  bool has_ext4_da_write_pages_extent() const { return at<143>().valid(); }
+  ::protozero::ConstBytes ext4_da_write_pages_extent() const { return at<143>().as_bytes(); }
+  bool has_ext4_direct_io_enter() const { return at<144>().valid(); }
+  ::protozero::ConstBytes ext4_direct_io_enter() const { return at<144>().as_bytes(); }
+  bool has_ext4_direct_io_exit() const { return at<145>().valid(); }
+  ::protozero::ConstBytes ext4_direct_io_exit() const { return at<145>().as_bytes(); }
+  bool has_ext4_discard_blocks() const { return at<146>().valid(); }
+  ::protozero::ConstBytes ext4_discard_blocks() const { return at<146>().as_bytes(); }
+  bool has_ext4_discard_preallocations() const { return at<147>().valid(); }
+  ::protozero::ConstBytes ext4_discard_preallocations() const { return at<147>().as_bytes(); }
+  bool has_ext4_drop_inode() const { return at<148>().valid(); }
+  ::protozero::ConstBytes ext4_drop_inode() const { return at<148>().as_bytes(); }
+  bool has_ext4_es_cache_extent() const { return at<149>().valid(); }
+  ::protozero::ConstBytes ext4_es_cache_extent() const { return at<149>().as_bytes(); }
+  bool has_ext4_es_find_delayed_extent_range_enter() const { return at<150>().valid(); }
+  ::protozero::ConstBytes ext4_es_find_delayed_extent_range_enter() const { return at<150>().as_bytes(); }
+  bool has_ext4_es_find_delayed_extent_range_exit() const { return at<151>().valid(); }
+  ::protozero::ConstBytes ext4_es_find_delayed_extent_range_exit() const { return at<151>().as_bytes(); }
+  bool has_ext4_es_insert_extent() const { return at<152>().valid(); }
+  ::protozero::ConstBytes ext4_es_insert_extent() const { return at<152>().as_bytes(); }
+  bool has_ext4_es_lookup_extent_enter() const { return at<153>().valid(); }
+  ::protozero::ConstBytes ext4_es_lookup_extent_enter() const { return at<153>().as_bytes(); }
+  bool has_ext4_es_lookup_extent_exit() const { return at<154>().valid(); }
+  ::protozero::ConstBytes ext4_es_lookup_extent_exit() const { return at<154>().as_bytes(); }
+  bool has_ext4_es_remove_extent() const { return at<155>().valid(); }
+  ::protozero::ConstBytes ext4_es_remove_extent() const { return at<155>().as_bytes(); }
+  bool has_ext4_es_shrink() const { return at<156>().valid(); }
+  ::protozero::ConstBytes ext4_es_shrink() const { return at<156>().as_bytes(); }
+  bool has_ext4_es_shrink_count() const { return at<157>().valid(); }
+  ::protozero::ConstBytes ext4_es_shrink_count() const { return at<157>().as_bytes(); }
+  bool has_ext4_es_shrink_scan_enter() const { return at<158>().valid(); }
+  ::protozero::ConstBytes ext4_es_shrink_scan_enter() const { return at<158>().as_bytes(); }
+  bool has_ext4_es_shrink_scan_exit() const { return at<159>().valid(); }
+  ::protozero::ConstBytes ext4_es_shrink_scan_exit() const { return at<159>().as_bytes(); }
+  bool has_ext4_evict_inode() const { return at<160>().valid(); }
+  ::protozero::ConstBytes ext4_evict_inode() const { return at<160>().as_bytes(); }
+  bool has_ext4_ext_convert_to_initialized_enter() const { return at<161>().valid(); }
+  ::protozero::ConstBytes ext4_ext_convert_to_initialized_enter() const { return at<161>().as_bytes(); }
+  bool has_ext4_ext_convert_to_initialized_fastpath() const { return at<162>().valid(); }
+  ::protozero::ConstBytes ext4_ext_convert_to_initialized_fastpath() const { return at<162>().as_bytes(); }
+  bool has_ext4_ext_handle_unwritten_extents() const { return at<163>().valid(); }
+  ::protozero::ConstBytes ext4_ext_handle_unwritten_extents() const { return at<163>().as_bytes(); }
+  bool has_ext4_ext_in_cache() const { return at<164>().valid(); }
+  ::protozero::ConstBytes ext4_ext_in_cache() const { return at<164>().as_bytes(); }
+  bool has_ext4_ext_load_extent() const { return at<165>().valid(); }
+  ::protozero::ConstBytes ext4_ext_load_extent() const { return at<165>().as_bytes(); }
+  bool has_ext4_ext_map_blocks_enter() const { return at<166>().valid(); }
+  ::protozero::ConstBytes ext4_ext_map_blocks_enter() const { return at<166>().as_bytes(); }
+  bool has_ext4_ext_map_blocks_exit() const { return at<167>().valid(); }
+  ::protozero::ConstBytes ext4_ext_map_blocks_exit() const { return at<167>().as_bytes(); }
+  bool has_ext4_ext_put_in_cache() const { return at<168>().valid(); }
+  ::protozero::ConstBytes ext4_ext_put_in_cache() const { return at<168>().as_bytes(); }
+  bool has_ext4_ext_remove_space() const { return at<169>().valid(); }
+  ::protozero::ConstBytes ext4_ext_remove_space() const { return at<169>().as_bytes(); }
+  bool has_ext4_ext_remove_space_done() const { return at<170>().valid(); }
+  ::protozero::ConstBytes ext4_ext_remove_space_done() const { return at<170>().as_bytes(); }
+  bool has_ext4_ext_rm_idx() const { return at<171>().valid(); }
+  ::protozero::ConstBytes ext4_ext_rm_idx() const { return at<171>().as_bytes(); }
+  bool has_ext4_ext_rm_leaf() const { return at<172>().valid(); }
+  ::protozero::ConstBytes ext4_ext_rm_leaf() const { return at<172>().as_bytes(); }
+  bool has_ext4_ext_show_extent() const { return at<173>().valid(); }
+  ::protozero::ConstBytes ext4_ext_show_extent() const { return at<173>().as_bytes(); }
+  bool has_ext4_fallocate_enter() const { return at<174>().valid(); }
+  ::protozero::ConstBytes ext4_fallocate_enter() const { return at<174>().as_bytes(); }
+  bool has_ext4_fallocate_exit() const { return at<175>().valid(); }
+  ::protozero::ConstBytes ext4_fallocate_exit() const { return at<175>().as_bytes(); }
+  bool has_ext4_find_delalloc_range() const { return at<176>().valid(); }
+  ::protozero::ConstBytes ext4_find_delalloc_range() const { return at<176>().as_bytes(); }
+  bool has_ext4_forget() const { return at<177>().valid(); }
+  ::protozero::ConstBytes ext4_forget() const { return at<177>().as_bytes(); }
+  bool has_ext4_free_blocks() const { return at<178>().valid(); }
+  ::protozero::ConstBytes ext4_free_blocks() const { return at<178>().as_bytes(); }
+  bool has_ext4_free_inode() const { return at<179>().valid(); }
+  ::protozero::ConstBytes ext4_free_inode() const { return at<179>().as_bytes(); }
+  bool has_ext4_get_implied_cluster_alloc_exit() const { return at<180>().valid(); }
+  ::protozero::ConstBytes ext4_get_implied_cluster_alloc_exit() const { return at<180>().as_bytes(); }
+  bool has_ext4_get_reserved_cluster_alloc() const { return at<181>().valid(); }
+  ::protozero::ConstBytes ext4_get_reserved_cluster_alloc() const { return at<181>().as_bytes(); }
+  bool has_ext4_ind_map_blocks_enter() const { return at<182>().valid(); }
+  ::protozero::ConstBytes ext4_ind_map_blocks_enter() const { return at<182>().as_bytes(); }
+  bool has_ext4_ind_map_blocks_exit() const { return at<183>().valid(); }
+  ::protozero::ConstBytes ext4_ind_map_blocks_exit() const { return at<183>().as_bytes(); }
+  bool has_ext4_insert_range() const { return at<184>().valid(); }
+  ::protozero::ConstBytes ext4_insert_range() const { return at<184>().as_bytes(); }
+  bool has_ext4_invalidatepage() const { return at<185>().valid(); }
+  ::protozero::ConstBytes ext4_invalidatepage() const { return at<185>().as_bytes(); }
+  bool has_ext4_journal_start() const { return at<186>().valid(); }
+  ::protozero::ConstBytes ext4_journal_start() const { return at<186>().as_bytes(); }
+  bool has_ext4_journal_start_reserved() const { return at<187>().valid(); }
+  ::protozero::ConstBytes ext4_journal_start_reserved() const { return at<187>().as_bytes(); }
+  bool has_ext4_journalled_invalidatepage() const { return at<188>().valid(); }
+  ::protozero::ConstBytes ext4_journalled_invalidatepage() const { return at<188>().as_bytes(); }
+  bool has_ext4_journalled_write_end() const { return at<189>().valid(); }
+  ::protozero::ConstBytes ext4_journalled_write_end() const { return at<189>().as_bytes(); }
+  bool has_ext4_load_inode() const { return at<190>().valid(); }
+  ::protozero::ConstBytes ext4_load_inode() const { return at<190>().as_bytes(); }
+  bool has_ext4_load_inode_bitmap() const { return at<191>().valid(); }
+  ::protozero::ConstBytes ext4_load_inode_bitmap() const { return at<191>().as_bytes(); }
+  bool has_ext4_mark_inode_dirty() const { return at<192>().valid(); }
+  ::protozero::ConstBytes ext4_mark_inode_dirty() const { return at<192>().as_bytes(); }
+  bool has_ext4_mb_bitmap_load() const { return at<193>().valid(); }
+  ::protozero::ConstBytes ext4_mb_bitmap_load() const { return at<193>().as_bytes(); }
+  bool has_ext4_mb_buddy_bitmap_load() const { return at<194>().valid(); }
+  ::protozero::ConstBytes ext4_mb_buddy_bitmap_load() const { return at<194>().as_bytes(); }
+  bool has_ext4_mb_discard_preallocations() const { return at<195>().valid(); }
+  ::protozero::ConstBytes ext4_mb_discard_preallocations() const { return at<195>().as_bytes(); }
+  bool has_ext4_mb_new_group_pa() const { return at<196>().valid(); }
+  ::protozero::ConstBytes ext4_mb_new_group_pa() const { return at<196>().as_bytes(); }
+  bool has_ext4_mb_new_inode_pa() const { return at<197>().valid(); }
+  ::protozero::ConstBytes ext4_mb_new_inode_pa() const { return at<197>().as_bytes(); }
+  bool has_ext4_mb_release_group_pa() const { return at<198>().valid(); }
+  ::protozero::ConstBytes ext4_mb_release_group_pa() const { return at<198>().as_bytes(); }
+  bool has_ext4_mb_release_inode_pa() const { return at<199>().valid(); }
+  ::protozero::ConstBytes ext4_mb_release_inode_pa() const { return at<199>().as_bytes(); }
+  bool has_ext4_mballoc_alloc() const { return at<200>().valid(); }
+  ::protozero::ConstBytes ext4_mballoc_alloc() const { return at<200>().as_bytes(); }
+  bool has_ext4_mballoc_discard() const { return at<201>().valid(); }
+  ::protozero::ConstBytes ext4_mballoc_discard() const { return at<201>().as_bytes(); }
+  bool has_ext4_mballoc_free() const { return at<202>().valid(); }
+  ::protozero::ConstBytes ext4_mballoc_free() const { return at<202>().as_bytes(); }
+  bool has_ext4_mballoc_prealloc() const { return at<203>().valid(); }
+  ::protozero::ConstBytes ext4_mballoc_prealloc() const { return at<203>().as_bytes(); }
+  bool has_ext4_other_inode_update_time() const { return at<204>().valid(); }
+  ::protozero::ConstBytes ext4_other_inode_update_time() const { return at<204>().as_bytes(); }
+  bool has_ext4_punch_hole() const { return at<205>().valid(); }
+  ::protozero::ConstBytes ext4_punch_hole() const { return at<205>().as_bytes(); }
+  bool has_ext4_read_block_bitmap_load() const { return at<206>().valid(); }
+  ::protozero::ConstBytes ext4_read_block_bitmap_load() const { return at<206>().as_bytes(); }
+  bool has_ext4_readpage() const { return at<207>().valid(); }
+  ::protozero::ConstBytes ext4_readpage() const { return at<207>().as_bytes(); }
+  bool has_ext4_releasepage() const { return at<208>().valid(); }
+  ::protozero::ConstBytes ext4_releasepage() const { return at<208>().as_bytes(); }
+  bool has_ext4_remove_blocks() const { return at<209>().valid(); }
+  ::protozero::ConstBytes ext4_remove_blocks() const { return at<209>().as_bytes(); }
+  bool has_ext4_request_blocks() const { return at<210>().valid(); }
+  ::protozero::ConstBytes ext4_request_blocks() const { return at<210>().as_bytes(); }
+  bool has_ext4_request_inode() const { return at<211>().valid(); }
+  ::protozero::ConstBytes ext4_request_inode() const { return at<211>().as_bytes(); }
+  bool has_ext4_sync_fs() const { return at<212>().valid(); }
+  ::protozero::ConstBytes ext4_sync_fs() const { return at<212>().as_bytes(); }
+  bool has_ext4_trim_all_free() const { return at<213>().valid(); }
+  ::protozero::ConstBytes ext4_trim_all_free() const { return at<213>().as_bytes(); }
+  bool has_ext4_trim_extent() const { return at<214>().valid(); }
+  ::protozero::ConstBytes ext4_trim_extent() const { return at<214>().as_bytes(); }
+  bool has_ext4_truncate_enter() const { return at<215>().valid(); }
+  ::protozero::ConstBytes ext4_truncate_enter() const { return at<215>().as_bytes(); }
+  bool has_ext4_truncate_exit() const { return at<216>().valid(); }
+  ::protozero::ConstBytes ext4_truncate_exit() const { return at<216>().as_bytes(); }
+  bool has_ext4_unlink_enter() const { return at<217>().valid(); }
+  ::protozero::ConstBytes ext4_unlink_enter() const { return at<217>().as_bytes(); }
+  bool has_ext4_unlink_exit() const { return at<218>().valid(); }
+  ::protozero::ConstBytes ext4_unlink_exit() const { return at<218>().as_bytes(); }
+  bool has_ext4_write_begin() const { return at<219>().valid(); }
+  ::protozero::ConstBytes ext4_write_begin() const { return at<219>().as_bytes(); }
+  bool has_ext4_write_end() const { return at<230>().valid(); }
+  ::protozero::ConstBytes ext4_write_end() const { return at<230>().as_bytes(); }
+  bool has_ext4_writepage() const { return at<231>().valid(); }
+  ::protozero::ConstBytes ext4_writepage() const { return at<231>().as_bytes(); }
+  bool has_ext4_writepages() const { return at<232>().valid(); }
+  ::protozero::ConstBytes ext4_writepages() const { return at<232>().as_bytes(); }
+  bool has_ext4_writepages_result() const { return at<233>().valid(); }
+  ::protozero::ConstBytes ext4_writepages_result() const { return at<233>().as_bytes(); }
+  bool has_ext4_zero_range() const { return at<234>().valid(); }
+  ::protozero::ConstBytes ext4_zero_range() const { return at<234>().as_bytes(); }
+  bool has_task_newtask() const { return at<235>().valid(); }
+  ::protozero::ConstBytes task_newtask() const { return at<235>().as_bytes(); }
+  bool has_task_rename() const { return at<236>().valid(); }
+  ::protozero::ConstBytes task_rename() const { return at<236>().as_bytes(); }
+  bool has_sched_process_exec() const { return at<237>().valid(); }
+  ::protozero::ConstBytes sched_process_exec() const { return at<237>().as_bytes(); }
+  bool has_sched_process_exit() const { return at<238>().valid(); }
+  ::protozero::ConstBytes sched_process_exit() const { return at<238>().as_bytes(); }
+  bool has_sched_process_fork() const { return at<239>().valid(); }
+  ::protozero::ConstBytes sched_process_fork() const { return at<239>().as_bytes(); }
+  bool has_sched_process_free() const { return at<240>().valid(); }
+  ::protozero::ConstBytes sched_process_free() const { return at<240>().as_bytes(); }
+  bool has_sched_process_hang() const { return at<241>().valid(); }
+  ::protozero::ConstBytes sched_process_hang() const { return at<241>().as_bytes(); }
+  bool has_sched_process_wait() const { return at<242>().valid(); }
+  ::protozero::ConstBytes sched_process_wait() const { return at<242>().as_bytes(); }
+  bool has_f2fs_do_submit_bio() const { return at<243>().valid(); }
+  ::protozero::ConstBytes f2fs_do_submit_bio() const { return at<243>().as_bytes(); }
+  bool has_f2fs_evict_inode() const { return at<244>().valid(); }
+  ::protozero::ConstBytes f2fs_evict_inode() const { return at<244>().as_bytes(); }
+  bool has_f2fs_fallocate() const { return at<245>().valid(); }
+  ::protozero::ConstBytes f2fs_fallocate() const { return at<245>().as_bytes(); }
+  bool has_f2fs_get_data_block() const { return at<246>().valid(); }
+  ::protozero::ConstBytes f2fs_get_data_block() const { return at<246>().as_bytes(); }
+  bool has_f2fs_get_victim() const { return at<247>().valid(); }
+  ::protozero::ConstBytes f2fs_get_victim() const { return at<247>().as_bytes(); }
+  bool has_f2fs_iget() const { return at<248>().valid(); }
+  ::protozero::ConstBytes f2fs_iget() const { return at<248>().as_bytes(); }
+  bool has_f2fs_iget_exit() const { return at<249>().valid(); }
+  ::protozero::ConstBytes f2fs_iget_exit() const { return at<249>().as_bytes(); }
+  bool has_f2fs_new_inode() const { return at<250>().valid(); }
+  ::protozero::ConstBytes f2fs_new_inode() const { return at<250>().as_bytes(); }
+  bool has_f2fs_readpage() const { return at<251>().valid(); }
+  ::protozero::ConstBytes f2fs_readpage() const { return at<251>().as_bytes(); }
+  bool has_f2fs_reserve_new_block() const { return at<252>().valid(); }
+  ::protozero::ConstBytes f2fs_reserve_new_block() const { return at<252>().as_bytes(); }
+  bool has_f2fs_set_page_dirty() const { return at<253>().valid(); }
+  ::protozero::ConstBytes f2fs_set_page_dirty() const { return at<253>().as_bytes(); }
+  bool has_f2fs_submit_write_page() const { return at<254>().valid(); }
+  ::protozero::ConstBytes f2fs_submit_write_page() const { return at<254>().as_bytes(); }
+  bool has_f2fs_sync_file_enter() const { return at<255>().valid(); }
+  ::protozero::ConstBytes f2fs_sync_file_enter() const { return at<255>().as_bytes(); }
+  bool has_f2fs_sync_file_exit() const { return at<256>().valid(); }
+  ::protozero::ConstBytes f2fs_sync_file_exit() const { return at<256>().as_bytes(); }
+  bool has_f2fs_sync_fs() const { return at<257>().valid(); }
+  ::protozero::ConstBytes f2fs_sync_fs() const { return at<257>().as_bytes(); }
+  bool has_f2fs_truncate() const { return at<258>().valid(); }
+  ::protozero::ConstBytes f2fs_truncate() const { return at<258>().as_bytes(); }
+  bool has_f2fs_truncate_blocks_enter() const { return at<259>().valid(); }
+  ::protozero::ConstBytes f2fs_truncate_blocks_enter() const { return at<259>().as_bytes(); }
+  bool has_f2fs_truncate_blocks_exit() const { return at<260>().valid(); }
+  ::protozero::ConstBytes f2fs_truncate_blocks_exit() const { return at<260>().as_bytes(); }
+  bool has_f2fs_truncate_data_blocks_range() const { return at<261>().valid(); }
+  ::protozero::ConstBytes f2fs_truncate_data_blocks_range() const { return at<261>().as_bytes(); }
+  bool has_f2fs_truncate_inode_blocks_enter() const { return at<262>().valid(); }
+  ::protozero::ConstBytes f2fs_truncate_inode_blocks_enter() const { return at<262>().as_bytes(); }
+  bool has_f2fs_truncate_inode_blocks_exit() const { return at<263>().valid(); }
+  ::protozero::ConstBytes f2fs_truncate_inode_blocks_exit() const { return at<263>().as_bytes(); }
+  bool has_f2fs_truncate_node() const { return at<264>().valid(); }
+  ::protozero::ConstBytes f2fs_truncate_node() const { return at<264>().as_bytes(); }
+  bool has_f2fs_truncate_nodes_enter() const { return at<265>().valid(); }
+  ::protozero::ConstBytes f2fs_truncate_nodes_enter() const { return at<265>().as_bytes(); }
+  bool has_f2fs_truncate_nodes_exit() const { return at<266>().valid(); }
+  ::protozero::ConstBytes f2fs_truncate_nodes_exit() const { return at<266>().as_bytes(); }
+  bool has_f2fs_truncate_partial_nodes() const { return at<267>().valid(); }
+  ::protozero::ConstBytes f2fs_truncate_partial_nodes() const { return at<267>().as_bytes(); }
+  bool has_f2fs_unlink_enter() const { return at<268>().valid(); }
+  ::protozero::ConstBytes f2fs_unlink_enter() const { return at<268>().as_bytes(); }
+  bool has_f2fs_unlink_exit() const { return at<269>().valid(); }
+  ::protozero::ConstBytes f2fs_unlink_exit() const { return at<269>().as_bytes(); }
+  bool has_f2fs_vm_page_mkwrite() const { return at<270>().valid(); }
+  ::protozero::ConstBytes f2fs_vm_page_mkwrite() const { return at<270>().as_bytes(); }
+  bool has_f2fs_write_begin() const { return at<271>().valid(); }
+  ::protozero::ConstBytes f2fs_write_begin() const { return at<271>().as_bytes(); }
+  bool has_f2fs_write_checkpoint() const { return at<272>().valid(); }
+  ::protozero::ConstBytes f2fs_write_checkpoint() const { return at<272>().as_bytes(); }
+  bool has_f2fs_write_end() const { return at<273>().valid(); }
+  ::protozero::ConstBytes f2fs_write_end() const { return at<273>().as_bytes(); }
+  bool has_alloc_pages_iommu_end() const { return at<274>().valid(); }
+  ::protozero::ConstBytes alloc_pages_iommu_end() const { return at<274>().as_bytes(); }
+  bool has_alloc_pages_iommu_fail() const { return at<275>().valid(); }
+  ::protozero::ConstBytes alloc_pages_iommu_fail() const { return at<275>().as_bytes(); }
+  bool has_alloc_pages_iommu_start() const { return at<276>().valid(); }
+  ::protozero::ConstBytes alloc_pages_iommu_start() const { return at<276>().as_bytes(); }
+  bool has_alloc_pages_sys_end() const { return at<277>().valid(); }
+  ::protozero::ConstBytes alloc_pages_sys_end() const { return at<277>().as_bytes(); }
+  bool has_alloc_pages_sys_fail() const { return at<278>().valid(); }
+  ::protozero::ConstBytes alloc_pages_sys_fail() const { return at<278>().as_bytes(); }
+  bool has_alloc_pages_sys_start() const { return at<279>().valid(); }
+  ::protozero::ConstBytes alloc_pages_sys_start() const { return at<279>().as_bytes(); }
+  bool has_dma_alloc_contiguous_retry() const { return at<280>().valid(); }
+  ::protozero::ConstBytes dma_alloc_contiguous_retry() const { return at<280>().as_bytes(); }
+  bool has_iommu_map_range() const { return at<281>().valid(); }
+  ::protozero::ConstBytes iommu_map_range() const { return at<281>().as_bytes(); }
+  bool has_iommu_sec_ptbl_map_range_end() const { return at<282>().valid(); }
+  ::protozero::ConstBytes iommu_sec_ptbl_map_range_end() const { return at<282>().as_bytes(); }
+  bool has_iommu_sec_ptbl_map_range_start() const { return at<283>().valid(); }
+  ::protozero::ConstBytes iommu_sec_ptbl_map_range_start() const { return at<283>().as_bytes(); }
+  bool has_ion_alloc_buffer_end() const { return at<284>().valid(); }
+  ::protozero::ConstBytes ion_alloc_buffer_end() const { return at<284>().as_bytes(); }
+  bool has_ion_alloc_buffer_fail() const { return at<285>().valid(); }
+  ::protozero::ConstBytes ion_alloc_buffer_fail() const { return at<285>().as_bytes(); }
+  bool has_ion_alloc_buffer_fallback() const { return at<286>().valid(); }
+  ::protozero::ConstBytes ion_alloc_buffer_fallback() const { return at<286>().as_bytes(); }
+  bool has_ion_alloc_buffer_start() const { return at<287>().valid(); }
+  ::protozero::ConstBytes ion_alloc_buffer_start() const { return at<287>().as_bytes(); }
+  bool has_ion_cp_alloc_retry() const { return at<288>().valid(); }
+  ::protozero::ConstBytes ion_cp_alloc_retry() const { return at<288>().as_bytes(); }
+  bool has_ion_cp_secure_buffer_end() const { return at<289>().valid(); }
+  ::protozero::ConstBytes ion_cp_secure_buffer_end() const { return at<289>().as_bytes(); }
+  bool has_ion_cp_secure_buffer_start() const { return at<290>().valid(); }
+  ::protozero::ConstBytes ion_cp_secure_buffer_start() const { return at<290>().as_bytes(); }
+  bool has_ion_prefetching() const { return at<291>().valid(); }
+  ::protozero::ConstBytes ion_prefetching() const { return at<291>().as_bytes(); }
+  bool has_ion_secure_cma_add_to_pool_end() const { return at<292>().valid(); }
+  ::protozero::ConstBytes ion_secure_cma_add_to_pool_end() const { return at<292>().as_bytes(); }
+  bool has_ion_secure_cma_add_to_pool_start() const { return at<293>().valid(); }
+  ::protozero::ConstBytes ion_secure_cma_add_to_pool_start() const { return at<293>().as_bytes(); }
+  bool has_ion_secure_cma_allocate_end() const { return at<294>().valid(); }
+  ::protozero::ConstBytes ion_secure_cma_allocate_end() const { return at<294>().as_bytes(); }
+  bool has_ion_secure_cma_allocate_start() const { return at<295>().valid(); }
+  ::protozero::ConstBytes ion_secure_cma_allocate_start() const { return at<295>().as_bytes(); }
+  bool has_ion_secure_cma_shrink_pool_end() const { return at<296>().valid(); }
+  ::protozero::ConstBytes ion_secure_cma_shrink_pool_end() const { return at<296>().as_bytes(); }
+  bool has_ion_secure_cma_shrink_pool_start() const { return at<297>().valid(); }
+  ::protozero::ConstBytes ion_secure_cma_shrink_pool_start() const { return at<297>().as_bytes(); }
+  bool has_kfree() const { return at<298>().valid(); }
+  ::protozero::ConstBytes kfree() const { return at<298>().as_bytes(); }
+  bool has_kmalloc() const { return at<299>().valid(); }
+  ::protozero::ConstBytes kmalloc() const { return at<299>().as_bytes(); }
+  bool has_kmalloc_node() const { return at<300>().valid(); }
+  ::protozero::ConstBytes kmalloc_node() const { return at<300>().as_bytes(); }
+  bool has_kmem_cache_alloc() const { return at<301>().valid(); }
+  ::protozero::ConstBytes kmem_cache_alloc() const { return at<301>().as_bytes(); }
+  bool has_kmem_cache_alloc_node() const { return at<302>().valid(); }
+  ::protozero::ConstBytes kmem_cache_alloc_node() const { return at<302>().as_bytes(); }
+  bool has_kmem_cache_free() const { return at<303>().valid(); }
+  ::protozero::ConstBytes kmem_cache_free() const { return at<303>().as_bytes(); }
+  bool has_migrate_pages_end() const { return at<304>().valid(); }
+  ::protozero::ConstBytes migrate_pages_end() const { return at<304>().as_bytes(); }
+  bool has_migrate_pages_start() const { return at<305>().valid(); }
+  ::protozero::ConstBytes migrate_pages_start() const { return at<305>().as_bytes(); }
+  bool has_migrate_retry() const { return at<306>().valid(); }
+  ::protozero::ConstBytes migrate_retry() const { return at<306>().as_bytes(); }
+  bool has_mm_page_alloc() const { return at<307>().valid(); }
+  ::protozero::ConstBytes mm_page_alloc() const { return at<307>().as_bytes(); }
+  bool has_mm_page_alloc_extfrag() const { return at<308>().valid(); }
+  ::protozero::ConstBytes mm_page_alloc_extfrag() const { return at<308>().as_bytes(); }
+  bool has_mm_page_alloc_zone_locked() const { return at<309>().valid(); }
+  ::protozero::ConstBytes mm_page_alloc_zone_locked() const { return at<309>().as_bytes(); }
+  bool has_mm_page_free() const { return at<310>().valid(); }
+  ::protozero::ConstBytes mm_page_free() const { return at<310>().as_bytes(); }
+  bool has_mm_page_free_batched() const { return at<311>().valid(); }
+  ::protozero::ConstBytes mm_page_free_batched() const { return at<311>().as_bytes(); }
+  bool has_mm_page_pcpu_drain() const { return at<312>().valid(); }
+  ::protozero::ConstBytes mm_page_pcpu_drain() const { return at<312>().as_bytes(); }
+  bool has_rss_stat() const { return at<313>().valid(); }
+  ::protozero::ConstBytes rss_stat() const { return at<313>().as_bytes(); }
+  bool has_ion_heap_shrink() const { return at<314>().valid(); }
+  ::protozero::ConstBytes ion_heap_shrink() const { return at<314>().as_bytes(); }
+  bool has_ion_heap_grow() const { return at<315>().valid(); }
+  ::protozero::ConstBytes ion_heap_grow() const { return at<315>().as_bytes(); }
+  bool has_fence_init() const { return at<316>().valid(); }
+  ::protozero::ConstBytes fence_init() const { return at<316>().as_bytes(); }
+  bool has_fence_destroy() const { return at<317>().valid(); }
+  ::protozero::ConstBytes fence_destroy() const { return at<317>().as_bytes(); }
+  bool has_fence_enable_signal() const { return at<318>().valid(); }
+  ::protozero::ConstBytes fence_enable_signal() const { return at<318>().as_bytes(); }
+  bool has_fence_signaled() const { return at<319>().valid(); }
+  ::protozero::ConstBytes fence_signaled() const { return at<319>().as_bytes(); }
+  bool has_clk_enable() const { return at<320>().valid(); }
+  ::protozero::ConstBytes clk_enable() const { return at<320>().as_bytes(); }
+  bool has_clk_disable() const { return at<321>().valid(); }
+  ::protozero::ConstBytes clk_disable() const { return at<321>().as_bytes(); }
+  bool has_clk_set_rate() const { return at<322>().valid(); }
+  ::protozero::ConstBytes clk_set_rate() const { return at<322>().as_bytes(); }
+  bool has_binder_transaction_alloc_buf() const { return at<323>().valid(); }
+  ::protozero::ConstBytes binder_transaction_alloc_buf() const { return at<323>().as_bytes(); }
+  bool has_signal_deliver() const { return at<324>().valid(); }
+  ::protozero::ConstBytes signal_deliver() const { return at<324>().as_bytes(); }
+  bool has_signal_generate() const { return at<325>().valid(); }
+  ::protozero::ConstBytes signal_generate() const { return at<325>().as_bytes(); }
+  bool has_oom_score_adj_update() const { return at<326>().valid(); }
+  ::protozero::ConstBytes oom_score_adj_update() const { return at<326>().as_bytes(); }
+  bool has_generic() const { return at<327>().valid(); }
+  ::protozero::ConstBytes generic() const { return at<327>().as_bytes(); }
+  bool has_mm_event_record() const { return at<328>().valid(); }
+  ::protozero::ConstBytes mm_event_record() const { return at<328>().as_bytes(); }
+  bool has_sys_enter() const { return at<329>().valid(); }
+  ::protozero::ConstBytes sys_enter() const { return at<329>().as_bytes(); }
+  bool has_sys_exit() const { return at<330>().valid(); }
+  ::protozero::ConstBytes sys_exit() const { return at<330>().as_bytes(); }
+  bool has_zero() const { return at<331>().valid(); }
+  ::protozero::ConstBytes zero() const { return at<331>().as_bytes(); }
+  bool has_gpu_frequency() const { return at<332>().valid(); }
+  ::protozero::ConstBytes gpu_frequency() const { return at<332>().as_bytes(); }
+  bool has_sde_tracing_mark_write() const { return at<333>().valid(); }
+  ::protozero::ConstBytes sde_tracing_mark_write() const { return at<333>().as_bytes(); }
+  bool has_mark_victim() const { return at<334>().valid(); }
+  ::protozero::ConstBytes mark_victim() const { return at<334>().as_bytes(); }
+  bool has_ion_stat() const { return at<335>().valid(); }
+  ::protozero::ConstBytes ion_stat() const { return at<335>().as_bytes(); }
+  bool has_ion_buffer_create() const { return at<336>().valid(); }
+  ::protozero::ConstBytes ion_buffer_create() const { return at<336>().as_bytes(); }
+  bool has_ion_buffer_destroy() const { return at<337>().valid(); }
+  ::protozero::ConstBytes ion_buffer_destroy() const { return at<337>().as_bytes(); }
+  bool has_scm_call_start() const { return at<338>().valid(); }
+  ::protozero::ConstBytes scm_call_start() const { return at<338>().as_bytes(); }
+  bool has_scm_call_end() const { return at<339>().valid(); }
+  ::protozero::ConstBytes scm_call_end() const { return at<339>().as_bytes(); }
+  bool has_gpu_mem_total() const { return at<340>().valid(); }
+  ::protozero::ConstBytes gpu_mem_total() const { return at<340>().as_bytes(); }
+  bool has_thermal_temperature() const { return at<341>().valid(); }
+  ::protozero::ConstBytes thermal_temperature() const { return at<341>().as_bytes(); }
+  bool has_cdev_update() const { return at<342>().valid(); }
+  ::protozero::ConstBytes cdev_update() const { return at<342>().as_bytes(); }
+  bool has_cpuhp_exit() const { return at<343>().valid(); }
+  ::protozero::ConstBytes cpuhp_exit() const { return at<343>().as_bytes(); }
+  bool has_cpuhp_multi_enter() const { return at<344>().valid(); }
+  ::protozero::ConstBytes cpuhp_multi_enter() const { return at<344>().as_bytes(); }
+  bool has_cpuhp_enter() const { return at<345>().valid(); }
+  ::protozero::ConstBytes cpuhp_enter() const { return at<345>().as_bytes(); }
+  bool has_cpuhp_latency() const { return at<346>().valid(); }
+  ::protozero::ConstBytes cpuhp_latency() const { return at<346>().as_bytes(); }
+  bool has_fastrpc_dma_stat() const { return at<347>().valid(); }
+  ::protozero::ConstBytes fastrpc_dma_stat() const { return at<347>().as_bytes(); }
+  bool has_dpu_tracing_mark_write() const { return at<348>().valid(); }
+  ::protozero::ConstBytes dpu_tracing_mark_write() const { return at<348>().as_bytes(); }
+  bool has_g2d_tracing_mark_write() const { return at<349>().valid(); }
+  ::protozero::ConstBytes g2d_tracing_mark_write() const { return at<349>().as_bytes(); }
+  bool has_mali_tracing_mark_write() const { return at<350>().valid(); }
+  ::protozero::ConstBytes mali_tracing_mark_write() const { return at<350>().as_bytes(); }
+  bool has_dma_heap_stat() const { return at<351>().valid(); }
+  ::protozero::ConstBytes dma_heap_stat() const { return at<351>().as_bytes(); }
+  bool has_cpuhp_pause() const { return at<352>().valid(); }
+  ::protozero::ConstBytes cpuhp_pause() const { return at<352>().as_bytes(); }
+  bool has_sched_pi_setprio() const { return at<353>().valid(); }
+  ::protozero::ConstBytes sched_pi_setprio() const { return at<353>().as_bytes(); }
+  bool has_sde_sde_evtlog() const { return at<354>().valid(); }
+  ::protozero::ConstBytes sde_sde_evtlog() const { return at<354>().as_bytes(); }
+  bool has_sde_sde_perf_calc_crtc() const { return at<355>().valid(); }
+  ::protozero::ConstBytes sde_sde_perf_calc_crtc() const { return at<355>().as_bytes(); }
+  bool has_sde_sde_perf_crtc_update() const { return at<356>().valid(); }
+  ::protozero::ConstBytes sde_sde_perf_crtc_update() const { return at<356>().as_bytes(); }
+  bool has_sde_sde_perf_set_qos_luts() const { return at<357>().valid(); }
+  ::protozero::ConstBytes sde_sde_perf_set_qos_luts() const { return at<357>().as_bytes(); }
+  bool has_sde_sde_perf_update_bus() const { return at<358>().valid(); }
+  ::protozero::ConstBytes sde_sde_perf_update_bus() const { return at<358>().as_bytes(); }
+  bool has_rss_stat_throttled() const { return at<359>().valid(); }
+  ::protozero::ConstBytes rss_stat_throttled() const { return at<359>().as_bytes(); }
+  bool has_netif_receive_skb() const { return at<360>().valid(); }
+  ::protozero::ConstBytes netif_receive_skb() const { return at<360>().as_bytes(); }
+  bool has_net_dev_xmit() const { return at<361>().valid(); }
+  ::protozero::ConstBytes net_dev_xmit() const { return at<361>().as_bytes(); }
+  bool has_inet_sock_set_state() const { return at<362>().valid(); }
+  ::protozero::ConstBytes inet_sock_set_state() const { return at<362>().as_bytes(); }
+  bool has_tcp_retransmit_skb() const { return at<363>().valid(); }
+  ::protozero::ConstBytes tcp_retransmit_skb() const { return at<363>().as_bytes(); }
+  bool has_cros_ec_sensorhub_data() const { return at<364>().valid(); }
+  ::protozero::ConstBytes cros_ec_sensorhub_data() const { return at<364>().as_bytes(); }
+  bool has_napi_gro_receive_entry() const { return at<365>().valid(); }
+  ::protozero::ConstBytes napi_gro_receive_entry() const { return at<365>().as_bytes(); }
+  bool has_napi_gro_receive_exit() const { return at<366>().valid(); }
+  ::protozero::ConstBytes napi_gro_receive_exit() const { return at<366>().as_bytes(); }
+  bool has_kfree_skb() const { return at<367>().valid(); }
+  ::protozero::ConstBytes kfree_skb() const { return at<367>().as_bytes(); }
+  bool has_kvm_access_fault() const { return at<368>().valid(); }
+  ::protozero::ConstBytes kvm_access_fault() const { return at<368>().as_bytes(); }
+  bool has_kvm_ack_irq() const { return at<369>().valid(); }
+  ::protozero::ConstBytes kvm_ack_irq() const { return at<369>().as_bytes(); }
+  bool has_kvm_age_hva() const { return at<370>().valid(); }
+  ::protozero::ConstBytes kvm_age_hva() const { return at<370>().as_bytes(); }
+  bool has_kvm_age_page() const { return at<371>().valid(); }
+  ::protozero::ConstBytes kvm_age_page() const { return at<371>().as_bytes(); }
+  bool has_kvm_arm_clear_debug() const { return at<372>().valid(); }
+  ::protozero::ConstBytes kvm_arm_clear_debug() const { return at<372>().as_bytes(); }
+  bool has_kvm_arm_set_dreg32() const { return at<373>().valid(); }
+  ::protozero::ConstBytes kvm_arm_set_dreg32() const { return at<373>().as_bytes(); }
+  bool has_kvm_arm_set_regset() const { return at<374>().valid(); }
+  ::protozero::ConstBytes kvm_arm_set_regset() const { return at<374>().as_bytes(); }
+  bool has_kvm_arm_setup_debug() const { return at<375>().valid(); }
+  ::protozero::ConstBytes kvm_arm_setup_debug() const { return at<375>().as_bytes(); }
+  bool has_kvm_entry() const { return at<376>().valid(); }
+  ::protozero::ConstBytes kvm_entry() const { return at<376>().as_bytes(); }
+  bool has_kvm_exit() const { return at<377>().valid(); }
+  ::protozero::ConstBytes kvm_exit() const { return at<377>().as_bytes(); }
+  bool has_kvm_fpu() const { return at<378>().valid(); }
+  ::protozero::ConstBytes kvm_fpu() const { return at<378>().as_bytes(); }
+  bool has_kvm_get_timer_map() const { return at<379>().valid(); }
+  ::protozero::ConstBytes kvm_get_timer_map() const { return at<379>().as_bytes(); }
+  bool has_kvm_guest_fault() const { return at<380>().valid(); }
+  ::protozero::ConstBytes kvm_guest_fault() const { return at<380>().as_bytes(); }
+  bool has_kvm_handle_sys_reg() const { return at<381>().valid(); }
+  ::protozero::ConstBytes kvm_handle_sys_reg() const { return at<381>().as_bytes(); }
+  bool has_kvm_hvc_arm64() const { return at<382>().valid(); }
+  ::protozero::ConstBytes kvm_hvc_arm64() const { return at<382>().as_bytes(); }
+  bool has_kvm_irq_line() const { return at<383>().valid(); }
+  ::protozero::ConstBytes kvm_irq_line() const { return at<383>().as_bytes(); }
+  bool has_kvm_mmio() const { return at<384>().valid(); }
+  ::protozero::ConstBytes kvm_mmio() const { return at<384>().as_bytes(); }
+  bool has_kvm_mmio_emulate() const { return at<385>().valid(); }
+  ::protozero::ConstBytes kvm_mmio_emulate() const { return at<385>().as_bytes(); }
+  bool has_kvm_set_guest_debug() const { return at<386>().valid(); }
+  ::protozero::ConstBytes kvm_set_guest_debug() const { return at<386>().as_bytes(); }
+  bool has_kvm_set_irq() const { return at<387>().valid(); }
+  ::protozero::ConstBytes kvm_set_irq() const { return at<387>().as_bytes(); }
+  bool has_kvm_set_spte_hva() const { return at<388>().valid(); }
+  ::protozero::ConstBytes kvm_set_spte_hva() const { return at<388>().as_bytes(); }
+  bool has_kvm_set_way_flush() const { return at<389>().valid(); }
+  ::protozero::ConstBytes kvm_set_way_flush() const { return at<389>().as_bytes(); }
+  bool has_kvm_sys_access() const { return at<390>().valid(); }
+  ::protozero::ConstBytes kvm_sys_access() const { return at<390>().as_bytes(); }
+  bool has_kvm_test_age_hva() const { return at<391>().valid(); }
+  ::protozero::ConstBytes kvm_test_age_hva() const { return at<391>().as_bytes(); }
+  bool has_kvm_timer_emulate() const { return at<392>().valid(); }
+  ::protozero::ConstBytes kvm_timer_emulate() const { return at<392>().as_bytes(); }
+  bool has_kvm_timer_hrtimer_expire() const { return at<393>().valid(); }
+  ::protozero::ConstBytes kvm_timer_hrtimer_expire() const { return at<393>().as_bytes(); }
+  bool has_kvm_timer_restore_state() const { return at<394>().valid(); }
+  ::protozero::ConstBytes kvm_timer_restore_state() const { return at<394>().as_bytes(); }
+  bool has_kvm_timer_save_state() const { return at<395>().valid(); }
+  ::protozero::ConstBytes kvm_timer_save_state() const { return at<395>().as_bytes(); }
+  bool has_kvm_timer_update_irq() const { return at<396>().valid(); }
+  ::protozero::ConstBytes kvm_timer_update_irq() const { return at<396>().as_bytes(); }
+  bool has_kvm_toggle_cache() const { return at<397>().valid(); }
+  ::protozero::ConstBytes kvm_toggle_cache() const { return at<397>().as_bytes(); }
+  bool has_kvm_unmap_hva_range() const { return at<398>().valid(); }
+  ::protozero::ConstBytes kvm_unmap_hva_range() const { return at<398>().as_bytes(); }
+  bool has_kvm_userspace_exit() const { return at<399>().valid(); }
+  ::protozero::ConstBytes kvm_userspace_exit() const { return at<399>().as_bytes(); }
+  bool has_kvm_vcpu_wakeup() const { return at<400>().valid(); }
+  ::protozero::ConstBytes kvm_vcpu_wakeup() const { return at<400>().as_bytes(); }
+  bool has_kvm_wfx_arm64() const { return at<401>().valid(); }
+  ::protozero::ConstBytes kvm_wfx_arm64() const { return at<401>().as_bytes(); }
+  bool has_trap_reg() const { return at<402>().valid(); }
+  ::protozero::ConstBytes trap_reg() const { return at<402>().as_bytes(); }
+  bool has_vgic_update_irq_pending() const { return at<403>().valid(); }
+  ::protozero::ConstBytes vgic_update_irq_pending() const { return at<403>().as_bytes(); }
+  bool has_wakeup_source_activate() const { return at<404>().valid(); }
+  ::protozero::ConstBytes wakeup_source_activate() const { return at<404>().as_bytes(); }
+  bool has_wakeup_source_deactivate() const { return at<405>().valid(); }
+  ::protozero::ConstBytes wakeup_source_deactivate() const { return at<405>().as_bytes(); }
+  bool has_ufshcd_command() const { return at<406>().valid(); }
+  ::protozero::ConstBytes ufshcd_command() const { return at<406>().as_bytes(); }
+  bool has_ufshcd_clk_gating() const { return at<407>().valid(); }
+  ::protozero::ConstBytes ufshcd_clk_gating() const { return at<407>().as_bytes(); }
+  bool has_console() const { return at<408>().valid(); }
+  ::protozero::ConstBytes console() const { return at<408>().as_bytes(); }
+  bool has_drm_vblank_event() const { return at<409>().valid(); }
+  ::protozero::ConstBytes drm_vblank_event() const { return at<409>().as_bytes(); }
+  bool has_drm_vblank_event_delivered() const { return at<410>().valid(); }
+  ::protozero::ConstBytes drm_vblank_event_delivered() const { return at<410>().as_bytes(); }
+  bool has_drm_sched_job() const { return at<411>().valid(); }
+  ::protozero::ConstBytes drm_sched_job() const { return at<411>().as_bytes(); }
+  bool has_drm_run_job() const { return at<412>().valid(); }
+  ::protozero::ConstBytes drm_run_job() const { return at<412>().as_bytes(); }
+  bool has_drm_sched_process_job() const { return at<413>().valid(); }
+  ::protozero::ConstBytes drm_sched_process_job() const { return at<413>().as_bytes(); }
+  bool has_dma_fence_init() const { return at<414>().valid(); }
+  ::protozero::ConstBytes dma_fence_init() const { return at<414>().as_bytes(); }
+  bool has_dma_fence_emit() const { return at<415>().valid(); }
+  ::protozero::ConstBytes dma_fence_emit() const { return at<415>().as_bytes(); }
+  bool has_dma_fence_signaled() const { return at<416>().valid(); }
+  ::protozero::ConstBytes dma_fence_signaled() const { return at<416>().as_bytes(); }
+  bool has_dma_fence_wait_start() const { return at<417>().valid(); }
+  ::protozero::ConstBytes dma_fence_wait_start() const { return at<417>().as_bytes(); }
+  bool has_dma_fence_wait_end() const { return at<418>().valid(); }
+  ::protozero::ConstBytes dma_fence_wait_end() const { return at<418>().as_bytes(); }
+  bool has_f2fs_iostat() const { return at<419>().valid(); }
+  ::protozero::ConstBytes f2fs_iostat() const { return at<419>().as_bytes(); }
+  bool has_f2fs_iostat_latency() const { return at<420>().valid(); }
+  ::protozero::ConstBytes f2fs_iostat_latency() const { return at<420>().as_bytes(); }
+  bool has_sched_cpu_util_cfs() const { return at<421>().valid(); }
+  ::protozero::ConstBytes sched_cpu_util_cfs() const { return at<421>().as_bytes(); }
+  bool has_v4l2_qbuf() const { return at<422>().valid(); }
+  ::protozero::ConstBytes v4l2_qbuf() const { return at<422>().as_bytes(); }
+  bool has_v4l2_dqbuf() const { return at<423>().valid(); }
+  ::protozero::ConstBytes v4l2_dqbuf() const { return at<423>().as_bytes(); }
+  bool has_vb2_v4l2_buf_queue() const { return at<424>().valid(); }
+  ::protozero::ConstBytes vb2_v4l2_buf_queue() const { return at<424>().as_bytes(); }
+  bool has_vb2_v4l2_buf_done() const { return at<425>().valid(); }
+  ::protozero::ConstBytes vb2_v4l2_buf_done() const { return at<425>().as_bytes(); }
+  bool has_vb2_v4l2_qbuf() const { return at<426>().valid(); }
+  ::protozero::ConstBytes vb2_v4l2_qbuf() const { return at<426>().as_bytes(); }
+  bool has_vb2_v4l2_dqbuf() const { return at<427>().valid(); }
+  ::protozero::ConstBytes vb2_v4l2_dqbuf() const { return at<427>().as_bytes(); }
+  bool has_dsi_cmd_fifo_status() const { return at<428>().valid(); }
+  ::protozero::ConstBytes dsi_cmd_fifo_status() const { return at<428>().as_bytes(); }
+  bool has_dsi_rx() const { return at<429>().valid(); }
+  ::protozero::ConstBytes dsi_rx() const { return at<429>().as_bytes(); }
+  bool has_dsi_tx() const { return at<430>().valid(); }
+  ::protozero::ConstBytes dsi_tx() const { return at<430>().as_bytes(); }
+  bool has_android_fs_dataread_end() const { return at<431>().valid(); }
+  ::protozero::ConstBytes android_fs_dataread_end() const { return at<431>().as_bytes(); }
+  bool has_android_fs_dataread_start() const { return at<432>().valid(); }
+  ::protozero::ConstBytes android_fs_dataread_start() const { return at<432>().as_bytes(); }
+  bool has_android_fs_datawrite_end() const { return at<433>().valid(); }
+  ::protozero::ConstBytes android_fs_datawrite_end() const { return at<433>().as_bytes(); }
+  bool has_android_fs_datawrite_start() const { return at<434>().valid(); }
+  ::protozero::ConstBytes android_fs_datawrite_start() const { return at<434>().as_bytes(); }
+  bool has_android_fs_fsync_end() const { return at<435>().valid(); }
+  ::protozero::ConstBytes android_fs_fsync_end() const { return at<435>().as_bytes(); }
+  bool has_android_fs_fsync_start() const { return at<436>().valid(); }
+  ::protozero::ConstBytes android_fs_fsync_start() const { return at<436>().as_bytes(); }
+  bool has_funcgraph_entry() const { return at<437>().valid(); }
+  ::protozero::ConstBytes funcgraph_entry() const { return at<437>().as_bytes(); }
+  bool has_funcgraph_exit() const { return at<438>().valid(); }
+  ::protozero::ConstBytes funcgraph_exit() const { return at<438>().as_bytes(); }
+  bool has_virtio_video_cmd() const { return at<439>().valid(); }
+  ::protozero::ConstBytes virtio_video_cmd() const { return at<439>().as_bytes(); }
+  bool has_virtio_video_cmd_done() const { return at<440>().valid(); }
+  ::protozero::ConstBytes virtio_video_cmd_done() const { return at<440>().as_bytes(); }
+  bool has_virtio_video_resource_queue() const { return at<441>().valid(); }
+  ::protozero::ConstBytes virtio_video_resource_queue() const { return at<441>().as_bytes(); }
+  bool has_virtio_video_resource_queue_done() const { return at<442>().valid(); }
+  ::protozero::ConstBytes virtio_video_resource_queue_done() const { return at<442>().as_bytes(); }
+  bool has_mm_shrink_slab_start() const { return at<443>().valid(); }
+  ::protozero::ConstBytes mm_shrink_slab_start() const { return at<443>().as_bytes(); }
+  bool has_mm_shrink_slab_end() const { return at<444>().valid(); }
+  ::protozero::ConstBytes mm_shrink_slab_end() const { return at<444>().as_bytes(); }
+  bool has_trusty_smc() const { return at<445>().valid(); }
+  ::protozero::ConstBytes trusty_smc() const { return at<445>().as_bytes(); }
+  bool has_trusty_smc_done() const { return at<446>().valid(); }
+  ::protozero::ConstBytes trusty_smc_done() const { return at<446>().as_bytes(); }
+  bool has_trusty_std_call32() const { return at<447>().valid(); }
+  ::protozero::ConstBytes trusty_std_call32() const { return at<447>().as_bytes(); }
+  bool has_trusty_std_call32_done() const { return at<448>().valid(); }
+  ::protozero::ConstBytes trusty_std_call32_done() const { return at<448>().as_bytes(); }
+  bool has_trusty_share_memory() const { return at<449>().valid(); }
+  ::protozero::ConstBytes trusty_share_memory() const { return at<449>().as_bytes(); }
+  bool has_trusty_share_memory_done() const { return at<450>().valid(); }
+  ::protozero::ConstBytes trusty_share_memory_done() const { return at<450>().as_bytes(); }
+  bool has_trusty_reclaim_memory() const { return at<451>().valid(); }
+  ::protozero::ConstBytes trusty_reclaim_memory() const { return at<451>().as_bytes(); }
+  bool has_trusty_reclaim_memory_done() const { return at<452>().valid(); }
+  ::protozero::ConstBytes trusty_reclaim_memory_done() const { return at<452>().as_bytes(); }
+  bool has_trusty_irq() const { return at<453>().valid(); }
+  ::protozero::ConstBytes trusty_irq() const { return at<453>().as_bytes(); }
+  bool has_trusty_ipc_handle_event() const { return at<454>().valid(); }
+  ::protozero::ConstBytes trusty_ipc_handle_event() const { return at<454>().as_bytes(); }
+  bool has_trusty_ipc_connect() const { return at<455>().valid(); }
+  ::protozero::ConstBytes trusty_ipc_connect() const { return at<455>().as_bytes(); }
+  bool has_trusty_ipc_connect_end() const { return at<456>().valid(); }
+  ::protozero::ConstBytes trusty_ipc_connect_end() const { return at<456>().as_bytes(); }
+  bool has_trusty_ipc_write() const { return at<457>().valid(); }
+  ::protozero::ConstBytes trusty_ipc_write() const { return at<457>().as_bytes(); }
+  bool has_trusty_ipc_poll() const { return at<458>().valid(); }
+  ::protozero::ConstBytes trusty_ipc_poll() const { return at<458>().as_bytes(); }
+  bool has_trusty_ipc_read() const { return at<460>().valid(); }
+  ::protozero::ConstBytes trusty_ipc_read() const { return at<460>().as_bytes(); }
+  bool has_trusty_ipc_read_end() const { return at<461>().valid(); }
+  ::protozero::ConstBytes trusty_ipc_read_end() const { return at<461>().as_bytes(); }
+  bool has_trusty_ipc_rx() const { return at<462>().valid(); }
+  ::protozero::ConstBytes trusty_ipc_rx() const { return at<462>().as_bytes(); }
+  bool has_trusty_enqueue_nop() const { return at<464>().valid(); }
+  ::protozero::ConstBytes trusty_enqueue_nop() const { return at<464>().as_bytes(); }
+  bool has_cma_alloc_start() const { return at<465>().valid(); }
+  ::protozero::ConstBytes cma_alloc_start() const { return at<465>().as_bytes(); }
+  bool has_cma_alloc_info() const { return at<466>().valid(); }
+  ::protozero::ConstBytes cma_alloc_info() const { return at<466>().as_bytes(); }
+  bool has_lwis_tracing_mark_write() const { return at<467>().valid(); }
+  ::protozero::ConstBytes lwis_tracing_mark_write() const { return at<467>().as_bytes(); }
+  bool has_virtio_gpu_cmd_queue() const { return at<468>().valid(); }
+  ::protozero::ConstBytes virtio_gpu_cmd_queue() const { return at<468>().as_bytes(); }
+  bool has_virtio_gpu_cmd_response() const { return at<469>().valid(); }
+  ::protozero::ConstBytes virtio_gpu_cmd_response() const { return at<469>().as_bytes(); }
+  bool has_mali_mali_kcpu_cqs_set() const { return at<470>().valid(); }
+  ::protozero::ConstBytes mali_mali_kcpu_cqs_set() const { return at<470>().as_bytes(); }
+  bool has_mali_mali_kcpu_cqs_wait_start() const { return at<471>().valid(); }
+  ::protozero::ConstBytes mali_mali_kcpu_cqs_wait_start() const { return at<471>().as_bytes(); }
+  bool has_mali_mali_kcpu_cqs_wait_end() const { return at<472>().valid(); }
+  ::protozero::ConstBytes mali_mali_kcpu_cqs_wait_end() const { return at<472>().as_bytes(); }
+  bool has_mali_mali_kcpu_fence_signal() const { return at<473>().valid(); }
+  ::protozero::ConstBytes mali_mali_kcpu_fence_signal() const { return at<473>().as_bytes(); }
+  bool has_mali_mali_kcpu_fence_wait_start() const { return at<474>().valid(); }
+  ::protozero::ConstBytes mali_mali_kcpu_fence_wait_start() const { return at<474>().as_bytes(); }
+  bool has_mali_mali_kcpu_fence_wait_end() const { return at<475>().valid(); }
+  ::protozero::ConstBytes mali_mali_kcpu_fence_wait_end() const { return at<475>().as_bytes(); }
+  bool has_hyp_enter() const { return at<476>().valid(); }
+  ::protozero::ConstBytes hyp_enter() const { return at<476>().as_bytes(); }
+  bool has_hyp_exit() const { return at<477>().valid(); }
+  ::protozero::ConstBytes hyp_exit() const { return at<477>().as_bytes(); }
+  bool has_host_hcall() const { return at<478>().valid(); }
+  ::protozero::ConstBytes host_hcall() const { return at<478>().as_bytes(); }
+  bool has_host_smc() const { return at<479>().valid(); }
+  ::protozero::ConstBytes host_smc() const { return at<479>().as_bytes(); }
+  bool has_host_mem_abort() const { return at<480>().valid(); }
+  ::protozero::ConstBytes host_mem_abort() const { return at<480>().as_bytes(); }
+  bool has_suspend_resume_minimal() const { return at<481>().valid(); }
+  ::protozero::ConstBytes suspend_resume_minimal() const { return at<481>().as_bytes(); }
+  bool has_mali_mali_csf_interrupt_start() const { return at<482>().valid(); }
+  ::protozero::ConstBytes mali_mali_csf_interrupt_start() const { return at<482>().as_bytes(); }
+  bool has_mali_mali_csf_interrupt_end() const { return at<483>().valid(); }
+  ::protozero::ConstBytes mali_mali_csf_interrupt_end() const { return at<483>().as_bytes(); }
+  bool has_samsung_tracing_mark_write() const { return at<484>().valid(); }
+  ::protozero::ConstBytes samsung_tracing_mark_write() const { return at<484>().as_bytes(); }
+  bool has_binder_command() const { return at<485>().valid(); }
+  ::protozero::ConstBytes binder_command() const { return at<485>().as_bytes(); }
+  bool has_binder_return() const { return at<486>().valid(); }
+  ::protozero::ConstBytes binder_return() const { return at<486>().as_bytes(); }
+  bool has_sched_switch_with_ctrs() const { return at<487>().valid(); }
+  ::protozero::ConstBytes sched_switch_with_ctrs() const { return at<487>().as_bytes(); }
+  bool has_gpu_work_period() const { return at<488>().valid(); }
+  ::protozero::ConstBytes gpu_work_period() const { return at<488>().as_bytes(); }
+  bool has_rpm_status() const { return at<489>().valid(); }
+  ::protozero::ConstBytes rpm_status() const { return at<489>().as_bytes(); }
+  bool has_panel_write_generic() const { return at<490>().valid(); }
+  ::protozero::ConstBytes panel_write_generic() const { return at<490>().as_bytes(); }
+  bool has_sched_migrate_task() const { return at<491>().valid(); }
+  ::protozero::ConstBytes sched_migrate_task() const { return at<491>().as_bytes(); }
+  bool has_dpu_dsi_cmd_fifo_status() const { return at<492>().valid(); }
+  ::protozero::ConstBytes dpu_dsi_cmd_fifo_status() const { return at<492>().as_bytes(); }
+  bool has_dpu_dsi_rx() const { return at<493>().valid(); }
+  ::protozero::ConstBytes dpu_dsi_rx() const { return at<493>().as_bytes(); }
+  bool has_dpu_dsi_tx() const { return at<494>().valid(); }
+  ::protozero::ConstBytes dpu_dsi_tx() const { return at<494>().as_bytes(); }
+  bool has_f2fs_background_gc() const { return at<495>().valid(); }
+  ::protozero::ConstBytes f2fs_background_gc() const { return at<495>().as_bytes(); }
+  bool has_f2fs_gc_begin() const { return at<496>().valid(); }
+  ::protozero::ConstBytes f2fs_gc_begin() const { return at<496>().as_bytes(); }
+  bool has_f2fs_gc_end() const { return at<497>().valid(); }
+  ::protozero::ConstBytes f2fs_gc_end() const { return at<497>().as_bytes(); }
+  bool has_fastrpc_dma_free() const { return at<498>().valid(); }
+  ::protozero::ConstBytes fastrpc_dma_free() const { return at<498>().as_bytes(); }
+  bool has_fastrpc_dma_alloc() const { return at<499>().valid(); }
+  ::protozero::ConstBytes fastrpc_dma_alloc() const { return at<499>().as_bytes(); }
+  bool has_fastrpc_dma_unmap() const { return at<500>().valid(); }
+  ::protozero::ConstBytes fastrpc_dma_unmap() const { return at<500>().as_bytes(); }
+  bool has_fastrpc_dma_map() const { return at<501>().valid(); }
+  ::protozero::ConstBytes fastrpc_dma_map() const { return at<501>().as_bytes(); }
+  bool has_google_icc_event() const { return at<502>().valid(); }
+  ::protozero::ConstBytes google_icc_event() const { return at<502>().as_bytes(); }
+  bool has_google_irm_event() const { return at<503>().valid(); }
+  ::protozero::ConstBytes google_irm_event() const { return at<503>().as_bytes(); }
+  bool has_device_pm_callback_start() const { return at<504>().valid(); }
+  ::protozero::ConstBytes device_pm_callback_start() const { return at<504>().as_bytes(); }
+  bool has_device_pm_callback_end() const { return at<505>().valid(); }
+  ::protozero::ConstBytes device_pm_callback_end() const { return at<505>().as_bytes(); }
+};
+
+class FtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = FtraceEvent_Decoder;
+  enum : int32_t {
+    kTimestampFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kCommonFlagsFieldNumber = 5,
+    kPrintFieldNumber = 3,
+    kSchedSwitchFieldNumber = 4,
+    kCpuFrequencyFieldNumber = 11,
+    kCpuFrequencyLimitsFieldNumber = 12,
+    kCpuIdleFieldNumber = 13,
+    kClockEnableFieldNumber = 14,
+    kClockDisableFieldNumber = 15,
+    kClockSetRateFieldNumber = 16,
+    kSchedWakeupFieldNumber = 17,
+    kSchedBlockedReasonFieldNumber = 18,
+    kSchedCpuHotplugFieldNumber = 19,
+    kSchedWakingFieldNumber = 20,
+    kIpiEntryFieldNumber = 21,
+    kIpiExitFieldNumber = 22,
+    kIpiRaiseFieldNumber = 23,
+    kSoftirqEntryFieldNumber = 24,
+    kSoftirqExitFieldNumber = 25,
+    kSoftirqRaiseFieldNumber = 26,
+    kI2cReadFieldNumber = 27,
+    kI2cWriteFieldNumber = 28,
+    kI2cResultFieldNumber = 29,
+    kI2cReplyFieldNumber = 30,
+    kSmbusReadFieldNumber = 31,
+    kSmbusWriteFieldNumber = 32,
+    kSmbusResultFieldNumber = 33,
+    kSmbusReplyFieldNumber = 34,
+    kLowmemoryKillFieldNumber = 35,
+    kIrqHandlerEntryFieldNumber = 36,
+    kIrqHandlerExitFieldNumber = 37,
+    kSyncPtFieldNumber = 38,
+    kSyncTimelineFieldNumber = 39,
+    kSyncWaitFieldNumber = 40,
+    kExt4DaWriteBeginFieldNumber = 41,
+    kExt4DaWriteEndFieldNumber = 42,
+    kExt4SyncFileEnterFieldNumber = 43,
+    kExt4SyncFileExitFieldNumber = 44,
+    kBlockRqIssueFieldNumber = 45,
+    kMmVmscanDirectReclaimBeginFieldNumber = 46,
+    kMmVmscanDirectReclaimEndFieldNumber = 47,
+    kMmVmscanKswapdWakeFieldNumber = 48,
+    kMmVmscanKswapdSleepFieldNumber = 49,
+    kBinderTransactionFieldNumber = 50,
+    kBinderTransactionReceivedFieldNumber = 51,
+    kBinderSetPriorityFieldNumber = 52,
+    kBinderLockFieldNumber = 53,
+    kBinderLockedFieldNumber = 54,
+    kBinderUnlockFieldNumber = 55,
+    kWorkqueueActivateWorkFieldNumber = 56,
+    kWorkqueueExecuteEndFieldNumber = 57,
+    kWorkqueueExecuteStartFieldNumber = 58,
+    kWorkqueueQueueWorkFieldNumber = 59,
+    kRegulatorDisableFieldNumber = 60,
+    kRegulatorDisableCompleteFieldNumber = 61,
+    kRegulatorEnableFieldNumber = 62,
+    kRegulatorEnableCompleteFieldNumber = 63,
+    kRegulatorEnableDelayFieldNumber = 64,
+    kRegulatorSetVoltageFieldNumber = 65,
+    kRegulatorSetVoltageCompleteFieldNumber = 66,
+    kCgroupAttachTaskFieldNumber = 67,
+    kCgroupMkdirFieldNumber = 68,
+    kCgroupRemountFieldNumber = 69,
+    kCgroupRmdirFieldNumber = 70,
+    kCgroupTransferTasksFieldNumber = 71,
+    kCgroupDestroyRootFieldNumber = 72,
+    kCgroupReleaseFieldNumber = 73,
+    kCgroupRenameFieldNumber = 74,
+    kCgroupSetupRootFieldNumber = 75,
+    kMdpCmdKickoffFieldNumber = 76,
+    kMdpCommitFieldNumber = 77,
+    kMdpPerfSetOtFieldNumber = 78,
+    kMdpSsppChangeFieldNumber = 79,
+    kTracingMarkWriteFieldNumber = 80,
+    kMdpCmdPingpongDoneFieldNumber = 81,
+    kMdpCompareBwFieldNumber = 82,
+    kMdpPerfSetPanicLutsFieldNumber = 83,
+    kMdpSsppSetFieldNumber = 84,
+    kMdpCmdReadptrDoneFieldNumber = 85,
+    kMdpMisrCrcFieldNumber = 86,
+    kMdpPerfSetQosLutsFieldNumber = 87,
+    kMdpTraceCounterFieldNumber = 88,
+    kMdpCmdReleaseBwFieldNumber = 89,
+    kMdpMixerUpdateFieldNumber = 90,
+    kMdpPerfSetWmLevelsFieldNumber = 91,
+    kMdpVideoUnderrunDoneFieldNumber = 92,
+    kMdpCmdWaitPingpongFieldNumber = 93,
+    kMdpPerfPrefillCalcFieldNumber = 94,
+    kMdpPerfUpdateBusFieldNumber = 95,
+    kRotatorBwAoAsContextFieldNumber = 96,
+    kMmFilemapAddToPageCacheFieldNumber = 97,
+    kMmFilemapDeleteFromPageCacheFieldNumber = 98,
+    kMmCompactionBeginFieldNumber = 99,
+    kMmCompactionDeferCompactionFieldNumber = 100,
+    kMmCompactionDeferredFieldNumber = 101,
+    kMmCompactionDeferResetFieldNumber = 102,
+    kMmCompactionEndFieldNumber = 103,
+    kMmCompactionFinishedFieldNumber = 104,
+    kMmCompactionIsolateFreepagesFieldNumber = 105,
+    kMmCompactionIsolateMigratepagesFieldNumber = 106,
+    kMmCompactionKcompactdSleepFieldNumber = 107,
+    kMmCompactionKcompactdWakeFieldNumber = 108,
+    kMmCompactionMigratepagesFieldNumber = 109,
+    kMmCompactionSuitableFieldNumber = 110,
+    kMmCompactionTryToCompactPagesFieldNumber = 111,
+    kMmCompactionWakeupKcompactdFieldNumber = 112,
+    kSuspendResumeFieldNumber = 113,
+    kSchedWakeupNewFieldNumber = 114,
+    kBlockBioBackmergeFieldNumber = 115,
+    kBlockBioBounceFieldNumber = 116,
+    kBlockBioCompleteFieldNumber = 117,
+    kBlockBioFrontmergeFieldNumber = 118,
+    kBlockBioQueueFieldNumber = 119,
+    kBlockBioRemapFieldNumber = 120,
+    kBlockDirtyBufferFieldNumber = 121,
+    kBlockGetrqFieldNumber = 122,
+    kBlockPlugFieldNumber = 123,
+    kBlockRqAbortFieldNumber = 124,
+    kBlockRqCompleteFieldNumber = 125,
+    kBlockRqInsertFieldNumber = 126,
+    kBlockRqRemapFieldNumber = 128,
+    kBlockRqRequeueFieldNumber = 129,
+    kBlockSleeprqFieldNumber = 130,
+    kBlockSplitFieldNumber = 131,
+    kBlockTouchBufferFieldNumber = 132,
+    kBlockUnplugFieldNumber = 133,
+    kExt4AllocDaBlocksFieldNumber = 134,
+    kExt4AllocateBlocksFieldNumber = 135,
+    kExt4AllocateInodeFieldNumber = 136,
+    kExt4BeginOrderedTruncateFieldNumber = 137,
+    kExt4CollapseRangeFieldNumber = 138,
+    kExt4DaReleaseSpaceFieldNumber = 139,
+    kExt4DaReserveSpaceFieldNumber = 140,
+    kExt4DaUpdateReserveSpaceFieldNumber = 141,
+    kExt4DaWritePagesFieldNumber = 142,
+    kExt4DaWritePagesExtentFieldNumber = 143,
+    kExt4DirectIOEnterFieldNumber = 144,
+    kExt4DirectIOExitFieldNumber = 145,
+    kExt4DiscardBlocksFieldNumber = 146,
+    kExt4DiscardPreallocationsFieldNumber = 147,
+    kExt4DropInodeFieldNumber = 148,
+    kExt4EsCacheExtentFieldNumber = 149,
+    kExt4EsFindDelayedExtentRangeEnterFieldNumber = 150,
+    kExt4EsFindDelayedExtentRangeExitFieldNumber = 151,
+    kExt4EsInsertExtentFieldNumber = 152,
+    kExt4EsLookupExtentEnterFieldNumber = 153,
+    kExt4EsLookupExtentExitFieldNumber = 154,
+    kExt4EsRemoveExtentFieldNumber = 155,
+    kExt4EsShrinkFieldNumber = 156,
+    kExt4EsShrinkCountFieldNumber = 157,
+    kExt4EsShrinkScanEnterFieldNumber = 158,
+    kExt4EsShrinkScanExitFieldNumber = 159,
+    kExt4EvictInodeFieldNumber = 160,
+    kExt4ExtConvertToInitializedEnterFieldNumber = 161,
+    kExt4ExtConvertToInitializedFastpathFieldNumber = 162,
+    kExt4ExtHandleUnwrittenExtentsFieldNumber = 163,
+    kExt4ExtInCacheFieldNumber = 164,
+    kExt4ExtLoadExtentFieldNumber = 165,
+    kExt4ExtMapBlocksEnterFieldNumber = 166,
+    kExt4ExtMapBlocksExitFieldNumber = 167,
+    kExt4ExtPutInCacheFieldNumber = 168,
+    kExt4ExtRemoveSpaceFieldNumber = 169,
+    kExt4ExtRemoveSpaceDoneFieldNumber = 170,
+    kExt4ExtRmIdxFieldNumber = 171,
+    kExt4ExtRmLeafFieldNumber = 172,
+    kExt4ExtShowExtentFieldNumber = 173,
+    kExt4FallocateEnterFieldNumber = 174,
+    kExt4FallocateExitFieldNumber = 175,
+    kExt4FindDelallocRangeFieldNumber = 176,
+    kExt4ForgetFieldNumber = 177,
+    kExt4FreeBlocksFieldNumber = 178,
+    kExt4FreeInodeFieldNumber = 179,
+    kExt4GetImpliedClusterAllocExitFieldNumber = 180,
+    kExt4GetReservedClusterAllocFieldNumber = 181,
+    kExt4IndMapBlocksEnterFieldNumber = 182,
+    kExt4IndMapBlocksExitFieldNumber = 183,
+    kExt4InsertRangeFieldNumber = 184,
+    kExt4InvalidatepageFieldNumber = 185,
+    kExt4JournalStartFieldNumber = 186,
+    kExt4JournalStartReservedFieldNumber = 187,
+    kExt4JournalledInvalidatepageFieldNumber = 188,
+    kExt4JournalledWriteEndFieldNumber = 189,
+    kExt4LoadInodeFieldNumber = 190,
+    kExt4LoadInodeBitmapFieldNumber = 191,
+    kExt4MarkInodeDirtyFieldNumber = 192,
+    kExt4MbBitmapLoadFieldNumber = 193,
+    kExt4MbBuddyBitmapLoadFieldNumber = 194,
+    kExt4MbDiscardPreallocationsFieldNumber = 195,
+    kExt4MbNewGroupPaFieldNumber = 196,
+    kExt4MbNewInodePaFieldNumber = 197,
+    kExt4MbReleaseGroupPaFieldNumber = 198,
+    kExt4MbReleaseInodePaFieldNumber = 199,
+    kExt4MballocAllocFieldNumber = 200,
+    kExt4MballocDiscardFieldNumber = 201,
+    kExt4MballocFreeFieldNumber = 202,
+    kExt4MballocPreallocFieldNumber = 203,
+    kExt4OtherInodeUpdateTimeFieldNumber = 204,
+    kExt4PunchHoleFieldNumber = 205,
+    kExt4ReadBlockBitmapLoadFieldNumber = 206,
+    kExt4ReadpageFieldNumber = 207,
+    kExt4ReleasepageFieldNumber = 208,
+    kExt4RemoveBlocksFieldNumber = 209,
+    kExt4RequestBlocksFieldNumber = 210,
+    kExt4RequestInodeFieldNumber = 211,
+    kExt4SyncFsFieldNumber = 212,
+    kExt4TrimAllFreeFieldNumber = 213,
+    kExt4TrimExtentFieldNumber = 214,
+    kExt4TruncateEnterFieldNumber = 215,
+    kExt4TruncateExitFieldNumber = 216,
+    kExt4UnlinkEnterFieldNumber = 217,
+    kExt4UnlinkExitFieldNumber = 218,
+    kExt4WriteBeginFieldNumber = 219,
+    kExt4WriteEndFieldNumber = 230,
+    kExt4WritepageFieldNumber = 231,
+    kExt4WritepagesFieldNumber = 232,
+    kExt4WritepagesResultFieldNumber = 233,
+    kExt4ZeroRangeFieldNumber = 234,
+    kTaskNewtaskFieldNumber = 235,
+    kTaskRenameFieldNumber = 236,
+    kSchedProcessExecFieldNumber = 237,
+    kSchedProcessExitFieldNumber = 238,
+    kSchedProcessForkFieldNumber = 239,
+    kSchedProcessFreeFieldNumber = 240,
+    kSchedProcessHangFieldNumber = 241,
+    kSchedProcessWaitFieldNumber = 242,
+    kF2fsDoSubmitBioFieldNumber = 243,
+    kF2fsEvictInodeFieldNumber = 244,
+    kF2fsFallocateFieldNumber = 245,
+    kF2fsGetDataBlockFieldNumber = 246,
+    kF2fsGetVictimFieldNumber = 247,
+    kF2fsIgetFieldNumber = 248,
+    kF2fsIgetExitFieldNumber = 249,
+    kF2fsNewInodeFieldNumber = 250,
+    kF2fsReadpageFieldNumber = 251,
+    kF2fsReserveNewBlockFieldNumber = 252,
+    kF2fsSetPageDirtyFieldNumber = 253,
+    kF2fsSubmitWritePageFieldNumber = 254,
+    kF2fsSyncFileEnterFieldNumber = 255,
+    kF2fsSyncFileExitFieldNumber = 256,
+    kF2fsSyncFsFieldNumber = 257,
+    kF2fsTruncateFieldNumber = 258,
+    kF2fsTruncateBlocksEnterFieldNumber = 259,
+    kF2fsTruncateBlocksExitFieldNumber = 260,
+    kF2fsTruncateDataBlocksRangeFieldNumber = 261,
+    kF2fsTruncateInodeBlocksEnterFieldNumber = 262,
+    kF2fsTruncateInodeBlocksExitFieldNumber = 263,
+    kF2fsTruncateNodeFieldNumber = 264,
+    kF2fsTruncateNodesEnterFieldNumber = 265,
+    kF2fsTruncateNodesExitFieldNumber = 266,
+    kF2fsTruncatePartialNodesFieldNumber = 267,
+    kF2fsUnlinkEnterFieldNumber = 268,
+    kF2fsUnlinkExitFieldNumber = 269,
+    kF2fsVmPageMkwriteFieldNumber = 270,
+    kF2fsWriteBeginFieldNumber = 271,
+    kF2fsWriteCheckpointFieldNumber = 272,
+    kF2fsWriteEndFieldNumber = 273,
+    kAllocPagesIommuEndFieldNumber = 274,
+    kAllocPagesIommuFailFieldNumber = 275,
+    kAllocPagesIommuStartFieldNumber = 276,
+    kAllocPagesSysEndFieldNumber = 277,
+    kAllocPagesSysFailFieldNumber = 278,
+    kAllocPagesSysStartFieldNumber = 279,
+    kDmaAllocContiguousRetryFieldNumber = 280,
+    kIommuMapRangeFieldNumber = 281,
+    kIommuSecPtblMapRangeEndFieldNumber = 282,
+    kIommuSecPtblMapRangeStartFieldNumber = 283,
+    kIonAllocBufferEndFieldNumber = 284,
+    kIonAllocBufferFailFieldNumber = 285,
+    kIonAllocBufferFallbackFieldNumber = 286,
+    kIonAllocBufferStartFieldNumber = 287,
+    kIonCpAllocRetryFieldNumber = 288,
+    kIonCpSecureBufferEndFieldNumber = 289,
+    kIonCpSecureBufferStartFieldNumber = 290,
+    kIonPrefetchingFieldNumber = 291,
+    kIonSecureCmaAddToPoolEndFieldNumber = 292,
+    kIonSecureCmaAddToPoolStartFieldNumber = 293,
+    kIonSecureCmaAllocateEndFieldNumber = 294,
+    kIonSecureCmaAllocateStartFieldNumber = 295,
+    kIonSecureCmaShrinkPoolEndFieldNumber = 296,
+    kIonSecureCmaShrinkPoolStartFieldNumber = 297,
+    kKfreeFieldNumber = 298,
+    kKmallocFieldNumber = 299,
+    kKmallocNodeFieldNumber = 300,
+    kKmemCacheAllocFieldNumber = 301,
+    kKmemCacheAllocNodeFieldNumber = 302,
+    kKmemCacheFreeFieldNumber = 303,
+    kMigratePagesEndFieldNumber = 304,
+    kMigratePagesStartFieldNumber = 305,
+    kMigrateRetryFieldNumber = 306,
+    kMmPageAllocFieldNumber = 307,
+    kMmPageAllocExtfragFieldNumber = 308,
+    kMmPageAllocZoneLockedFieldNumber = 309,
+    kMmPageFreeFieldNumber = 310,
+    kMmPageFreeBatchedFieldNumber = 311,
+    kMmPagePcpuDrainFieldNumber = 312,
+    kRssStatFieldNumber = 313,
+    kIonHeapShrinkFieldNumber = 314,
+    kIonHeapGrowFieldNumber = 315,
+    kFenceInitFieldNumber = 316,
+    kFenceDestroyFieldNumber = 317,
+    kFenceEnableSignalFieldNumber = 318,
+    kFenceSignaledFieldNumber = 319,
+    kClkEnableFieldNumber = 320,
+    kClkDisableFieldNumber = 321,
+    kClkSetRateFieldNumber = 322,
+    kBinderTransactionAllocBufFieldNumber = 323,
+    kSignalDeliverFieldNumber = 324,
+    kSignalGenerateFieldNumber = 325,
+    kOomScoreAdjUpdateFieldNumber = 326,
+    kGenericFieldNumber = 327,
+    kMmEventRecordFieldNumber = 328,
+    kSysEnterFieldNumber = 329,
+    kSysExitFieldNumber = 330,
+    kZeroFieldNumber = 331,
+    kGpuFrequencyFieldNumber = 332,
+    kSdeTracingMarkWriteFieldNumber = 333,
+    kMarkVictimFieldNumber = 334,
+    kIonStatFieldNumber = 335,
+    kIonBufferCreateFieldNumber = 336,
+    kIonBufferDestroyFieldNumber = 337,
+    kScmCallStartFieldNumber = 338,
+    kScmCallEndFieldNumber = 339,
+    kGpuMemTotalFieldNumber = 340,
+    kThermalTemperatureFieldNumber = 341,
+    kCdevUpdateFieldNumber = 342,
+    kCpuhpExitFieldNumber = 343,
+    kCpuhpMultiEnterFieldNumber = 344,
+    kCpuhpEnterFieldNumber = 345,
+    kCpuhpLatencyFieldNumber = 346,
+    kFastrpcDmaStatFieldNumber = 347,
+    kDpuTracingMarkWriteFieldNumber = 348,
+    kG2dTracingMarkWriteFieldNumber = 349,
+    kMaliTracingMarkWriteFieldNumber = 350,
+    kDmaHeapStatFieldNumber = 351,
+    kCpuhpPauseFieldNumber = 352,
+    kSchedPiSetprioFieldNumber = 353,
+    kSdeSdeEvtlogFieldNumber = 354,
+    kSdeSdePerfCalcCrtcFieldNumber = 355,
+    kSdeSdePerfCrtcUpdateFieldNumber = 356,
+    kSdeSdePerfSetQosLutsFieldNumber = 357,
+    kSdeSdePerfUpdateBusFieldNumber = 358,
+    kRssStatThrottledFieldNumber = 359,
+    kNetifReceiveSkbFieldNumber = 360,
+    kNetDevXmitFieldNumber = 361,
+    kInetSockSetStateFieldNumber = 362,
+    kTcpRetransmitSkbFieldNumber = 363,
+    kCrosEcSensorhubDataFieldNumber = 364,
+    kNapiGroReceiveEntryFieldNumber = 365,
+    kNapiGroReceiveExitFieldNumber = 366,
+    kKfreeSkbFieldNumber = 367,
+    kKvmAccessFaultFieldNumber = 368,
+    kKvmAckIrqFieldNumber = 369,
+    kKvmAgeHvaFieldNumber = 370,
+    kKvmAgePageFieldNumber = 371,
+    kKvmArmClearDebugFieldNumber = 372,
+    kKvmArmSetDreg32FieldNumber = 373,
+    kKvmArmSetRegsetFieldNumber = 374,
+    kKvmArmSetupDebugFieldNumber = 375,
+    kKvmEntryFieldNumber = 376,
+    kKvmExitFieldNumber = 377,
+    kKvmFpuFieldNumber = 378,
+    kKvmGetTimerMapFieldNumber = 379,
+    kKvmGuestFaultFieldNumber = 380,
+    kKvmHandleSysRegFieldNumber = 381,
+    kKvmHvcArm64FieldNumber = 382,
+    kKvmIrqLineFieldNumber = 383,
+    kKvmMmioFieldNumber = 384,
+    kKvmMmioEmulateFieldNumber = 385,
+    kKvmSetGuestDebugFieldNumber = 386,
+    kKvmSetIrqFieldNumber = 387,
+    kKvmSetSpteHvaFieldNumber = 388,
+    kKvmSetWayFlushFieldNumber = 389,
+    kKvmSysAccessFieldNumber = 390,
+    kKvmTestAgeHvaFieldNumber = 391,
+    kKvmTimerEmulateFieldNumber = 392,
+    kKvmTimerHrtimerExpireFieldNumber = 393,
+    kKvmTimerRestoreStateFieldNumber = 394,
+    kKvmTimerSaveStateFieldNumber = 395,
+    kKvmTimerUpdateIrqFieldNumber = 396,
+    kKvmToggleCacheFieldNumber = 397,
+    kKvmUnmapHvaRangeFieldNumber = 398,
+    kKvmUserspaceExitFieldNumber = 399,
+    kKvmVcpuWakeupFieldNumber = 400,
+    kKvmWfxArm64FieldNumber = 401,
+    kTrapRegFieldNumber = 402,
+    kVgicUpdateIrqPendingFieldNumber = 403,
+    kWakeupSourceActivateFieldNumber = 404,
+    kWakeupSourceDeactivateFieldNumber = 405,
+    kUfshcdCommandFieldNumber = 406,
+    kUfshcdClkGatingFieldNumber = 407,
+    kConsoleFieldNumber = 408,
+    kDrmVblankEventFieldNumber = 409,
+    kDrmVblankEventDeliveredFieldNumber = 410,
+    kDrmSchedJobFieldNumber = 411,
+    kDrmRunJobFieldNumber = 412,
+    kDrmSchedProcessJobFieldNumber = 413,
+    kDmaFenceInitFieldNumber = 414,
+    kDmaFenceEmitFieldNumber = 415,
+    kDmaFenceSignaledFieldNumber = 416,
+    kDmaFenceWaitStartFieldNumber = 417,
+    kDmaFenceWaitEndFieldNumber = 418,
+    kF2fsIostatFieldNumber = 419,
+    kF2fsIostatLatencyFieldNumber = 420,
+    kSchedCpuUtilCfsFieldNumber = 421,
+    kV4l2QbufFieldNumber = 422,
+    kV4l2DqbufFieldNumber = 423,
+    kVb2V4l2BufQueueFieldNumber = 424,
+    kVb2V4l2BufDoneFieldNumber = 425,
+    kVb2V4l2QbufFieldNumber = 426,
+    kVb2V4l2DqbufFieldNumber = 427,
+    kDsiCmdFifoStatusFieldNumber = 428,
+    kDsiRxFieldNumber = 429,
+    kDsiTxFieldNumber = 430,
+    kAndroidFsDatareadEndFieldNumber = 431,
+    kAndroidFsDatareadStartFieldNumber = 432,
+    kAndroidFsDatawriteEndFieldNumber = 433,
+    kAndroidFsDatawriteStartFieldNumber = 434,
+    kAndroidFsFsyncEndFieldNumber = 435,
+    kAndroidFsFsyncStartFieldNumber = 436,
+    kFuncgraphEntryFieldNumber = 437,
+    kFuncgraphExitFieldNumber = 438,
+    kVirtioVideoCmdFieldNumber = 439,
+    kVirtioVideoCmdDoneFieldNumber = 440,
+    kVirtioVideoResourceQueueFieldNumber = 441,
+    kVirtioVideoResourceQueueDoneFieldNumber = 442,
+    kMmShrinkSlabStartFieldNumber = 443,
+    kMmShrinkSlabEndFieldNumber = 444,
+    kTrustySmcFieldNumber = 445,
+    kTrustySmcDoneFieldNumber = 446,
+    kTrustyStdCall32FieldNumber = 447,
+    kTrustyStdCall32DoneFieldNumber = 448,
+    kTrustyShareMemoryFieldNumber = 449,
+    kTrustyShareMemoryDoneFieldNumber = 450,
+    kTrustyReclaimMemoryFieldNumber = 451,
+    kTrustyReclaimMemoryDoneFieldNumber = 452,
+    kTrustyIrqFieldNumber = 453,
+    kTrustyIpcHandleEventFieldNumber = 454,
+    kTrustyIpcConnectFieldNumber = 455,
+    kTrustyIpcConnectEndFieldNumber = 456,
+    kTrustyIpcWriteFieldNumber = 457,
+    kTrustyIpcPollFieldNumber = 458,
+    kTrustyIpcReadFieldNumber = 460,
+    kTrustyIpcReadEndFieldNumber = 461,
+    kTrustyIpcRxFieldNumber = 462,
+    kTrustyEnqueueNopFieldNumber = 464,
+    kCmaAllocStartFieldNumber = 465,
+    kCmaAllocInfoFieldNumber = 466,
+    kLwisTracingMarkWriteFieldNumber = 467,
+    kVirtioGpuCmdQueueFieldNumber = 468,
+    kVirtioGpuCmdResponseFieldNumber = 469,
+    kMaliMaliKCPUCQSSETFieldNumber = 470,
+    kMaliMaliKCPUCQSWAITSTARTFieldNumber = 471,
+    kMaliMaliKCPUCQSWAITENDFieldNumber = 472,
+    kMaliMaliKCPUFENCESIGNALFieldNumber = 473,
+    kMaliMaliKCPUFENCEWAITSTARTFieldNumber = 474,
+    kMaliMaliKCPUFENCEWAITENDFieldNumber = 475,
+    kHypEnterFieldNumber = 476,
+    kHypExitFieldNumber = 477,
+    kHostHcallFieldNumber = 478,
+    kHostSmcFieldNumber = 479,
+    kHostMemAbortFieldNumber = 480,
+    kSuspendResumeMinimalFieldNumber = 481,
+    kMaliMaliCSFINTERRUPTSTARTFieldNumber = 482,
+    kMaliMaliCSFINTERRUPTENDFieldNumber = 483,
+    kSamsungTracingMarkWriteFieldNumber = 484,
+    kBinderCommandFieldNumber = 485,
+    kBinderReturnFieldNumber = 486,
+    kSchedSwitchWithCtrsFieldNumber = 487,
+    kGpuWorkPeriodFieldNumber = 488,
+    kRpmStatusFieldNumber = 489,
+    kPanelWriteGenericFieldNumber = 490,
+    kSchedMigrateTaskFieldNumber = 491,
+    kDpuDsiCmdFifoStatusFieldNumber = 492,
+    kDpuDsiRxFieldNumber = 493,
+    kDpuDsiTxFieldNumber = 494,
+    kF2fsBackgroundGcFieldNumber = 495,
+    kF2fsGcBeginFieldNumber = 496,
+    kF2fsGcEndFieldNumber = 497,
+    kFastrpcDmaFreeFieldNumber = 498,
+    kFastrpcDmaAllocFieldNumber = 499,
+    kFastrpcDmaUnmapFieldNumber = 500,
+    kFastrpcDmaMapFieldNumber = 501,
+    kGoogleIccEventFieldNumber = 502,
+    kGoogleIrmEventFieldNumber = 503,
+    kDevicePmCallbackStartFieldNumber = 504,
+    kDevicePmCallbackEndFieldNumber = 505,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FtraceEvent"; }
+
+
+  using FieldMetadata_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Timestamp kTimestamp{};
+  void set_timestamp(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timestamp::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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_CommonFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CommonFlags kCommonFlags{};
+  void set_common_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CommonFlags::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_Print =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PrintFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Print kPrint{};
+  template <typename T = PrintFtraceEvent> T* set_print() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_SchedSwitch =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SchedSwitchFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SchedSwitch kSchedSwitch{};
+  template <typename T = SchedSwitchFtraceEvent> T* set_sched_switch() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_CpuFrequency =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CpuFrequencyFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CpuFrequency kCpuFrequency{};
+  template <typename T = CpuFrequencyFtraceEvent> T* set_cpu_frequency() {
+    return BeginNestedMessage<T>(11);
+  }
+
+
+  using FieldMetadata_CpuFrequencyLimits =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CpuFrequencyLimitsFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CpuFrequencyLimits kCpuFrequencyLimits{};
+  template <typename T = CpuFrequencyLimitsFtraceEvent> T* set_cpu_frequency_limits() {
+    return BeginNestedMessage<T>(12);
+  }
+
+
+  using FieldMetadata_CpuIdle =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CpuIdleFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CpuIdle kCpuIdle{};
+  template <typename T = CpuIdleFtraceEvent> T* set_cpu_idle() {
+    return BeginNestedMessage<T>(13);
+  }
+
+
+  using FieldMetadata_ClockEnable =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ClockEnableFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_ClockEnable kClockEnable{};
+  template <typename T = ClockEnableFtraceEvent> T* set_clock_enable() {
+    return BeginNestedMessage<T>(14);
+  }
+
+
+  using FieldMetadata_ClockDisable =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ClockDisableFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_ClockDisable kClockDisable{};
+  template <typename T = ClockDisableFtraceEvent> T* set_clock_disable() {
+    return BeginNestedMessage<T>(15);
+  }
+
+
+  using FieldMetadata_ClockSetRate =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ClockSetRateFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_ClockSetRate kClockSetRate{};
+  template <typename T = ClockSetRateFtraceEvent> T* set_clock_set_rate() {
+    return BeginNestedMessage<T>(16);
+  }
+
+
+  using FieldMetadata_SchedWakeup =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SchedWakeupFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SchedWakeup kSchedWakeup{};
+  template <typename T = SchedWakeupFtraceEvent> T* set_sched_wakeup() {
+    return BeginNestedMessage<T>(17);
+  }
+
+
+  using FieldMetadata_SchedBlockedReason =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SchedBlockedReasonFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SchedBlockedReason kSchedBlockedReason{};
+  template <typename T = SchedBlockedReasonFtraceEvent> T* set_sched_blocked_reason() {
+    return BeginNestedMessage<T>(18);
+  }
+
+
+  using FieldMetadata_SchedCpuHotplug =
+    ::protozero::proto_utils::FieldMetadata<
+      19,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SchedCpuHotplugFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SchedCpuHotplug kSchedCpuHotplug{};
+  template <typename T = SchedCpuHotplugFtraceEvent> T* set_sched_cpu_hotplug() {
+    return BeginNestedMessage<T>(19);
+  }
+
+
+  using FieldMetadata_SchedWaking =
+    ::protozero::proto_utils::FieldMetadata<
+      20,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SchedWakingFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SchedWaking kSchedWaking{};
+  template <typename T = SchedWakingFtraceEvent> T* set_sched_waking() {
+    return BeginNestedMessage<T>(20);
+  }
+
+
+  using FieldMetadata_IpiEntry =
+    ::protozero::proto_utils::FieldMetadata<
+      21,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IpiEntryFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IpiEntry kIpiEntry{};
+  template <typename T = IpiEntryFtraceEvent> T* set_ipi_entry() {
+    return BeginNestedMessage<T>(21);
+  }
+
+
+  using FieldMetadata_IpiExit =
+    ::protozero::proto_utils::FieldMetadata<
+      22,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IpiExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IpiExit kIpiExit{};
+  template <typename T = IpiExitFtraceEvent> T* set_ipi_exit() {
+    return BeginNestedMessage<T>(22);
+  }
+
+
+  using FieldMetadata_IpiRaise =
+    ::protozero::proto_utils::FieldMetadata<
+      23,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IpiRaiseFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IpiRaise kIpiRaise{};
+  template <typename T = IpiRaiseFtraceEvent> T* set_ipi_raise() {
+    return BeginNestedMessage<T>(23);
+  }
+
+
+  using FieldMetadata_SoftirqEntry =
+    ::protozero::proto_utils::FieldMetadata<
+      24,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SoftirqEntryFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SoftirqEntry kSoftirqEntry{};
+  template <typename T = SoftirqEntryFtraceEvent> T* set_softirq_entry() {
+    return BeginNestedMessage<T>(24);
+  }
+
+
+  using FieldMetadata_SoftirqExit =
+    ::protozero::proto_utils::FieldMetadata<
+      25,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SoftirqExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SoftirqExit kSoftirqExit{};
+  template <typename T = SoftirqExitFtraceEvent> T* set_softirq_exit() {
+    return BeginNestedMessage<T>(25);
+  }
+
+
+  using FieldMetadata_SoftirqRaise =
+    ::protozero::proto_utils::FieldMetadata<
+      26,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SoftirqRaiseFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SoftirqRaise kSoftirqRaise{};
+  template <typename T = SoftirqRaiseFtraceEvent> T* set_softirq_raise() {
+    return BeginNestedMessage<T>(26);
+  }
+
+
+  using FieldMetadata_I2cRead =
+    ::protozero::proto_utils::FieldMetadata<
+      27,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      I2cReadFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_I2cRead kI2cRead{};
+  template <typename T = I2cReadFtraceEvent> T* set_i2c_read() {
+    return BeginNestedMessage<T>(27);
+  }
+
+
+  using FieldMetadata_I2cWrite =
+    ::protozero::proto_utils::FieldMetadata<
+      28,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      I2cWriteFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_I2cWrite kI2cWrite{};
+  template <typename T = I2cWriteFtraceEvent> T* set_i2c_write() {
+    return BeginNestedMessage<T>(28);
+  }
+
+
+  using FieldMetadata_I2cResult =
+    ::protozero::proto_utils::FieldMetadata<
+      29,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      I2cResultFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_I2cResult kI2cResult{};
+  template <typename T = I2cResultFtraceEvent> T* set_i2c_result() {
+    return BeginNestedMessage<T>(29);
+  }
+
+
+  using FieldMetadata_I2cReply =
+    ::protozero::proto_utils::FieldMetadata<
+      30,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      I2cReplyFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_I2cReply kI2cReply{};
+  template <typename T = I2cReplyFtraceEvent> T* set_i2c_reply() {
+    return BeginNestedMessage<T>(30);
+  }
+
+
+  using FieldMetadata_SmbusRead =
+    ::protozero::proto_utils::FieldMetadata<
+      31,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SmbusReadFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SmbusRead kSmbusRead{};
+  template <typename T = SmbusReadFtraceEvent> T* set_smbus_read() {
+    return BeginNestedMessage<T>(31);
+  }
+
+
+  using FieldMetadata_SmbusWrite =
+    ::protozero::proto_utils::FieldMetadata<
+      32,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SmbusWriteFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SmbusWrite kSmbusWrite{};
+  template <typename T = SmbusWriteFtraceEvent> T* set_smbus_write() {
+    return BeginNestedMessage<T>(32);
+  }
+
+
+  using FieldMetadata_SmbusResult =
+    ::protozero::proto_utils::FieldMetadata<
+      33,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SmbusResultFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SmbusResult kSmbusResult{};
+  template <typename T = SmbusResultFtraceEvent> T* set_smbus_result() {
+    return BeginNestedMessage<T>(33);
+  }
+
+
+  using FieldMetadata_SmbusReply =
+    ::protozero::proto_utils::FieldMetadata<
+      34,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SmbusReplyFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SmbusReply kSmbusReply{};
+  template <typename T = SmbusReplyFtraceEvent> T* set_smbus_reply() {
+    return BeginNestedMessage<T>(34);
+  }
+
+
+  using FieldMetadata_LowmemoryKill =
+    ::protozero::proto_utils::FieldMetadata<
+      35,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      LowmemoryKillFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_LowmemoryKill kLowmemoryKill{};
+  template <typename T = LowmemoryKillFtraceEvent> T* set_lowmemory_kill() {
+    return BeginNestedMessage<T>(35);
+  }
+
+
+  using FieldMetadata_IrqHandlerEntry =
+    ::protozero::proto_utils::FieldMetadata<
+      36,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IrqHandlerEntryFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IrqHandlerEntry kIrqHandlerEntry{};
+  template <typename T = IrqHandlerEntryFtraceEvent> T* set_irq_handler_entry() {
+    return BeginNestedMessage<T>(36);
+  }
+
+
+  using FieldMetadata_IrqHandlerExit =
+    ::protozero::proto_utils::FieldMetadata<
+      37,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IrqHandlerExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IrqHandlerExit kIrqHandlerExit{};
+  template <typename T = IrqHandlerExitFtraceEvent> T* set_irq_handler_exit() {
+    return BeginNestedMessage<T>(37);
+  }
+
+
+  using FieldMetadata_SyncPt =
+    ::protozero::proto_utils::FieldMetadata<
+      38,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SyncPtFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SyncPt kSyncPt{};
+  template <typename T = SyncPtFtraceEvent> T* set_sync_pt() {
+    return BeginNestedMessage<T>(38);
+  }
+
+
+  using FieldMetadata_SyncTimeline =
+    ::protozero::proto_utils::FieldMetadata<
+      39,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SyncTimelineFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SyncTimeline kSyncTimeline{};
+  template <typename T = SyncTimelineFtraceEvent> T* set_sync_timeline() {
+    return BeginNestedMessage<T>(39);
+  }
+
+
+  using FieldMetadata_SyncWait =
+    ::protozero::proto_utils::FieldMetadata<
+      40,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SyncWaitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SyncWait kSyncWait{};
+  template <typename T = SyncWaitFtraceEvent> T* set_sync_wait() {
+    return BeginNestedMessage<T>(40);
+  }
+
+
+  using FieldMetadata_Ext4DaWriteBegin =
+    ::protozero::proto_utils::FieldMetadata<
+      41,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4DaWriteBeginFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4DaWriteBegin kExt4DaWriteBegin{};
+  template <typename T = Ext4DaWriteBeginFtraceEvent> T* set_ext4_da_write_begin() {
+    return BeginNestedMessage<T>(41);
+  }
+
+
+  using FieldMetadata_Ext4DaWriteEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      42,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4DaWriteEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4DaWriteEnd kExt4DaWriteEnd{};
+  template <typename T = Ext4DaWriteEndFtraceEvent> T* set_ext4_da_write_end() {
+    return BeginNestedMessage<T>(42);
+  }
+
+
+  using FieldMetadata_Ext4SyncFileEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      43,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4SyncFileEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4SyncFileEnter kExt4SyncFileEnter{};
+  template <typename T = Ext4SyncFileEnterFtraceEvent> T* set_ext4_sync_file_enter() {
+    return BeginNestedMessage<T>(43);
+  }
+
+
+  using FieldMetadata_Ext4SyncFileExit =
+    ::protozero::proto_utils::FieldMetadata<
+      44,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4SyncFileExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4SyncFileExit kExt4SyncFileExit{};
+  template <typename T = Ext4SyncFileExitFtraceEvent> T* set_ext4_sync_file_exit() {
+    return BeginNestedMessage<T>(44);
+  }
+
+
+  using FieldMetadata_BlockRqIssue =
+    ::protozero::proto_utils::FieldMetadata<
+      45,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockRqIssueFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockRqIssue kBlockRqIssue{};
+  template <typename T = BlockRqIssueFtraceEvent> T* set_block_rq_issue() {
+    return BeginNestedMessage<T>(45);
+  }
+
+
+  using FieldMetadata_MmVmscanDirectReclaimBegin =
+    ::protozero::proto_utils::FieldMetadata<
+      46,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmVmscanDirectReclaimBeginFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmVmscanDirectReclaimBegin kMmVmscanDirectReclaimBegin{};
+  template <typename T = MmVmscanDirectReclaimBeginFtraceEvent> T* set_mm_vmscan_direct_reclaim_begin() {
+    return BeginNestedMessage<T>(46);
+  }
+
+
+  using FieldMetadata_MmVmscanDirectReclaimEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      47,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmVmscanDirectReclaimEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmVmscanDirectReclaimEnd kMmVmscanDirectReclaimEnd{};
+  template <typename T = MmVmscanDirectReclaimEndFtraceEvent> T* set_mm_vmscan_direct_reclaim_end() {
+    return BeginNestedMessage<T>(47);
+  }
+
+
+  using FieldMetadata_MmVmscanKswapdWake =
+    ::protozero::proto_utils::FieldMetadata<
+      48,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmVmscanKswapdWakeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmVmscanKswapdWake kMmVmscanKswapdWake{};
+  template <typename T = MmVmscanKswapdWakeFtraceEvent> T* set_mm_vmscan_kswapd_wake() {
+    return BeginNestedMessage<T>(48);
+  }
+
+
+  using FieldMetadata_MmVmscanKswapdSleep =
+    ::protozero::proto_utils::FieldMetadata<
+      49,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmVmscanKswapdSleepFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmVmscanKswapdSleep kMmVmscanKswapdSleep{};
+  template <typename T = MmVmscanKswapdSleepFtraceEvent> T* set_mm_vmscan_kswapd_sleep() {
+    return BeginNestedMessage<T>(49);
+  }
+
+
+  using FieldMetadata_BinderTransaction =
+    ::protozero::proto_utils::FieldMetadata<
+      50,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BinderTransactionFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BinderTransaction kBinderTransaction{};
+  template <typename T = BinderTransactionFtraceEvent> T* set_binder_transaction() {
+    return BeginNestedMessage<T>(50);
+  }
+
+
+  using FieldMetadata_BinderTransactionReceived =
+    ::protozero::proto_utils::FieldMetadata<
+      51,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BinderTransactionReceivedFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BinderTransactionReceived kBinderTransactionReceived{};
+  template <typename T = BinderTransactionReceivedFtraceEvent> T* set_binder_transaction_received() {
+    return BeginNestedMessage<T>(51);
+  }
+
+
+  using FieldMetadata_BinderSetPriority =
+    ::protozero::proto_utils::FieldMetadata<
+      52,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BinderSetPriorityFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BinderSetPriority kBinderSetPriority{};
+  template <typename T = BinderSetPriorityFtraceEvent> T* set_binder_set_priority() {
+    return BeginNestedMessage<T>(52);
+  }
+
+
+  using FieldMetadata_BinderLock =
+    ::protozero::proto_utils::FieldMetadata<
+      53,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BinderLockFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BinderLock kBinderLock{};
+  template <typename T = BinderLockFtraceEvent> T* set_binder_lock() {
+    return BeginNestedMessage<T>(53);
+  }
+
+
+  using FieldMetadata_BinderLocked =
+    ::protozero::proto_utils::FieldMetadata<
+      54,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BinderLockedFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BinderLocked kBinderLocked{};
+  template <typename T = BinderLockedFtraceEvent> T* set_binder_locked() {
+    return BeginNestedMessage<T>(54);
+  }
+
+
+  using FieldMetadata_BinderUnlock =
+    ::protozero::proto_utils::FieldMetadata<
+      55,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BinderUnlockFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BinderUnlock kBinderUnlock{};
+  template <typename T = BinderUnlockFtraceEvent> T* set_binder_unlock() {
+    return BeginNestedMessage<T>(55);
+  }
+
+
+  using FieldMetadata_WorkqueueActivateWork =
+    ::protozero::proto_utils::FieldMetadata<
+      56,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      WorkqueueActivateWorkFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_WorkqueueActivateWork kWorkqueueActivateWork{};
+  template <typename T = WorkqueueActivateWorkFtraceEvent> T* set_workqueue_activate_work() {
+    return BeginNestedMessage<T>(56);
+  }
+
+
+  using FieldMetadata_WorkqueueExecuteEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      57,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      WorkqueueExecuteEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_WorkqueueExecuteEnd kWorkqueueExecuteEnd{};
+  template <typename T = WorkqueueExecuteEndFtraceEvent> T* set_workqueue_execute_end() {
+    return BeginNestedMessage<T>(57);
+  }
+
+
+  using FieldMetadata_WorkqueueExecuteStart =
+    ::protozero::proto_utils::FieldMetadata<
+      58,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      WorkqueueExecuteStartFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_WorkqueueExecuteStart kWorkqueueExecuteStart{};
+  template <typename T = WorkqueueExecuteStartFtraceEvent> T* set_workqueue_execute_start() {
+    return BeginNestedMessage<T>(58);
+  }
+
+
+  using FieldMetadata_WorkqueueQueueWork =
+    ::protozero::proto_utils::FieldMetadata<
+      59,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      WorkqueueQueueWorkFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_WorkqueueQueueWork kWorkqueueQueueWork{};
+  template <typename T = WorkqueueQueueWorkFtraceEvent> T* set_workqueue_queue_work() {
+    return BeginNestedMessage<T>(59);
+  }
+
+
+  using FieldMetadata_RegulatorDisable =
+    ::protozero::proto_utils::FieldMetadata<
+      60,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RegulatorDisableFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_RegulatorDisable kRegulatorDisable{};
+  template <typename T = RegulatorDisableFtraceEvent> T* set_regulator_disable() {
+    return BeginNestedMessage<T>(60);
+  }
+
+
+  using FieldMetadata_RegulatorDisableComplete =
+    ::protozero::proto_utils::FieldMetadata<
+      61,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RegulatorDisableCompleteFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_RegulatorDisableComplete kRegulatorDisableComplete{};
+  template <typename T = RegulatorDisableCompleteFtraceEvent> T* set_regulator_disable_complete() {
+    return BeginNestedMessage<T>(61);
+  }
+
+
+  using FieldMetadata_RegulatorEnable =
+    ::protozero::proto_utils::FieldMetadata<
+      62,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RegulatorEnableFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_RegulatorEnable kRegulatorEnable{};
+  template <typename T = RegulatorEnableFtraceEvent> T* set_regulator_enable() {
+    return BeginNestedMessage<T>(62);
+  }
+
+
+  using FieldMetadata_RegulatorEnableComplete =
+    ::protozero::proto_utils::FieldMetadata<
+      63,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RegulatorEnableCompleteFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_RegulatorEnableComplete kRegulatorEnableComplete{};
+  template <typename T = RegulatorEnableCompleteFtraceEvent> T* set_regulator_enable_complete() {
+    return BeginNestedMessage<T>(63);
+  }
+
+
+  using FieldMetadata_RegulatorEnableDelay =
+    ::protozero::proto_utils::FieldMetadata<
+      64,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RegulatorEnableDelayFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_RegulatorEnableDelay kRegulatorEnableDelay{};
+  template <typename T = RegulatorEnableDelayFtraceEvent> T* set_regulator_enable_delay() {
+    return BeginNestedMessage<T>(64);
+  }
+
+
+  using FieldMetadata_RegulatorSetVoltage =
+    ::protozero::proto_utils::FieldMetadata<
+      65,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RegulatorSetVoltageFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_RegulatorSetVoltage kRegulatorSetVoltage{};
+  template <typename T = RegulatorSetVoltageFtraceEvent> T* set_regulator_set_voltage() {
+    return BeginNestedMessage<T>(65);
+  }
+
+
+  using FieldMetadata_RegulatorSetVoltageComplete =
+    ::protozero::proto_utils::FieldMetadata<
+      66,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RegulatorSetVoltageCompleteFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_RegulatorSetVoltageComplete kRegulatorSetVoltageComplete{};
+  template <typename T = RegulatorSetVoltageCompleteFtraceEvent> T* set_regulator_set_voltage_complete() {
+    return BeginNestedMessage<T>(66);
+  }
+
+
+  using FieldMetadata_CgroupAttachTask =
+    ::protozero::proto_utils::FieldMetadata<
+      67,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CgroupAttachTaskFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CgroupAttachTask kCgroupAttachTask{};
+  template <typename T = CgroupAttachTaskFtraceEvent> T* set_cgroup_attach_task() {
+    return BeginNestedMessage<T>(67);
+  }
+
+
+  using FieldMetadata_CgroupMkdir =
+    ::protozero::proto_utils::FieldMetadata<
+      68,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CgroupMkdirFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CgroupMkdir kCgroupMkdir{};
+  template <typename T = CgroupMkdirFtraceEvent> T* set_cgroup_mkdir() {
+    return BeginNestedMessage<T>(68);
+  }
+
+
+  using FieldMetadata_CgroupRemount =
+    ::protozero::proto_utils::FieldMetadata<
+      69,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CgroupRemountFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CgroupRemount kCgroupRemount{};
+  template <typename T = CgroupRemountFtraceEvent> T* set_cgroup_remount() {
+    return BeginNestedMessage<T>(69);
+  }
+
+
+  using FieldMetadata_CgroupRmdir =
+    ::protozero::proto_utils::FieldMetadata<
+      70,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CgroupRmdirFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CgroupRmdir kCgroupRmdir{};
+  template <typename T = CgroupRmdirFtraceEvent> T* set_cgroup_rmdir() {
+    return BeginNestedMessage<T>(70);
+  }
+
+
+  using FieldMetadata_CgroupTransferTasks =
+    ::protozero::proto_utils::FieldMetadata<
+      71,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CgroupTransferTasksFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CgroupTransferTasks kCgroupTransferTasks{};
+  template <typename T = CgroupTransferTasksFtraceEvent> T* set_cgroup_transfer_tasks() {
+    return BeginNestedMessage<T>(71);
+  }
+
+
+  using FieldMetadata_CgroupDestroyRoot =
+    ::protozero::proto_utils::FieldMetadata<
+      72,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CgroupDestroyRootFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CgroupDestroyRoot kCgroupDestroyRoot{};
+  template <typename T = CgroupDestroyRootFtraceEvent> T* set_cgroup_destroy_root() {
+    return BeginNestedMessage<T>(72);
+  }
+
+
+  using FieldMetadata_CgroupRelease =
+    ::protozero::proto_utils::FieldMetadata<
+      73,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CgroupReleaseFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CgroupRelease kCgroupRelease{};
+  template <typename T = CgroupReleaseFtraceEvent> T* set_cgroup_release() {
+    return BeginNestedMessage<T>(73);
+  }
+
+
+  using FieldMetadata_CgroupRename =
+    ::protozero::proto_utils::FieldMetadata<
+      74,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CgroupRenameFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CgroupRename kCgroupRename{};
+  template <typename T = CgroupRenameFtraceEvent> T* set_cgroup_rename() {
+    return BeginNestedMessage<T>(74);
+  }
+
+
+  using FieldMetadata_CgroupSetupRoot =
+    ::protozero::proto_utils::FieldMetadata<
+      75,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CgroupSetupRootFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CgroupSetupRoot kCgroupSetupRoot{};
+  template <typename T = CgroupSetupRootFtraceEvent> T* set_cgroup_setup_root() {
+    return BeginNestedMessage<T>(75);
+  }
+
+
+  using FieldMetadata_MdpCmdKickoff =
+    ::protozero::proto_utils::FieldMetadata<
+      76,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpCmdKickoffFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpCmdKickoff kMdpCmdKickoff{};
+  template <typename T = MdpCmdKickoffFtraceEvent> T* set_mdp_cmd_kickoff() {
+    return BeginNestedMessage<T>(76);
+  }
+
+
+  using FieldMetadata_MdpCommit =
+    ::protozero::proto_utils::FieldMetadata<
+      77,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpCommitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpCommit kMdpCommit{};
+  template <typename T = MdpCommitFtraceEvent> T* set_mdp_commit() {
+    return BeginNestedMessage<T>(77);
+  }
+
+
+  using FieldMetadata_MdpPerfSetOt =
+    ::protozero::proto_utils::FieldMetadata<
+      78,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpPerfSetOtFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpPerfSetOt kMdpPerfSetOt{};
+  template <typename T = MdpPerfSetOtFtraceEvent> T* set_mdp_perf_set_ot() {
+    return BeginNestedMessage<T>(78);
+  }
+
+
+  using FieldMetadata_MdpSsppChange =
+    ::protozero::proto_utils::FieldMetadata<
+      79,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpSsppChangeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpSsppChange kMdpSsppChange{};
+  template <typename T = MdpSsppChangeFtraceEvent> T* set_mdp_sspp_change() {
+    return BeginNestedMessage<T>(79);
+  }
+
+
+  using FieldMetadata_TracingMarkWrite =
+    ::protozero::proto_utils::FieldMetadata<
+      80,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TracingMarkWriteFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TracingMarkWrite kTracingMarkWrite{};
+  template <typename T = TracingMarkWriteFtraceEvent> T* set_tracing_mark_write() {
+    return BeginNestedMessage<T>(80);
+  }
+
+
+  using FieldMetadata_MdpCmdPingpongDone =
+    ::protozero::proto_utils::FieldMetadata<
+      81,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpCmdPingpongDoneFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpCmdPingpongDone kMdpCmdPingpongDone{};
+  template <typename T = MdpCmdPingpongDoneFtraceEvent> T* set_mdp_cmd_pingpong_done() {
+    return BeginNestedMessage<T>(81);
+  }
+
+
+  using FieldMetadata_MdpCompareBw =
+    ::protozero::proto_utils::FieldMetadata<
+      82,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpCompareBwFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpCompareBw kMdpCompareBw{};
+  template <typename T = MdpCompareBwFtraceEvent> T* set_mdp_compare_bw() {
+    return BeginNestedMessage<T>(82);
+  }
+
+
+  using FieldMetadata_MdpPerfSetPanicLuts =
+    ::protozero::proto_utils::FieldMetadata<
+      83,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpPerfSetPanicLutsFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpPerfSetPanicLuts kMdpPerfSetPanicLuts{};
+  template <typename T = MdpPerfSetPanicLutsFtraceEvent> T* set_mdp_perf_set_panic_luts() {
+    return BeginNestedMessage<T>(83);
+  }
+
+
+  using FieldMetadata_MdpSsppSet =
+    ::protozero::proto_utils::FieldMetadata<
+      84,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpSsppSetFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpSsppSet kMdpSsppSet{};
+  template <typename T = MdpSsppSetFtraceEvent> T* set_mdp_sspp_set() {
+    return BeginNestedMessage<T>(84);
+  }
+
+
+  using FieldMetadata_MdpCmdReadptrDone =
+    ::protozero::proto_utils::FieldMetadata<
+      85,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpCmdReadptrDoneFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpCmdReadptrDone kMdpCmdReadptrDone{};
+  template <typename T = MdpCmdReadptrDoneFtraceEvent> T* set_mdp_cmd_readptr_done() {
+    return BeginNestedMessage<T>(85);
+  }
+
+
+  using FieldMetadata_MdpMisrCrc =
+    ::protozero::proto_utils::FieldMetadata<
+      86,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpMisrCrcFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpMisrCrc kMdpMisrCrc{};
+  template <typename T = MdpMisrCrcFtraceEvent> T* set_mdp_misr_crc() {
+    return BeginNestedMessage<T>(86);
+  }
+
+
+  using FieldMetadata_MdpPerfSetQosLuts =
+    ::protozero::proto_utils::FieldMetadata<
+      87,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpPerfSetQosLutsFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpPerfSetQosLuts kMdpPerfSetQosLuts{};
+  template <typename T = MdpPerfSetQosLutsFtraceEvent> T* set_mdp_perf_set_qos_luts() {
+    return BeginNestedMessage<T>(87);
+  }
+
+
+  using FieldMetadata_MdpTraceCounter =
+    ::protozero::proto_utils::FieldMetadata<
+      88,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpTraceCounterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpTraceCounter kMdpTraceCounter{};
+  template <typename T = MdpTraceCounterFtraceEvent> T* set_mdp_trace_counter() {
+    return BeginNestedMessage<T>(88);
+  }
+
+
+  using FieldMetadata_MdpCmdReleaseBw =
+    ::protozero::proto_utils::FieldMetadata<
+      89,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpCmdReleaseBwFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpCmdReleaseBw kMdpCmdReleaseBw{};
+  template <typename T = MdpCmdReleaseBwFtraceEvent> T* set_mdp_cmd_release_bw() {
+    return BeginNestedMessage<T>(89);
+  }
+
+
+  using FieldMetadata_MdpMixerUpdate =
+    ::protozero::proto_utils::FieldMetadata<
+      90,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpMixerUpdateFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpMixerUpdate kMdpMixerUpdate{};
+  template <typename T = MdpMixerUpdateFtraceEvent> T* set_mdp_mixer_update() {
+    return BeginNestedMessage<T>(90);
+  }
+
+
+  using FieldMetadata_MdpPerfSetWmLevels =
+    ::protozero::proto_utils::FieldMetadata<
+      91,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpPerfSetWmLevelsFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpPerfSetWmLevels kMdpPerfSetWmLevels{};
+  template <typename T = MdpPerfSetWmLevelsFtraceEvent> T* set_mdp_perf_set_wm_levels() {
+    return BeginNestedMessage<T>(91);
+  }
+
+
+  using FieldMetadata_MdpVideoUnderrunDone =
+    ::protozero::proto_utils::FieldMetadata<
+      92,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpVideoUnderrunDoneFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpVideoUnderrunDone kMdpVideoUnderrunDone{};
+  template <typename T = MdpVideoUnderrunDoneFtraceEvent> T* set_mdp_video_underrun_done() {
+    return BeginNestedMessage<T>(92);
+  }
+
+
+  using FieldMetadata_MdpCmdWaitPingpong =
+    ::protozero::proto_utils::FieldMetadata<
+      93,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpCmdWaitPingpongFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpCmdWaitPingpong kMdpCmdWaitPingpong{};
+  template <typename T = MdpCmdWaitPingpongFtraceEvent> T* set_mdp_cmd_wait_pingpong() {
+    return BeginNestedMessage<T>(93);
+  }
+
+
+  using FieldMetadata_MdpPerfPrefillCalc =
+    ::protozero::proto_utils::FieldMetadata<
+      94,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpPerfPrefillCalcFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpPerfPrefillCalc kMdpPerfPrefillCalc{};
+  template <typename T = MdpPerfPrefillCalcFtraceEvent> T* set_mdp_perf_prefill_calc() {
+    return BeginNestedMessage<T>(94);
+  }
+
+
+  using FieldMetadata_MdpPerfUpdateBus =
+    ::protozero::proto_utils::FieldMetadata<
+      95,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpPerfUpdateBusFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpPerfUpdateBus kMdpPerfUpdateBus{};
+  template <typename T = MdpPerfUpdateBusFtraceEvent> T* set_mdp_perf_update_bus() {
+    return BeginNestedMessage<T>(95);
+  }
+
+
+  using FieldMetadata_RotatorBwAoAsContext =
+    ::protozero::proto_utils::FieldMetadata<
+      96,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RotatorBwAoAsContextFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_RotatorBwAoAsContext kRotatorBwAoAsContext{};
+  template <typename T = RotatorBwAoAsContextFtraceEvent> T* set_rotator_bw_ao_as_context() {
+    return BeginNestedMessage<T>(96);
+  }
+
+
+  using FieldMetadata_MmFilemapAddToPageCache =
+    ::protozero::proto_utils::FieldMetadata<
+      97,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmFilemapAddToPageCacheFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmFilemapAddToPageCache kMmFilemapAddToPageCache{};
+  template <typename T = MmFilemapAddToPageCacheFtraceEvent> T* set_mm_filemap_add_to_page_cache() {
+    return BeginNestedMessage<T>(97);
+  }
+
+
+  using FieldMetadata_MmFilemapDeleteFromPageCache =
+    ::protozero::proto_utils::FieldMetadata<
+      98,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmFilemapDeleteFromPageCacheFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmFilemapDeleteFromPageCache kMmFilemapDeleteFromPageCache{};
+  template <typename T = MmFilemapDeleteFromPageCacheFtraceEvent> T* set_mm_filemap_delete_from_page_cache() {
+    return BeginNestedMessage<T>(98);
+  }
+
+
+  using FieldMetadata_MmCompactionBegin =
+    ::protozero::proto_utils::FieldMetadata<
+      99,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmCompactionBeginFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmCompactionBegin kMmCompactionBegin{};
+  template <typename T = MmCompactionBeginFtraceEvent> T* set_mm_compaction_begin() {
+    return BeginNestedMessage<T>(99);
+  }
+
+
+  using FieldMetadata_MmCompactionDeferCompaction =
+    ::protozero::proto_utils::FieldMetadata<
+      100,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmCompactionDeferCompactionFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmCompactionDeferCompaction kMmCompactionDeferCompaction{};
+  template <typename T = MmCompactionDeferCompactionFtraceEvent> T* set_mm_compaction_defer_compaction() {
+    return BeginNestedMessage<T>(100);
+  }
+
+
+  using FieldMetadata_MmCompactionDeferred =
+    ::protozero::proto_utils::FieldMetadata<
+      101,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmCompactionDeferredFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmCompactionDeferred kMmCompactionDeferred{};
+  template <typename T = MmCompactionDeferredFtraceEvent> T* set_mm_compaction_deferred() {
+    return BeginNestedMessage<T>(101);
+  }
+
+
+  using FieldMetadata_MmCompactionDeferReset =
+    ::protozero::proto_utils::FieldMetadata<
+      102,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmCompactionDeferResetFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmCompactionDeferReset kMmCompactionDeferReset{};
+  template <typename T = MmCompactionDeferResetFtraceEvent> T* set_mm_compaction_defer_reset() {
+    return BeginNestedMessage<T>(102);
+  }
+
+
+  using FieldMetadata_MmCompactionEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      103,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmCompactionEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmCompactionEnd kMmCompactionEnd{};
+  template <typename T = MmCompactionEndFtraceEvent> T* set_mm_compaction_end() {
+    return BeginNestedMessage<T>(103);
+  }
+
+
+  using FieldMetadata_MmCompactionFinished =
+    ::protozero::proto_utils::FieldMetadata<
+      104,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmCompactionFinishedFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmCompactionFinished kMmCompactionFinished{};
+  template <typename T = MmCompactionFinishedFtraceEvent> T* set_mm_compaction_finished() {
+    return BeginNestedMessage<T>(104);
+  }
+
+
+  using FieldMetadata_MmCompactionIsolateFreepages =
+    ::protozero::proto_utils::FieldMetadata<
+      105,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmCompactionIsolateFreepagesFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmCompactionIsolateFreepages kMmCompactionIsolateFreepages{};
+  template <typename T = MmCompactionIsolateFreepagesFtraceEvent> T* set_mm_compaction_isolate_freepages() {
+    return BeginNestedMessage<T>(105);
+  }
+
+
+  using FieldMetadata_MmCompactionIsolateMigratepages =
+    ::protozero::proto_utils::FieldMetadata<
+      106,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmCompactionIsolateMigratepagesFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmCompactionIsolateMigratepages kMmCompactionIsolateMigratepages{};
+  template <typename T = MmCompactionIsolateMigratepagesFtraceEvent> T* set_mm_compaction_isolate_migratepages() {
+    return BeginNestedMessage<T>(106);
+  }
+
+
+  using FieldMetadata_MmCompactionKcompactdSleep =
+    ::protozero::proto_utils::FieldMetadata<
+      107,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmCompactionKcompactdSleepFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmCompactionKcompactdSleep kMmCompactionKcompactdSleep{};
+  template <typename T = MmCompactionKcompactdSleepFtraceEvent> T* set_mm_compaction_kcompactd_sleep() {
+    return BeginNestedMessage<T>(107);
+  }
+
+
+  using FieldMetadata_MmCompactionKcompactdWake =
+    ::protozero::proto_utils::FieldMetadata<
+      108,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmCompactionKcompactdWakeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmCompactionKcompactdWake kMmCompactionKcompactdWake{};
+  template <typename T = MmCompactionKcompactdWakeFtraceEvent> T* set_mm_compaction_kcompactd_wake() {
+    return BeginNestedMessage<T>(108);
+  }
+
+
+  using FieldMetadata_MmCompactionMigratepages =
+    ::protozero::proto_utils::FieldMetadata<
+      109,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmCompactionMigratepagesFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmCompactionMigratepages kMmCompactionMigratepages{};
+  template <typename T = MmCompactionMigratepagesFtraceEvent> T* set_mm_compaction_migratepages() {
+    return BeginNestedMessage<T>(109);
+  }
+
+
+  using FieldMetadata_MmCompactionSuitable =
+    ::protozero::proto_utils::FieldMetadata<
+      110,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmCompactionSuitableFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmCompactionSuitable kMmCompactionSuitable{};
+  template <typename T = MmCompactionSuitableFtraceEvent> T* set_mm_compaction_suitable() {
+    return BeginNestedMessage<T>(110);
+  }
+
+
+  using FieldMetadata_MmCompactionTryToCompactPages =
+    ::protozero::proto_utils::FieldMetadata<
+      111,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmCompactionTryToCompactPagesFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmCompactionTryToCompactPages kMmCompactionTryToCompactPages{};
+  template <typename T = MmCompactionTryToCompactPagesFtraceEvent> T* set_mm_compaction_try_to_compact_pages() {
+    return BeginNestedMessage<T>(111);
+  }
+
+
+  using FieldMetadata_MmCompactionWakeupKcompactd =
+    ::protozero::proto_utils::FieldMetadata<
+      112,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmCompactionWakeupKcompactdFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmCompactionWakeupKcompactd kMmCompactionWakeupKcompactd{};
+  template <typename T = MmCompactionWakeupKcompactdFtraceEvent> T* set_mm_compaction_wakeup_kcompactd() {
+    return BeginNestedMessage<T>(112);
+  }
+
+
+  using FieldMetadata_SuspendResume =
+    ::protozero::proto_utils::FieldMetadata<
+      113,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SuspendResumeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SuspendResume kSuspendResume{};
+  template <typename T = SuspendResumeFtraceEvent> T* set_suspend_resume() {
+    return BeginNestedMessage<T>(113);
+  }
+
+
+  using FieldMetadata_SchedWakeupNew =
+    ::protozero::proto_utils::FieldMetadata<
+      114,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SchedWakeupNewFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SchedWakeupNew kSchedWakeupNew{};
+  template <typename T = SchedWakeupNewFtraceEvent> T* set_sched_wakeup_new() {
+    return BeginNestedMessage<T>(114);
+  }
+
+
+  using FieldMetadata_BlockBioBackmerge =
+    ::protozero::proto_utils::FieldMetadata<
+      115,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockBioBackmergeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockBioBackmerge kBlockBioBackmerge{};
+  template <typename T = BlockBioBackmergeFtraceEvent> T* set_block_bio_backmerge() {
+    return BeginNestedMessage<T>(115);
+  }
+
+
+  using FieldMetadata_BlockBioBounce =
+    ::protozero::proto_utils::FieldMetadata<
+      116,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockBioBounceFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockBioBounce kBlockBioBounce{};
+  template <typename T = BlockBioBounceFtraceEvent> T* set_block_bio_bounce() {
+    return BeginNestedMessage<T>(116);
+  }
+
+
+  using FieldMetadata_BlockBioComplete =
+    ::protozero::proto_utils::FieldMetadata<
+      117,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockBioCompleteFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockBioComplete kBlockBioComplete{};
+  template <typename T = BlockBioCompleteFtraceEvent> T* set_block_bio_complete() {
+    return BeginNestedMessage<T>(117);
+  }
+
+
+  using FieldMetadata_BlockBioFrontmerge =
+    ::protozero::proto_utils::FieldMetadata<
+      118,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockBioFrontmergeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockBioFrontmerge kBlockBioFrontmerge{};
+  template <typename T = BlockBioFrontmergeFtraceEvent> T* set_block_bio_frontmerge() {
+    return BeginNestedMessage<T>(118);
+  }
+
+
+  using FieldMetadata_BlockBioQueue =
+    ::protozero::proto_utils::FieldMetadata<
+      119,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockBioQueueFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockBioQueue kBlockBioQueue{};
+  template <typename T = BlockBioQueueFtraceEvent> T* set_block_bio_queue() {
+    return BeginNestedMessage<T>(119);
+  }
+
+
+  using FieldMetadata_BlockBioRemap =
+    ::protozero::proto_utils::FieldMetadata<
+      120,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockBioRemapFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockBioRemap kBlockBioRemap{};
+  template <typename T = BlockBioRemapFtraceEvent> T* set_block_bio_remap() {
+    return BeginNestedMessage<T>(120);
+  }
+
+
+  using FieldMetadata_BlockDirtyBuffer =
+    ::protozero::proto_utils::FieldMetadata<
+      121,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockDirtyBufferFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockDirtyBuffer kBlockDirtyBuffer{};
+  template <typename T = BlockDirtyBufferFtraceEvent> T* set_block_dirty_buffer() {
+    return BeginNestedMessage<T>(121);
+  }
+
+
+  using FieldMetadata_BlockGetrq =
+    ::protozero::proto_utils::FieldMetadata<
+      122,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockGetrqFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockGetrq kBlockGetrq{};
+  template <typename T = BlockGetrqFtraceEvent> T* set_block_getrq() {
+    return BeginNestedMessage<T>(122);
+  }
+
+
+  using FieldMetadata_BlockPlug =
+    ::protozero::proto_utils::FieldMetadata<
+      123,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockPlugFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockPlug kBlockPlug{};
+  template <typename T = BlockPlugFtraceEvent> T* set_block_plug() {
+    return BeginNestedMessage<T>(123);
+  }
+
+
+  using FieldMetadata_BlockRqAbort =
+    ::protozero::proto_utils::FieldMetadata<
+      124,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockRqAbortFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockRqAbort kBlockRqAbort{};
+  template <typename T = BlockRqAbortFtraceEvent> T* set_block_rq_abort() {
+    return BeginNestedMessage<T>(124);
+  }
+
+
+  using FieldMetadata_BlockRqComplete =
+    ::protozero::proto_utils::FieldMetadata<
+      125,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockRqCompleteFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockRqComplete kBlockRqComplete{};
+  template <typename T = BlockRqCompleteFtraceEvent> T* set_block_rq_complete() {
+    return BeginNestedMessage<T>(125);
+  }
+
+
+  using FieldMetadata_BlockRqInsert =
+    ::protozero::proto_utils::FieldMetadata<
+      126,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockRqInsertFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockRqInsert kBlockRqInsert{};
+  template <typename T = BlockRqInsertFtraceEvent> T* set_block_rq_insert() {
+    return BeginNestedMessage<T>(126);
+  }
+
+
+  using FieldMetadata_BlockRqRemap =
+    ::protozero::proto_utils::FieldMetadata<
+      128,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockRqRemapFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockRqRemap kBlockRqRemap{};
+  template <typename T = BlockRqRemapFtraceEvent> T* set_block_rq_remap() {
+    return BeginNestedMessage<T>(128);
+  }
+
+
+  using FieldMetadata_BlockRqRequeue =
+    ::protozero::proto_utils::FieldMetadata<
+      129,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockRqRequeueFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockRqRequeue kBlockRqRequeue{};
+  template <typename T = BlockRqRequeueFtraceEvent> T* set_block_rq_requeue() {
+    return BeginNestedMessage<T>(129);
+  }
+
+
+  using FieldMetadata_BlockSleeprq =
+    ::protozero::proto_utils::FieldMetadata<
+      130,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockSleeprqFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockSleeprq kBlockSleeprq{};
+  template <typename T = BlockSleeprqFtraceEvent> T* set_block_sleeprq() {
+    return BeginNestedMessage<T>(130);
+  }
+
+
+  using FieldMetadata_BlockSplit =
+    ::protozero::proto_utils::FieldMetadata<
+      131,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockSplitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockSplit kBlockSplit{};
+  template <typename T = BlockSplitFtraceEvent> T* set_block_split() {
+    return BeginNestedMessage<T>(131);
+  }
+
+
+  using FieldMetadata_BlockTouchBuffer =
+    ::protozero::proto_utils::FieldMetadata<
+      132,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockTouchBufferFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockTouchBuffer kBlockTouchBuffer{};
+  template <typename T = BlockTouchBufferFtraceEvent> T* set_block_touch_buffer() {
+    return BeginNestedMessage<T>(132);
+  }
+
+
+  using FieldMetadata_BlockUnplug =
+    ::protozero::proto_utils::FieldMetadata<
+      133,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockUnplugFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockUnplug kBlockUnplug{};
+  template <typename T = BlockUnplugFtraceEvent> T* set_block_unplug() {
+    return BeginNestedMessage<T>(133);
+  }
+
+
+  using FieldMetadata_Ext4AllocDaBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      134,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4AllocDaBlocksFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4AllocDaBlocks kExt4AllocDaBlocks{};
+  template <typename T = Ext4AllocDaBlocksFtraceEvent> T* set_ext4_alloc_da_blocks() {
+    return BeginNestedMessage<T>(134);
+  }
+
+
+  using FieldMetadata_Ext4AllocateBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      135,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4AllocateBlocksFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4AllocateBlocks kExt4AllocateBlocks{};
+  template <typename T = Ext4AllocateBlocksFtraceEvent> T* set_ext4_allocate_blocks() {
+    return BeginNestedMessage<T>(135);
+  }
+
+
+  using FieldMetadata_Ext4AllocateInode =
+    ::protozero::proto_utils::FieldMetadata<
+      136,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4AllocateInodeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4AllocateInode kExt4AllocateInode{};
+  template <typename T = Ext4AllocateInodeFtraceEvent> T* set_ext4_allocate_inode() {
+    return BeginNestedMessage<T>(136);
+  }
+
+
+  using FieldMetadata_Ext4BeginOrderedTruncate =
+    ::protozero::proto_utils::FieldMetadata<
+      137,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4BeginOrderedTruncateFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4BeginOrderedTruncate kExt4BeginOrderedTruncate{};
+  template <typename T = Ext4BeginOrderedTruncateFtraceEvent> T* set_ext4_begin_ordered_truncate() {
+    return BeginNestedMessage<T>(137);
+  }
+
+
+  using FieldMetadata_Ext4CollapseRange =
+    ::protozero::proto_utils::FieldMetadata<
+      138,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4CollapseRangeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4CollapseRange kExt4CollapseRange{};
+  template <typename T = Ext4CollapseRangeFtraceEvent> T* set_ext4_collapse_range() {
+    return BeginNestedMessage<T>(138);
+  }
+
+
+  using FieldMetadata_Ext4DaReleaseSpace =
+    ::protozero::proto_utils::FieldMetadata<
+      139,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4DaReleaseSpaceFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4DaReleaseSpace kExt4DaReleaseSpace{};
+  template <typename T = Ext4DaReleaseSpaceFtraceEvent> T* set_ext4_da_release_space() {
+    return BeginNestedMessage<T>(139);
+  }
+
+
+  using FieldMetadata_Ext4DaReserveSpace =
+    ::protozero::proto_utils::FieldMetadata<
+      140,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4DaReserveSpaceFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4DaReserveSpace kExt4DaReserveSpace{};
+  template <typename T = Ext4DaReserveSpaceFtraceEvent> T* set_ext4_da_reserve_space() {
+    return BeginNestedMessage<T>(140);
+  }
+
+
+  using FieldMetadata_Ext4DaUpdateReserveSpace =
+    ::protozero::proto_utils::FieldMetadata<
+      141,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4DaUpdateReserveSpaceFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4DaUpdateReserveSpace kExt4DaUpdateReserveSpace{};
+  template <typename T = Ext4DaUpdateReserveSpaceFtraceEvent> T* set_ext4_da_update_reserve_space() {
+    return BeginNestedMessage<T>(141);
+  }
+
+
+  using FieldMetadata_Ext4DaWritePages =
+    ::protozero::proto_utils::FieldMetadata<
+      142,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4DaWritePagesFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4DaWritePages kExt4DaWritePages{};
+  template <typename T = Ext4DaWritePagesFtraceEvent> T* set_ext4_da_write_pages() {
+    return BeginNestedMessage<T>(142);
+  }
+
+
+  using FieldMetadata_Ext4DaWritePagesExtent =
+    ::protozero::proto_utils::FieldMetadata<
+      143,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4DaWritePagesExtentFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4DaWritePagesExtent kExt4DaWritePagesExtent{};
+  template <typename T = Ext4DaWritePagesExtentFtraceEvent> T* set_ext4_da_write_pages_extent() {
+    return BeginNestedMessage<T>(143);
+  }
+
+
+  using FieldMetadata_Ext4DirectIOEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      144,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4DirectIOEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4DirectIOEnter kExt4DirectIOEnter{};
+  template <typename T = Ext4DirectIOEnterFtraceEvent> T* set_ext4_direct_io_enter() {
+    return BeginNestedMessage<T>(144);
+  }
+
+
+  using FieldMetadata_Ext4DirectIOExit =
+    ::protozero::proto_utils::FieldMetadata<
+      145,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4DirectIOExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4DirectIOExit kExt4DirectIOExit{};
+  template <typename T = Ext4DirectIOExitFtraceEvent> T* set_ext4_direct_io_exit() {
+    return BeginNestedMessage<T>(145);
+  }
+
+
+  using FieldMetadata_Ext4DiscardBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      146,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4DiscardBlocksFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4DiscardBlocks kExt4DiscardBlocks{};
+  template <typename T = Ext4DiscardBlocksFtraceEvent> T* set_ext4_discard_blocks() {
+    return BeginNestedMessage<T>(146);
+  }
+
+
+  using FieldMetadata_Ext4DiscardPreallocations =
+    ::protozero::proto_utils::FieldMetadata<
+      147,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4DiscardPreallocationsFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4DiscardPreallocations kExt4DiscardPreallocations{};
+  template <typename T = Ext4DiscardPreallocationsFtraceEvent> T* set_ext4_discard_preallocations() {
+    return BeginNestedMessage<T>(147);
+  }
+
+
+  using FieldMetadata_Ext4DropInode =
+    ::protozero::proto_utils::FieldMetadata<
+      148,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4DropInodeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4DropInode kExt4DropInode{};
+  template <typename T = Ext4DropInodeFtraceEvent> T* set_ext4_drop_inode() {
+    return BeginNestedMessage<T>(148);
+  }
+
+
+  using FieldMetadata_Ext4EsCacheExtent =
+    ::protozero::proto_utils::FieldMetadata<
+      149,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4EsCacheExtentFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4EsCacheExtent kExt4EsCacheExtent{};
+  template <typename T = Ext4EsCacheExtentFtraceEvent> T* set_ext4_es_cache_extent() {
+    return BeginNestedMessage<T>(149);
+  }
+
+
+  using FieldMetadata_Ext4EsFindDelayedExtentRangeEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      150,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4EsFindDelayedExtentRangeEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4EsFindDelayedExtentRangeEnter kExt4EsFindDelayedExtentRangeEnter{};
+  template <typename T = Ext4EsFindDelayedExtentRangeEnterFtraceEvent> T* set_ext4_es_find_delayed_extent_range_enter() {
+    return BeginNestedMessage<T>(150);
+  }
+
+
+  using FieldMetadata_Ext4EsFindDelayedExtentRangeExit =
+    ::protozero::proto_utils::FieldMetadata<
+      151,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4EsFindDelayedExtentRangeExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4EsFindDelayedExtentRangeExit kExt4EsFindDelayedExtentRangeExit{};
+  template <typename T = Ext4EsFindDelayedExtentRangeExitFtraceEvent> T* set_ext4_es_find_delayed_extent_range_exit() {
+    return BeginNestedMessage<T>(151);
+  }
+
+
+  using FieldMetadata_Ext4EsInsertExtent =
+    ::protozero::proto_utils::FieldMetadata<
+      152,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4EsInsertExtentFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4EsInsertExtent kExt4EsInsertExtent{};
+  template <typename T = Ext4EsInsertExtentFtraceEvent> T* set_ext4_es_insert_extent() {
+    return BeginNestedMessage<T>(152);
+  }
+
+
+  using FieldMetadata_Ext4EsLookupExtentEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      153,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4EsLookupExtentEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4EsLookupExtentEnter kExt4EsLookupExtentEnter{};
+  template <typename T = Ext4EsLookupExtentEnterFtraceEvent> T* set_ext4_es_lookup_extent_enter() {
+    return BeginNestedMessage<T>(153);
+  }
+
+
+  using FieldMetadata_Ext4EsLookupExtentExit =
+    ::protozero::proto_utils::FieldMetadata<
+      154,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4EsLookupExtentExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4EsLookupExtentExit kExt4EsLookupExtentExit{};
+  template <typename T = Ext4EsLookupExtentExitFtraceEvent> T* set_ext4_es_lookup_extent_exit() {
+    return BeginNestedMessage<T>(154);
+  }
+
+
+  using FieldMetadata_Ext4EsRemoveExtent =
+    ::protozero::proto_utils::FieldMetadata<
+      155,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4EsRemoveExtentFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4EsRemoveExtent kExt4EsRemoveExtent{};
+  template <typename T = Ext4EsRemoveExtentFtraceEvent> T* set_ext4_es_remove_extent() {
+    return BeginNestedMessage<T>(155);
+  }
+
+
+  using FieldMetadata_Ext4EsShrink =
+    ::protozero::proto_utils::FieldMetadata<
+      156,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4EsShrinkFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4EsShrink kExt4EsShrink{};
+  template <typename T = Ext4EsShrinkFtraceEvent> T* set_ext4_es_shrink() {
+    return BeginNestedMessage<T>(156);
+  }
+
+
+  using FieldMetadata_Ext4EsShrinkCount =
+    ::protozero::proto_utils::FieldMetadata<
+      157,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4EsShrinkCountFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4EsShrinkCount kExt4EsShrinkCount{};
+  template <typename T = Ext4EsShrinkCountFtraceEvent> T* set_ext4_es_shrink_count() {
+    return BeginNestedMessage<T>(157);
+  }
+
+
+  using FieldMetadata_Ext4EsShrinkScanEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      158,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4EsShrinkScanEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4EsShrinkScanEnter kExt4EsShrinkScanEnter{};
+  template <typename T = Ext4EsShrinkScanEnterFtraceEvent> T* set_ext4_es_shrink_scan_enter() {
+    return BeginNestedMessage<T>(158);
+  }
+
+
+  using FieldMetadata_Ext4EsShrinkScanExit =
+    ::protozero::proto_utils::FieldMetadata<
+      159,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4EsShrinkScanExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4EsShrinkScanExit kExt4EsShrinkScanExit{};
+  template <typename T = Ext4EsShrinkScanExitFtraceEvent> T* set_ext4_es_shrink_scan_exit() {
+    return BeginNestedMessage<T>(159);
+  }
+
+
+  using FieldMetadata_Ext4EvictInode =
+    ::protozero::proto_utils::FieldMetadata<
+      160,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4EvictInodeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4EvictInode kExt4EvictInode{};
+  template <typename T = Ext4EvictInodeFtraceEvent> T* set_ext4_evict_inode() {
+    return BeginNestedMessage<T>(160);
+  }
+
+
+  using FieldMetadata_Ext4ExtConvertToInitializedEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      161,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4ExtConvertToInitializedEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4ExtConvertToInitializedEnter kExt4ExtConvertToInitializedEnter{};
+  template <typename T = Ext4ExtConvertToInitializedEnterFtraceEvent> T* set_ext4_ext_convert_to_initialized_enter() {
+    return BeginNestedMessage<T>(161);
+  }
+
+
+  using FieldMetadata_Ext4ExtConvertToInitializedFastpath =
+    ::protozero::proto_utils::FieldMetadata<
+      162,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4ExtConvertToInitializedFastpathFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4ExtConvertToInitializedFastpath kExt4ExtConvertToInitializedFastpath{};
+  template <typename T = Ext4ExtConvertToInitializedFastpathFtraceEvent> T* set_ext4_ext_convert_to_initialized_fastpath() {
+    return BeginNestedMessage<T>(162);
+  }
+
+
+  using FieldMetadata_Ext4ExtHandleUnwrittenExtents =
+    ::protozero::proto_utils::FieldMetadata<
+      163,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4ExtHandleUnwrittenExtentsFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4ExtHandleUnwrittenExtents kExt4ExtHandleUnwrittenExtents{};
+  template <typename T = Ext4ExtHandleUnwrittenExtentsFtraceEvent> T* set_ext4_ext_handle_unwritten_extents() {
+    return BeginNestedMessage<T>(163);
+  }
+
+
+  using FieldMetadata_Ext4ExtInCache =
+    ::protozero::proto_utils::FieldMetadata<
+      164,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4ExtInCacheFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4ExtInCache kExt4ExtInCache{};
+  template <typename T = Ext4ExtInCacheFtraceEvent> T* set_ext4_ext_in_cache() {
+    return BeginNestedMessage<T>(164);
+  }
+
+
+  using FieldMetadata_Ext4ExtLoadExtent =
+    ::protozero::proto_utils::FieldMetadata<
+      165,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4ExtLoadExtentFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4ExtLoadExtent kExt4ExtLoadExtent{};
+  template <typename T = Ext4ExtLoadExtentFtraceEvent> T* set_ext4_ext_load_extent() {
+    return BeginNestedMessage<T>(165);
+  }
+
+
+  using FieldMetadata_Ext4ExtMapBlocksEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      166,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4ExtMapBlocksEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4ExtMapBlocksEnter kExt4ExtMapBlocksEnter{};
+  template <typename T = Ext4ExtMapBlocksEnterFtraceEvent> T* set_ext4_ext_map_blocks_enter() {
+    return BeginNestedMessage<T>(166);
+  }
+
+
+  using FieldMetadata_Ext4ExtMapBlocksExit =
+    ::protozero::proto_utils::FieldMetadata<
+      167,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4ExtMapBlocksExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4ExtMapBlocksExit kExt4ExtMapBlocksExit{};
+  template <typename T = Ext4ExtMapBlocksExitFtraceEvent> T* set_ext4_ext_map_blocks_exit() {
+    return BeginNestedMessage<T>(167);
+  }
+
+
+  using FieldMetadata_Ext4ExtPutInCache =
+    ::protozero::proto_utils::FieldMetadata<
+      168,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4ExtPutInCacheFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4ExtPutInCache kExt4ExtPutInCache{};
+  template <typename T = Ext4ExtPutInCacheFtraceEvent> T* set_ext4_ext_put_in_cache() {
+    return BeginNestedMessage<T>(168);
+  }
+
+
+  using FieldMetadata_Ext4ExtRemoveSpace =
+    ::protozero::proto_utils::FieldMetadata<
+      169,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4ExtRemoveSpaceFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4ExtRemoveSpace kExt4ExtRemoveSpace{};
+  template <typename T = Ext4ExtRemoveSpaceFtraceEvent> T* set_ext4_ext_remove_space() {
+    return BeginNestedMessage<T>(169);
+  }
+
+
+  using FieldMetadata_Ext4ExtRemoveSpaceDone =
+    ::protozero::proto_utils::FieldMetadata<
+      170,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4ExtRemoveSpaceDoneFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4ExtRemoveSpaceDone kExt4ExtRemoveSpaceDone{};
+  template <typename T = Ext4ExtRemoveSpaceDoneFtraceEvent> T* set_ext4_ext_remove_space_done() {
+    return BeginNestedMessage<T>(170);
+  }
+
+
+  using FieldMetadata_Ext4ExtRmIdx =
+    ::protozero::proto_utils::FieldMetadata<
+      171,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4ExtRmIdxFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4ExtRmIdx kExt4ExtRmIdx{};
+  template <typename T = Ext4ExtRmIdxFtraceEvent> T* set_ext4_ext_rm_idx() {
+    return BeginNestedMessage<T>(171);
+  }
+
+
+  using FieldMetadata_Ext4ExtRmLeaf =
+    ::protozero::proto_utils::FieldMetadata<
+      172,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4ExtRmLeafFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4ExtRmLeaf kExt4ExtRmLeaf{};
+  template <typename T = Ext4ExtRmLeafFtraceEvent> T* set_ext4_ext_rm_leaf() {
+    return BeginNestedMessage<T>(172);
+  }
+
+
+  using FieldMetadata_Ext4ExtShowExtent =
+    ::protozero::proto_utils::FieldMetadata<
+      173,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4ExtShowExtentFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4ExtShowExtent kExt4ExtShowExtent{};
+  template <typename T = Ext4ExtShowExtentFtraceEvent> T* set_ext4_ext_show_extent() {
+    return BeginNestedMessage<T>(173);
+  }
+
+
+  using FieldMetadata_Ext4FallocateEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      174,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4FallocateEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4FallocateEnter kExt4FallocateEnter{};
+  template <typename T = Ext4FallocateEnterFtraceEvent> T* set_ext4_fallocate_enter() {
+    return BeginNestedMessage<T>(174);
+  }
+
+
+  using FieldMetadata_Ext4FallocateExit =
+    ::protozero::proto_utils::FieldMetadata<
+      175,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4FallocateExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4FallocateExit kExt4FallocateExit{};
+  template <typename T = Ext4FallocateExitFtraceEvent> T* set_ext4_fallocate_exit() {
+    return BeginNestedMessage<T>(175);
+  }
+
+
+  using FieldMetadata_Ext4FindDelallocRange =
+    ::protozero::proto_utils::FieldMetadata<
+      176,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4FindDelallocRangeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4FindDelallocRange kExt4FindDelallocRange{};
+  template <typename T = Ext4FindDelallocRangeFtraceEvent> T* set_ext4_find_delalloc_range() {
+    return BeginNestedMessage<T>(176);
+  }
+
+
+  using FieldMetadata_Ext4Forget =
+    ::protozero::proto_utils::FieldMetadata<
+      177,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4ForgetFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4Forget kExt4Forget{};
+  template <typename T = Ext4ForgetFtraceEvent> T* set_ext4_forget() {
+    return BeginNestedMessage<T>(177);
+  }
+
+
+  using FieldMetadata_Ext4FreeBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      178,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4FreeBlocksFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4FreeBlocks kExt4FreeBlocks{};
+  template <typename T = Ext4FreeBlocksFtraceEvent> T* set_ext4_free_blocks() {
+    return BeginNestedMessage<T>(178);
+  }
+
+
+  using FieldMetadata_Ext4FreeInode =
+    ::protozero::proto_utils::FieldMetadata<
+      179,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4FreeInodeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4FreeInode kExt4FreeInode{};
+  template <typename T = Ext4FreeInodeFtraceEvent> T* set_ext4_free_inode() {
+    return BeginNestedMessage<T>(179);
+  }
+
+
+  using FieldMetadata_Ext4GetImpliedClusterAllocExit =
+    ::protozero::proto_utils::FieldMetadata<
+      180,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4GetImpliedClusterAllocExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4GetImpliedClusterAllocExit kExt4GetImpliedClusterAllocExit{};
+  template <typename T = Ext4GetImpliedClusterAllocExitFtraceEvent> T* set_ext4_get_implied_cluster_alloc_exit() {
+    return BeginNestedMessage<T>(180);
+  }
+
+
+  using FieldMetadata_Ext4GetReservedClusterAlloc =
+    ::protozero::proto_utils::FieldMetadata<
+      181,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4GetReservedClusterAllocFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4GetReservedClusterAlloc kExt4GetReservedClusterAlloc{};
+  template <typename T = Ext4GetReservedClusterAllocFtraceEvent> T* set_ext4_get_reserved_cluster_alloc() {
+    return BeginNestedMessage<T>(181);
+  }
+
+
+  using FieldMetadata_Ext4IndMapBlocksEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      182,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4IndMapBlocksEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4IndMapBlocksEnter kExt4IndMapBlocksEnter{};
+  template <typename T = Ext4IndMapBlocksEnterFtraceEvent> T* set_ext4_ind_map_blocks_enter() {
+    return BeginNestedMessage<T>(182);
+  }
+
+
+  using FieldMetadata_Ext4IndMapBlocksExit =
+    ::protozero::proto_utils::FieldMetadata<
+      183,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4IndMapBlocksExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4IndMapBlocksExit kExt4IndMapBlocksExit{};
+  template <typename T = Ext4IndMapBlocksExitFtraceEvent> T* set_ext4_ind_map_blocks_exit() {
+    return BeginNestedMessage<T>(183);
+  }
+
+
+  using FieldMetadata_Ext4InsertRange =
+    ::protozero::proto_utils::FieldMetadata<
+      184,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4InsertRangeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4InsertRange kExt4InsertRange{};
+  template <typename T = Ext4InsertRangeFtraceEvent> T* set_ext4_insert_range() {
+    return BeginNestedMessage<T>(184);
+  }
+
+
+  using FieldMetadata_Ext4Invalidatepage =
+    ::protozero::proto_utils::FieldMetadata<
+      185,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4InvalidatepageFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4Invalidatepage kExt4Invalidatepage{};
+  template <typename T = Ext4InvalidatepageFtraceEvent> T* set_ext4_invalidatepage() {
+    return BeginNestedMessage<T>(185);
+  }
+
+
+  using FieldMetadata_Ext4JournalStart =
+    ::protozero::proto_utils::FieldMetadata<
+      186,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4JournalStartFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4JournalStart kExt4JournalStart{};
+  template <typename T = Ext4JournalStartFtraceEvent> T* set_ext4_journal_start() {
+    return BeginNestedMessage<T>(186);
+  }
+
+
+  using FieldMetadata_Ext4JournalStartReserved =
+    ::protozero::proto_utils::FieldMetadata<
+      187,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4JournalStartReservedFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4JournalStartReserved kExt4JournalStartReserved{};
+  template <typename T = Ext4JournalStartReservedFtraceEvent> T* set_ext4_journal_start_reserved() {
+    return BeginNestedMessage<T>(187);
+  }
+
+
+  using FieldMetadata_Ext4JournalledInvalidatepage =
+    ::protozero::proto_utils::FieldMetadata<
+      188,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4JournalledInvalidatepageFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4JournalledInvalidatepage kExt4JournalledInvalidatepage{};
+  template <typename T = Ext4JournalledInvalidatepageFtraceEvent> T* set_ext4_journalled_invalidatepage() {
+    return BeginNestedMessage<T>(188);
+  }
+
+
+  using FieldMetadata_Ext4JournalledWriteEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      189,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4JournalledWriteEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4JournalledWriteEnd kExt4JournalledWriteEnd{};
+  template <typename T = Ext4JournalledWriteEndFtraceEvent> T* set_ext4_journalled_write_end() {
+    return BeginNestedMessage<T>(189);
+  }
+
+
+  using FieldMetadata_Ext4LoadInode =
+    ::protozero::proto_utils::FieldMetadata<
+      190,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4LoadInodeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4LoadInode kExt4LoadInode{};
+  template <typename T = Ext4LoadInodeFtraceEvent> T* set_ext4_load_inode() {
+    return BeginNestedMessage<T>(190);
+  }
+
+
+  using FieldMetadata_Ext4LoadInodeBitmap =
+    ::protozero::proto_utils::FieldMetadata<
+      191,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4LoadInodeBitmapFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4LoadInodeBitmap kExt4LoadInodeBitmap{};
+  template <typename T = Ext4LoadInodeBitmapFtraceEvent> T* set_ext4_load_inode_bitmap() {
+    return BeginNestedMessage<T>(191);
+  }
+
+
+  using FieldMetadata_Ext4MarkInodeDirty =
+    ::protozero::proto_utils::FieldMetadata<
+      192,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4MarkInodeDirtyFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4MarkInodeDirty kExt4MarkInodeDirty{};
+  template <typename T = Ext4MarkInodeDirtyFtraceEvent> T* set_ext4_mark_inode_dirty() {
+    return BeginNestedMessage<T>(192);
+  }
+
+
+  using FieldMetadata_Ext4MbBitmapLoad =
+    ::protozero::proto_utils::FieldMetadata<
+      193,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4MbBitmapLoadFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4MbBitmapLoad kExt4MbBitmapLoad{};
+  template <typename T = Ext4MbBitmapLoadFtraceEvent> T* set_ext4_mb_bitmap_load() {
+    return BeginNestedMessage<T>(193);
+  }
+
+
+  using FieldMetadata_Ext4MbBuddyBitmapLoad =
+    ::protozero::proto_utils::FieldMetadata<
+      194,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4MbBuddyBitmapLoadFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4MbBuddyBitmapLoad kExt4MbBuddyBitmapLoad{};
+  template <typename T = Ext4MbBuddyBitmapLoadFtraceEvent> T* set_ext4_mb_buddy_bitmap_load() {
+    return BeginNestedMessage<T>(194);
+  }
+
+
+  using FieldMetadata_Ext4MbDiscardPreallocations =
+    ::protozero::proto_utils::FieldMetadata<
+      195,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4MbDiscardPreallocationsFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4MbDiscardPreallocations kExt4MbDiscardPreallocations{};
+  template <typename T = Ext4MbDiscardPreallocationsFtraceEvent> T* set_ext4_mb_discard_preallocations() {
+    return BeginNestedMessage<T>(195);
+  }
+
+
+  using FieldMetadata_Ext4MbNewGroupPa =
+    ::protozero::proto_utils::FieldMetadata<
+      196,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4MbNewGroupPaFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4MbNewGroupPa kExt4MbNewGroupPa{};
+  template <typename T = Ext4MbNewGroupPaFtraceEvent> T* set_ext4_mb_new_group_pa() {
+    return BeginNestedMessage<T>(196);
+  }
+
+
+  using FieldMetadata_Ext4MbNewInodePa =
+    ::protozero::proto_utils::FieldMetadata<
+      197,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4MbNewInodePaFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4MbNewInodePa kExt4MbNewInodePa{};
+  template <typename T = Ext4MbNewInodePaFtraceEvent> T* set_ext4_mb_new_inode_pa() {
+    return BeginNestedMessage<T>(197);
+  }
+
+
+  using FieldMetadata_Ext4MbReleaseGroupPa =
+    ::protozero::proto_utils::FieldMetadata<
+      198,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4MbReleaseGroupPaFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4MbReleaseGroupPa kExt4MbReleaseGroupPa{};
+  template <typename T = Ext4MbReleaseGroupPaFtraceEvent> T* set_ext4_mb_release_group_pa() {
+    return BeginNestedMessage<T>(198);
+  }
+
+
+  using FieldMetadata_Ext4MbReleaseInodePa =
+    ::protozero::proto_utils::FieldMetadata<
+      199,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4MbReleaseInodePaFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4MbReleaseInodePa kExt4MbReleaseInodePa{};
+  template <typename T = Ext4MbReleaseInodePaFtraceEvent> T* set_ext4_mb_release_inode_pa() {
+    return BeginNestedMessage<T>(199);
+  }
+
+
+  using FieldMetadata_Ext4MballocAlloc =
+    ::protozero::proto_utils::FieldMetadata<
+      200,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4MballocAllocFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4MballocAlloc kExt4MballocAlloc{};
+  template <typename T = Ext4MballocAllocFtraceEvent> T* set_ext4_mballoc_alloc() {
+    return BeginNestedMessage<T>(200);
+  }
+
+
+  using FieldMetadata_Ext4MballocDiscard =
+    ::protozero::proto_utils::FieldMetadata<
+      201,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4MballocDiscardFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4MballocDiscard kExt4MballocDiscard{};
+  template <typename T = Ext4MballocDiscardFtraceEvent> T* set_ext4_mballoc_discard() {
+    return BeginNestedMessage<T>(201);
+  }
+
+
+  using FieldMetadata_Ext4MballocFree =
+    ::protozero::proto_utils::FieldMetadata<
+      202,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4MballocFreeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4MballocFree kExt4MballocFree{};
+  template <typename T = Ext4MballocFreeFtraceEvent> T* set_ext4_mballoc_free() {
+    return BeginNestedMessage<T>(202);
+  }
+
+
+  using FieldMetadata_Ext4MballocPrealloc =
+    ::protozero::proto_utils::FieldMetadata<
+      203,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4MballocPreallocFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4MballocPrealloc kExt4MballocPrealloc{};
+  template <typename T = Ext4MballocPreallocFtraceEvent> T* set_ext4_mballoc_prealloc() {
+    return BeginNestedMessage<T>(203);
+  }
+
+
+  using FieldMetadata_Ext4OtherInodeUpdateTime =
+    ::protozero::proto_utils::FieldMetadata<
+      204,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4OtherInodeUpdateTimeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4OtherInodeUpdateTime kExt4OtherInodeUpdateTime{};
+  template <typename T = Ext4OtherInodeUpdateTimeFtraceEvent> T* set_ext4_other_inode_update_time() {
+    return BeginNestedMessage<T>(204);
+  }
+
+
+  using FieldMetadata_Ext4PunchHole =
+    ::protozero::proto_utils::FieldMetadata<
+      205,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4PunchHoleFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4PunchHole kExt4PunchHole{};
+  template <typename T = Ext4PunchHoleFtraceEvent> T* set_ext4_punch_hole() {
+    return BeginNestedMessage<T>(205);
+  }
+
+
+  using FieldMetadata_Ext4ReadBlockBitmapLoad =
+    ::protozero::proto_utils::FieldMetadata<
+      206,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4ReadBlockBitmapLoadFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4ReadBlockBitmapLoad kExt4ReadBlockBitmapLoad{};
+  template <typename T = Ext4ReadBlockBitmapLoadFtraceEvent> T* set_ext4_read_block_bitmap_load() {
+    return BeginNestedMessage<T>(206);
+  }
+
+
+  using FieldMetadata_Ext4Readpage =
+    ::protozero::proto_utils::FieldMetadata<
+      207,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4ReadpageFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4Readpage kExt4Readpage{};
+  template <typename T = Ext4ReadpageFtraceEvent> T* set_ext4_readpage() {
+    return BeginNestedMessage<T>(207);
+  }
+
+
+  using FieldMetadata_Ext4Releasepage =
+    ::protozero::proto_utils::FieldMetadata<
+      208,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4ReleasepageFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4Releasepage kExt4Releasepage{};
+  template <typename T = Ext4ReleasepageFtraceEvent> T* set_ext4_releasepage() {
+    return BeginNestedMessage<T>(208);
+  }
+
+
+  using FieldMetadata_Ext4RemoveBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      209,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4RemoveBlocksFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4RemoveBlocks kExt4RemoveBlocks{};
+  template <typename T = Ext4RemoveBlocksFtraceEvent> T* set_ext4_remove_blocks() {
+    return BeginNestedMessage<T>(209);
+  }
+
+
+  using FieldMetadata_Ext4RequestBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      210,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4RequestBlocksFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4RequestBlocks kExt4RequestBlocks{};
+  template <typename T = Ext4RequestBlocksFtraceEvent> T* set_ext4_request_blocks() {
+    return BeginNestedMessage<T>(210);
+  }
+
+
+  using FieldMetadata_Ext4RequestInode =
+    ::protozero::proto_utils::FieldMetadata<
+      211,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4RequestInodeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4RequestInode kExt4RequestInode{};
+  template <typename T = Ext4RequestInodeFtraceEvent> T* set_ext4_request_inode() {
+    return BeginNestedMessage<T>(211);
+  }
+
+
+  using FieldMetadata_Ext4SyncFs =
+    ::protozero::proto_utils::FieldMetadata<
+      212,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4SyncFsFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4SyncFs kExt4SyncFs{};
+  template <typename T = Ext4SyncFsFtraceEvent> T* set_ext4_sync_fs() {
+    return BeginNestedMessage<T>(212);
+  }
+
+
+  using FieldMetadata_Ext4TrimAllFree =
+    ::protozero::proto_utils::FieldMetadata<
+      213,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4TrimAllFreeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4TrimAllFree kExt4TrimAllFree{};
+  template <typename T = Ext4TrimAllFreeFtraceEvent> T* set_ext4_trim_all_free() {
+    return BeginNestedMessage<T>(213);
+  }
+
+
+  using FieldMetadata_Ext4TrimExtent =
+    ::protozero::proto_utils::FieldMetadata<
+      214,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4TrimExtentFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4TrimExtent kExt4TrimExtent{};
+  template <typename T = Ext4TrimExtentFtraceEvent> T* set_ext4_trim_extent() {
+    return BeginNestedMessage<T>(214);
+  }
+
+
+  using FieldMetadata_Ext4TruncateEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      215,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4TruncateEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4TruncateEnter kExt4TruncateEnter{};
+  template <typename T = Ext4TruncateEnterFtraceEvent> T* set_ext4_truncate_enter() {
+    return BeginNestedMessage<T>(215);
+  }
+
+
+  using FieldMetadata_Ext4TruncateExit =
+    ::protozero::proto_utils::FieldMetadata<
+      216,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4TruncateExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4TruncateExit kExt4TruncateExit{};
+  template <typename T = Ext4TruncateExitFtraceEvent> T* set_ext4_truncate_exit() {
+    return BeginNestedMessage<T>(216);
+  }
+
+
+  using FieldMetadata_Ext4UnlinkEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      217,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4UnlinkEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4UnlinkEnter kExt4UnlinkEnter{};
+  template <typename T = Ext4UnlinkEnterFtraceEvent> T* set_ext4_unlink_enter() {
+    return BeginNestedMessage<T>(217);
+  }
+
+
+  using FieldMetadata_Ext4UnlinkExit =
+    ::protozero::proto_utils::FieldMetadata<
+      218,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4UnlinkExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4UnlinkExit kExt4UnlinkExit{};
+  template <typename T = Ext4UnlinkExitFtraceEvent> T* set_ext4_unlink_exit() {
+    return BeginNestedMessage<T>(218);
+  }
+
+
+  using FieldMetadata_Ext4WriteBegin =
+    ::protozero::proto_utils::FieldMetadata<
+      219,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4WriteBeginFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4WriteBegin kExt4WriteBegin{};
+  template <typename T = Ext4WriteBeginFtraceEvent> T* set_ext4_write_begin() {
+    return BeginNestedMessage<T>(219);
+  }
+
+
+  using FieldMetadata_Ext4WriteEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      230,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4WriteEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4WriteEnd kExt4WriteEnd{};
+  template <typename T = Ext4WriteEndFtraceEvent> T* set_ext4_write_end() {
+    return BeginNestedMessage<T>(230);
+  }
+
+
+  using FieldMetadata_Ext4Writepage =
+    ::protozero::proto_utils::FieldMetadata<
+      231,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4WritepageFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4Writepage kExt4Writepage{};
+  template <typename T = Ext4WritepageFtraceEvent> T* set_ext4_writepage() {
+    return BeginNestedMessage<T>(231);
+  }
+
+
+  using FieldMetadata_Ext4Writepages =
+    ::protozero::proto_utils::FieldMetadata<
+      232,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4WritepagesFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4Writepages kExt4Writepages{};
+  template <typename T = Ext4WritepagesFtraceEvent> T* set_ext4_writepages() {
+    return BeginNestedMessage<T>(232);
+  }
+
+
+  using FieldMetadata_Ext4WritepagesResult =
+    ::protozero::proto_utils::FieldMetadata<
+      233,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4WritepagesResultFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4WritepagesResult kExt4WritepagesResult{};
+  template <typename T = Ext4WritepagesResultFtraceEvent> T* set_ext4_writepages_result() {
+    return BeginNestedMessage<T>(233);
+  }
+
+
+  using FieldMetadata_Ext4ZeroRange =
+    ::protozero::proto_utils::FieldMetadata<
+      234,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4ZeroRangeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4ZeroRange kExt4ZeroRange{};
+  template <typename T = Ext4ZeroRangeFtraceEvent> T* set_ext4_zero_range() {
+    return BeginNestedMessage<T>(234);
+  }
+
+
+  using FieldMetadata_TaskNewtask =
+    ::protozero::proto_utils::FieldMetadata<
+      235,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TaskNewtaskFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TaskNewtask kTaskNewtask{};
+  template <typename T = TaskNewtaskFtraceEvent> T* set_task_newtask() {
+    return BeginNestedMessage<T>(235);
+  }
+
+
+  using FieldMetadata_TaskRename =
+    ::protozero::proto_utils::FieldMetadata<
+      236,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TaskRenameFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TaskRename kTaskRename{};
+  template <typename T = TaskRenameFtraceEvent> T* set_task_rename() {
+    return BeginNestedMessage<T>(236);
+  }
+
+
+  using FieldMetadata_SchedProcessExec =
+    ::protozero::proto_utils::FieldMetadata<
+      237,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SchedProcessExecFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SchedProcessExec kSchedProcessExec{};
+  template <typename T = SchedProcessExecFtraceEvent> T* set_sched_process_exec() {
+    return BeginNestedMessage<T>(237);
+  }
+
+
+  using FieldMetadata_SchedProcessExit =
+    ::protozero::proto_utils::FieldMetadata<
+      238,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SchedProcessExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SchedProcessExit kSchedProcessExit{};
+  template <typename T = SchedProcessExitFtraceEvent> T* set_sched_process_exit() {
+    return BeginNestedMessage<T>(238);
+  }
+
+
+  using FieldMetadata_SchedProcessFork =
+    ::protozero::proto_utils::FieldMetadata<
+      239,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SchedProcessForkFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SchedProcessFork kSchedProcessFork{};
+  template <typename T = SchedProcessForkFtraceEvent> T* set_sched_process_fork() {
+    return BeginNestedMessage<T>(239);
+  }
+
+
+  using FieldMetadata_SchedProcessFree =
+    ::protozero::proto_utils::FieldMetadata<
+      240,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SchedProcessFreeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SchedProcessFree kSchedProcessFree{};
+  template <typename T = SchedProcessFreeFtraceEvent> T* set_sched_process_free() {
+    return BeginNestedMessage<T>(240);
+  }
+
+
+  using FieldMetadata_SchedProcessHang =
+    ::protozero::proto_utils::FieldMetadata<
+      241,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SchedProcessHangFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SchedProcessHang kSchedProcessHang{};
+  template <typename T = SchedProcessHangFtraceEvent> T* set_sched_process_hang() {
+    return BeginNestedMessage<T>(241);
+  }
+
+
+  using FieldMetadata_SchedProcessWait =
+    ::protozero::proto_utils::FieldMetadata<
+      242,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SchedProcessWaitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SchedProcessWait kSchedProcessWait{};
+  template <typename T = SchedProcessWaitFtraceEvent> T* set_sched_process_wait() {
+    return BeginNestedMessage<T>(242);
+  }
+
+
+  using FieldMetadata_F2fsDoSubmitBio =
+    ::protozero::proto_utils::FieldMetadata<
+      243,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsDoSubmitBioFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsDoSubmitBio kF2fsDoSubmitBio{};
+  template <typename T = F2fsDoSubmitBioFtraceEvent> T* set_f2fs_do_submit_bio() {
+    return BeginNestedMessage<T>(243);
+  }
+
+
+  using FieldMetadata_F2fsEvictInode =
+    ::protozero::proto_utils::FieldMetadata<
+      244,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsEvictInodeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsEvictInode kF2fsEvictInode{};
+  template <typename T = F2fsEvictInodeFtraceEvent> T* set_f2fs_evict_inode() {
+    return BeginNestedMessage<T>(244);
+  }
+
+
+  using FieldMetadata_F2fsFallocate =
+    ::protozero::proto_utils::FieldMetadata<
+      245,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsFallocateFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsFallocate kF2fsFallocate{};
+  template <typename T = F2fsFallocateFtraceEvent> T* set_f2fs_fallocate() {
+    return BeginNestedMessage<T>(245);
+  }
+
+
+  using FieldMetadata_F2fsGetDataBlock =
+    ::protozero::proto_utils::FieldMetadata<
+      246,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsGetDataBlockFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsGetDataBlock kF2fsGetDataBlock{};
+  template <typename T = F2fsGetDataBlockFtraceEvent> T* set_f2fs_get_data_block() {
+    return BeginNestedMessage<T>(246);
+  }
+
+
+  using FieldMetadata_F2fsGetVictim =
+    ::protozero::proto_utils::FieldMetadata<
+      247,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsGetVictimFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsGetVictim kF2fsGetVictim{};
+  template <typename T = F2fsGetVictimFtraceEvent> T* set_f2fs_get_victim() {
+    return BeginNestedMessage<T>(247);
+  }
+
+
+  using FieldMetadata_F2fsIget =
+    ::protozero::proto_utils::FieldMetadata<
+      248,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsIgetFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsIget kF2fsIget{};
+  template <typename T = F2fsIgetFtraceEvent> T* set_f2fs_iget() {
+    return BeginNestedMessage<T>(248);
+  }
+
+
+  using FieldMetadata_F2fsIgetExit =
+    ::protozero::proto_utils::FieldMetadata<
+      249,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsIgetExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsIgetExit kF2fsIgetExit{};
+  template <typename T = F2fsIgetExitFtraceEvent> T* set_f2fs_iget_exit() {
+    return BeginNestedMessage<T>(249);
+  }
+
+
+  using FieldMetadata_F2fsNewInode =
+    ::protozero::proto_utils::FieldMetadata<
+      250,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsNewInodeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsNewInode kF2fsNewInode{};
+  template <typename T = F2fsNewInodeFtraceEvent> T* set_f2fs_new_inode() {
+    return BeginNestedMessage<T>(250);
+  }
+
+
+  using FieldMetadata_F2fsReadpage =
+    ::protozero::proto_utils::FieldMetadata<
+      251,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsReadpageFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsReadpage kF2fsReadpage{};
+  template <typename T = F2fsReadpageFtraceEvent> T* set_f2fs_readpage() {
+    return BeginNestedMessage<T>(251);
+  }
+
+
+  using FieldMetadata_F2fsReserveNewBlock =
+    ::protozero::proto_utils::FieldMetadata<
+      252,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsReserveNewBlockFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsReserveNewBlock kF2fsReserveNewBlock{};
+  template <typename T = F2fsReserveNewBlockFtraceEvent> T* set_f2fs_reserve_new_block() {
+    return BeginNestedMessage<T>(252);
+  }
+
+
+  using FieldMetadata_F2fsSetPageDirty =
+    ::protozero::proto_utils::FieldMetadata<
+      253,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsSetPageDirtyFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsSetPageDirty kF2fsSetPageDirty{};
+  template <typename T = F2fsSetPageDirtyFtraceEvent> T* set_f2fs_set_page_dirty() {
+    return BeginNestedMessage<T>(253);
+  }
+
+
+  using FieldMetadata_F2fsSubmitWritePage =
+    ::protozero::proto_utils::FieldMetadata<
+      254,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsSubmitWritePageFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsSubmitWritePage kF2fsSubmitWritePage{};
+  template <typename T = F2fsSubmitWritePageFtraceEvent> T* set_f2fs_submit_write_page() {
+    return BeginNestedMessage<T>(254);
+  }
+
+
+  using FieldMetadata_F2fsSyncFileEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      255,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsSyncFileEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsSyncFileEnter kF2fsSyncFileEnter{};
+  template <typename T = F2fsSyncFileEnterFtraceEvent> T* set_f2fs_sync_file_enter() {
+    return BeginNestedMessage<T>(255);
+  }
+
+
+  using FieldMetadata_F2fsSyncFileExit =
+    ::protozero::proto_utils::FieldMetadata<
+      256,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsSyncFileExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsSyncFileExit kF2fsSyncFileExit{};
+  template <typename T = F2fsSyncFileExitFtraceEvent> T* set_f2fs_sync_file_exit() {
+    return BeginNestedMessage<T>(256);
+  }
+
+
+  using FieldMetadata_F2fsSyncFs =
+    ::protozero::proto_utils::FieldMetadata<
+      257,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsSyncFsFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsSyncFs kF2fsSyncFs{};
+  template <typename T = F2fsSyncFsFtraceEvent> T* set_f2fs_sync_fs() {
+    return BeginNestedMessage<T>(257);
+  }
+
+
+  using FieldMetadata_F2fsTruncate =
+    ::protozero::proto_utils::FieldMetadata<
+      258,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsTruncateFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsTruncate kF2fsTruncate{};
+  template <typename T = F2fsTruncateFtraceEvent> T* set_f2fs_truncate() {
+    return BeginNestedMessage<T>(258);
+  }
+
+
+  using FieldMetadata_F2fsTruncateBlocksEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      259,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsTruncateBlocksEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsTruncateBlocksEnter kF2fsTruncateBlocksEnter{};
+  template <typename T = F2fsTruncateBlocksEnterFtraceEvent> T* set_f2fs_truncate_blocks_enter() {
+    return BeginNestedMessage<T>(259);
+  }
+
+
+  using FieldMetadata_F2fsTruncateBlocksExit =
+    ::protozero::proto_utils::FieldMetadata<
+      260,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsTruncateBlocksExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsTruncateBlocksExit kF2fsTruncateBlocksExit{};
+  template <typename T = F2fsTruncateBlocksExitFtraceEvent> T* set_f2fs_truncate_blocks_exit() {
+    return BeginNestedMessage<T>(260);
+  }
+
+
+  using FieldMetadata_F2fsTruncateDataBlocksRange =
+    ::protozero::proto_utils::FieldMetadata<
+      261,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsTruncateDataBlocksRangeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsTruncateDataBlocksRange kF2fsTruncateDataBlocksRange{};
+  template <typename T = F2fsTruncateDataBlocksRangeFtraceEvent> T* set_f2fs_truncate_data_blocks_range() {
+    return BeginNestedMessage<T>(261);
+  }
+
+
+  using FieldMetadata_F2fsTruncateInodeBlocksEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      262,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsTruncateInodeBlocksEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsTruncateInodeBlocksEnter kF2fsTruncateInodeBlocksEnter{};
+  template <typename T = F2fsTruncateInodeBlocksEnterFtraceEvent> T* set_f2fs_truncate_inode_blocks_enter() {
+    return BeginNestedMessage<T>(262);
+  }
+
+
+  using FieldMetadata_F2fsTruncateInodeBlocksExit =
+    ::protozero::proto_utils::FieldMetadata<
+      263,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsTruncateInodeBlocksExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsTruncateInodeBlocksExit kF2fsTruncateInodeBlocksExit{};
+  template <typename T = F2fsTruncateInodeBlocksExitFtraceEvent> T* set_f2fs_truncate_inode_blocks_exit() {
+    return BeginNestedMessage<T>(263);
+  }
+
+
+  using FieldMetadata_F2fsTruncateNode =
+    ::protozero::proto_utils::FieldMetadata<
+      264,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsTruncateNodeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsTruncateNode kF2fsTruncateNode{};
+  template <typename T = F2fsTruncateNodeFtraceEvent> T* set_f2fs_truncate_node() {
+    return BeginNestedMessage<T>(264);
+  }
+
+
+  using FieldMetadata_F2fsTruncateNodesEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      265,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsTruncateNodesEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsTruncateNodesEnter kF2fsTruncateNodesEnter{};
+  template <typename T = F2fsTruncateNodesEnterFtraceEvent> T* set_f2fs_truncate_nodes_enter() {
+    return BeginNestedMessage<T>(265);
+  }
+
+
+  using FieldMetadata_F2fsTruncateNodesExit =
+    ::protozero::proto_utils::FieldMetadata<
+      266,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsTruncateNodesExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsTruncateNodesExit kF2fsTruncateNodesExit{};
+  template <typename T = F2fsTruncateNodesExitFtraceEvent> T* set_f2fs_truncate_nodes_exit() {
+    return BeginNestedMessage<T>(266);
+  }
+
+
+  using FieldMetadata_F2fsTruncatePartialNodes =
+    ::protozero::proto_utils::FieldMetadata<
+      267,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsTruncatePartialNodesFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsTruncatePartialNodes kF2fsTruncatePartialNodes{};
+  template <typename T = F2fsTruncatePartialNodesFtraceEvent> T* set_f2fs_truncate_partial_nodes() {
+    return BeginNestedMessage<T>(267);
+  }
+
+
+  using FieldMetadata_F2fsUnlinkEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      268,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsUnlinkEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsUnlinkEnter kF2fsUnlinkEnter{};
+  template <typename T = F2fsUnlinkEnterFtraceEvent> T* set_f2fs_unlink_enter() {
+    return BeginNestedMessage<T>(268);
+  }
+
+
+  using FieldMetadata_F2fsUnlinkExit =
+    ::protozero::proto_utils::FieldMetadata<
+      269,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsUnlinkExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsUnlinkExit kF2fsUnlinkExit{};
+  template <typename T = F2fsUnlinkExitFtraceEvent> T* set_f2fs_unlink_exit() {
+    return BeginNestedMessage<T>(269);
+  }
+
+
+  using FieldMetadata_F2fsVmPageMkwrite =
+    ::protozero::proto_utils::FieldMetadata<
+      270,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsVmPageMkwriteFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsVmPageMkwrite kF2fsVmPageMkwrite{};
+  template <typename T = F2fsVmPageMkwriteFtraceEvent> T* set_f2fs_vm_page_mkwrite() {
+    return BeginNestedMessage<T>(270);
+  }
+
+
+  using FieldMetadata_F2fsWriteBegin =
+    ::protozero::proto_utils::FieldMetadata<
+      271,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsWriteBeginFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsWriteBegin kF2fsWriteBegin{};
+  template <typename T = F2fsWriteBeginFtraceEvent> T* set_f2fs_write_begin() {
+    return BeginNestedMessage<T>(271);
+  }
+
+
+  using FieldMetadata_F2fsWriteCheckpoint =
+    ::protozero::proto_utils::FieldMetadata<
+      272,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsWriteCheckpointFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsWriteCheckpoint kF2fsWriteCheckpoint{};
+  template <typename T = F2fsWriteCheckpointFtraceEvent> T* set_f2fs_write_checkpoint() {
+    return BeginNestedMessage<T>(272);
+  }
+
+
+  using FieldMetadata_F2fsWriteEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      273,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsWriteEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsWriteEnd kF2fsWriteEnd{};
+  template <typename T = F2fsWriteEndFtraceEvent> T* set_f2fs_write_end() {
+    return BeginNestedMessage<T>(273);
+  }
+
+
+  using FieldMetadata_AllocPagesIommuEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      274,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AllocPagesIommuEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_AllocPagesIommuEnd kAllocPagesIommuEnd{};
+  template <typename T = AllocPagesIommuEndFtraceEvent> T* set_alloc_pages_iommu_end() {
+    return BeginNestedMessage<T>(274);
+  }
+
+
+  using FieldMetadata_AllocPagesIommuFail =
+    ::protozero::proto_utils::FieldMetadata<
+      275,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AllocPagesIommuFailFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_AllocPagesIommuFail kAllocPagesIommuFail{};
+  template <typename T = AllocPagesIommuFailFtraceEvent> T* set_alloc_pages_iommu_fail() {
+    return BeginNestedMessage<T>(275);
+  }
+
+
+  using FieldMetadata_AllocPagesIommuStart =
+    ::protozero::proto_utils::FieldMetadata<
+      276,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AllocPagesIommuStartFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_AllocPagesIommuStart kAllocPagesIommuStart{};
+  template <typename T = AllocPagesIommuStartFtraceEvent> T* set_alloc_pages_iommu_start() {
+    return BeginNestedMessage<T>(276);
+  }
+
+
+  using FieldMetadata_AllocPagesSysEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      277,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AllocPagesSysEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_AllocPagesSysEnd kAllocPagesSysEnd{};
+  template <typename T = AllocPagesSysEndFtraceEvent> T* set_alloc_pages_sys_end() {
+    return BeginNestedMessage<T>(277);
+  }
+
+
+  using FieldMetadata_AllocPagesSysFail =
+    ::protozero::proto_utils::FieldMetadata<
+      278,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AllocPagesSysFailFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_AllocPagesSysFail kAllocPagesSysFail{};
+  template <typename T = AllocPagesSysFailFtraceEvent> T* set_alloc_pages_sys_fail() {
+    return BeginNestedMessage<T>(278);
+  }
+
+
+  using FieldMetadata_AllocPagesSysStart =
+    ::protozero::proto_utils::FieldMetadata<
+      279,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AllocPagesSysStartFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_AllocPagesSysStart kAllocPagesSysStart{};
+  template <typename T = AllocPagesSysStartFtraceEvent> T* set_alloc_pages_sys_start() {
+    return BeginNestedMessage<T>(279);
+  }
+
+
+  using FieldMetadata_DmaAllocContiguousRetry =
+    ::protozero::proto_utils::FieldMetadata<
+      280,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DmaAllocContiguousRetryFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_DmaAllocContiguousRetry kDmaAllocContiguousRetry{};
+  template <typename T = DmaAllocContiguousRetryFtraceEvent> T* set_dma_alloc_contiguous_retry() {
+    return BeginNestedMessage<T>(280);
+  }
+
+
+  using FieldMetadata_IommuMapRange =
+    ::protozero::proto_utils::FieldMetadata<
+      281,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IommuMapRangeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IommuMapRange kIommuMapRange{};
+  template <typename T = IommuMapRangeFtraceEvent> T* set_iommu_map_range() {
+    return BeginNestedMessage<T>(281);
+  }
+
+
+  using FieldMetadata_IommuSecPtblMapRangeEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      282,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IommuSecPtblMapRangeEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IommuSecPtblMapRangeEnd kIommuSecPtblMapRangeEnd{};
+  template <typename T = IommuSecPtblMapRangeEndFtraceEvent> T* set_iommu_sec_ptbl_map_range_end() {
+    return BeginNestedMessage<T>(282);
+  }
+
+
+  using FieldMetadata_IommuSecPtblMapRangeStart =
+    ::protozero::proto_utils::FieldMetadata<
+      283,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IommuSecPtblMapRangeStartFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IommuSecPtblMapRangeStart kIommuSecPtblMapRangeStart{};
+  template <typename T = IommuSecPtblMapRangeStartFtraceEvent> T* set_iommu_sec_ptbl_map_range_start() {
+    return BeginNestedMessage<T>(283);
+  }
+
+
+  using FieldMetadata_IonAllocBufferEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      284,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonAllocBufferEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonAllocBufferEnd kIonAllocBufferEnd{};
+  template <typename T = IonAllocBufferEndFtraceEvent> T* set_ion_alloc_buffer_end() {
+    return BeginNestedMessage<T>(284);
+  }
+
+
+  using FieldMetadata_IonAllocBufferFail =
+    ::protozero::proto_utils::FieldMetadata<
+      285,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonAllocBufferFailFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonAllocBufferFail kIonAllocBufferFail{};
+  template <typename T = IonAllocBufferFailFtraceEvent> T* set_ion_alloc_buffer_fail() {
+    return BeginNestedMessage<T>(285);
+  }
+
+
+  using FieldMetadata_IonAllocBufferFallback =
+    ::protozero::proto_utils::FieldMetadata<
+      286,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonAllocBufferFallbackFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonAllocBufferFallback kIonAllocBufferFallback{};
+  template <typename T = IonAllocBufferFallbackFtraceEvent> T* set_ion_alloc_buffer_fallback() {
+    return BeginNestedMessage<T>(286);
+  }
+
+
+  using FieldMetadata_IonAllocBufferStart =
+    ::protozero::proto_utils::FieldMetadata<
+      287,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonAllocBufferStartFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonAllocBufferStart kIonAllocBufferStart{};
+  template <typename T = IonAllocBufferStartFtraceEvent> T* set_ion_alloc_buffer_start() {
+    return BeginNestedMessage<T>(287);
+  }
+
+
+  using FieldMetadata_IonCpAllocRetry =
+    ::protozero::proto_utils::FieldMetadata<
+      288,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonCpAllocRetryFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonCpAllocRetry kIonCpAllocRetry{};
+  template <typename T = IonCpAllocRetryFtraceEvent> T* set_ion_cp_alloc_retry() {
+    return BeginNestedMessage<T>(288);
+  }
+
+
+  using FieldMetadata_IonCpSecureBufferEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      289,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonCpSecureBufferEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonCpSecureBufferEnd kIonCpSecureBufferEnd{};
+  template <typename T = IonCpSecureBufferEndFtraceEvent> T* set_ion_cp_secure_buffer_end() {
+    return BeginNestedMessage<T>(289);
+  }
+
+
+  using FieldMetadata_IonCpSecureBufferStart =
+    ::protozero::proto_utils::FieldMetadata<
+      290,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonCpSecureBufferStartFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonCpSecureBufferStart kIonCpSecureBufferStart{};
+  template <typename T = IonCpSecureBufferStartFtraceEvent> T* set_ion_cp_secure_buffer_start() {
+    return BeginNestedMessage<T>(290);
+  }
+
+
+  using FieldMetadata_IonPrefetching =
+    ::protozero::proto_utils::FieldMetadata<
+      291,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonPrefetchingFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonPrefetching kIonPrefetching{};
+  template <typename T = IonPrefetchingFtraceEvent> T* set_ion_prefetching() {
+    return BeginNestedMessage<T>(291);
+  }
+
+
+  using FieldMetadata_IonSecureCmaAddToPoolEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      292,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonSecureCmaAddToPoolEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonSecureCmaAddToPoolEnd kIonSecureCmaAddToPoolEnd{};
+  template <typename T = IonSecureCmaAddToPoolEndFtraceEvent> T* set_ion_secure_cma_add_to_pool_end() {
+    return BeginNestedMessage<T>(292);
+  }
+
+
+  using FieldMetadata_IonSecureCmaAddToPoolStart =
+    ::protozero::proto_utils::FieldMetadata<
+      293,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonSecureCmaAddToPoolStartFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonSecureCmaAddToPoolStart kIonSecureCmaAddToPoolStart{};
+  template <typename T = IonSecureCmaAddToPoolStartFtraceEvent> T* set_ion_secure_cma_add_to_pool_start() {
+    return BeginNestedMessage<T>(293);
+  }
+
+
+  using FieldMetadata_IonSecureCmaAllocateEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      294,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonSecureCmaAllocateEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonSecureCmaAllocateEnd kIonSecureCmaAllocateEnd{};
+  template <typename T = IonSecureCmaAllocateEndFtraceEvent> T* set_ion_secure_cma_allocate_end() {
+    return BeginNestedMessage<T>(294);
+  }
+
+
+  using FieldMetadata_IonSecureCmaAllocateStart =
+    ::protozero::proto_utils::FieldMetadata<
+      295,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonSecureCmaAllocateStartFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonSecureCmaAllocateStart kIonSecureCmaAllocateStart{};
+  template <typename T = IonSecureCmaAllocateStartFtraceEvent> T* set_ion_secure_cma_allocate_start() {
+    return BeginNestedMessage<T>(295);
+  }
+
+
+  using FieldMetadata_IonSecureCmaShrinkPoolEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      296,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonSecureCmaShrinkPoolEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonSecureCmaShrinkPoolEnd kIonSecureCmaShrinkPoolEnd{};
+  template <typename T = IonSecureCmaShrinkPoolEndFtraceEvent> T* set_ion_secure_cma_shrink_pool_end() {
+    return BeginNestedMessage<T>(296);
+  }
+
+
+  using FieldMetadata_IonSecureCmaShrinkPoolStart =
+    ::protozero::proto_utils::FieldMetadata<
+      297,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonSecureCmaShrinkPoolStartFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonSecureCmaShrinkPoolStart kIonSecureCmaShrinkPoolStart{};
+  template <typename T = IonSecureCmaShrinkPoolStartFtraceEvent> T* set_ion_secure_cma_shrink_pool_start() {
+    return BeginNestedMessage<T>(297);
+  }
+
+
+  using FieldMetadata_Kfree =
+    ::protozero::proto_utils::FieldMetadata<
+      298,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KfreeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Kfree kKfree{};
+  template <typename T = KfreeFtraceEvent> T* set_kfree() {
+    return BeginNestedMessage<T>(298);
+  }
+
+
+  using FieldMetadata_Kmalloc =
+    ::protozero::proto_utils::FieldMetadata<
+      299,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KmallocFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Kmalloc kKmalloc{};
+  template <typename T = KmallocFtraceEvent> T* set_kmalloc() {
+    return BeginNestedMessage<T>(299);
+  }
+
+
+  using FieldMetadata_KmallocNode =
+    ::protozero::proto_utils::FieldMetadata<
+      300,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KmallocNodeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KmallocNode kKmallocNode{};
+  template <typename T = KmallocNodeFtraceEvent> T* set_kmalloc_node() {
+    return BeginNestedMessage<T>(300);
+  }
+
+
+  using FieldMetadata_KmemCacheAlloc =
+    ::protozero::proto_utils::FieldMetadata<
+      301,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KmemCacheAllocFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KmemCacheAlloc kKmemCacheAlloc{};
+  template <typename T = KmemCacheAllocFtraceEvent> T* set_kmem_cache_alloc() {
+    return BeginNestedMessage<T>(301);
+  }
+
+
+  using FieldMetadata_KmemCacheAllocNode =
+    ::protozero::proto_utils::FieldMetadata<
+      302,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KmemCacheAllocNodeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KmemCacheAllocNode kKmemCacheAllocNode{};
+  template <typename T = KmemCacheAllocNodeFtraceEvent> T* set_kmem_cache_alloc_node() {
+    return BeginNestedMessage<T>(302);
+  }
+
+
+  using FieldMetadata_KmemCacheFree =
+    ::protozero::proto_utils::FieldMetadata<
+      303,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KmemCacheFreeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KmemCacheFree kKmemCacheFree{};
+  template <typename T = KmemCacheFreeFtraceEvent> T* set_kmem_cache_free() {
+    return BeginNestedMessage<T>(303);
+  }
+
+
+  using FieldMetadata_MigratePagesEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      304,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MigratePagesEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MigratePagesEnd kMigratePagesEnd{};
+  template <typename T = MigratePagesEndFtraceEvent> T* set_migrate_pages_end() {
+    return BeginNestedMessage<T>(304);
+  }
+
+
+  using FieldMetadata_MigratePagesStart =
+    ::protozero::proto_utils::FieldMetadata<
+      305,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MigratePagesStartFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MigratePagesStart kMigratePagesStart{};
+  template <typename T = MigratePagesStartFtraceEvent> T* set_migrate_pages_start() {
+    return BeginNestedMessage<T>(305);
+  }
+
+
+  using FieldMetadata_MigrateRetry =
+    ::protozero::proto_utils::FieldMetadata<
+      306,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MigrateRetryFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MigrateRetry kMigrateRetry{};
+  template <typename T = MigrateRetryFtraceEvent> T* set_migrate_retry() {
+    return BeginNestedMessage<T>(306);
+  }
+
+
+  using FieldMetadata_MmPageAlloc =
+    ::protozero::proto_utils::FieldMetadata<
+      307,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmPageAllocFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmPageAlloc kMmPageAlloc{};
+  template <typename T = MmPageAllocFtraceEvent> T* set_mm_page_alloc() {
+    return BeginNestedMessage<T>(307);
+  }
+
+
+  using FieldMetadata_MmPageAllocExtfrag =
+    ::protozero::proto_utils::FieldMetadata<
+      308,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmPageAllocExtfragFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmPageAllocExtfrag kMmPageAllocExtfrag{};
+  template <typename T = MmPageAllocExtfragFtraceEvent> T* set_mm_page_alloc_extfrag() {
+    return BeginNestedMessage<T>(308);
+  }
+
+
+  using FieldMetadata_MmPageAllocZoneLocked =
+    ::protozero::proto_utils::FieldMetadata<
+      309,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmPageAllocZoneLockedFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmPageAllocZoneLocked kMmPageAllocZoneLocked{};
+  template <typename T = MmPageAllocZoneLockedFtraceEvent> T* set_mm_page_alloc_zone_locked() {
+    return BeginNestedMessage<T>(309);
+  }
+
+
+  using FieldMetadata_MmPageFree =
+    ::protozero::proto_utils::FieldMetadata<
+      310,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmPageFreeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmPageFree kMmPageFree{};
+  template <typename T = MmPageFreeFtraceEvent> T* set_mm_page_free() {
+    return BeginNestedMessage<T>(310);
+  }
+
+
+  using FieldMetadata_MmPageFreeBatched =
+    ::protozero::proto_utils::FieldMetadata<
+      311,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmPageFreeBatchedFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmPageFreeBatched kMmPageFreeBatched{};
+  template <typename T = MmPageFreeBatchedFtraceEvent> T* set_mm_page_free_batched() {
+    return BeginNestedMessage<T>(311);
+  }
+
+
+  using FieldMetadata_MmPagePcpuDrain =
+    ::protozero::proto_utils::FieldMetadata<
+      312,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmPagePcpuDrainFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmPagePcpuDrain kMmPagePcpuDrain{};
+  template <typename T = MmPagePcpuDrainFtraceEvent> T* set_mm_page_pcpu_drain() {
+    return BeginNestedMessage<T>(312);
+  }
+
+
+  using FieldMetadata_RssStat =
+    ::protozero::proto_utils::FieldMetadata<
+      313,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RssStatFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_RssStat kRssStat{};
+  template <typename T = RssStatFtraceEvent> T* set_rss_stat() {
+    return BeginNestedMessage<T>(313);
+  }
+
+
+  using FieldMetadata_IonHeapShrink =
+    ::protozero::proto_utils::FieldMetadata<
+      314,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonHeapShrinkFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonHeapShrink kIonHeapShrink{};
+  template <typename T = IonHeapShrinkFtraceEvent> T* set_ion_heap_shrink() {
+    return BeginNestedMessage<T>(314);
+  }
+
+
+  using FieldMetadata_IonHeapGrow =
+    ::protozero::proto_utils::FieldMetadata<
+      315,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonHeapGrowFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonHeapGrow kIonHeapGrow{};
+  template <typename T = IonHeapGrowFtraceEvent> T* set_ion_heap_grow() {
+    return BeginNestedMessage<T>(315);
+  }
+
+
+  using FieldMetadata_FenceInit =
+    ::protozero::proto_utils::FieldMetadata<
+      316,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FenceInitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_FenceInit kFenceInit{};
+  template <typename T = FenceInitFtraceEvent> T* set_fence_init() {
+    return BeginNestedMessage<T>(316);
+  }
+
+
+  using FieldMetadata_FenceDestroy =
+    ::protozero::proto_utils::FieldMetadata<
+      317,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FenceDestroyFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_FenceDestroy kFenceDestroy{};
+  template <typename T = FenceDestroyFtraceEvent> T* set_fence_destroy() {
+    return BeginNestedMessage<T>(317);
+  }
+
+
+  using FieldMetadata_FenceEnableSignal =
+    ::protozero::proto_utils::FieldMetadata<
+      318,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FenceEnableSignalFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_FenceEnableSignal kFenceEnableSignal{};
+  template <typename T = FenceEnableSignalFtraceEvent> T* set_fence_enable_signal() {
+    return BeginNestedMessage<T>(318);
+  }
+
+
+  using FieldMetadata_FenceSignaled =
+    ::protozero::proto_utils::FieldMetadata<
+      319,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FenceSignaledFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_FenceSignaled kFenceSignaled{};
+  template <typename T = FenceSignaledFtraceEvent> T* set_fence_signaled() {
+    return BeginNestedMessage<T>(319);
+  }
+
+
+  using FieldMetadata_ClkEnable =
+    ::protozero::proto_utils::FieldMetadata<
+      320,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ClkEnableFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_ClkEnable kClkEnable{};
+  template <typename T = ClkEnableFtraceEvent> T* set_clk_enable() {
+    return BeginNestedMessage<T>(320);
+  }
+
+
+  using FieldMetadata_ClkDisable =
+    ::protozero::proto_utils::FieldMetadata<
+      321,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ClkDisableFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_ClkDisable kClkDisable{};
+  template <typename T = ClkDisableFtraceEvent> T* set_clk_disable() {
+    return BeginNestedMessage<T>(321);
+  }
+
+
+  using FieldMetadata_ClkSetRate =
+    ::protozero::proto_utils::FieldMetadata<
+      322,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ClkSetRateFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_ClkSetRate kClkSetRate{};
+  template <typename T = ClkSetRateFtraceEvent> T* set_clk_set_rate() {
+    return BeginNestedMessage<T>(322);
+  }
+
+
+  using FieldMetadata_BinderTransactionAllocBuf =
+    ::protozero::proto_utils::FieldMetadata<
+      323,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BinderTransactionAllocBufFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BinderTransactionAllocBuf kBinderTransactionAllocBuf{};
+  template <typename T = BinderTransactionAllocBufFtraceEvent> T* set_binder_transaction_alloc_buf() {
+    return BeginNestedMessage<T>(323);
+  }
+
+
+  using FieldMetadata_SignalDeliver =
+    ::protozero::proto_utils::FieldMetadata<
+      324,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SignalDeliverFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SignalDeliver kSignalDeliver{};
+  template <typename T = SignalDeliverFtraceEvent> T* set_signal_deliver() {
+    return BeginNestedMessage<T>(324);
+  }
+
+
+  using FieldMetadata_SignalGenerate =
+    ::protozero::proto_utils::FieldMetadata<
+      325,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SignalGenerateFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SignalGenerate kSignalGenerate{};
+  template <typename T = SignalGenerateFtraceEvent> T* set_signal_generate() {
+    return BeginNestedMessage<T>(325);
+  }
+
+
+  using FieldMetadata_OomScoreAdjUpdate =
+    ::protozero::proto_utils::FieldMetadata<
+      326,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      OomScoreAdjUpdateFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_OomScoreAdjUpdate kOomScoreAdjUpdate{};
+  template <typename T = OomScoreAdjUpdateFtraceEvent> T* set_oom_score_adj_update() {
+    return BeginNestedMessage<T>(326);
+  }
+
+
+  using FieldMetadata_Generic =
+    ::protozero::proto_utils::FieldMetadata<
+      327,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GenericFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Generic kGeneric{};
+  template <typename T = GenericFtraceEvent> T* set_generic() {
+    return BeginNestedMessage<T>(327);
+  }
+
+
+  using FieldMetadata_MmEventRecord =
+    ::protozero::proto_utils::FieldMetadata<
+      328,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmEventRecordFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmEventRecord kMmEventRecord{};
+  template <typename T = MmEventRecordFtraceEvent> T* set_mm_event_record() {
+    return BeginNestedMessage<T>(328);
+  }
+
+
+  using FieldMetadata_SysEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      329,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SysEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SysEnter kSysEnter{};
+  template <typename T = SysEnterFtraceEvent> T* set_sys_enter() {
+    return BeginNestedMessage<T>(329);
+  }
+
+
+  using FieldMetadata_SysExit =
+    ::protozero::proto_utils::FieldMetadata<
+      330,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SysExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SysExit kSysExit{};
+  template <typename T = SysExitFtraceEvent> T* set_sys_exit() {
+    return BeginNestedMessage<T>(330);
+  }
+
+
+  using FieldMetadata_Zero =
+    ::protozero::proto_utils::FieldMetadata<
+      331,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ZeroFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Zero kZero{};
+  template <typename T = ZeroFtraceEvent> T* set_zero() {
+    return BeginNestedMessage<T>(331);
+  }
+
+
+  using FieldMetadata_GpuFrequency =
+    ::protozero::proto_utils::FieldMetadata<
+      332,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuFrequencyFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_GpuFrequency kGpuFrequency{};
+  template <typename T = GpuFrequencyFtraceEvent> T* set_gpu_frequency() {
+    return BeginNestedMessage<T>(332);
+  }
+
+
+  using FieldMetadata_SdeTracingMarkWrite =
+    ::protozero::proto_utils::FieldMetadata<
+      333,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SdeTracingMarkWriteFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SdeTracingMarkWrite kSdeTracingMarkWrite{};
+  template <typename T = SdeTracingMarkWriteFtraceEvent> T* set_sde_tracing_mark_write() {
+    return BeginNestedMessage<T>(333);
+  }
+
+
+  using FieldMetadata_MarkVictim =
+    ::protozero::proto_utils::FieldMetadata<
+      334,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MarkVictimFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MarkVictim kMarkVictim{};
+  template <typename T = MarkVictimFtraceEvent> T* set_mark_victim() {
+    return BeginNestedMessage<T>(334);
+  }
+
+
+  using FieldMetadata_IonStat =
+    ::protozero::proto_utils::FieldMetadata<
+      335,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonStatFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonStat kIonStat{};
+  template <typename T = IonStatFtraceEvent> T* set_ion_stat() {
+    return BeginNestedMessage<T>(335);
+  }
+
+
+  using FieldMetadata_IonBufferCreate =
+    ::protozero::proto_utils::FieldMetadata<
+      336,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonBufferCreateFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonBufferCreate kIonBufferCreate{};
+  template <typename T = IonBufferCreateFtraceEvent> T* set_ion_buffer_create() {
+    return BeginNestedMessage<T>(336);
+  }
+
+
+  using FieldMetadata_IonBufferDestroy =
+    ::protozero::proto_utils::FieldMetadata<
+      337,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonBufferDestroyFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonBufferDestroy kIonBufferDestroy{};
+  template <typename T = IonBufferDestroyFtraceEvent> T* set_ion_buffer_destroy() {
+    return BeginNestedMessage<T>(337);
+  }
+
+
+  using FieldMetadata_ScmCallStart =
+    ::protozero::proto_utils::FieldMetadata<
+      338,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ScmCallStartFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_ScmCallStart kScmCallStart{};
+  template <typename T = ScmCallStartFtraceEvent> T* set_scm_call_start() {
+    return BeginNestedMessage<T>(338);
+  }
+
+
+  using FieldMetadata_ScmCallEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      339,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ScmCallEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_ScmCallEnd kScmCallEnd{};
+  template <typename T = ScmCallEndFtraceEvent> T* set_scm_call_end() {
+    return BeginNestedMessage<T>(339);
+  }
+
+
+  using FieldMetadata_GpuMemTotal =
+    ::protozero::proto_utils::FieldMetadata<
+      340,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuMemTotalFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_GpuMemTotal kGpuMemTotal{};
+  template <typename T = GpuMemTotalFtraceEvent> T* set_gpu_mem_total() {
+    return BeginNestedMessage<T>(340);
+  }
+
+
+  using FieldMetadata_ThermalTemperature =
+    ::protozero::proto_utils::FieldMetadata<
+      341,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ThermalTemperatureFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_ThermalTemperature kThermalTemperature{};
+  template <typename T = ThermalTemperatureFtraceEvent> T* set_thermal_temperature() {
+    return BeginNestedMessage<T>(341);
+  }
+
+
+  using FieldMetadata_CdevUpdate =
+    ::protozero::proto_utils::FieldMetadata<
+      342,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CdevUpdateFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CdevUpdate kCdevUpdate{};
+  template <typename T = CdevUpdateFtraceEvent> T* set_cdev_update() {
+    return BeginNestedMessage<T>(342);
+  }
+
+
+  using FieldMetadata_CpuhpExit =
+    ::protozero::proto_utils::FieldMetadata<
+      343,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CpuhpExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CpuhpExit kCpuhpExit{};
+  template <typename T = CpuhpExitFtraceEvent> T* set_cpuhp_exit() {
+    return BeginNestedMessage<T>(343);
+  }
+
+
+  using FieldMetadata_CpuhpMultiEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      344,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CpuhpMultiEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CpuhpMultiEnter kCpuhpMultiEnter{};
+  template <typename T = CpuhpMultiEnterFtraceEvent> T* set_cpuhp_multi_enter() {
+    return BeginNestedMessage<T>(344);
+  }
+
+
+  using FieldMetadata_CpuhpEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      345,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CpuhpEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CpuhpEnter kCpuhpEnter{};
+  template <typename T = CpuhpEnterFtraceEvent> T* set_cpuhp_enter() {
+    return BeginNestedMessage<T>(345);
+  }
+
+
+  using FieldMetadata_CpuhpLatency =
+    ::protozero::proto_utils::FieldMetadata<
+      346,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CpuhpLatencyFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CpuhpLatency kCpuhpLatency{};
+  template <typename T = CpuhpLatencyFtraceEvent> T* set_cpuhp_latency() {
+    return BeginNestedMessage<T>(346);
+  }
+
+
+  using FieldMetadata_FastrpcDmaStat =
+    ::protozero::proto_utils::FieldMetadata<
+      347,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FastrpcDmaStatFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_FastrpcDmaStat kFastrpcDmaStat{};
+  template <typename T = FastrpcDmaStatFtraceEvent> T* set_fastrpc_dma_stat() {
+    return BeginNestedMessage<T>(347);
+  }
+
+
+  using FieldMetadata_DpuTracingMarkWrite =
+    ::protozero::proto_utils::FieldMetadata<
+      348,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DpuTracingMarkWriteFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_DpuTracingMarkWrite kDpuTracingMarkWrite{};
+  template <typename T = DpuTracingMarkWriteFtraceEvent> T* set_dpu_tracing_mark_write() {
+    return BeginNestedMessage<T>(348);
+  }
+
+
+  using FieldMetadata_G2dTracingMarkWrite =
+    ::protozero::proto_utils::FieldMetadata<
+      349,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      G2dTracingMarkWriteFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_G2dTracingMarkWrite kG2dTracingMarkWrite{};
+  template <typename T = G2dTracingMarkWriteFtraceEvent> T* set_g2d_tracing_mark_write() {
+    return BeginNestedMessage<T>(349);
+  }
+
+
+  using FieldMetadata_MaliTracingMarkWrite =
+    ::protozero::proto_utils::FieldMetadata<
+      350,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MaliTracingMarkWriteFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MaliTracingMarkWrite kMaliTracingMarkWrite{};
+  template <typename T = MaliTracingMarkWriteFtraceEvent> T* set_mali_tracing_mark_write() {
+    return BeginNestedMessage<T>(350);
+  }
+
+
+  using FieldMetadata_DmaHeapStat =
+    ::protozero::proto_utils::FieldMetadata<
+      351,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DmaHeapStatFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_DmaHeapStat kDmaHeapStat{};
+  template <typename T = DmaHeapStatFtraceEvent> T* set_dma_heap_stat() {
+    return BeginNestedMessage<T>(351);
+  }
+
+
+  using FieldMetadata_CpuhpPause =
+    ::protozero::proto_utils::FieldMetadata<
+      352,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CpuhpPauseFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CpuhpPause kCpuhpPause{};
+  template <typename T = CpuhpPauseFtraceEvent> T* set_cpuhp_pause() {
+    return BeginNestedMessage<T>(352);
+  }
+
+
+  using FieldMetadata_SchedPiSetprio =
+    ::protozero::proto_utils::FieldMetadata<
+      353,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SchedPiSetprioFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SchedPiSetprio kSchedPiSetprio{};
+  template <typename T = SchedPiSetprioFtraceEvent> T* set_sched_pi_setprio() {
+    return BeginNestedMessage<T>(353);
+  }
+
+
+  using FieldMetadata_SdeSdeEvtlog =
+    ::protozero::proto_utils::FieldMetadata<
+      354,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SdeSdeEvtlogFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SdeSdeEvtlog kSdeSdeEvtlog{};
+  template <typename T = SdeSdeEvtlogFtraceEvent> T* set_sde_sde_evtlog() {
+    return BeginNestedMessage<T>(354);
+  }
+
+
+  using FieldMetadata_SdeSdePerfCalcCrtc =
+    ::protozero::proto_utils::FieldMetadata<
+      355,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SdeSdePerfCalcCrtcFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SdeSdePerfCalcCrtc kSdeSdePerfCalcCrtc{};
+  template <typename T = SdeSdePerfCalcCrtcFtraceEvent> T* set_sde_sde_perf_calc_crtc() {
+    return BeginNestedMessage<T>(355);
+  }
+
+
+  using FieldMetadata_SdeSdePerfCrtcUpdate =
+    ::protozero::proto_utils::FieldMetadata<
+      356,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SdeSdePerfCrtcUpdateFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SdeSdePerfCrtcUpdate kSdeSdePerfCrtcUpdate{};
+  template <typename T = SdeSdePerfCrtcUpdateFtraceEvent> T* set_sde_sde_perf_crtc_update() {
+    return BeginNestedMessage<T>(356);
+  }
+
+
+  using FieldMetadata_SdeSdePerfSetQosLuts =
+    ::protozero::proto_utils::FieldMetadata<
+      357,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SdeSdePerfSetQosLutsFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SdeSdePerfSetQosLuts kSdeSdePerfSetQosLuts{};
+  template <typename T = SdeSdePerfSetQosLutsFtraceEvent> T* set_sde_sde_perf_set_qos_luts() {
+    return BeginNestedMessage<T>(357);
+  }
+
+
+  using FieldMetadata_SdeSdePerfUpdateBus =
+    ::protozero::proto_utils::FieldMetadata<
+      358,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SdeSdePerfUpdateBusFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SdeSdePerfUpdateBus kSdeSdePerfUpdateBus{};
+  template <typename T = SdeSdePerfUpdateBusFtraceEvent> T* set_sde_sde_perf_update_bus() {
+    return BeginNestedMessage<T>(358);
+  }
+
+
+  using FieldMetadata_RssStatThrottled =
+    ::protozero::proto_utils::FieldMetadata<
+      359,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RssStatThrottledFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_RssStatThrottled kRssStatThrottled{};
+  template <typename T = RssStatThrottledFtraceEvent> T* set_rss_stat_throttled() {
+    return BeginNestedMessage<T>(359);
+  }
+
+
+  using FieldMetadata_NetifReceiveSkb =
+    ::protozero::proto_utils::FieldMetadata<
+      360,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      NetifReceiveSkbFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_NetifReceiveSkb kNetifReceiveSkb{};
+  template <typename T = NetifReceiveSkbFtraceEvent> T* set_netif_receive_skb() {
+    return BeginNestedMessage<T>(360);
+  }
+
+
+  using FieldMetadata_NetDevXmit =
+    ::protozero::proto_utils::FieldMetadata<
+      361,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      NetDevXmitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_NetDevXmit kNetDevXmit{};
+  template <typename T = NetDevXmitFtraceEvent> T* set_net_dev_xmit() {
+    return BeginNestedMessage<T>(361);
+  }
+
+
+  using FieldMetadata_InetSockSetState =
+    ::protozero::proto_utils::FieldMetadata<
+      362,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InetSockSetStateFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_InetSockSetState kInetSockSetState{};
+  template <typename T = InetSockSetStateFtraceEvent> T* set_inet_sock_set_state() {
+    return BeginNestedMessage<T>(362);
+  }
+
+
+  using FieldMetadata_TcpRetransmitSkb =
+    ::protozero::proto_utils::FieldMetadata<
+      363,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TcpRetransmitSkbFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TcpRetransmitSkb kTcpRetransmitSkb{};
+  template <typename T = TcpRetransmitSkbFtraceEvent> T* set_tcp_retransmit_skb() {
+    return BeginNestedMessage<T>(363);
+  }
+
+
+  using FieldMetadata_CrosEcSensorhubData =
+    ::protozero::proto_utils::FieldMetadata<
+      364,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CrosEcSensorhubDataFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CrosEcSensorhubData kCrosEcSensorhubData{};
+  template <typename T = CrosEcSensorhubDataFtraceEvent> T* set_cros_ec_sensorhub_data() {
+    return BeginNestedMessage<T>(364);
+  }
+
+
+  using FieldMetadata_NapiGroReceiveEntry =
+    ::protozero::proto_utils::FieldMetadata<
+      365,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      NapiGroReceiveEntryFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_NapiGroReceiveEntry kNapiGroReceiveEntry{};
+  template <typename T = NapiGroReceiveEntryFtraceEvent> T* set_napi_gro_receive_entry() {
+    return BeginNestedMessage<T>(365);
+  }
+
+
+  using FieldMetadata_NapiGroReceiveExit =
+    ::protozero::proto_utils::FieldMetadata<
+      366,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      NapiGroReceiveExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_NapiGroReceiveExit kNapiGroReceiveExit{};
+  template <typename T = NapiGroReceiveExitFtraceEvent> T* set_napi_gro_receive_exit() {
+    return BeginNestedMessage<T>(366);
+  }
+
+
+  using FieldMetadata_KfreeSkb =
+    ::protozero::proto_utils::FieldMetadata<
+      367,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KfreeSkbFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KfreeSkb kKfreeSkb{};
+  template <typename T = KfreeSkbFtraceEvent> T* set_kfree_skb() {
+    return BeginNestedMessage<T>(367);
+  }
+
+
+  using FieldMetadata_KvmAccessFault =
+    ::protozero::proto_utils::FieldMetadata<
+      368,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmAccessFaultFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmAccessFault kKvmAccessFault{};
+  template <typename T = KvmAccessFaultFtraceEvent> T* set_kvm_access_fault() {
+    return BeginNestedMessage<T>(368);
+  }
+
+
+  using FieldMetadata_KvmAckIrq =
+    ::protozero::proto_utils::FieldMetadata<
+      369,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmAckIrqFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmAckIrq kKvmAckIrq{};
+  template <typename T = KvmAckIrqFtraceEvent> T* set_kvm_ack_irq() {
+    return BeginNestedMessage<T>(369);
+  }
+
+
+  using FieldMetadata_KvmAgeHva =
+    ::protozero::proto_utils::FieldMetadata<
+      370,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmAgeHvaFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmAgeHva kKvmAgeHva{};
+  template <typename T = KvmAgeHvaFtraceEvent> T* set_kvm_age_hva() {
+    return BeginNestedMessage<T>(370);
+  }
+
+
+  using FieldMetadata_KvmAgePage =
+    ::protozero::proto_utils::FieldMetadata<
+      371,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmAgePageFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmAgePage kKvmAgePage{};
+  template <typename T = KvmAgePageFtraceEvent> T* set_kvm_age_page() {
+    return BeginNestedMessage<T>(371);
+  }
+
+
+  using FieldMetadata_KvmArmClearDebug =
+    ::protozero::proto_utils::FieldMetadata<
+      372,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmArmClearDebugFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmArmClearDebug kKvmArmClearDebug{};
+  template <typename T = KvmArmClearDebugFtraceEvent> T* set_kvm_arm_clear_debug() {
+    return BeginNestedMessage<T>(372);
+  }
+
+
+  using FieldMetadata_KvmArmSetDreg32 =
+    ::protozero::proto_utils::FieldMetadata<
+      373,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmArmSetDreg32FtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmArmSetDreg32 kKvmArmSetDreg32{};
+  template <typename T = KvmArmSetDreg32FtraceEvent> T* set_kvm_arm_set_dreg32() {
+    return BeginNestedMessage<T>(373);
+  }
+
+
+  using FieldMetadata_KvmArmSetRegset =
+    ::protozero::proto_utils::FieldMetadata<
+      374,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmArmSetRegsetFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmArmSetRegset kKvmArmSetRegset{};
+  template <typename T = KvmArmSetRegsetFtraceEvent> T* set_kvm_arm_set_regset() {
+    return BeginNestedMessage<T>(374);
+  }
+
+
+  using FieldMetadata_KvmArmSetupDebug =
+    ::protozero::proto_utils::FieldMetadata<
+      375,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmArmSetupDebugFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmArmSetupDebug kKvmArmSetupDebug{};
+  template <typename T = KvmArmSetupDebugFtraceEvent> T* set_kvm_arm_setup_debug() {
+    return BeginNestedMessage<T>(375);
+  }
+
+
+  using FieldMetadata_KvmEntry =
+    ::protozero::proto_utils::FieldMetadata<
+      376,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmEntryFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmEntry kKvmEntry{};
+  template <typename T = KvmEntryFtraceEvent> T* set_kvm_entry() {
+    return BeginNestedMessage<T>(376);
+  }
+
+
+  using FieldMetadata_KvmExit =
+    ::protozero::proto_utils::FieldMetadata<
+      377,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmExit kKvmExit{};
+  template <typename T = KvmExitFtraceEvent> T* set_kvm_exit() {
+    return BeginNestedMessage<T>(377);
+  }
+
+
+  using FieldMetadata_KvmFpu =
+    ::protozero::proto_utils::FieldMetadata<
+      378,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmFpuFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmFpu kKvmFpu{};
+  template <typename T = KvmFpuFtraceEvent> T* set_kvm_fpu() {
+    return BeginNestedMessage<T>(378);
+  }
+
+
+  using FieldMetadata_KvmGetTimerMap =
+    ::protozero::proto_utils::FieldMetadata<
+      379,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmGetTimerMapFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmGetTimerMap kKvmGetTimerMap{};
+  template <typename T = KvmGetTimerMapFtraceEvent> T* set_kvm_get_timer_map() {
+    return BeginNestedMessage<T>(379);
+  }
+
+
+  using FieldMetadata_KvmGuestFault =
+    ::protozero::proto_utils::FieldMetadata<
+      380,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmGuestFaultFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmGuestFault kKvmGuestFault{};
+  template <typename T = KvmGuestFaultFtraceEvent> T* set_kvm_guest_fault() {
+    return BeginNestedMessage<T>(380);
+  }
+
+
+  using FieldMetadata_KvmHandleSysReg =
+    ::protozero::proto_utils::FieldMetadata<
+      381,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmHandleSysRegFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmHandleSysReg kKvmHandleSysReg{};
+  template <typename T = KvmHandleSysRegFtraceEvent> T* set_kvm_handle_sys_reg() {
+    return BeginNestedMessage<T>(381);
+  }
+
+
+  using FieldMetadata_KvmHvcArm64 =
+    ::protozero::proto_utils::FieldMetadata<
+      382,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmHvcArm64FtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmHvcArm64 kKvmHvcArm64{};
+  template <typename T = KvmHvcArm64FtraceEvent> T* set_kvm_hvc_arm64() {
+    return BeginNestedMessage<T>(382);
+  }
+
+
+  using FieldMetadata_KvmIrqLine =
+    ::protozero::proto_utils::FieldMetadata<
+      383,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmIrqLineFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmIrqLine kKvmIrqLine{};
+  template <typename T = KvmIrqLineFtraceEvent> T* set_kvm_irq_line() {
+    return BeginNestedMessage<T>(383);
+  }
+
+
+  using FieldMetadata_KvmMmio =
+    ::protozero::proto_utils::FieldMetadata<
+      384,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmMmioFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmMmio kKvmMmio{};
+  template <typename T = KvmMmioFtraceEvent> T* set_kvm_mmio() {
+    return BeginNestedMessage<T>(384);
+  }
+
+
+  using FieldMetadata_KvmMmioEmulate =
+    ::protozero::proto_utils::FieldMetadata<
+      385,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmMmioEmulateFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmMmioEmulate kKvmMmioEmulate{};
+  template <typename T = KvmMmioEmulateFtraceEvent> T* set_kvm_mmio_emulate() {
+    return BeginNestedMessage<T>(385);
+  }
+
+
+  using FieldMetadata_KvmSetGuestDebug =
+    ::protozero::proto_utils::FieldMetadata<
+      386,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmSetGuestDebugFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmSetGuestDebug kKvmSetGuestDebug{};
+  template <typename T = KvmSetGuestDebugFtraceEvent> T* set_kvm_set_guest_debug() {
+    return BeginNestedMessage<T>(386);
+  }
+
+
+  using FieldMetadata_KvmSetIrq =
+    ::protozero::proto_utils::FieldMetadata<
+      387,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmSetIrqFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmSetIrq kKvmSetIrq{};
+  template <typename T = KvmSetIrqFtraceEvent> T* set_kvm_set_irq() {
+    return BeginNestedMessage<T>(387);
+  }
+
+
+  using FieldMetadata_KvmSetSpteHva =
+    ::protozero::proto_utils::FieldMetadata<
+      388,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmSetSpteHvaFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmSetSpteHva kKvmSetSpteHva{};
+  template <typename T = KvmSetSpteHvaFtraceEvent> T* set_kvm_set_spte_hva() {
+    return BeginNestedMessage<T>(388);
+  }
+
+
+  using FieldMetadata_KvmSetWayFlush =
+    ::protozero::proto_utils::FieldMetadata<
+      389,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmSetWayFlushFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmSetWayFlush kKvmSetWayFlush{};
+  template <typename T = KvmSetWayFlushFtraceEvent> T* set_kvm_set_way_flush() {
+    return BeginNestedMessage<T>(389);
+  }
+
+
+  using FieldMetadata_KvmSysAccess =
+    ::protozero::proto_utils::FieldMetadata<
+      390,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmSysAccessFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmSysAccess kKvmSysAccess{};
+  template <typename T = KvmSysAccessFtraceEvent> T* set_kvm_sys_access() {
+    return BeginNestedMessage<T>(390);
+  }
+
+
+  using FieldMetadata_KvmTestAgeHva =
+    ::protozero::proto_utils::FieldMetadata<
+      391,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmTestAgeHvaFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmTestAgeHva kKvmTestAgeHva{};
+  template <typename T = KvmTestAgeHvaFtraceEvent> T* set_kvm_test_age_hva() {
+    return BeginNestedMessage<T>(391);
+  }
+
+
+  using FieldMetadata_KvmTimerEmulate =
+    ::protozero::proto_utils::FieldMetadata<
+      392,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmTimerEmulateFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmTimerEmulate kKvmTimerEmulate{};
+  template <typename T = KvmTimerEmulateFtraceEvent> T* set_kvm_timer_emulate() {
+    return BeginNestedMessage<T>(392);
+  }
+
+
+  using FieldMetadata_KvmTimerHrtimerExpire =
+    ::protozero::proto_utils::FieldMetadata<
+      393,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmTimerHrtimerExpireFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmTimerHrtimerExpire kKvmTimerHrtimerExpire{};
+  template <typename T = KvmTimerHrtimerExpireFtraceEvent> T* set_kvm_timer_hrtimer_expire() {
+    return BeginNestedMessage<T>(393);
+  }
+
+
+  using FieldMetadata_KvmTimerRestoreState =
+    ::protozero::proto_utils::FieldMetadata<
+      394,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmTimerRestoreStateFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmTimerRestoreState kKvmTimerRestoreState{};
+  template <typename T = KvmTimerRestoreStateFtraceEvent> T* set_kvm_timer_restore_state() {
+    return BeginNestedMessage<T>(394);
+  }
+
+
+  using FieldMetadata_KvmTimerSaveState =
+    ::protozero::proto_utils::FieldMetadata<
+      395,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmTimerSaveStateFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmTimerSaveState kKvmTimerSaveState{};
+  template <typename T = KvmTimerSaveStateFtraceEvent> T* set_kvm_timer_save_state() {
+    return BeginNestedMessage<T>(395);
+  }
+
+
+  using FieldMetadata_KvmTimerUpdateIrq =
+    ::protozero::proto_utils::FieldMetadata<
+      396,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmTimerUpdateIrqFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmTimerUpdateIrq kKvmTimerUpdateIrq{};
+  template <typename T = KvmTimerUpdateIrqFtraceEvent> T* set_kvm_timer_update_irq() {
+    return BeginNestedMessage<T>(396);
+  }
+
+
+  using FieldMetadata_KvmToggleCache =
+    ::protozero::proto_utils::FieldMetadata<
+      397,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmToggleCacheFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmToggleCache kKvmToggleCache{};
+  template <typename T = KvmToggleCacheFtraceEvent> T* set_kvm_toggle_cache() {
+    return BeginNestedMessage<T>(397);
+  }
+
+
+  using FieldMetadata_KvmUnmapHvaRange =
+    ::protozero::proto_utils::FieldMetadata<
+      398,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmUnmapHvaRangeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmUnmapHvaRange kKvmUnmapHvaRange{};
+  template <typename T = KvmUnmapHvaRangeFtraceEvent> T* set_kvm_unmap_hva_range() {
+    return BeginNestedMessage<T>(398);
+  }
+
+
+  using FieldMetadata_KvmUserspaceExit =
+    ::protozero::proto_utils::FieldMetadata<
+      399,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmUserspaceExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmUserspaceExit kKvmUserspaceExit{};
+  template <typename T = KvmUserspaceExitFtraceEvent> T* set_kvm_userspace_exit() {
+    return BeginNestedMessage<T>(399);
+  }
+
+
+  using FieldMetadata_KvmVcpuWakeup =
+    ::protozero::proto_utils::FieldMetadata<
+      400,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmVcpuWakeupFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmVcpuWakeup kKvmVcpuWakeup{};
+  template <typename T = KvmVcpuWakeupFtraceEvent> T* set_kvm_vcpu_wakeup() {
+    return BeginNestedMessage<T>(400);
+  }
+
+
+  using FieldMetadata_KvmWfxArm64 =
+    ::protozero::proto_utils::FieldMetadata<
+      401,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmWfxArm64FtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmWfxArm64 kKvmWfxArm64{};
+  template <typename T = KvmWfxArm64FtraceEvent> T* set_kvm_wfx_arm64() {
+    return BeginNestedMessage<T>(401);
+  }
+
+
+  using FieldMetadata_TrapReg =
+    ::protozero::proto_utils::FieldMetadata<
+      402,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrapRegFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrapReg kTrapReg{};
+  template <typename T = TrapRegFtraceEvent> T* set_trap_reg() {
+    return BeginNestedMessage<T>(402);
+  }
+
+
+  using FieldMetadata_VgicUpdateIrqPending =
+    ::protozero::proto_utils::FieldMetadata<
+      403,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      VgicUpdateIrqPendingFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_VgicUpdateIrqPending kVgicUpdateIrqPending{};
+  template <typename T = VgicUpdateIrqPendingFtraceEvent> T* set_vgic_update_irq_pending() {
+    return BeginNestedMessage<T>(403);
+  }
+
+
+  using FieldMetadata_WakeupSourceActivate =
+    ::protozero::proto_utils::FieldMetadata<
+      404,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      WakeupSourceActivateFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_WakeupSourceActivate kWakeupSourceActivate{};
+  template <typename T = WakeupSourceActivateFtraceEvent> T* set_wakeup_source_activate() {
+    return BeginNestedMessage<T>(404);
+  }
+
+
+  using FieldMetadata_WakeupSourceDeactivate =
+    ::protozero::proto_utils::FieldMetadata<
+      405,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      WakeupSourceDeactivateFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_WakeupSourceDeactivate kWakeupSourceDeactivate{};
+  template <typename T = WakeupSourceDeactivateFtraceEvent> T* set_wakeup_source_deactivate() {
+    return BeginNestedMessage<T>(405);
+  }
+
+
+  using FieldMetadata_UfshcdCommand =
+    ::protozero::proto_utils::FieldMetadata<
+      406,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      UfshcdCommandFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_UfshcdCommand kUfshcdCommand{};
+  template <typename T = UfshcdCommandFtraceEvent> T* set_ufshcd_command() {
+    return BeginNestedMessage<T>(406);
+  }
+
+
+  using FieldMetadata_UfshcdClkGating =
+    ::protozero::proto_utils::FieldMetadata<
+      407,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      UfshcdClkGatingFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_UfshcdClkGating kUfshcdClkGating{};
+  template <typename T = UfshcdClkGatingFtraceEvent> T* set_ufshcd_clk_gating() {
+    return BeginNestedMessage<T>(407);
+  }
+
+
+  using FieldMetadata_Console =
+    ::protozero::proto_utils::FieldMetadata<
+      408,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ConsoleFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Console kConsole{};
+  template <typename T = ConsoleFtraceEvent> T* set_console() {
+    return BeginNestedMessage<T>(408);
+  }
+
+
+  using FieldMetadata_DrmVblankEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      409,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DrmVblankEventFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_DrmVblankEvent kDrmVblankEvent{};
+  template <typename T = DrmVblankEventFtraceEvent> T* set_drm_vblank_event() {
+    return BeginNestedMessage<T>(409);
+  }
+
+
+  using FieldMetadata_DrmVblankEventDelivered =
+    ::protozero::proto_utils::FieldMetadata<
+      410,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DrmVblankEventDeliveredFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_DrmVblankEventDelivered kDrmVblankEventDelivered{};
+  template <typename T = DrmVblankEventDeliveredFtraceEvent> T* set_drm_vblank_event_delivered() {
+    return BeginNestedMessage<T>(410);
+  }
+
+
+  using FieldMetadata_DrmSchedJob =
+    ::protozero::proto_utils::FieldMetadata<
+      411,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DrmSchedJobFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_DrmSchedJob kDrmSchedJob{};
+  template <typename T = DrmSchedJobFtraceEvent> T* set_drm_sched_job() {
+    return BeginNestedMessage<T>(411);
+  }
+
+
+  using FieldMetadata_DrmRunJob =
+    ::protozero::proto_utils::FieldMetadata<
+      412,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DrmRunJobFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_DrmRunJob kDrmRunJob{};
+  template <typename T = DrmRunJobFtraceEvent> T* set_drm_run_job() {
+    return BeginNestedMessage<T>(412);
+  }
+
+
+  using FieldMetadata_DrmSchedProcessJob =
+    ::protozero::proto_utils::FieldMetadata<
+      413,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DrmSchedProcessJobFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_DrmSchedProcessJob kDrmSchedProcessJob{};
+  template <typename T = DrmSchedProcessJobFtraceEvent> T* set_drm_sched_process_job() {
+    return BeginNestedMessage<T>(413);
+  }
+
+
+  using FieldMetadata_DmaFenceInit =
+    ::protozero::proto_utils::FieldMetadata<
+      414,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DmaFenceInitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_DmaFenceInit kDmaFenceInit{};
+  template <typename T = DmaFenceInitFtraceEvent> T* set_dma_fence_init() {
+    return BeginNestedMessage<T>(414);
+  }
+
+
+  using FieldMetadata_DmaFenceEmit =
+    ::protozero::proto_utils::FieldMetadata<
+      415,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DmaFenceEmitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_DmaFenceEmit kDmaFenceEmit{};
+  template <typename T = DmaFenceEmitFtraceEvent> T* set_dma_fence_emit() {
+    return BeginNestedMessage<T>(415);
+  }
+
+
+  using FieldMetadata_DmaFenceSignaled =
+    ::protozero::proto_utils::FieldMetadata<
+      416,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DmaFenceSignaledFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_DmaFenceSignaled kDmaFenceSignaled{};
+  template <typename T = DmaFenceSignaledFtraceEvent> T* set_dma_fence_signaled() {
+    return BeginNestedMessage<T>(416);
+  }
+
+
+  using FieldMetadata_DmaFenceWaitStart =
+    ::protozero::proto_utils::FieldMetadata<
+      417,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DmaFenceWaitStartFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_DmaFenceWaitStart kDmaFenceWaitStart{};
+  template <typename T = DmaFenceWaitStartFtraceEvent> T* set_dma_fence_wait_start() {
+    return BeginNestedMessage<T>(417);
+  }
+
+
+  using FieldMetadata_DmaFenceWaitEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      418,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DmaFenceWaitEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_DmaFenceWaitEnd kDmaFenceWaitEnd{};
+  template <typename T = DmaFenceWaitEndFtraceEvent> T* set_dma_fence_wait_end() {
+    return BeginNestedMessage<T>(418);
+  }
+
+
+  using FieldMetadata_F2fsIostat =
+    ::protozero::proto_utils::FieldMetadata<
+      419,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsIostatFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsIostat kF2fsIostat{};
+  template <typename T = F2fsIostatFtraceEvent> T* set_f2fs_iostat() {
+    return BeginNestedMessage<T>(419);
+  }
+
+
+  using FieldMetadata_F2fsIostatLatency =
+    ::protozero::proto_utils::FieldMetadata<
+      420,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsIostatLatencyFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsIostatLatency kF2fsIostatLatency{};
+  template <typename T = F2fsIostatLatencyFtraceEvent> T* set_f2fs_iostat_latency() {
+    return BeginNestedMessage<T>(420);
+  }
+
+
+  using FieldMetadata_SchedCpuUtilCfs =
+    ::protozero::proto_utils::FieldMetadata<
+      421,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SchedCpuUtilCfsFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SchedCpuUtilCfs kSchedCpuUtilCfs{};
+  template <typename T = SchedCpuUtilCfsFtraceEvent> T* set_sched_cpu_util_cfs() {
+    return BeginNestedMessage<T>(421);
+  }
+
+
+  using FieldMetadata_V4l2Qbuf =
+    ::protozero::proto_utils::FieldMetadata<
+      422,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      V4l2QbufFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_V4l2Qbuf kV4l2Qbuf{};
+  template <typename T = V4l2QbufFtraceEvent> T* set_v4l2_qbuf() {
+    return BeginNestedMessage<T>(422);
+  }
+
+
+  using FieldMetadata_V4l2Dqbuf =
+    ::protozero::proto_utils::FieldMetadata<
+      423,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      V4l2DqbufFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_V4l2Dqbuf kV4l2Dqbuf{};
+  template <typename T = V4l2DqbufFtraceEvent> T* set_v4l2_dqbuf() {
+    return BeginNestedMessage<T>(423);
+  }
+
+
+  using FieldMetadata_Vb2V4l2BufQueue =
+    ::protozero::proto_utils::FieldMetadata<
+      424,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Vb2V4l2BufQueueFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Vb2V4l2BufQueue kVb2V4l2BufQueue{};
+  template <typename T = Vb2V4l2BufQueueFtraceEvent> T* set_vb2_v4l2_buf_queue() {
+    return BeginNestedMessage<T>(424);
+  }
+
+
+  using FieldMetadata_Vb2V4l2BufDone =
+    ::protozero::proto_utils::FieldMetadata<
+      425,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Vb2V4l2BufDoneFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Vb2V4l2BufDone kVb2V4l2BufDone{};
+  template <typename T = Vb2V4l2BufDoneFtraceEvent> T* set_vb2_v4l2_buf_done() {
+    return BeginNestedMessage<T>(425);
+  }
+
+
+  using FieldMetadata_Vb2V4l2Qbuf =
+    ::protozero::proto_utils::FieldMetadata<
+      426,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Vb2V4l2QbufFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Vb2V4l2Qbuf kVb2V4l2Qbuf{};
+  template <typename T = Vb2V4l2QbufFtraceEvent> T* set_vb2_v4l2_qbuf() {
+    return BeginNestedMessage<T>(426);
+  }
+
+
+  using FieldMetadata_Vb2V4l2Dqbuf =
+    ::protozero::proto_utils::FieldMetadata<
+      427,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Vb2V4l2DqbufFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Vb2V4l2Dqbuf kVb2V4l2Dqbuf{};
+  template <typename T = Vb2V4l2DqbufFtraceEvent> T* set_vb2_v4l2_dqbuf() {
+    return BeginNestedMessage<T>(427);
+  }
+
+
+  using FieldMetadata_DsiCmdFifoStatus =
+    ::protozero::proto_utils::FieldMetadata<
+      428,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DsiCmdFifoStatusFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_DsiCmdFifoStatus kDsiCmdFifoStatus{};
+  template <typename T = DsiCmdFifoStatusFtraceEvent> T* set_dsi_cmd_fifo_status() {
+    return BeginNestedMessage<T>(428);
+  }
+
+
+  using FieldMetadata_DsiRx =
+    ::protozero::proto_utils::FieldMetadata<
+      429,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DsiRxFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_DsiRx kDsiRx{};
+  template <typename T = DsiRxFtraceEvent> T* set_dsi_rx() {
+    return BeginNestedMessage<T>(429);
+  }
+
+
+  using FieldMetadata_DsiTx =
+    ::protozero::proto_utils::FieldMetadata<
+      430,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DsiTxFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_DsiTx kDsiTx{};
+  template <typename T = DsiTxFtraceEvent> T* set_dsi_tx() {
+    return BeginNestedMessage<T>(430);
+  }
+
+
+  using FieldMetadata_AndroidFsDatareadEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      431,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidFsDatareadEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_AndroidFsDatareadEnd kAndroidFsDatareadEnd{};
+  template <typename T = AndroidFsDatareadEndFtraceEvent> T* set_android_fs_dataread_end() {
+    return BeginNestedMessage<T>(431);
+  }
+
+
+  using FieldMetadata_AndroidFsDatareadStart =
+    ::protozero::proto_utils::FieldMetadata<
+      432,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidFsDatareadStartFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_AndroidFsDatareadStart kAndroidFsDatareadStart{};
+  template <typename T = AndroidFsDatareadStartFtraceEvent> T* set_android_fs_dataread_start() {
+    return BeginNestedMessage<T>(432);
+  }
+
+
+  using FieldMetadata_AndroidFsDatawriteEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      433,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidFsDatawriteEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_AndroidFsDatawriteEnd kAndroidFsDatawriteEnd{};
+  template <typename T = AndroidFsDatawriteEndFtraceEvent> T* set_android_fs_datawrite_end() {
+    return BeginNestedMessage<T>(433);
+  }
+
+
+  using FieldMetadata_AndroidFsDatawriteStart =
+    ::protozero::proto_utils::FieldMetadata<
+      434,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidFsDatawriteStartFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_AndroidFsDatawriteStart kAndroidFsDatawriteStart{};
+  template <typename T = AndroidFsDatawriteStartFtraceEvent> T* set_android_fs_datawrite_start() {
+    return BeginNestedMessage<T>(434);
+  }
+
+
+  using FieldMetadata_AndroidFsFsyncEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      435,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidFsFsyncEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_AndroidFsFsyncEnd kAndroidFsFsyncEnd{};
+  template <typename T = AndroidFsFsyncEndFtraceEvent> T* set_android_fs_fsync_end() {
+    return BeginNestedMessage<T>(435);
+  }
+
+
+  using FieldMetadata_AndroidFsFsyncStart =
+    ::protozero::proto_utils::FieldMetadata<
+      436,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidFsFsyncStartFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_AndroidFsFsyncStart kAndroidFsFsyncStart{};
+  template <typename T = AndroidFsFsyncStartFtraceEvent> T* set_android_fs_fsync_start() {
+    return BeginNestedMessage<T>(436);
+  }
+
+
+  using FieldMetadata_FuncgraphEntry =
+    ::protozero::proto_utils::FieldMetadata<
+      437,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FuncgraphEntryFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_FuncgraphEntry kFuncgraphEntry{};
+  template <typename T = FuncgraphEntryFtraceEvent> T* set_funcgraph_entry() {
+    return BeginNestedMessage<T>(437);
+  }
+
+
+  using FieldMetadata_FuncgraphExit =
+    ::protozero::proto_utils::FieldMetadata<
+      438,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FuncgraphExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_FuncgraphExit kFuncgraphExit{};
+  template <typename T = FuncgraphExitFtraceEvent> T* set_funcgraph_exit() {
+    return BeginNestedMessage<T>(438);
+  }
+
+
+  using FieldMetadata_VirtioVideoCmd =
+    ::protozero::proto_utils::FieldMetadata<
+      439,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      VirtioVideoCmdFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_VirtioVideoCmd kVirtioVideoCmd{};
+  template <typename T = VirtioVideoCmdFtraceEvent> T* set_virtio_video_cmd() {
+    return BeginNestedMessage<T>(439);
+  }
+
+
+  using FieldMetadata_VirtioVideoCmdDone =
+    ::protozero::proto_utils::FieldMetadata<
+      440,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      VirtioVideoCmdDoneFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_VirtioVideoCmdDone kVirtioVideoCmdDone{};
+  template <typename T = VirtioVideoCmdDoneFtraceEvent> T* set_virtio_video_cmd_done() {
+    return BeginNestedMessage<T>(440);
+  }
+
+
+  using FieldMetadata_VirtioVideoResourceQueue =
+    ::protozero::proto_utils::FieldMetadata<
+      441,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      VirtioVideoResourceQueueFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_VirtioVideoResourceQueue kVirtioVideoResourceQueue{};
+  template <typename T = VirtioVideoResourceQueueFtraceEvent> T* set_virtio_video_resource_queue() {
+    return BeginNestedMessage<T>(441);
+  }
+
+
+  using FieldMetadata_VirtioVideoResourceQueueDone =
+    ::protozero::proto_utils::FieldMetadata<
+      442,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      VirtioVideoResourceQueueDoneFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_VirtioVideoResourceQueueDone kVirtioVideoResourceQueueDone{};
+  template <typename T = VirtioVideoResourceQueueDoneFtraceEvent> T* set_virtio_video_resource_queue_done() {
+    return BeginNestedMessage<T>(442);
+  }
+
+
+  using FieldMetadata_MmShrinkSlabStart =
+    ::protozero::proto_utils::FieldMetadata<
+      443,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmShrinkSlabStartFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmShrinkSlabStart kMmShrinkSlabStart{};
+  template <typename T = MmShrinkSlabStartFtraceEvent> T* set_mm_shrink_slab_start() {
+    return BeginNestedMessage<T>(443);
+  }
+
+
+  using FieldMetadata_MmShrinkSlabEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      444,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmShrinkSlabEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmShrinkSlabEnd kMmShrinkSlabEnd{};
+  template <typename T = MmShrinkSlabEndFtraceEvent> T* set_mm_shrink_slab_end() {
+    return BeginNestedMessage<T>(444);
+  }
+
+
+  using FieldMetadata_TrustySmc =
+    ::protozero::proto_utils::FieldMetadata<
+      445,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrustySmcFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrustySmc kTrustySmc{};
+  template <typename T = TrustySmcFtraceEvent> T* set_trusty_smc() {
+    return BeginNestedMessage<T>(445);
+  }
+
+
+  using FieldMetadata_TrustySmcDone =
+    ::protozero::proto_utils::FieldMetadata<
+      446,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrustySmcDoneFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrustySmcDone kTrustySmcDone{};
+  template <typename T = TrustySmcDoneFtraceEvent> T* set_trusty_smc_done() {
+    return BeginNestedMessage<T>(446);
+  }
+
+
+  using FieldMetadata_TrustyStdCall32 =
+    ::protozero::proto_utils::FieldMetadata<
+      447,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrustyStdCall32FtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrustyStdCall32 kTrustyStdCall32{};
+  template <typename T = TrustyStdCall32FtraceEvent> T* set_trusty_std_call32() {
+    return BeginNestedMessage<T>(447);
+  }
+
+
+  using FieldMetadata_TrustyStdCall32Done =
+    ::protozero::proto_utils::FieldMetadata<
+      448,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrustyStdCall32DoneFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrustyStdCall32Done kTrustyStdCall32Done{};
+  template <typename T = TrustyStdCall32DoneFtraceEvent> T* set_trusty_std_call32_done() {
+    return BeginNestedMessage<T>(448);
+  }
+
+
+  using FieldMetadata_TrustyShareMemory =
+    ::protozero::proto_utils::FieldMetadata<
+      449,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrustyShareMemoryFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrustyShareMemory kTrustyShareMemory{};
+  template <typename T = TrustyShareMemoryFtraceEvent> T* set_trusty_share_memory() {
+    return BeginNestedMessage<T>(449);
+  }
+
+
+  using FieldMetadata_TrustyShareMemoryDone =
+    ::protozero::proto_utils::FieldMetadata<
+      450,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrustyShareMemoryDoneFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrustyShareMemoryDone kTrustyShareMemoryDone{};
+  template <typename T = TrustyShareMemoryDoneFtraceEvent> T* set_trusty_share_memory_done() {
+    return BeginNestedMessage<T>(450);
+  }
+
+
+  using FieldMetadata_TrustyReclaimMemory =
+    ::protozero::proto_utils::FieldMetadata<
+      451,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrustyReclaimMemoryFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrustyReclaimMemory kTrustyReclaimMemory{};
+  template <typename T = TrustyReclaimMemoryFtraceEvent> T* set_trusty_reclaim_memory() {
+    return BeginNestedMessage<T>(451);
+  }
+
+
+  using FieldMetadata_TrustyReclaimMemoryDone =
+    ::protozero::proto_utils::FieldMetadata<
+      452,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrustyReclaimMemoryDoneFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrustyReclaimMemoryDone kTrustyReclaimMemoryDone{};
+  template <typename T = TrustyReclaimMemoryDoneFtraceEvent> T* set_trusty_reclaim_memory_done() {
+    return BeginNestedMessage<T>(452);
+  }
+
+
+  using FieldMetadata_TrustyIrq =
+    ::protozero::proto_utils::FieldMetadata<
+      453,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrustyIrqFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrustyIrq kTrustyIrq{};
+  template <typename T = TrustyIrqFtraceEvent> T* set_trusty_irq() {
+    return BeginNestedMessage<T>(453);
+  }
+
+
+  using FieldMetadata_TrustyIpcHandleEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      454,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrustyIpcHandleEventFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrustyIpcHandleEvent kTrustyIpcHandleEvent{};
+  template <typename T = TrustyIpcHandleEventFtraceEvent> T* set_trusty_ipc_handle_event() {
+    return BeginNestedMessage<T>(454);
+  }
+
+
+  using FieldMetadata_TrustyIpcConnect =
+    ::protozero::proto_utils::FieldMetadata<
+      455,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrustyIpcConnectFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrustyIpcConnect kTrustyIpcConnect{};
+  template <typename T = TrustyIpcConnectFtraceEvent> T* set_trusty_ipc_connect() {
+    return BeginNestedMessage<T>(455);
+  }
+
+
+  using FieldMetadata_TrustyIpcConnectEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      456,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrustyIpcConnectEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrustyIpcConnectEnd kTrustyIpcConnectEnd{};
+  template <typename T = TrustyIpcConnectEndFtraceEvent> T* set_trusty_ipc_connect_end() {
+    return BeginNestedMessage<T>(456);
+  }
+
+
+  using FieldMetadata_TrustyIpcWrite =
+    ::protozero::proto_utils::FieldMetadata<
+      457,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrustyIpcWriteFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrustyIpcWrite kTrustyIpcWrite{};
+  template <typename T = TrustyIpcWriteFtraceEvent> T* set_trusty_ipc_write() {
+    return BeginNestedMessage<T>(457);
+  }
+
+
+  using FieldMetadata_TrustyIpcPoll =
+    ::protozero::proto_utils::FieldMetadata<
+      458,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrustyIpcPollFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrustyIpcPoll kTrustyIpcPoll{};
+  template <typename T = TrustyIpcPollFtraceEvent> T* set_trusty_ipc_poll() {
+    return BeginNestedMessage<T>(458);
+  }
+
+
+  using FieldMetadata_TrustyIpcRead =
+    ::protozero::proto_utils::FieldMetadata<
+      460,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrustyIpcReadFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrustyIpcRead kTrustyIpcRead{};
+  template <typename T = TrustyIpcReadFtraceEvent> T* set_trusty_ipc_read() {
+    return BeginNestedMessage<T>(460);
+  }
+
+
+  using FieldMetadata_TrustyIpcReadEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      461,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrustyIpcReadEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrustyIpcReadEnd kTrustyIpcReadEnd{};
+  template <typename T = TrustyIpcReadEndFtraceEvent> T* set_trusty_ipc_read_end() {
+    return BeginNestedMessage<T>(461);
+  }
+
+
+  using FieldMetadata_TrustyIpcRx =
+    ::protozero::proto_utils::FieldMetadata<
+      462,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrustyIpcRxFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrustyIpcRx kTrustyIpcRx{};
+  template <typename T = TrustyIpcRxFtraceEvent> T* set_trusty_ipc_rx() {
+    return BeginNestedMessage<T>(462);
+  }
+
+
+  using FieldMetadata_TrustyEnqueueNop =
+    ::protozero::proto_utils::FieldMetadata<
+      464,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrustyEnqueueNopFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrustyEnqueueNop kTrustyEnqueueNop{};
+  template <typename T = TrustyEnqueueNopFtraceEvent> T* set_trusty_enqueue_nop() {
+    return BeginNestedMessage<T>(464);
+  }
+
+
+  using FieldMetadata_CmaAllocStart =
+    ::protozero::proto_utils::FieldMetadata<
+      465,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CmaAllocStartFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CmaAllocStart kCmaAllocStart{};
+  template <typename T = CmaAllocStartFtraceEvent> T* set_cma_alloc_start() {
+    return BeginNestedMessage<T>(465);
+  }
+
+
+  using FieldMetadata_CmaAllocInfo =
+    ::protozero::proto_utils::FieldMetadata<
+      466,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CmaAllocInfoFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CmaAllocInfo kCmaAllocInfo{};
+  template <typename T = CmaAllocInfoFtraceEvent> T* set_cma_alloc_info() {
+    return BeginNestedMessage<T>(466);
+  }
+
+
+  using FieldMetadata_LwisTracingMarkWrite =
+    ::protozero::proto_utils::FieldMetadata<
+      467,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      LwisTracingMarkWriteFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_LwisTracingMarkWrite kLwisTracingMarkWrite{};
+  template <typename T = LwisTracingMarkWriteFtraceEvent> T* set_lwis_tracing_mark_write() {
+    return BeginNestedMessage<T>(467);
+  }
+
+
+  using FieldMetadata_VirtioGpuCmdQueue =
+    ::protozero::proto_utils::FieldMetadata<
+      468,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      VirtioGpuCmdQueueFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_VirtioGpuCmdQueue kVirtioGpuCmdQueue{};
+  template <typename T = VirtioGpuCmdQueueFtraceEvent> T* set_virtio_gpu_cmd_queue() {
+    return BeginNestedMessage<T>(468);
+  }
+
+
+  using FieldMetadata_VirtioGpuCmdResponse =
+    ::protozero::proto_utils::FieldMetadata<
+      469,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      VirtioGpuCmdResponseFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_VirtioGpuCmdResponse kVirtioGpuCmdResponse{};
+  template <typename T = VirtioGpuCmdResponseFtraceEvent> T* set_virtio_gpu_cmd_response() {
+    return BeginNestedMessage<T>(469);
+  }
+
+
+  using FieldMetadata_MaliMaliKCPUCQSSET =
+    ::protozero::proto_utils::FieldMetadata<
+      470,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MaliMaliKCPUCQSSETFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MaliMaliKCPUCQSSET kMaliMaliKCPUCQSSET{};
+  template <typename T = MaliMaliKCPUCQSSETFtraceEvent> T* set_mali_mali_kcpu_cqs_set() {
+    return BeginNestedMessage<T>(470);
+  }
+
+
+  using FieldMetadata_MaliMaliKCPUCQSWAITSTART =
+    ::protozero::proto_utils::FieldMetadata<
+      471,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MaliMaliKCPUCQSWAITSTARTFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MaliMaliKCPUCQSWAITSTART kMaliMaliKCPUCQSWAITSTART{};
+  template <typename T = MaliMaliKCPUCQSWAITSTARTFtraceEvent> T* set_mali_mali_kcpu_cqs_wait_start() {
+    return BeginNestedMessage<T>(471);
+  }
+
+
+  using FieldMetadata_MaliMaliKCPUCQSWAITEND =
+    ::protozero::proto_utils::FieldMetadata<
+      472,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MaliMaliKCPUCQSWAITENDFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MaliMaliKCPUCQSWAITEND kMaliMaliKCPUCQSWAITEND{};
+  template <typename T = MaliMaliKCPUCQSWAITENDFtraceEvent> T* set_mali_mali_kcpu_cqs_wait_end() {
+    return BeginNestedMessage<T>(472);
+  }
+
+
+  using FieldMetadata_MaliMaliKCPUFENCESIGNAL =
+    ::protozero::proto_utils::FieldMetadata<
+      473,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MaliMaliKCPUFENCESIGNALFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MaliMaliKCPUFENCESIGNAL kMaliMaliKCPUFENCESIGNAL{};
+  template <typename T = MaliMaliKCPUFENCESIGNALFtraceEvent> T* set_mali_mali_kcpu_fence_signal() {
+    return BeginNestedMessage<T>(473);
+  }
+
+
+  using FieldMetadata_MaliMaliKCPUFENCEWAITSTART =
+    ::protozero::proto_utils::FieldMetadata<
+      474,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MaliMaliKCPUFENCEWAITSTARTFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MaliMaliKCPUFENCEWAITSTART kMaliMaliKCPUFENCEWAITSTART{};
+  template <typename T = MaliMaliKCPUFENCEWAITSTARTFtraceEvent> T* set_mali_mali_kcpu_fence_wait_start() {
+    return BeginNestedMessage<T>(474);
+  }
+
+
+  using FieldMetadata_MaliMaliKCPUFENCEWAITEND =
+    ::protozero::proto_utils::FieldMetadata<
+      475,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MaliMaliKCPUFENCEWAITENDFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MaliMaliKCPUFENCEWAITEND kMaliMaliKCPUFENCEWAITEND{};
+  template <typename T = MaliMaliKCPUFENCEWAITENDFtraceEvent> T* set_mali_mali_kcpu_fence_wait_end() {
+    return BeginNestedMessage<T>(475);
+  }
+
+
+  using FieldMetadata_HypEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      476,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      HypEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_HypEnter kHypEnter{};
+  template <typename T = HypEnterFtraceEvent> T* set_hyp_enter() {
+    return BeginNestedMessage<T>(476);
+  }
+
+
+  using FieldMetadata_HypExit =
+    ::protozero::proto_utils::FieldMetadata<
+      477,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      HypExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_HypExit kHypExit{};
+  template <typename T = HypExitFtraceEvent> T* set_hyp_exit() {
+    return BeginNestedMessage<T>(477);
+  }
+
+
+  using FieldMetadata_HostHcall =
+    ::protozero::proto_utils::FieldMetadata<
+      478,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      HostHcallFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_HostHcall kHostHcall{};
+  template <typename T = HostHcallFtraceEvent> T* set_host_hcall() {
+    return BeginNestedMessage<T>(478);
+  }
+
+
+  using FieldMetadata_HostSmc =
+    ::protozero::proto_utils::FieldMetadata<
+      479,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      HostSmcFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_HostSmc kHostSmc{};
+  template <typename T = HostSmcFtraceEvent> T* set_host_smc() {
+    return BeginNestedMessage<T>(479);
+  }
+
+
+  using FieldMetadata_HostMemAbort =
+    ::protozero::proto_utils::FieldMetadata<
+      480,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      HostMemAbortFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_HostMemAbort kHostMemAbort{};
+  template <typename T = HostMemAbortFtraceEvent> T* set_host_mem_abort() {
+    return BeginNestedMessage<T>(480);
+  }
+
+
+  using FieldMetadata_SuspendResumeMinimal =
+    ::protozero::proto_utils::FieldMetadata<
+      481,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SuspendResumeMinimalFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SuspendResumeMinimal kSuspendResumeMinimal{};
+  template <typename T = SuspendResumeMinimalFtraceEvent> T* set_suspend_resume_minimal() {
+    return BeginNestedMessage<T>(481);
+  }
+
+
+  using FieldMetadata_MaliMaliCSFINTERRUPTSTART =
+    ::protozero::proto_utils::FieldMetadata<
+      482,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MaliMaliCSFINTERRUPTSTARTFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MaliMaliCSFINTERRUPTSTART kMaliMaliCSFINTERRUPTSTART{};
+  template <typename T = MaliMaliCSFINTERRUPTSTARTFtraceEvent> T* set_mali_mali_csf_interrupt_start() {
+    return BeginNestedMessage<T>(482);
+  }
+
+
+  using FieldMetadata_MaliMaliCSFINTERRUPTEND =
+    ::protozero::proto_utils::FieldMetadata<
+      483,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MaliMaliCSFINTERRUPTENDFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MaliMaliCSFINTERRUPTEND kMaliMaliCSFINTERRUPTEND{};
+  template <typename T = MaliMaliCSFINTERRUPTENDFtraceEvent> T* set_mali_mali_csf_interrupt_end() {
+    return BeginNestedMessage<T>(483);
+  }
+
+
+  using FieldMetadata_SamsungTracingMarkWrite =
+    ::protozero::proto_utils::FieldMetadata<
+      484,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SamsungTracingMarkWriteFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SamsungTracingMarkWrite kSamsungTracingMarkWrite{};
+  template <typename T = SamsungTracingMarkWriteFtraceEvent> T* set_samsung_tracing_mark_write() {
+    return BeginNestedMessage<T>(484);
+  }
+
+
+  using FieldMetadata_BinderCommand =
+    ::protozero::proto_utils::FieldMetadata<
+      485,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BinderCommandFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BinderCommand kBinderCommand{};
+  template <typename T = BinderCommandFtraceEvent> T* set_binder_command() {
+    return BeginNestedMessage<T>(485);
+  }
+
+
+  using FieldMetadata_BinderReturn =
+    ::protozero::proto_utils::FieldMetadata<
+      486,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BinderReturnFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BinderReturn kBinderReturn{};
+  template <typename T = BinderReturnFtraceEvent> T* set_binder_return() {
+    return BeginNestedMessage<T>(486);
+  }
+
+
+  using FieldMetadata_SchedSwitchWithCtrs =
+    ::protozero::proto_utils::FieldMetadata<
+      487,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SchedSwitchWithCtrsFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SchedSwitchWithCtrs kSchedSwitchWithCtrs{};
+  template <typename T = SchedSwitchWithCtrsFtraceEvent> T* set_sched_switch_with_ctrs() {
+    return BeginNestedMessage<T>(487);
+  }
+
+
+  using FieldMetadata_GpuWorkPeriod =
+    ::protozero::proto_utils::FieldMetadata<
+      488,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuWorkPeriodFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_GpuWorkPeriod kGpuWorkPeriod{};
+  template <typename T = GpuWorkPeriodFtraceEvent> T* set_gpu_work_period() {
+    return BeginNestedMessage<T>(488);
+  }
+
+
+  using FieldMetadata_RpmStatus =
+    ::protozero::proto_utils::FieldMetadata<
+      489,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RpmStatusFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_RpmStatus kRpmStatus{};
+  template <typename T = RpmStatusFtraceEvent> T* set_rpm_status() {
+    return BeginNestedMessage<T>(489);
+  }
+
+
+  using FieldMetadata_PanelWriteGeneric =
+    ::protozero::proto_utils::FieldMetadata<
+      490,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PanelWriteGenericFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_PanelWriteGeneric kPanelWriteGeneric{};
+  template <typename T = PanelWriteGenericFtraceEvent> T* set_panel_write_generic() {
+    return BeginNestedMessage<T>(490);
+  }
+
+
+  using FieldMetadata_SchedMigrateTask =
+    ::protozero::proto_utils::FieldMetadata<
+      491,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SchedMigrateTaskFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SchedMigrateTask kSchedMigrateTask{};
+  template <typename T = SchedMigrateTaskFtraceEvent> T* set_sched_migrate_task() {
+    return BeginNestedMessage<T>(491);
+  }
+
+
+  using FieldMetadata_DpuDsiCmdFifoStatus =
+    ::protozero::proto_utils::FieldMetadata<
+      492,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DpuDsiCmdFifoStatusFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_DpuDsiCmdFifoStatus kDpuDsiCmdFifoStatus{};
+  template <typename T = DpuDsiCmdFifoStatusFtraceEvent> T* set_dpu_dsi_cmd_fifo_status() {
+    return BeginNestedMessage<T>(492);
+  }
+
+
+  using FieldMetadata_DpuDsiRx =
+    ::protozero::proto_utils::FieldMetadata<
+      493,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DpuDsiRxFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_DpuDsiRx kDpuDsiRx{};
+  template <typename T = DpuDsiRxFtraceEvent> T* set_dpu_dsi_rx() {
+    return BeginNestedMessage<T>(493);
+  }
+
+
+  using FieldMetadata_DpuDsiTx =
+    ::protozero::proto_utils::FieldMetadata<
+      494,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DpuDsiTxFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_DpuDsiTx kDpuDsiTx{};
+  template <typename T = DpuDsiTxFtraceEvent> T* set_dpu_dsi_tx() {
+    return BeginNestedMessage<T>(494);
+  }
+
+
+  using FieldMetadata_F2fsBackgroundGc =
+    ::protozero::proto_utils::FieldMetadata<
+      495,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsBackgroundGcFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsBackgroundGc kF2fsBackgroundGc{};
+  template <typename T = F2fsBackgroundGcFtraceEvent> T* set_f2fs_background_gc() {
+    return BeginNestedMessage<T>(495);
+  }
+
+
+  using FieldMetadata_F2fsGcBegin =
+    ::protozero::proto_utils::FieldMetadata<
+      496,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsGcBeginFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsGcBegin kF2fsGcBegin{};
+  template <typename T = F2fsGcBeginFtraceEvent> T* set_f2fs_gc_begin() {
+    return BeginNestedMessage<T>(496);
+  }
+
+
+  using FieldMetadata_F2fsGcEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      497,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsGcEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsGcEnd kF2fsGcEnd{};
+  template <typename T = F2fsGcEndFtraceEvent> T* set_f2fs_gc_end() {
+    return BeginNestedMessage<T>(497);
+  }
+
+
+  using FieldMetadata_FastrpcDmaFree =
+    ::protozero::proto_utils::FieldMetadata<
+      498,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FastrpcDmaFreeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_FastrpcDmaFree kFastrpcDmaFree{};
+  template <typename T = FastrpcDmaFreeFtraceEvent> T* set_fastrpc_dma_free() {
+    return BeginNestedMessage<T>(498);
+  }
+
+
+  using FieldMetadata_FastrpcDmaAlloc =
+    ::protozero::proto_utils::FieldMetadata<
+      499,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FastrpcDmaAllocFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_FastrpcDmaAlloc kFastrpcDmaAlloc{};
+  template <typename T = FastrpcDmaAllocFtraceEvent> T* set_fastrpc_dma_alloc() {
+    return BeginNestedMessage<T>(499);
+  }
+
+
+  using FieldMetadata_FastrpcDmaUnmap =
+    ::protozero::proto_utils::FieldMetadata<
+      500,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FastrpcDmaUnmapFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_FastrpcDmaUnmap kFastrpcDmaUnmap{};
+  template <typename T = FastrpcDmaUnmapFtraceEvent> T* set_fastrpc_dma_unmap() {
+    return BeginNestedMessage<T>(500);
+  }
+
+
+  using FieldMetadata_FastrpcDmaMap =
+    ::protozero::proto_utils::FieldMetadata<
+      501,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FastrpcDmaMapFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_FastrpcDmaMap kFastrpcDmaMap{};
+  template <typename T = FastrpcDmaMapFtraceEvent> T* set_fastrpc_dma_map() {
+    return BeginNestedMessage<T>(501);
+  }
+
+
+  using FieldMetadata_GoogleIccEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      502,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GoogleIccEventFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_GoogleIccEvent kGoogleIccEvent{};
+  template <typename T = GoogleIccEventFtraceEvent> T* set_google_icc_event() {
+    return BeginNestedMessage<T>(502);
+  }
+
+
+  using FieldMetadata_GoogleIrmEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      503,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GoogleIrmEventFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_GoogleIrmEvent kGoogleIrmEvent{};
+  template <typename T = GoogleIrmEventFtraceEvent> T* set_google_irm_event() {
+    return BeginNestedMessage<T>(503);
+  }
+
+
+  using FieldMetadata_DevicePmCallbackStart =
+    ::protozero::proto_utils::FieldMetadata<
+      504,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DevicePmCallbackStartFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_DevicePmCallbackStart kDevicePmCallbackStart{};
+  template <typename T = DevicePmCallbackStartFtraceEvent> T* set_device_pm_callback_start() {
+    return BeginNestedMessage<T>(504);
+  }
+
+
+  using FieldMetadata_DevicePmCallbackEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      505,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DevicePmCallbackEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_DevicePmCallbackEnd kDevicePmCallbackEnd{};
+  template <typename T = DevicePmCallbackEndFtraceEvent> T* set_device_pm_callback_end() {
+    return BeginNestedMessage<T>(505);
+  }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/ftrace_event_bundle.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_FTRACE_EVENT_BUNDLE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_FTRACE_EVENT_BUNDLE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class FtraceEvent;
+class FtraceEventBundle_CompactSched;
+class FtraceEventBundle_FtraceError;
+enum FtraceClock : int32_t;
+enum FtraceParseStatus : int32_t;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+enum FtraceClock : int32_t {
+  FTRACE_CLOCK_UNSPECIFIED = 0,
+  FTRACE_CLOCK_UNKNOWN = 1,
+  FTRACE_CLOCK_GLOBAL = 2,
+  FTRACE_CLOCK_LOCAL = 3,
+  FTRACE_CLOCK_MONO_RAW = 4,
+};
+
+constexpr FtraceClock FtraceClock_MIN = FtraceClock::FTRACE_CLOCK_UNSPECIFIED;
+constexpr FtraceClock FtraceClock_MAX = FtraceClock::FTRACE_CLOCK_MONO_RAW;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* FtraceClock_Name(::perfetto::protos::pbzero::FtraceClock value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::FtraceClock::FTRACE_CLOCK_UNSPECIFIED:
+    return "FTRACE_CLOCK_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::FtraceClock::FTRACE_CLOCK_UNKNOWN:
+    return "FTRACE_CLOCK_UNKNOWN";
+
+  case ::perfetto::protos::pbzero::FtraceClock::FTRACE_CLOCK_GLOBAL:
+    return "FTRACE_CLOCK_GLOBAL";
+
+  case ::perfetto::protos::pbzero::FtraceClock::FTRACE_CLOCK_LOCAL:
+    return "FTRACE_CLOCK_LOCAL";
+
+  case ::perfetto::protos::pbzero::FtraceClock::FTRACE_CLOCK_MONO_RAW:
+    return "FTRACE_CLOCK_MONO_RAW";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class FtraceEventBundle_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  FtraceEventBundle_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FtraceEventBundle_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FtraceEventBundle_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cpu() const { return at<1>().valid(); }
+  uint32_t cpu() const { return at<1>().as_uint32(); }
+  bool has_event() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> event() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_lost_events() const { return at<3>().valid(); }
+  bool lost_events() const { return at<3>().as_bool(); }
+  bool has_compact_sched() const { return at<4>().valid(); }
+  ::protozero::ConstBytes compact_sched() const { return at<4>().as_bytes(); }
+  bool has_ftrace_clock() const { return at<5>().valid(); }
+  int32_t ftrace_clock() const { return at<5>().as_int32(); }
+  bool has_ftrace_timestamp() const { return at<6>().valid(); }
+  int64_t ftrace_timestamp() const { return at<6>().as_int64(); }
+  bool has_boot_timestamp() const { return at<7>().valid(); }
+  int64_t boot_timestamp() const { return at<7>().as_int64(); }
+  bool has_error() const { return at<8>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> error() const { return GetRepeated<::protozero::ConstBytes>(8); }
+  bool has_last_read_event_timestamp() const { return at<9>().valid(); }
+  uint64_t last_read_event_timestamp() const { return at<9>().as_uint64(); }
+};
+
+class FtraceEventBundle : public ::protozero::Message {
+ public:
+  using Decoder = FtraceEventBundle_Decoder;
+  enum : int32_t {
+    kCpuFieldNumber = 1,
+    kEventFieldNumber = 2,
+    kLostEventsFieldNumber = 3,
+    kCompactSchedFieldNumber = 4,
+    kFtraceClockFieldNumber = 5,
+    kFtraceTimestampFieldNumber = 6,
+    kBootTimestampFieldNumber = 7,
+    kErrorFieldNumber = 8,
+    kLastReadEventTimestampFieldNumber = 9,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FtraceEventBundle"; }
+
+  using CompactSched = ::perfetto::protos::pbzero::FtraceEventBundle_CompactSched;
+  using FtraceError = ::perfetto::protos::pbzero::FtraceEventBundle_FtraceError;
+
+  using FieldMetadata_Cpu =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FtraceEventBundle>;
+
+  static constexpr FieldMetadata_Cpu kCpu{};
+  void set_cpu(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cpu::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_Event =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FtraceEvent,
+      FtraceEventBundle>;
+
+  static constexpr FieldMetadata_Event kEvent{};
+  template <typename T = FtraceEvent> T* add_event() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_LostEvents =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FtraceEventBundle>;
+
+  static constexpr FieldMetadata_LostEvents kLostEvents{};
+  void set_lost_events(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_LostEvents::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_CompactSched =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FtraceEventBundle_CompactSched,
+      FtraceEventBundle>;
+
+  static constexpr FieldMetadata_CompactSched kCompactSched{};
+  template <typename T = FtraceEventBundle_CompactSched> T* set_compact_sched() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_FtraceClock =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      FtraceClock,
+      FtraceEventBundle>;
+
+  static constexpr FieldMetadata_FtraceClock kFtraceClock{};
+  void set_ftrace_clock(FtraceClock value) {
+    static constexpr uint32_t field_id = FieldMetadata_FtraceClock::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_FtraceTimestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      FtraceEventBundle>;
+
+  static constexpr FieldMetadata_FtraceTimestamp kFtraceTimestamp{};
+  void set_ftrace_timestamp(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FtraceTimestamp::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_BootTimestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      FtraceEventBundle>;
+
+  static constexpr FieldMetadata_BootTimestamp kBootTimestamp{};
+  void set_boot_timestamp(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BootTimestamp::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_Error =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FtraceEventBundle_FtraceError,
+      FtraceEventBundle>;
+
+  static constexpr FieldMetadata_Error kError{};
+  template <typename T = FtraceEventBundle_FtraceError> T* add_error() {
+    return BeginNestedMessage<T>(8);
+  }
+
+
+  using FieldMetadata_LastReadEventTimestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FtraceEventBundle>;
+
+  static constexpr FieldMetadata_LastReadEventTimestamp kLastReadEventTimestamp{};
+  void set_last_read_event_timestamp(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LastReadEventTimestamp::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 FtraceEventBundle_FtraceError_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FtraceEventBundle_FtraceError_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FtraceEventBundle_FtraceError_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FtraceEventBundle_FtraceError_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_timestamp() const { return at<1>().valid(); }
+  uint64_t timestamp() const { return at<1>().as_uint64(); }
+  bool has_status() const { return at<2>().valid(); }
+  int32_t status() const { return at<2>().as_int32(); }
+};
+
+class FtraceEventBundle_FtraceError : public ::protozero::Message {
+ public:
+  using Decoder = FtraceEventBundle_FtraceError_Decoder;
+  enum : int32_t {
+    kTimestampFieldNumber = 1,
+    kStatusFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FtraceEventBundle.FtraceError"; }
+
+
+  using FieldMetadata_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FtraceEventBundle_FtraceError>;
+
+  static constexpr FieldMetadata_Timestamp kTimestamp{};
+  void set_timestamp(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timestamp::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_Status =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      FtraceParseStatus,
+      FtraceEventBundle_FtraceError>;
+
+  static constexpr FieldMetadata_Status kStatus{};
+  void set_status(FtraceParseStatus value) {
+    static constexpr uint32_t field_id = FieldMetadata_Status::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);
+  }
+};
+
+class FtraceEventBundle_CompactSched_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/12, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  FtraceEventBundle_CompactSched_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FtraceEventBundle_CompactSched_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FtraceEventBundle_CompactSched_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_intern_table() const { return at<5>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> intern_table() const { return GetRepeated<::protozero::ConstChars>(5); }
+  bool has_switch_timestamp() const { return at<1>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, uint64_t> switch_timestamp(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, uint64_t>(1, parse_error_ptr); }
+  bool has_switch_prev_state() const { return at<2>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, int64_t> switch_prev_state(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, int64_t>(2, parse_error_ptr); }
+  bool has_switch_next_pid() const { return at<3>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, int32_t> switch_next_pid(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, int32_t>(3, parse_error_ptr); }
+  bool has_switch_next_prio() const { return at<4>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, int32_t> switch_next_prio(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, int32_t>(4, parse_error_ptr); }
+  bool has_switch_next_comm_index() const { return at<6>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, uint32_t> switch_next_comm_index(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, uint32_t>(6, parse_error_ptr); }
+  bool has_waking_timestamp() const { return at<7>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, uint64_t> waking_timestamp(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, uint64_t>(7, parse_error_ptr); }
+  bool has_waking_pid() const { return at<8>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, int32_t> waking_pid(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, int32_t>(8, parse_error_ptr); }
+  bool has_waking_target_cpu() const { return at<9>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, int32_t> waking_target_cpu(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, int32_t>(9, parse_error_ptr); }
+  bool has_waking_prio() const { return at<10>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, int32_t> waking_prio(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, int32_t>(10, parse_error_ptr); }
+  bool has_waking_comm_index() const { return at<11>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, uint32_t> waking_comm_index(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, uint32_t>(11, parse_error_ptr); }
+  bool has_waking_common_flags() const { return at<12>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, uint32_t> waking_common_flags(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, uint32_t>(12, parse_error_ptr); }
+};
+
+class FtraceEventBundle_CompactSched : public ::protozero::Message {
+ public:
+  using Decoder = FtraceEventBundle_CompactSched_Decoder;
+  enum : int32_t {
+    kInternTableFieldNumber = 5,
+    kSwitchTimestampFieldNumber = 1,
+    kSwitchPrevStateFieldNumber = 2,
+    kSwitchNextPidFieldNumber = 3,
+    kSwitchNextPrioFieldNumber = 4,
+    kSwitchNextCommIndexFieldNumber = 6,
+    kWakingTimestampFieldNumber = 7,
+    kWakingPidFieldNumber = 8,
+    kWakingTargetCpuFieldNumber = 9,
+    kWakingPrioFieldNumber = 10,
+    kWakingCommIndexFieldNumber = 11,
+    kWakingCommonFlagsFieldNumber = 12,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FtraceEventBundle.CompactSched"; }
+
+
+  using FieldMetadata_InternTable =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FtraceEventBundle_CompactSched>;
+
+  static constexpr FieldMetadata_InternTable kInternTable{};
+  void add_intern_table(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_InternTable::kFieldId, data, size);
+  }
+  void add_intern_table(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_InternTable::kFieldId, chars.data, chars.size);
+  }
+  void add_intern_table(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_InternTable::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_SwitchTimestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FtraceEventBundle_CompactSched>;
+
+  static constexpr FieldMetadata_SwitchTimestamp kSwitchTimestamp{};
+  void set_switch_timestamp(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_SwitchTimestamp::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_SwitchPrevState =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      FtraceEventBundle_CompactSched>;
+
+  static constexpr FieldMetadata_SwitchPrevState kSwitchPrevState{};
+  void set_switch_prev_state(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_SwitchPrevState::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_SwitchNextPid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FtraceEventBundle_CompactSched>;
+
+  static constexpr FieldMetadata_SwitchNextPid kSwitchNextPid{};
+  void set_switch_next_pid(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_SwitchNextPid::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_SwitchNextPrio =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FtraceEventBundle_CompactSched>;
+
+  static constexpr FieldMetadata_SwitchNextPrio kSwitchNextPrio{};
+  void set_switch_next_prio(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_SwitchNextPrio::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_SwitchNextCommIndex =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FtraceEventBundle_CompactSched>;
+
+  static constexpr FieldMetadata_SwitchNextCommIndex kSwitchNextCommIndex{};
+  void set_switch_next_comm_index(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_SwitchNextCommIndex::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_WakingTimestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FtraceEventBundle_CompactSched>;
+
+  static constexpr FieldMetadata_WakingTimestamp kWakingTimestamp{};
+  void set_waking_timestamp(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_WakingTimestamp::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_WakingPid =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FtraceEventBundle_CompactSched>;
+
+  static constexpr FieldMetadata_WakingPid kWakingPid{};
+  void set_waking_pid(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_WakingPid::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_WakingTargetCpu =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FtraceEventBundle_CompactSched>;
+
+  static constexpr FieldMetadata_WakingTargetCpu kWakingTargetCpu{};
+  void set_waking_target_cpu(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_WakingTargetCpu::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_WakingPrio =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FtraceEventBundle_CompactSched>;
+
+  static constexpr FieldMetadata_WakingPrio kWakingPrio{};
+  void set_waking_prio(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_WakingPrio::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_WakingCommIndex =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FtraceEventBundle_CompactSched>;
+
+  static constexpr FieldMetadata_WakingCommIndex kWakingCommIndex{};
+  void set_waking_comm_index(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_WakingCommIndex::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_WakingCommonFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FtraceEventBundle_CompactSched>;
+
+  static constexpr FieldMetadata_WakingCommonFlags kWakingCommonFlags{};
+  void set_waking_common_flags(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_WakingCommonFlags::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/ftrace_stats.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_FTRACE_STATS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_FTRACE_STATS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class FtraceCpuStats;
+enum FtraceParseStatus : int32_t;
+namespace perfetto_pbzero_enum_FtraceStats {
+enum Phase : int32_t;
+}  // namespace perfetto_pbzero_enum_FtraceStats
+using FtraceStats_Phase = perfetto_pbzero_enum_FtraceStats::Phase;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+enum FtraceParseStatus : int32_t {
+  FTRACE_STATUS_UNSPECIFIED = 0,
+  FTRACE_STATUS_OK = 1,
+  FTRACE_STATUS_UNEXPECTED_READ_ERROR = 2,
+  FTRACE_STATUS_PARTIAL_PAGE_READ = 3,
+  FTRACE_STATUS_ABI_INVALID_PAGE_HEADER = 4,
+  FTRACE_STATUS_ABI_SHORT_EVENT_HEADER = 5,
+  FTRACE_STATUS_ABI_NULL_PADDING = 6,
+  FTRACE_STATUS_ABI_SHORT_PADDING_LENGTH = 7,
+  FTRACE_STATUS_ABI_INVALID_PADDING_LENGTH = 8,
+  FTRACE_STATUS_ABI_SHORT_TIME_EXTEND = 9,
+  FTRACE_STATUS_ABI_SHORT_TIME_STAMP = 10,
+  FTRACE_STATUS_ABI_SHORT_DATA_LENGTH = 11,
+  FTRACE_STATUS_ABI_ZERO_DATA_LENGTH = 12,
+  FTRACE_STATUS_ABI_INVALID_DATA_LENGTH = 13,
+  FTRACE_STATUS_ABI_SHORT_EVENT_ID = 14,
+  FTRACE_STATUS_ABI_END_OVERFLOW = 15,
+  FTRACE_STATUS_SHORT_COMPACT_EVENT = 16,
+  FTRACE_STATUS_INVALID_EVENT = 17,
+};
+
+constexpr FtraceParseStatus FtraceParseStatus_MIN = FtraceParseStatus::FTRACE_STATUS_UNSPECIFIED;
+constexpr FtraceParseStatus FtraceParseStatus_MAX = FtraceParseStatus::FTRACE_STATUS_INVALID_EVENT;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* FtraceParseStatus_Name(::perfetto::protos::pbzero::FtraceParseStatus value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::FtraceParseStatus::FTRACE_STATUS_UNSPECIFIED:
+    return "FTRACE_STATUS_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::FtraceParseStatus::FTRACE_STATUS_OK:
+    return "FTRACE_STATUS_OK";
+
+  case ::perfetto::protos::pbzero::FtraceParseStatus::FTRACE_STATUS_UNEXPECTED_READ_ERROR:
+    return "FTRACE_STATUS_UNEXPECTED_READ_ERROR";
+
+  case ::perfetto::protos::pbzero::FtraceParseStatus::FTRACE_STATUS_PARTIAL_PAGE_READ:
+    return "FTRACE_STATUS_PARTIAL_PAGE_READ";
+
+  case ::perfetto::protos::pbzero::FtraceParseStatus::FTRACE_STATUS_ABI_INVALID_PAGE_HEADER:
+    return "FTRACE_STATUS_ABI_INVALID_PAGE_HEADER";
+
+  case ::perfetto::protos::pbzero::FtraceParseStatus::FTRACE_STATUS_ABI_SHORT_EVENT_HEADER:
+    return "FTRACE_STATUS_ABI_SHORT_EVENT_HEADER";
+
+  case ::perfetto::protos::pbzero::FtraceParseStatus::FTRACE_STATUS_ABI_NULL_PADDING:
+    return "FTRACE_STATUS_ABI_NULL_PADDING";
+
+  case ::perfetto::protos::pbzero::FtraceParseStatus::FTRACE_STATUS_ABI_SHORT_PADDING_LENGTH:
+    return "FTRACE_STATUS_ABI_SHORT_PADDING_LENGTH";
+
+  case ::perfetto::protos::pbzero::FtraceParseStatus::FTRACE_STATUS_ABI_INVALID_PADDING_LENGTH:
+    return "FTRACE_STATUS_ABI_INVALID_PADDING_LENGTH";
+
+  case ::perfetto::protos::pbzero::FtraceParseStatus::FTRACE_STATUS_ABI_SHORT_TIME_EXTEND:
+    return "FTRACE_STATUS_ABI_SHORT_TIME_EXTEND";
+
+  case ::perfetto::protos::pbzero::FtraceParseStatus::FTRACE_STATUS_ABI_SHORT_TIME_STAMP:
+    return "FTRACE_STATUS_ABI_SHORT_TIME_STAMP";
+
+  case ::perfetto::protos::pbzero::FtraceParseStatus::FTRACE_STATUS_ABI_SHORT_DATA_LENGTH:
+    return "FTRACE_STATUS_ABI_SHORT_DATA_LENGTH";
+
+  case ::perfetto::protos::pbzero::FtraceParseStatus::FTRACE_STATUS_ABI_ZERO_DATA_LENGTH:
+    return "FTRACE_STATUS_ABI_ZERO_DATA_LENGTH";
+
+  case ::perfetto::protos::pbzero::FtraceParseStatus::FTRACE_STATUS_ABI_INVALID_DATA_LENGTH:
+    return "FTRACE_STATUS_ABI_INVALID_DATA_LENGTH";
+
+  case ::perfetto::protos::pbzero::FtraceParseStatus::FTRACE_STATUS_ABI_SHORT_EVENT_ID:
+    return "FTRACE_STATUS_ABI_SHORT_EVENT_ID";
+
+  case ::perfetto::protos::pbzero::FtraceParseStatus::FTRACE_STATUS_ABI_END_OVERFLOW:
+    return "FTRACE_STATUS_ABI_END_OVERFLOW";
+
+  case ::perfetto::protos::pbzero::FtraceParseStatus::FTRACE_STATUS_SHORT_COMPACT_EVENT:
+    return "FTRACE_STATUS_SHORT_COMPACT_EVENT";
+
+  case ::perfetto::protos::pbzero::FtraceParseStatus::FTRACE_STATUS_INVALID_EVENT:
+    return "FTRACE_STATUS_INVALID_EVENT";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_FtraceStats {
+enum Phase : int32_t {
+  UNSPECIFIED = 0,
+  START_OF_TRACE = 1,
+  END_OF_TRACE = 2,
+};
+} // namespace perfetto_pbzero_enum_FtraceStats
+using FtraceStats_Phase = perfetto_pbzero_enum_FtraceStats::Phase;
+
+
+constexpr FtraceStats_Phase FtraceStats_Phase_MIN = FtraceStats_Phase::UNSPECIFIED;
+constexpr FtraceStats_Phase FtraceStats_Phase_MAX = FtraceStats_Phase::END_OF_TRACE;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* FtraceStats_Phase_Name(::perfetto::protos::pbzero::FtraceStats_Phase value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::FtraceStats_Phase::UNSPECIFIED:
+    return "UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::FtraceStats_Phase::START_OF_TRACE:
+    return "START_OF_TRACE";
+
+  case ::perfetto::protos::pbzero::FtraceStats_Phase::END_OF_TRACE:
+    return "END_OF_TRACE";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class FtraceStats_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  FtraceStats_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FtraceStats_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FtraceStats_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_phase() const { return at<1>().valid(); }
+  int32_t phase() const { return at<1>().as_int32(); }
+  bool has_cpu_stats() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> cpu_stats() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_kernel_symbols_parsed() const { return at<3>().valid(); }
+  uint32_t kernel_symbols_parsed() const { return at<3>().as_uint32(); }
+  bool has_kernel_symbols_mem_kb() const { return at<4>().valid(); }
+  uint32_t kernel_symbols_mem_kb() const { return at<4>().as_uint32(); }
+  bool has_atrace_errors() const { return at<5>().valid(); }
+  ::protozero::ConstChars atrace_errors() const { return at<5>().as_string(); }
+  bool has_unknown_ftrace_events() const { return at<6>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> unknown_ftrace_events() const { return GetRepeated<::protozero::ConstChars>(6); }
+  bool has_failed_ftrace_events() const { return at<7>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> failed_ftrace_events() const { return GetRepeated<::protozero::ConstChars>(7); }
+  bool has_preserve_ftrace_buffer() const { return at<8>().valid(); }
+  bool preserve_ftrace_buffer() const { return at<8>().as_bool(); }
+  bool has_ftrace_parse_errors() const { return at<9>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> ftrace_parse_errors() const { return GetRepeated<int32_t>(9); }
+};
+
+class FtraceStats : public ::protozero::Message {
+ public:
+  using Decoder = FtraceStats_Decoder;
+  enum : int32_t {
+    kPhaseFieldNumber = 1,
+    kCpuStatsFieldNumber = 2,
+    kKernelSymbolsParsedFieldNumber = 3,
+    kKernelSymbolsMemKbFieldNumber = 4,
+    kAtraceErrorsFieldNumber = 5,
+    kUnknownFtraceEventsFieldNumber = 6,
+    kFailedFtraceEventsFieldNumber = 7,
+    kPreserveFtraceBufferFieldNumber = 8,
+    kFtraceParseErrorsFieldNumber = 9,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FtraceStats"; }
+
+
+  using Phase = ::perfetto::protos::pbzero::FtraceStats_Phase;
+  static inline const char* Phase_Name(Phase value) {
+    return ::perfetto::protos::pbzero::FtraceStats_Phase_Name(value);
+  }
+  static inline const Phase UNSPECIFIED = Phase::UNSPECIFIED;
+  static inline const Phase START_OF_TRACE = Phase::START_OF_TRACE;
+  static inline const Phase END_OF_TRACE = Phase::END_OF_TRACE;
+
+  using FieldMetadata_Phase =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      FtraceStats_Phase,
+      FtraceStats>;
+
+  static constexpr FieldMetadata_Phase kPhase{};
+  void set_phase(FtraceStats_Phase value) {
+    static constexpr uint32_t field_id = FieldMetadata_Phase::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_CpuStats =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FtraceCpuStats,
+      FtraceStats>;
+
+  static constexpr FieldMetadata_CpuStats kCpuStats{};
+  template <typename T = FtraceCpuStats> T* add_cpu_stats() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_KernelSymbolsParsed =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FtraceStats>;
+
+  static constexpr FieldMetadata_KernelSymbolsParsed kKernelSymbolsParsed{};
+  void set_kernel_symbols_parsed(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KernelSymbolsParsed::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_KernelSymbolsMemKb =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FtraceStats>;
+
+  static constexpr FieldMetadata_KernelSymbolsMemKb kKernelSymbolsMemKb{};
+  void set_kernel_symbols_mem_kb(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KernelSymbolsMemKb::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_AtraceErrors =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FtraceStats>;
+
+  static constexpr FieldMetadata_AtraceErrors kAtraceErrors{};
+  void set_atrace_errors(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_AtraceErrors::kFieldId, data, size);
+  }
+  void set_atrace_errors(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_AtraceErrors::kFieldId, chars.data, chars.size);
+  }
+  void set_atrace_errors(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_AtraceErrors::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_UnknownFtraceEvents =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FtraceStats>;
+
+  static constexpr FieldMetadata_UnknownFtraceEvents kUnknownFtraceEvents{};
+  void add_unknown_ftrace_events(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_UnknownFtraceEvents::kFieldId, data, size);
+  }
+  void add_unknown_ftrace_events(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_UnknownFtraceEvents::kFieldId, chars.data, chars.size);
+  }
+  void add_unknown_ftrace_events(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_UnknownFtraceEvents::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_FailedFtraceEvents =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FtraceStats>;
+
+  static constexpr FieldMetadata_FailedFtraceEvents kFailedFtraceEvents{};
+  void add_failed_ftrace_events(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_FailedFtraceEvents::kFieldId, data, size);
+  }
+  void add_failed_ftrace_events(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_FailedFtraceEvents::kFieldId, chars.data, chars.size);
+  }
+  void add_failed_ftrace_events(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_FailedFtraceEvents::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_PreserveFtraceBuffer =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FtraceStats>;
+
+  static constexpr FieldMetadata_PreserveFtraceBuffer kPreserveFtraceBuffer{};
+  void set_preserve_ftrace_buffer(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_PreserveFtraceBuffer::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_FtraceParseErrors =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      FtraceParseStatus,
+      FtraceStats>;
+
+  static constexpr FieldMetadata_FtraceParseErrors kFtraceParseErrors{};
+  void add_ftrace_parse_errors(FtraceParseStatus value) {
+    static constexpr uint32_t field_id = FieldMetadata_FtraceParseErrors::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);
+  }
+};
+
+class FtraceCpuStats_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FtraceCpuStats_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FtraceCpuStats_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FtraceCpuStats_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cpu() const { return at<1>().valid(); }
+  uint64_t cpu() const { return at<1>().as_uint64(); }
+  bool has_entries() const { return at<2>().valid(); }
+  uint64_t entries() const { return at<2>().as_uint64(); }
+  bool has_overrun() const { return at<3>().valid(); }
+  uint64_t overrun() const { return at<3>().as_uint64(); }
+  bool has_commit_overrun() const { return at<4>().valid(); }
+  uint64_t commit_overrun() const { return at<4>().as_uint64(); }
+  bool has_bytes_read() const { return at<5>().valid(); }
+  uint64_t bytes_read() const { return at<5>().as_uint64(); }
+  bool has_oldest_event_ts() const { return at<6>().valid(); }
+  double oldest_event_ts() const { return at<6>().as_double(); }
+  bool has_now_ts() const { return at<7>().valid(); }
+  double now_ts() const { return at<7>().as_double(); }
+  bool has_dropped_events() const { return at<8>().valid(); }
+  uint64_t dropped_events() const { return at<8>().as_uint64(); }
+  bool has_read_events() const { return at<9>().valid(); }
+  uint64_t read_events() const { return at<9>().as_uint64(); }
+};
+
+class FtraceCpuStats : public ::protozero::Message {
+ public:
+  using Decoder = FtraceCpuStats_Decoder;
+  enum : int32_t {
+    kCpuFieldNumber = 1,
+    kEntriesFieldNumber = 2,
+    kOverrunFieldNumber = 3,
+    kCommitOverrunFieldNumber = 4,
+    kBytesReadFieldNumber = 5,
+    kOldestEventTsFieldNumber = 6,
+    kNowTsFieldNumber = 7,
+    kDroppedEventsFieldNumber = 8,
+    kReadEventsFieldNumber = 9,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FtraceCpuStats"; }
+
+
+  using FieldMetadata_Cpu =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FtraceCpuStats>;
+
+  static constexpr FieldMetadata_Cpu kCpu{};
+  void set_cpu(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cpu::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_Entries =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FtraceCpuStats>;
+
+  static constexpr FieldMetadata_Entries kEntries{};
+  void set_entries(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Entries::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_Overrun =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FtraceCpuStats>;
+
+  static constexpr FieldMetadata_Overrun kOverrun{};
+  void set_overrun(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Overrun::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_CommitOverrun =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FtraceCpuStats>;
+
+  static constexpr FieldMetadata_CommitOverrun kCommitOverrun{};
+  void set_commit_overrun(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CommitOverrun::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_BytesRead =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FtraceCpuStats>;
+
+  static constexpr FieldMetadata_BytesRead kBytesRead{};
+  void set_bytes_read(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BytesRead::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_OldestEventTs =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      FtraceCpuStats>;
+
+  static constexpr FieldMetadata_OldestEventTs kOldestEventTs{};
+  void set_oldest_event_ts(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_OldestEventTs::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);
+  }
+
+  using FieldMetadata_NowTs =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      FtraceCpuStats>;
+
+  static constexpr FieldMetadata_NowTs kNowTs{};
+  void set_now_ts(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_NowTs::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);
+  }
+
+  using FieldMetadata_DroppedEvents =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FtraceCpuStats>;
+
+  static constexpr FieldMetadata_DroppedEvents kDroppedEvents{};
+  void set_dropped_events(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DroppedEvents::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_ReadEvents =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FtraceCpuStats>;
+
+  static constexpr FieldMetadata_ReadEvents kReadEvents{};
+  void set_read_events(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReadEvents::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/test_bundle_wrapper.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_TEST_BUNDLE_WRAPPER_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_TEST_BUNDLE_WRAPPER_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class FtraceEventBundle;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class TestBundleWrapper_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TestBundleWrapper_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TestBundleWrapper_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TestBundleWrapper_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_before() const { return at<1>().valid(); }
+  ::protozero::ConstChars before() const { return at<1>().as_string(); }
+  bool has_bundle() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> bundle() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_after() const { return at<3>().valid(); }
+  ::protozero::ConstChars after() const { return at<3>().as_string(); }
+};
+
+class TestBundleWrapper : public ::protozero::Message {
+ public:
+  using Decoder = TestBundleWrapper_Decoder;
+  enum : int32_t {
+    kBeforeFieldNumber = 1,
+    kBundleFieldNumber = 2,
+    kAfterFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TestBundleWrapper"; }
+
+
+  using FieldMetadata_Before =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TestBundleWrapper>;
+
+  static constexpr FieldMetadata_Before kBefore{};
+  void set_before(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Before::kFieldId, data, size);
+  }
+  void set_before(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Before::kFieldId, chars.data, chars.size);
+  }
+  void set_before(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Before::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_Bundle =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FtraceEventBundle,
+      TestBundleWrapper>;
+
+  static constexpr FieldMetadata_Bundle kBundle{};
+  template <typename T = FtraceEventBundle> T* add_bundle() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_After =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TestBundleWrapper>;
+
+  static constexpr FieldMetadata_After kAfter{};
+  void set_after(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_After::kFieldId, data, size);
+  }
+  void set_after(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_After::kFieldId, chars.data, chars.size);
+  }
+  void set_after(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_After::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/generic.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_GENERIC_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_GENERIC_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class GenericFtraceEvent_Field;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class GenericFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  GenericFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GenericFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GenericFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_event_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars event_name() const { return at<1>().as_string(); }
+  bool has_field() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> field() const { return GetRepeated<::protozero::ConstBytes>(2); }
+};
+
+class GenericFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = GenericFtraceEvent_Decoder;
+  enum : int32_t {
+    kEventNameFieldNumber = 1,
+    kFieldFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GenericFtraceEvent"; }
+
+  using Field = ::perfetto::protos::pbzero::GenericFtraceEvent_Field;
+
+  using FieldMetadata_EventName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      GenericFtraceEvent>;
+
+  static constexpr FieldMetadata_EventName kEventName{};
+  void set_event_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_EventName::kFieldId, data, size);
+  }
+  void set_event_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_EventName::kFieldId, chars.data, chars.size);
+  }
+  void set_event_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_EventName::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_Field =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GenericFtraceEvent_Field,
+      GenericFtraceEvent>;
+
+  static constexpr FieldMetadata_Field kField{};
+  template <typename T = GenericFtraceEvent_Field> T* add_field() {
+    return BeginNestedMessage<T>(2);
+  }
+
+};
+
+class GenericFtraceEvent_Field_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  GenericFtraceEvent_Field_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GenericFtraceEvent_Field_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GenericFtraceEvent_Field_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_str_value() const { return at<3>().valid(); }
+  ::protozero::ConstChars str_value() const { return at<3>().as_string(); }
+  bool has_int_value() const { return at<4>().valid(); }
+  int64_t int_value() const { return at<4>().as_int64(); }
+  bool has_uint_value() const { return at<5>().valid(); }
+  uint64_t uint_value() const { return at<5>().as_uint64(); }
+};
+
+class GenericFtraceEvent_Field : public ::protozero::Message {
+ public:
+  using Decoder = GenericFtraceEvent_Field_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kStrValueFieldNumber = 3,
+    kIntValueFieldNumber = 4,
+    kUintValueFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GenericFtraceEvent.Field"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      GenericFtraceEvent_Field>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_StrValue =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      GenericFtraceEvent_Field>;
+
+  static constexpr FieldMetadata_StrValue kStrValue{};
+  void set_str_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_StrValue::kFieldId, data, size);
+  }
+  void set_str_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_StrValue::kFieldId, chars.data, chars.size);
+  }
+  void set_str_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_StrValue::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_IntValue =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      GenericFtraceEvent_Field>;
+
+  static constexpr FieldMetadata_IntValue kIntValue{};
+  void set_int_value(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IntValue::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_UintValue =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GenericFtraceEvent_Field>;
+
+  static constexpr FieldMetadata_UintValue kUintValue{};
+  void set_uint_value(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UintValue::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/android_fs.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_ANDROID_FS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_ANDROID_FS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class AndroidFsFsyncStartFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AndroidFsFsyncStartFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidFsFsyncStartFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidFsFsyncStartFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cmdline() const { return at<1>().valid(); }
+  ::protozero::ConstChars cmdline() const { return at<1>().as_string(); }
+  bool has_i_size() const { return at<2>().valid(); }
+  int64_t i_size() const { return at<2>().as_int64(); }
+  bool has_ino() const { return at<3>().valid(); }
+  uint64_t ino() const { return at<3>().as_uint64(); }
+  bool has_pathbuf() const { return at<4>().valid(); }
+  ::protozero::ConstChars pathbuf() const { return at<4>().as_string(); }
+  bool has_pid() const { return at<5>().valid(); }
+  int32_t pid() const { return at<5>().as_int32(); }
+};
+
+class AndroidFsFsyncStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = AndroidFsFsyncStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kCmdlineFieldNumber = 1,
+    kISizeFieldNumber = 2,
+    kInoFieldNumber = 3,
+    kPathbufFieldNumber = 4,
+    kPidFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidFsFsyncStartFtraceEvent"; }
+
+
+  using FieldMetadata_Cmdline =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidFsFsyncStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Cmdline kCmdline{};
+  void set_cmdline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cmdline::kFieldId, data, size);
+  }
+  void set_cmdline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Cmdline::kFieldId, chars.data, chars.size);
+  }
+  void set_cmdline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cmdline::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_ISize =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidFsFsyncStartFtraceEvent>;
+
+  static constexpr FieldMetadata_ISize kISize{};
+  void set_i_size(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ISize::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      AndroidFsFsyncStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Pathbuf =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidFsFsyncStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Pathbuf kPathbuf{};
+  void set_pathbuf(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Pathbuf::kFieldId, data, size);
+  }
+  void set_pathbuf(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Pathbuf::kFieldId, chars.data, chars.size);
+  }
+  void set_pathbuf(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pathbuf::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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidFsFsyncStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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);
+  }
+};
+
+class AndroidFsFsyncEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AndroidFsFsyncEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidFsFsyncEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidFsFsyncEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_bytes() const { return at<1>().valid(); }
+  int32_t bytes() const { return at<1>().as_int32(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_offset() const { return at<3>().valid(); }
+  int64_t offset() const { return at<3>().as_int64(); }
+};
+
+class AndroidFsFsyncEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = AndroidFsFsyncEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kBytesFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kOffsetFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidFsFsyncEndFtraceEvent"; }
+
+
+  using FieldMetadata_Bytes =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidFsFsyncEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Bytes kBytes{};
+  void set_bytes(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Bytes::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      AndroidFsFsyncEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Offset =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidFsFsyncEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Offset kOffset{};
+  void set_offset(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Offset::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 AndroidFsDatawriteStartFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AndroidFsDatawriteStartFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidFsDatawriteStartFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidFsDatawriteStartFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_bytes() const { return at<1>().valid(); }
+  int32_t bytes() const { return at<1>().as_int32(); }
+  bool has_cmdline() const { return at<2>().valid(); }
+  ::protozero::ConstChars cmdline() const { return at<2>().as_string(); }
+  bool has_i_size() const { return at<3>().valid(); }
+  int64_t i_size() const { return at<3>().as_int64(); }
+  bool has_ino() const { return at<4>().valid(); }
+  uint64_t ino() const { return at<4>().as_uint64(); }
+  bool has_offset() const { return at<5>().valid(); }
+  int64_t offset() const { return at<5>().as_int64(); }
+  bool has_pathbuf() const { return at<6>().valid(); }
+  ::protozero::ConstChars pathbuf() const { return at<6>().as_string(); }
+  bool has_pid() const { return at<7>().valid(); }
+  int32_t pid() const { return at<7>().as_int32(); }
+};
+
+class AndroidFsDatawriteStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = AndroidFsDatawriteStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kBytesFieldNumber = 1,
+    kCmdlineFieldNumber = 2,
+    kISizeFieldNumber = 3,
+    kInoFieldNumber = 4,
+    kOffsetFieldNumber = 5,
+    kPathbufFieldNumber = 6,
+    kPidFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidFsDatawriteStartFtraceEvent"; }
+
+
+  using FieldMetadata_Bytes =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidFsDatawriteStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Bytes kBytes{};
+  void set_bytes(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Bytes::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_Cmdline =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidFsDatawriteStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Cmdline kCmdline{};
+  void set_cmdline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cmdline::kFieldId, data, size);
+  }
+  void set_cmdline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Cmdline::kFieldId, chars.data, chars.size);
+  }
+  void set_cmdline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cmdline::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_ISize =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidFsDatawriteStartFtraceEvent>;
+
+  static constexpr FieldMetadata_ISize kISize{};
+  void set_i_size(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ISize::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      AndroidFsDatawriteStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Offset =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidFsDatawriteStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Offset kOffset{};
+  void set_offset(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Offset::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_Pathbuf =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidFsDatawriteStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Pathbuf kPathbuf{};
+  void set_pathbuf(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Pathbuf::kFieldId, data, size);
+  }
+  void set_pathbuf(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Pathbuf::kFieldId, chars.data, chars.size);
+  }
+  void set_pathbuf(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pathbuf::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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidFsDatawriteStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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);
+  }
+};
+
+class AndroidFsDatawriteEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AndroidFsDatawriteEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidFsDatawriteEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidFsDatawriteEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_bytes() const { return at<1>().valid(); }
+  int32_t bytes() const { return at<1>().as_int32(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_offset() const { return at<3>().valid(); }
+  int64_t offset() const { return at<3>().as_int64(); }
+};
+
+class AndroidFsDatawriteEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = AndroidFsDatawriteEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kBytesFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kOffsetFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidFsDatawriteEndFtraceEvent"; }
+
+
+  using FieldMetadata_Bytes =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidFsDatawriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Bytes kBytes{};
+  void set_bytes(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Bytes::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      AndroidFsDatawriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Offset =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidFsDatawriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Offset kOffset{};
+  void set_offset(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Offset::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 AndroidFsDatareadStartFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AndroidFsDatareadStartFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidFsDatareadStartFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidFsDatareadStartFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_bytes() const { return at<1>().valid(); }
+  int32_t bytes() const { return at<1>().as_int32(); }
+  bool has_cmdline() const { return at<2>().valid(); }
+  ::protozero::ConstChars cmdline() const { return at<2>().as_string(); }
+  bool has_i_size() const { return at<3>().valid(); }
+  int64_t i_size() const { return at<3>().as_int64(); }
+  bool has_ino() const { return at<4>().valid(); }
+  uint64_t ino() const { return at<4>().as_uint64(); }
+  bool has_offset() const { return at<5>().valid(); }
+  int64_t offset() const { return at<5>().as_int64(); }
+  bool has_pathbuf() const { return at<6>().valid(); }
+  ::protozero::ConstChars pathbuf() const { return at<6>().as_string(); }
+  bool has_pid() const { return at<7>().valid(); }
+  int32_t pid() const { return at<7>().as_int32(); }
+};
+
+class AndroidFsDatareadStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = AndroidFsDatareadStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kBytesFieldNumber = 1,
+    kCmdlineFieldNumber = 2,
+    kISizeFieldNumber = 3,
+    kInoFieldNumber = 4,
+    kOffsetFieldNumber = 5,
+    kPathbufFieldNumber = 6,
+    kPidFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidFsDatareadStartFtraceEvent"; }
+
+
+  using FieldMetadata_Bytes =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidFsDatareadStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Bytes kBytes{};
+  void set_bytes(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Bytes::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_Cmdline =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidFsDatareadStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Cmdline kCmdline{};
+  void set_cmdline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cmdline::kFieldId, data, size);
+  }
+  void set_cmdline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Cmdline::kFieldId, chars.data, chars.size);
+  }
+  void set_cmdline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cmdline::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_ISize =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidFsDatareadStartFtraceEvent>;
+
+  static constexpr FieldMetadata_ISize kISize{};
+  void set_i_size(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ISize::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      AndroidFsDatareadStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Offset =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidFsDatareadStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Offset kOffset{};
+  void set_offset(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Offset::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_Pathbuf =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidFsDatareadStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Pathbuf kPathbuf{};
+  void set_pathbuf(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Pathbuf::kFieldId, data, size);
+  }
+  void set_pathbuf(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Pathbuf::kFieldId, chars.data, chars.size);
+  }
+  void set_pathbuf(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pathbuf::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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidFsDatareadStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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);
+  }
+};
+
+class AndroidFsDatareadEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AndroidFsDatareadEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidFsDatareadEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidFsDatareadEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_bytes() const { return at<1>().valid(); }
+  int32_t bytes() const { return at<1>().as_int32(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_offset() const { return at<3>().valid(); }
+  int64_t offset() const { return at<3>().as_int64(); }
+};
+
+class AndroidFsDatareadEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = AndroidFsDatareadEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kBytesFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kOffsetFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidFsDatareadEndFtraceEvent"; }
+
+
+  using FieldMetadata_Bytes =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidFsDatareadEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Bytes kBytes{};
+  void set_bytes(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Bytes::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      AndroidFsDatareadEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Offset =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidFsDatareadEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Offset kOffset{};
+  void set_offset(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Offset::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/binder.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_BINDER_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_BINDER_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class BinderReturnFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BinderReturnFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BinderReturnFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BinderReturnFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cmd() const { return at<1>().valid(); }
+  uint32_t cmd() const { return at<1>().as_uint32(); }
+};
+
+class BinderReturnFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BinderReturnFtraceEvent_Decoder;
+  enum : int32_t {
+    kCmdFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BinderReturnFtraceEvent"; }
+
+
+  using FieldMetadata_Cmd =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BinderReturnFtraceEvent>;
+
+  static constexpr FieldMetadata_Cmd kCmd{};
+  void set_cmd(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cmd::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 BinderCommandFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BinderCommandFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BinderCommandFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BinderCommandFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cmd() const { return at<1>().valid(); }
+  uint32_t cmd() const { return at<1>().as_uint32(); }
+};
+
+class BinderCommandFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BinderCommandFtraceEvent_Decoder;
+  enum : int32_t {
+    kCmdFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BinderCommandFtraceEvent"; }
+
+
+  using FieldMetadata_Cmd =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BinderCommandFtraceEvent>;
+
+  static constexpr FieldMetadata_Cmd kCmd{};
+  void set_cmd(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cmd::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 BinderTransactionAllocBufFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BinderTransactionAllocBufFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BinderTransactionAllocBufFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BinderTransactionAllocBufFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_data_size() const { return at<1>().valid(); }
+  uint64_t data_size() const { return at<1>().as_uint64(); }
+  bool has_debug_id() const { return at<2>().valid(); }
+  int32_t debug_id() const { return at<2>().as_int32(); }
+  bool has_offsets_size() const { return at<3>().valid(); }
+  uint64_t offsets_size() const { return at<3>().as_uint64(); }
+  bool has_extra_buffers_size() const { return at<4>().valid(); }
+  uint64_t extra_buffers_size() const { return at<4>().as_uint64(); }
+};
+
+class BinderTransactionAllocBufFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BinderTransactionAllocBufFtraceEvent_Decoder;
+  enum : int32_t {
+    kDataSizeFieldNumber = 1,
+    kDebugIdFieldNumber = 2,
+    kOffsetsSizeFieldNumber = 3,
+    kExtraBuffersSizeFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BinderTransactionAllocBufFtraceEvent"; }
+
+
+  using FieldMetadata_DataSize =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BinderTransactionAllocBufFtraceEvent>;
+
+  static constexpr FieldMetadata_DataSize kDataSize{};
+  void set_data_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DataSize::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_DebugId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BinderTransactionAllocBufFtraceEvent>;
+
+  static constexpr FieldMetadata_DebugId kDebugId{};
+  void set_debug_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DebugId::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_OffsetsSize =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BinderTransactionAllocBufFtraceEvent>;
+
+  static constexpr FieldMetadata_OffsetsSize kOffsetsSize{};
+  void set_offsets_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OffsetsSize::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_ExtraBuffersSize =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BinderTransactionAllocBufFtraceEvent>;
+
+  static constexpr FieldMetadata_ExtraBuffersSize kExtraBuffersSize{};
+  void set_extra_buffers_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ExtraBuffersSize::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 BinderUnlockFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BinderUnlockFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BinderUnlockFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BinderUnlockFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_tag() const { return at<1>().valid(); }
+  ::protozero::ConstChars tag() const { return at<1>().as_string(); }
+};
+
+class BinderUnlockFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BinderUnlockFtraceEvent_Decoder;
+  enum : int32_t {
+    kTagFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BinderUnlockFtraceEvent"; }
+
+
+  using FieldMetadata_Tag =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BinderUnlockFtraceEvent>;
+
+  static constexpr FieldMetadata_Tag kTag{};
+  void set_tag(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Tag::kFieldId, data, size);
+  }
+  void set_tag(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Tag::kFieldId, chars.data, chars.size);
+  }
+  void set_tag(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tag::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 BinderLockedFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BinderLockedFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BinderLockedFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BinderLockedFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_tag() const { return at<1>().valid(); }
+  ::protozero::ConstChars tag() const { return at<1>().as_string(); }
+};
+
+class BinderLockedFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BinderLockedFtraceEvent_Decoder;
+  enum : int32_t {
+    kTagFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BinderLockedFtraceEvent"; }
+
+
+  using FieldMetadata_Tag =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BinderLockedFtraceEvent>;
+
+  static constexpr FieldMetadata_Tag kTag{};
+  void set_tag(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Tag::kFieldId, data, size);
+  }
+  void set_tag(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Tag::kFieldId, chars.data, chars.size);
+  }
+  void set_tag(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tag::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 BinderLockFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BinderLockFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BinderLockFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BinderLockFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_tag() const { return at<1>().valid(); }
+  ::protozero::ConstChars tag() const { return at<1>().as_string(); }
+};
+
+class BinderLockFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BinderLockFtraceEvent_Decoder;
+  enum : int32_t {
+    kTagFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BinderLockFtraceEvent"; }
+
+
+  using FieldMetadata_Tag =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BinderLockFtraceEvent>;
+
+  static constexpr FieldMetadata_Tag kTag{};
+  void set_tag(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Tag::kFieldId, data, size);
+  }
+  void set_tag(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Tag::kFieldId, chars.data, chars.size);
+  }
+  void set_tag(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tag::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 BinderSetPriorityFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BinderSetPriorityFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BinderSetPriorityFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BinderSetPriorityFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_proc() const { return at<1>().valid(); }
+  int32_t proc() const { return at<1>().as_int32(); }
+  bool has_thread() const { return at<2>().valid(); }
+  int32_t thread() const { return at<2>().as_int32(); }
+  bool has_old_prio() const { return at<3>().valid(); }
+  uint32_t old_prio() const { return at<3>().as_uint32(); }
+  bool has_new_prio() const { return at<4>().valid(); }
+  uint32_t new_prio() const { return at<4>().as_uint32(); }
+  bool has_desired_prio() const { return at<5>().valid(); }
+  uint32_t desired_prio() const { return at<5>().as_uint32(); }
+};
+
+class BinderSetPriorityFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BinderSetPriorityFtraceEvent_Decoder;
+  enum : int32_t {
+    kProcFieldNumber = 1,
+    kThreadFieldNumber = 2,
+    kOldPrioFieldNumber = 3,
+    kNewPrioFieldNumber = 4,
+    kDesiredPrioFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BinderSetPriorityFtraceEvent"; }
+
+
+  using FieldMetadata_Proc =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BinderSetPriorityFtraceEvent>;
+
+  static constexpr FieldMetadata_Proc kProc{};
+  void set_proc(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Proc::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_Thread =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BinderSetPriorityFtraceEvent>;
+
+  static constexpr FieldMetadata_Thread kThread{};
+  void set_thread(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Thread::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_OldPrio =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BinderSetPriorityFtraceEvent>;
+
+  static constexpr FieldMetadata_OldPrio kOldPrio{};
+  void set_old_prio(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OldPrio::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_NewPrio =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BinderSetPriorityFtraceEvent>;
+
+  static constexpr FieldMetadata_NewPrio kNewPrio{};
+  void set_new_prio(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NewPrio::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_DesiredPrio =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BinderSetPriorityFtraceEvent>;
+
+  static constexpr FieldMetadata_DesiredPrio kDesiredPrio{};
+  void set_desired_prio(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DesiredPrio::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 BinderTransactionReceivedFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BinderTransactionReceivedFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BinderTransactionReceivedFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BinderTransactionReceivedFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_debug_id() const { return at<1>().valid(); }
+  int32_t debug_id() const { return at<1>().as_int32(); }
+};
+
+class BinderTransactionReceivedFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BinderTransactionReceivedFtraceEvent_Decoder;
+  enum : int32_t {
+    kDebugIdFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BinderTransactionReceivedFtraceEvent"; }
+
+
+  using FieldMetadata_DebugId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BinderTransactionReceivedFtraceEvent>;
+
+  static constexpr FieldMetadata_DebugId kDebugId{};
+  void set_debug_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DebugId::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);
+  }
+};
+
+class BinderTransactionFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BinderTransactionFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BinderTransactionFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BinderTransactionFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_debug_id() const { return at<1>().valid(); }
+  int32_t debug_id() const { return at<1>().as_int32(); }
+  bool has_target_node() const { return at<2>().valid(); }
+  int32_t target_node() const { return at<2>().as_int32(); }
+  bool has_to_proc() const { return at<3>().valid(); }
+  int32_t to_proc() const { return at<3>().as_int32(); }
+  bool has_to_thread() const { return at<4>().valid(); }
+  int32_t to_thread() const { return at<4>().as_int32(); }
+  bool has_reply() const { return at<5>().valid(); }
+  int32_t reply() const { return at<5>().as_int32(); }
+  bool has_code() const { return at<6>().valid(); }
+  uint32_t code() const { return at<6>().as_uint32(); }
+  bool has_flags() const { return at<7>().valid(); }
+  uint32_t flags() const { return at<7>().as_uint32(); }
+};
+
+class BinderTransactionFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BinderTransactionFtraceEvent_Decoder;
+  enum : int32_t {
+    kDebugIdFieldNumber = 1,
+    kTargetNodeFieldNumber = 2,
+    kToProcFieldNumber = 3,
+    kToThreadFieldNumber = 4,
+    kReplyFieldNumber = 5,
+    kCodeFieldNumber = 6,
+    kFlagsFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BinderTransactionFtraceEvent"; }
+
+
+  using FieldMetadata_DebugId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BinderTransactionFtraceEvent>;
+
+  static constexpr FieldMetadata_DebugId kDebugId{};
+  void set_debug_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DebugId::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_TargetNode =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BinderTransactionFtraceEvent>;
+
+  static constexpr FieldMetadata_TargetNode kTargetNode{};
+  void set_target_node(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TargetNode::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_ToProc =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BinderTransactionFtraceEvent>;
+
+  static constexpr FieldMetadata_ToProc kToProc{};
+  void set_to_proc(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ToProc::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_ToThread =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BinderTransactionFtraceEvent>;
+
+  static constexpr FieldMetadata_ToThread kToThread{};
+  void set_to_thread(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ToThread::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_Reply =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BinderTransactionFtraceEvent>;
+
+  static constexpr FieldMetadata_Reply kReply{};
+  void set_reply(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Reply::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_Code =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BinderTransactionFtraceEvent>;
+
+  static constexpr FieldMetadata_Code kCode{};
+  void set_code(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Code::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BinderTransactionFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/block.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_BLOCK_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_BLOCK_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class BlockUnplugFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockUnplugFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockUnplugFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockUnplugFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_nr_rq() const { return at<1>().valid(); }
+  int32_t nr_rq() const { return at<1>().as_int32(); }
+  bool has_comm() const { return at<2>().valid(); }
+  ::protozero::ConstChars comm() const { return at<2>().as_string(); }
+};
+
+class BlockUnplugFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockUnplugFtraceEvent_Decoder;
+  enum : int32_t {
+    kNrRqFieldNumber = 1,
+    kCommFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockUnplugFtraceEvent"; }
+
+
+  using FieldMetadata_NrRq =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BlockUnplugFtraceEvent>;
+
+  static constexpr FieldMetadata_NrRq kNrRq{};
+  void set_nr_rq(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrRq::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_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockUnplugFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::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 BlockTouchBufferFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockTouchBufferFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockTouchBufferFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockTouchBufferFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_sector() const { return at<2>().valid(); }
+  uint64_t sector() const { return at<2>().as_uint64(); }
+  bool has_size() const { return at<3>().valid(); }
+  uint64_t size() const { return at<3>().as_uint64(); }
+};
+
+class BlockTouchBufferFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockTouchBufferFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kSectorFieldNumber = 2,
+    kSizeFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockTouchBufferFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockTouchBufferFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Sector =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockTouchBufferFtraceEvent>;
+
+  static constexpr FieldMetadata_Sector kSector{};
+  void set_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sector::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_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockTouchBufferFtraceEvent>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void set_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::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 BlockSplitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockSplitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockSplitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockSplitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_sector() const { return at<2>().valid(); }
+  uint64_t sector() const { return at<2>().as_uint64(); }
+  bool has_new_sector() const { return at<3>().valid(); }
+  uint64_t new_sector() const { return at<3>().as_uint64(); }
+  bool has_rwbs() const { return at<4>().valid(); }
+  ::protozero::ConstChars rwbs() const { return at<4>().as_string(); }
+  bool has_comm() const { return at<5>().valid(); }
+  ::protozero::ConstChars comm() const { return at<5>().as_string(); }
+};
+
+class BlockSplitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockSplitFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kSectorFieldNumber = 2,
+    kNewSectorFieldNumber = 3,
+    kRwbsFieldNumber = 4,
+    kCommFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockSplitFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockSplitFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Sector =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockSplitFtraceEvent>;
+
+  static constexpr FieldMetadata_Sector kSector{};
+  void set_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sector::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_NewSector =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockSplitFtraceEvent>;
+
+  static constexpr FieldMetadata_NewSector kNewSector{};
+  void set_new_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NewSector::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_Rwbs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockSplitFtraceEvent>;
+
+  static constexpr FieldMetadata_Rwbs kRwbs{};
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, size);
+  }
+  void set_rwbs(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, chars.data, chars.size);
+  }
+  void set_rwbs(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rwbs::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_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockSplitFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::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 BlockSleeprqFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockSleeprqFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockSleeprqFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockSleeprqFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_sector() const { return at<2>().valid(); }
+  uint64_t sector() const { return at<2>().as_uint64(); }
+  bool has_nr_sector() const { return at<3>().valid(); }
+  uint32_t nr_sector() const { return at<3>().as_uint32(); }
+  bool has_rwbs() const { return at<4>().valid(); }
+  ::protozero::ConstChars rwbs() const { return at<4>().as_string(); }
+  bool has_comm() const { return at<5>().valid(); }
+  ::protozero::ConstChars comm() const { return at<5>().as_string(); }
+};
+
+class BlockSleeprqFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockSleeprqFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kSectorFieldNumber = 2,
+    kNrSectorFieldNumber = 3,
+    kRwbsFieldNumber = 4,
+    kCommFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockSleeprqFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockSleeprqFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Sector =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockSleeprqFtraceEvent>;
+
+  static constexpr FieldMetadata_Sector kSector{};
+  void set_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sector::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_NrSector =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlockSleeprqFtraceEvent>;
+
+  static constexpr FieldMetadata_NrSector kNrSector{};
+  void set_nr_sector(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrSector::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_Rwbs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockSleeprqFtraceEvent>;
+
+  static constexpr FieldMetadata_Rwbs kRwbs{};
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, size);
+  }
+  void set_rwbs(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, chars.data, chars.size);
+  }
+  void set_rwbs(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rwbs::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_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockSleeprqFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::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 BlockRqRequeueFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockRqRequeueFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockRqRequeueFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockRqRequeueFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_sector() const { return at<2>().valid(); }
+  uint64_t sector() const { return at<2>().as_uint64(); }
+  bool has_nr_sector() const { return at<3>().valid(); }
+  uint32_t nr_sector() const { return at<3>().as_uint32(); }
+  bool has_errors() const { return at<4>().valid(); }
+  int32_t errors() const { return at<4>().as_int32(); }
+  bool has_rwbs() const { return at<5>().valid(); }
+  ::protozero::ConstChars rwbs() const { return at<5>().as_string(); }
+  bool has_cmd() const { return at<6>().valid(); }
+  ::protozero::ConstChars cmd() const { return at<6>().as_string(); }
+};
+
+class BlockRqRequeueFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockRqRequeueFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kSectorFieldNumber = 2,
+    kNrSectorFieldNumber = 3,
+    kErrorsFieldNumber = 4,
+    kRwbsFieldNumber = 5,
+    kCmdFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockRqRequeueFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockRqRequeueFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Sector =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockRqRequeueFtraceEvent>;
+
+  static constexpr FieldMetadata_Sector kSector{};
+  void set_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sector::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_NrSector =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlockRqRequeueFtraceEvent>;
+
+  static constexpr FieldMetadata_NrSector kNrSector{};
+  void set_nr_sector(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrSector::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_Errors =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BlockRqRequeueFtraceEvent>;
+
+  static constexpr FieldMetadata_Errors kErrors{};
+  void set_errors(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Errors::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_Rwbs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockRqRequeueFtraceEvent>;
+
+  static constexpr FieldMetadata_Rwbs kRwbs{};
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, size);
+  }
+  void set_rwbs(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, chars.data, chars.size);
+  }
+  void set_rwbs(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rwbs::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_Cmd =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockRqRequeueFtraceEvent>;
+
+  static constexpr FieldMetadata_Cmd kCmd{};
+  void set_cmd(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cmd::kFieldId, data, size);
+  }
+  void set_cmd(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Cmd::kFieldId, chars.data, chars.size);
+  }
+  void set_cmd(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cmd::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 BlockRqRemapFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockRqRemapFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockRqRemapFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockRqRemapFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_sector() const { return at<2>().valid(); }
+  uint64_t sector() const { return at<2>().as_uint64(); }
+  bool has_nr_sector() const { return at<3>().valid(); }
+  uint32_t nr_sector() const { return at<3>().as_uint32(); }
+  bool has_old_dev() const { return at<4>().valid(); }
+  uint64_t old_dev() const { return at<4>().as_uint64(); }
+  bool has_old_sector() const { return at<5>().valid(); }
+  uint64_t old_sector() const { return at<5>().as_uint64(); }
+  bool has_nr_bios() const { return at<6>().valid(); }
+  uint32_t nr_bios() const { return at<6>().as_uint32(); }
+  bool has_rwbs() const { return at<7>().valid(); }
+  ::protozero::ConstChars rwbs() const { return at<7>().as_string(); }
+};
+
+class BlockRqRemapFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockRqRemapFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kSectorFieldNumber = 2,
+    kNrSectorFieldNumber = 3,
+    kOldDevFieldNumber = 4,
+    kOldSectorFieldNumber = 5,
+    kNrBiosFieldNumber = 6,
+    kRwbsFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockRqRemapFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockRqRemapFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Sector =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockRqRemapFtraceEvent>;
+
+  static constexpr FieldMetadata_Sector kSector{};
+  void set_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sector::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_NrSector =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlockRqRemapFtraceEvent>;
+
+  static constexpr FieldMetadata_NrSector kNrSector{};
+  void set_nr_sector(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrSector::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_OldDev =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockRqRemapFtraceEvent>;
+
+  static constexpr FieldMetadata_OldDev kOldDev{};
+  void set_old_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OldDev::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_OldSector =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockRqRemapFtraceEvent>;
+
+  static constexpr FieldMetadata_OldSector kOldSector{};
+  void set_old_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OldSector::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_NrBios =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlockRqRemapFtraceEvent>;
+
+  static constexpr FieldMetadata_NrBios kNrBios{};
+  void set_nr_bios(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrBios::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_Rwbs =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockRqRemapFtraceEvent>;
+
+  static constexpr FieldMetadata_Rwbs kRwbs{};
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, size);
+  }
+  void set_rwbs(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, chars.data, chars.size);
+  }
+  void set_rwbs(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rwbs::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 BlockRqInsertFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockRqInsertFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockRqInsertFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockRqInsertFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_sector() const { return at<2>().valid(); }
+  uint64_t sector() const { return at<2>().as_uint64(); }
+  bool has_nr_sector() const { return at<3>().valid(); }
+  uint32_t nr_sector() const { return at<3>().as_uint32(); }
+  bool has_bytes() const { return at<4>().valid(); }
+  uint32_t bytes() const { return at<4>().as_uint32(); }
+  bool has_rwbs() const { return at<5>().valid(); }
+  ::protozero::ConstChars rwbs() const { return at<5>().as_string(); }
+  bool has_comm() const { return at<6>().valid(); }
+  ::protozero::ConstChars comm() const { return at<6>().as_string(); }
+  bool has_cmd() const { return at<7>().valid(); }
+  ::protozero::ConstChars cmd() const { return at<7>().as_string(); }
+};
+
+class BlockRqInsertFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockRqInsertFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kSectorFieldNumber = 2,
+    kNrSectorFieldNumber = 3,
+    kBytesFieldNumber = 4,
+    kRwbsFieldNumber = 5,
+    kCommFieldNumber = 6,
+    kCmdFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockRqInsertFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockRqInsertFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Sector =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockRqInsertFtraceEvent>;
+
+  static constexpr FieldMetadata_Sector kSector{};
+  void set_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sector::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_NrSector =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlockRqInsertFtraceEvent>;
+
+  static constexpr FieldMetadata_NrSector kNrSector{};
+  void set_nr_sector(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrSector::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_Bytes =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlockRqInsertFtraceEvent>;
+
+  static constexpr FieldMetadata_Bytes kBytes{};
+  void set_bytes(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Bytes::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_Rwbs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockRqInsertFtraceEvent>;
+
+  static constexpr FieldMetadata_Rwbs kRwbs{};
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, size);
+  }
+  void set_rwbs(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, chars.data, chars.size);
+  }
+  void set_rwbs(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rwbs::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_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockRqInsertFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::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_Cmd =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockRqInsertFtraceEvent>;
+
+  static constexpr FieldMetadata_Cmd kCmd{};
+  void set_cmd(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cmd::kFieldId, data, size);
+  }
+  void set_cmd(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Cmd::kFieldId, chars.data, chars.size);
+  }
+  void set_cmd(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cmd::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 BlockRqCompleteFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockRqCompleteFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockRqCompleteFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockRqCompleteFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_sector() const { return at<2>().valid(); }
+  uint64_t sector() const { return at<2>().as_uint64(); }
+  bool has_nr_sector() const { return at<3>().valid(); }
+  uint32_t nr_sector() const { return at<3>().as_uint32(); }
+  bool has_errors() const { return at<4>().valid(); }
+  int32_t errors() const { return at<4>().as_int32(); }
+  bool has_rwbs() const { return at<5>().valid(); }
+  ::protozero::ConstChars rwbs() const { return at<5>().as_string(); }
+  bool has_cmd() const { return at<6>().valid(); }
+  ::protozero::ConstChars cmd() const { return at<6>().as_string(); }
+  bool has_error() const { return at<7>().valid(); }
+  int32_t error() const { return at<7>().as_int32(); }
+};
+
+class BlockRqCompleteFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockRqCompleteFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kSectorFieldNumber = 2,
+    kNrSectorFieldNumber = 3,
+    kErrorsFieldNumber = 4,
+    kRwbsFieldNumber = 5,
+    kCmdFieldNumber = 6,
+    kErrorFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockRqCompleteFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockRqCompleteFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Sector =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockRqCompleteFtraceEvent>;
+
+  static constexpr FieldMetadata_Sector kSector{};
+  void set_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sector::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_NrSector =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlockRqCompleteFtraceEvent>;
+
+  static constexpr FieldMetadata_NrSector kNrSector{};
+  void set_nr_sector(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrSector::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_Errors =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BlockRqCompleteFtraceEvent>;
+
+  static constexpr FieldMetadata_Errors kErrors{};
+  void set_errors(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Errors::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_Rwbs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockRqCompleteFtraceEvent>;
+
+  static constexpr FieldMetadata_Rwbs kRwbs{};
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, size);
+  }
+  void set_rwbs(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, chars.data, chars.size);
+  }
+  void set_rwbs(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rwbs::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_Cmd =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockRqCompleteFtraceEvent>;
+
+  static constexpr FieldMetadata_Cmd kCmd{};
+  void set_cmd(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cmd::kFieldId, data, size);
+  }
+  void set_cmd(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Cmd::kFieldId, chars.data, chars.size);
+  }
+  void set_cmd(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cmd::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_Error =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BlockRqCompleteFtraceEvent>;
+
+  static constexpr FieldMetadata_Error kError{};
+  void set_error(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Error::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);
+  }
+};
+
+class BlockRqAbortFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockRqAbortFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockRqAbortFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockRqAbortFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_sector() const { return at<2>().valid(); }
+  uint64_t sector() const { return at<2>().as_uint64(); }
+  bool has_nr_sector() const { return at<3>().valid(); }
+  uint32_t nr_sector() const { return at<3>().as_uint32(); }
+  bool has_errors() const { return at<4>().valid(); }
+  int32_t errors() const { return at<4>().as_int32(); }
+  bool has_rwbs() const { return at<5>().valid(); }
+  ::protozero::ConstChars rwbs() const { return at<5>().as_string(); }
+  bool has_cmd() const { return at<6>().valid(); }
+  ::protozero::ConstChars cmd() const { return at<6>().as_string(); }
+};
+
+class BlockRqAbortFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockRqAbortFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kSectorFieldNumber = 2,
+    kNrSectorFieldNumber = 3,
+    kErrorsFieldNumber = 4,
+    kRwbsFieldNumber = 5,
+    kCmdFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockRqAbortFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockRqAbortFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Sector =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockRqAbortFtraceEvent>;
+
+  static constexpr FieldMetadata_Sector kSector{};
+  void set_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sector::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_NrSector =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlockRqAbortFtraceEvent>;
+
+  static constexpr FieldMetadata_NrSector kNrSector{};
+  void set_nr_sector(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrSector::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_Errors =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BlockRqAbortFtraceEvent>;
+
+  static constexpr FieldMetadata_Errors kErrors{};
+  void set_errors(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Errors::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_Rwbs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockRqAbortFtraceEvent>;
+
+  static constexpr FieldMetadata_Rwbs kRwbs{};
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, size);
+  }
+  void set_rwbs(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, chars.data, chars.size);
+  }
+  void set_rwbs(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rwbs::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_Cmd =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockRqAbortFtraceEvent>;
+
+  static constexpr FieldMetadata_Cmd kCmd{};
+  void set_cmd(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cmd::kFieldId, data, size);
+  }
+  void set_cmd(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Cmd::kFieldId, chars.data, chars.size);
+  }
+  void set_cmd(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cmd::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 BlockPlugFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockPlugFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockPlugFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockPlugFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_comm() const { return at<1>().valid(); }
+  ::protozero::ConstChars comm() const { return at<1>().as_string(); }
+};
+
+class BlockPlugFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockPlugFtraceEvent_Decoder;
+  enum : int32_t {
+    kCommFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockPlugFtraceEvent"; }
+
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockPlugFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::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 BlockGetrqFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockGetrqFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockGetrqFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockGetrqFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_sector() const { return at<2>().valid(); }
+  uint64_t sector() const { return at<2>().as_uint64(); }
+  bool has_nr_sector() const { return at<3>().valid(); }
+  uint32_t nr_sector() const { return at<3>().as_uint32(); }
+  bool has_rwbs() const { return at<4>().valid(); }
+  ::protozero::ConstChars rwbs() const { return at<4>().as_string(); }
+  bool has_comm() const { return at<5>().valid(); }
+  ::protozero::ConstChars comm() const { return at<5>().as_string(); }
+};
+
+class BlockGetrqFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockGetrqFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kSectorFieldNumber = 2,
+    kNrSectorFieldNumber = 3,
+    kRwbsFieldNumber = 4,
+    kCommFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockGetrqFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockGetrqFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Sector =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockGetrqFtraceEvent>;
+
+  static constexpr FieldMetadata_Sector kSector{};
+  void set_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sector::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_NrSector =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlockGetrqFtraceEvent>;
+
+  static constexpr FieldMetadata_NrSector kNrSector{};
+  void set_nr_sector(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrSector::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_Rwbs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockGetrqFtraceEvent>;
+
+  static constexpr FieldMetadata_Rwbs kRwbs{};
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, size);
+  }
+  void set_rwbs(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, chars.data, chars.size);
+  }
+  void set_rwbs(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rwbs::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_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockGetrqFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::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 BlockDirtyBufferFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockDirtyBufferFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockDirtyBufferFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockDirtyBufferFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_sector() const { return at<2>().valid(); }
+  uint64_t sector() const { return at<2>().as_uint64(); }
+  bool has_size() const { return at<3>().valid(); }
+  uint64_t size() const { return at<3>().as_uint64(); }
+};
+
+class BlockDirtyBufferFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockDirtyBufferFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kSectorFieldNumber = 2,
+    kSizeFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockDirtyBufferFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockDirtyBufferFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Sector =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockDirtyBufferFtraceEvent>;
+
+  static constexpr FieldMetadata_Sector kSector{};
+  void set_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sector::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_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockDirtyBufferFtraceEvent>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void set_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::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 BlockBioRemapFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockBioRemapFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockBioRemapFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockBioRemapFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_sector() const { return at<2>().valid(); }
+  uint64_t sector() const { return at<2>().as_uint64(); }
+  bool has_nr_sector() const { return at<3>().valid(); }
+  uint32_t nr_sector() const { return at<3>().as_uint32(); }
+  bool has_old_dev() const { return at<4>().valid(); }
+  uint64_t old_dev() const { return at<4>().as_uint64(); }
+  bool has_old_sector() const { return at<5>().valid(); }
+  uint64_t old_sector() const { return at<5>().as_uint64(); }
+  bool has_rwbs() const { return at<6>().valid(); }
+  ::protozero::ConstChars rwbs() const { return at<6>().as_string(); }
+};
+
+class BlockBioRemapFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockBioRemapFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kSectorFieldNumber = 2,
+    kNrSectorFieldNumber = 3,
+    kOldDevFieldNumber = 4,
+    kOldSectorFieldNumber = 5,
+    kRwbsFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockBioRemapFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockBioRemapFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Sector =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockBioRemapFtraceEvent>;
+
+  static constexpr FieldMetadata_Sector kSector{};
+  void set_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sector::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_NrSector =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlockBioRemapFtraceEvent>;
+
+  static constexpr FieldMetadata_NrSector kNrSector{};
+  void set_nr_sector(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrSector::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_OldDev =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockBioRemapFtraceEvent>;
+
+  static constexpr FieldMetadata_OldDev kOldDev{};
+  void set_old_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OldDev::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_OldSector =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockBioRemapFtraceEvent>;
+
+  static constexpr FieldMetadata_OldSector kOldSector{};
+  void set_old_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OldSector::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_Rwbs =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockBioRemapFtraceEvent>;
+
+  static constexpr FieldMetadata_Rwbs kRwbs{};
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, size);
+  }
+  void set_rwbs(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, chars.data, chars.size);
+  }
+  void set_rwbs(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rwbs::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 BlockBioQueueFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockBioQueueFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockBioQueueFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockBioQueueFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_sector() const { return at<2>().valid(); }
+  uint64_t sector() const { return at<2>().as_uint64(); }
+  bool has_nr_sector() const { return at<3>().valid(); }
+  uint32_t nr_sector() const { return at<3>().as_uint32(); }
+  bool has_rwbs() const { return at<4>().valid(); }
+  ::protozero::ConstChars rwbs() const { return at<4>().as_string(); }
+  bool has_comm() const { return at<5>().valid(); }
+  ::protozero::ConstChars comm() const { return at<5>().as_string(); }
+};
+
+class BlockBioQueueFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockBioQueueFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kSectorFieldNumber = 2,
+    kNrSectorFieldNumber = 3,
+    kRwbsFieldNumber = 4,
+    kCommFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockBioQueueFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockBioQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Sector =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockBioQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_Sector kSector{};
+  void set_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sector::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_NrSector =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlockBioQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_NrSector kNrSector{};
+  void set_nr_sector(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrSector::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_Rwbs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockBioQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_Rwbs kRwbs{};
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, size);
+  }
+  void set_rwbs(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, chars.data, chars.size);
+  }
+  void set_rwbs(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rwbs::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_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockBioQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::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 BlockBioFrontmergeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockBioFrontmergeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockBioFrontmergeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockBioFrontmergeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_sector() const { return at<2>().valid(); }
+  uint64_t sector() const { return at<2>().as_uint64(); }
+  bool has_nr_sector() const { return at<3>().valid(); }
+  uint32_t nr_sector() const { return at<3>().as_uint32(); }
+  bool has_rwbs() const { return at<4>().valid(); }
+  ::protozero::ConstChars rwbs() const { return at<4>().as_string(); }
+  bool has_comm() const { return at<5>().valid(); }
+  ::protozero::ConstChars comm() const { return at<5>().as_string(); }
+};
+
+class BlockBioFrontmergeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockBioFrontmergeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kSectorFieldNumber = 2,
+    kNrSectorFieldNumber = 3,
+    kRwbsFieldNumber = 4,
+    kCommFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockBioFrontmergeFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockBioFrontmergeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Sector =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockBioFrontmergeFtraceEvent>;
+
+  static constexpr FieldMetadata_Sector kSector{};
+  void set_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sector::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_NrSector =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlockBioFrontmergeFtraceEvent>;
+
+  static constexpr FieldMetadata_NrSector kNrSector{};
+  void set_nr_sector(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrSector::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_Rwbs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockBioFrontmergeFtraceEvent>;
+
+  static constexpr FieldMetadata_Rwbs kRwbs{};
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, size);
+  }
+  void set_rwbs(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, chars.data, chars.size);
+  }
+  void set_rwbs(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rwbs::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_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockBioFrontmergeFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::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 BlockBioCompleteFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockBioCompleteFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockBioCompleteFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockBioCompleteFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_sector() const { return at<2>().valid(); }
+  uint64_t sector() const { return at<2>().as_uint64(); }
+  bool has_nr_sector() const { return at<3>().valid(); }
+  uint32_t nr_sector() const { return at<3>().as_uint32(); }
+  bool has_error() const { return at<4>().valid(); }
+  int32_t error() const { return at<4>().as_int32(); }
+  bool has_rwbs() const { return at<5>().valid(); }
+  ::protozero::ConstChars rwbs() const { return at<5>().as_string(); }
+};
+
+class BlockBioCompleteFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockBioCompleteFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kSectorFieldNumber = 2,
+    kNrSectorFieldNumber = 3,
+    kErrorFieldNumber = 4,
+    kRwbsFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockBioCompleteFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockBioCompleteFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Sector =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockBioCompleteFtraceEvent>;
+
+  static constexpr FieldMetadata_Sector kSector{};
+  void set_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sector::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_NrSector =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlockBioCompleteFtraceEvent>;
+
+  static constexpr FieldMetadata_NrSector kNrSector{};
+  void set_nr_sector(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrSector::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_Error =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BlockBioCompleteFtraceEvent>;
+
+  static constexpr FieldMetadata_Error kError{};
+  void set_error(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Error::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_Rwbs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockBioCompleteFtraceEvent>;
+
+  static constexpr FieldMetadata_Rwbs kRwbs{};
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, size);
+  }
+  void set_rwbs(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, chars.data, chars.size);
+  }
+  void set_rwbs(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rwbs::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 BlockBioBounceFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockBioBounceFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockBioBounceFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockBioBounceFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_sector() const { return at<2>().valid(); }
+  uint64_t sector() const { return at<2>().as_uint64(); }
+  bool has_nr_sector() const { return at<3>().valid(); }
+  uint32_t nr_sector() const { return at<3>().as_uint32(); }
+  bool has_rwbs() const { return at<4>().valid(); }
+  ::protozero::ConstChars rwbs() const { return at<4>().as_string(); }
+  bool has_comm() const { return at<5>().valid(); }
+  ::protozero::ConstChars comm() const { return at<5>().as_string(); }
+};
+
+class BlockBioBounceFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockBioBounceFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kSectorFieldNumber = 2,
+    kNrSectorFieldNumber = 3,
+    kRwbsFieldNumber = 4,
+    kCommFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockBioBounceFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockBioBounceFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Sector =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockBioBounceFtraceEvent>;
+
+  static constexpr FieldMetadata_Sector kSector{};
+  void set_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sector::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_NrSector =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlockBioBounceFtraceEvent>;
+
+  static constexpr FieldMetadata_NrSector kNrSector{};
+  void set_nr_sector(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrSector::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_Rwbs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockBioBounceFtraceEvent>;
+
+  static constexpr FieldMetadata_Rwbs kRwbs{};
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, size);
+  }
+  void set_rwbs(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, chars.data, chars.size);
+  }
+  void set_rwbs(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rwbs::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_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockBioBounceFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::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 BlockBioBackmergeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockBioBackmergeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockBioBackmergeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockBioBackmergeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_sector() const { return at<2>().valid(); }
+  uint64_t sector() const { return at<2>().as_uint64(); }
+  bool has_nr_sector() const { return at<3>().valid(); }
+  uint32_t nr_sector() const { return at<3>().as_uint32(); }
+  bool has_rwbs() const { return at<4>().valid(); }
+  ::protozero::ConstChars rwbs() const { return at<4>().as_string(); }
+  bool has_comm() const { return at<5>().valid(); }
+  ::protozero::ConstChars comm() const { return at<5>().as_string(); }
+};
+
+class BlockBioBackmergeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockBioBackmergeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kSectorFieldNumber = 2,
+    kNrSectorFieldNumber = 3,
+    kRwbsFieldNumber = 4,
+    kCommFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockBioBackmergeFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockBioBackmergeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Sector =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockBioBackmergeFtraceEvent>;
+
+  static constexpr FieldMetadata_Sector kSector{};
+  void set_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sector::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_NrSector =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlockBioBackmergeFtraceEvent>;
+
+  static constexpr FieldMetadata_NrSector kNrSector{};
+  void set_nr_sector(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrSector::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_Rwbs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockBioBackmergeFtraceEvent>;
+
+  static constexpr FieldMetadata_Rwbs kRwbs{};
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, size);
+  }
+  void set_rwbs(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, chars.data, chars.size);
+  }
+  void set_rwbs(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rwbs::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_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockBioBackmergeFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::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 BlockRqIssueFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockRqIssueFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockRqIssueFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockRqIssueFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_sector() const { return at<2>().valid(); }
+  uint64_t sector() const { return at<2>().as_uint64(); }
+  bool has_nr_sector() const { return at<3>().valid(); }
+  uint32_t nr_sector() const { return at<3>().as_uint32(); }
+  bool has_bytes() const { return at<4>().valid(); }
+  uint32_t bytes() const { return at<4>().as_uint32(); }
+  bool has_rwbs() const { return at<5>().valid(); }
+  ::protozero::ConstChars rwbs() const { return at<5>().as_string(); }
+  bool has_comm() const { return at<6>().valid(); }
+  ::protozero::ConstChars comm() const { return at<6>().as_string(); }
+  bool has_cmd() const { return at<7>().valid(); }
+  ::protozero::ConstChars cmd() const { return at<7>().as_string(); }
+};
+
+class BlockRqIssueFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockRqIssueFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kSectorFieldNumber = 2,
+    kNrSectorFieldNumber = 3,
+    kBytesFieldNumber = 4,
+    kRwbsFieldNumber = 5,
+    kCommFieldNumber = 6,
+    kCmdFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockRqIssueFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockRqIssueFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Sector =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockRqIssueFtraceEvent>;
+
+  static constexpr FieldMetadata_Sector kSector{};
+  void set_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sector::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_NrSector =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlockRqIssueFtraceEvent>;
+
+  static constexpr FieldMetadata_NrSector kNrSector{};
+  void set_nr_sector(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrSector::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_Bytes =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlockRqIssueFtraceEvent>;
+
+  static constexpr FieldMetadata_Bytes kBytes{};
+  void set_bytes(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Bytes::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_Rwbs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockRqIssueFtraceEvent>;
+
+  static constexpr FieldMetadata_Rwbs kRwbs{};
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, size);
+  }
+  void set_rwbs(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, chars.data, chars.size);
+  }
+  void set_rwbs(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rwbs::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_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockRqIssueFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::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_Cmd =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockRqIssueFtraceEvent>;
+
+  static constexpr FieldMetadata_Cmd kCmd{};
+  void set_cmd(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cmd::kFieldId, data, size);
+  }
+  void set_cmd(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Cmd::kFieldId, chars.data, chars.size);
+  }
+  void set_cmd(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cmd::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/cgroup.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_CGROUP_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_CGROUP_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class CgroupSetupRootFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CgroupSetupRootFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CgroupSetupRootFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CgroupSetupRootFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_root() const { return at<1>().valid(); }
+  int32_t root() const { return at<1>().as_int32(); }
+  bool has_ss_mask() const { return at<2>().valid(); }
+  uint32_t ss_mask() const { return at<2>().as_uint32(); }
+  bool has_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars name() const { return at<3>().as_string(); }
+};
+
+class CgroupSetupRootFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CgroupSetupRootFtraceEvent_Decoder;
+  enum : int32_t {
+    kRootFieldNumber = 1,
+    kSsMaskFieldNumber = 2,
+    kNameFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CgroupSetupRootFtraceEvent"; }
+
+
+  using FieldMetadata_Root =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupSetupRootFtraceEvent>;
+
+  static constexpr FieldMetadata_Root kRoot{};
+  void set_root(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Root::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_SsMask =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CgroupSetupRootFtraceEvent>;
+
+  static constexpr FieldMetadata_SsMask kSsMask{};
+  void set_ss_mask(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SsMask::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CgroupSetupRootFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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);
+  }
+};
+
+class CgroupRenameFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CgroupRenameFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CgroupRenameFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CgroupRenameFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_root() const { return at<1>().valid(); }
+  int32_t root() const { return at<1>().as_int32(); }
+  bool has_id() const { return at<2>().valid(); }
+  int32_t id() const { return at<2>().as_int32(); }
+  bool has_cname() const { return at<3>().valid(); }
+  ::protozero::ConstChars cname() const { return at<3>().as_string(); }
+  bool has_level() const { return at<4>().valid(); }
+  int32_t level() const { return at<4>().as_int32(); }
+  bool has_path() const { return at<5>().valid(); }
+  ::protozero::ConstChars path() const { return at<5>().as_string(); }
+};
+
+class CgroupRenameFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CgroupRenameFtraceEvent_Decoder;
+  enum : int32_t {
+    kRootFieldNumber = 1,
+    kIdFieldNumber = 2,
+    kCnameFieldNumber = 3,
+    kLevelFieldNumber = 4,
+    kPathFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CgroupRenameFtraceEvent"; }
+
+
+  using FieldMetadata_Root =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupRenameFtraceEvent>;
+
+  static constexpr FieldMetadata_Root kRoot{};
+  void set_root(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Root::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_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupRenameFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::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_Cname =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CgroupRenameFtraceEvent>;
+
+  static constexpr FieldMetadata_Cname kCname{};
+  void set_cname(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cname::kFieldId, data, size);
+  }
+  void set_cname(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Cname::kFieldId, chars.data, chars.size);
+  }
+  void set_cname(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cname::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_Level =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupRenameFtraceEvent>;
+
+  static constexpr FieldMetadata_Level kLevel{};
+  void set_level(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Level::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_Path =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CgroupRenameFtraceEvent>;
+
+  static constexpr FieldMetadata_Path kPath{};
+  void set_path(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Path::kFieldId, data, size);
+  }
+  void set_path(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Path::kFieldId, chars.data, chars.size);
+  }
+  void set_path(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Path::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 CgroupReleaseFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CgroupReleaseFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CgroupReleaseFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CgroupReleaseFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_root() const { return at<1>().valid(); }
+  int32_t root() const { return at<1>().as_int32(); }
+  bool has_id() const { return at<2>().valid(); }
+  int32_t id() const { return at<2>().as_int32(); }
+  bool has_cname() const { return at<3>().valid(); }
+  ::protozero::ConstChars cname() const { return at<3>().as_string(); }
+  bool has_level() const { return at<4>().valid(); }
+  int32_t level() const { return at<4>().as_int32(); }
+  bool has_path() const { return at<5>().valid(); }
+  ::protozero::ConstChars path() const { return at<5>().as_string(); }
+};
+
+class CgroupReleaseFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CgroupReleaseFtraceEvent_Decoder;
+  enum : int32_t {
+    kRootFieldNumber = 1,
+    kIdFieldNumber = 2,
+    kCnameFieldNumber = 3,
+    kLevelFieldNumber = 4,
+    kPathFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CgroupReleaseFtraceEvent"; }
+
+
+  using FieldMetadata_Root =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupReleaseFtraceEvent>;
+
+  static constexpr FieldMetadata_Root kRoot{};
+  void set_root(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Root::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_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupReleaseFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::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_Cname =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CgroupReleaseFtraceEvent>;
+
+  static constexpr FieldMetadata_Cname kCname{};
+  void set_cname(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cname::kFieldId, data, size);
+  }
+  void set_cname(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Cname::kFieldId, chars.data, chars.size);
+  }
+  void set_cname(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cname::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_Level =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupReleaseFtraceEvent>;
+
+  static constexpr FieldMetadata_Level kLevel{};
+  void set_level(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Level::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_Path =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CgroupReleaseFtraceEvent>;
+
+  static constexpr FieldMetadata_Path kPath{};
+  void set_path(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Path::kFieldId, data, size);
+  }
+  void set_path(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Path::kFieldId, chars.data, chars.size);
+  }
+  void set_path(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Path::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 CgroupDestroyRootFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CgroupDestroyRootFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CgroupDestroyRootFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CgroupDestroyRootFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_root() const { return at<1>().valid(); }
+  int32_t root() const { return at<1>().as_int32(); }
+  bool has_ss_mask() const { return at<2>().valid(); }
+  uint32_t ss_mask() const { return at<2>().as_uint32(); }
+  bool has_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars name() const { return at<3>().as_string(); }
+};
+
+class CgroupDestroyRootFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CgroupDestroyRootFtraceEvent_Decoder;
+  enum : int32_t {
+    kRootFieldNumber = 1,
+    kSsMaskFieldNumber = 2,
+    kNameFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CgroupDestroyRootFtraceEvent"; }
+
+
+  using FieldMetadata_Root =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupDestroyRootFtraceEvent>;
+
+  static constexpr FieldMetadata_Root kRoot{};
+  void set_root(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Root::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_SsMask =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CgroupDestroyRootFtraceEvent>;
+
+  static constexpr FieldMetadata_SsMask kSsMask{};
+  void set_ss_mask(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SsMask::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CgroupDestroyRootFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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);
+  }
+};
+
+class CgroupTransferTasksFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CgroupTransferTasksFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CgroupTransferTasksFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CgroupTransferTasksFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dst_root() const { return at<1>().valid(); }
+  int32_t dst_root() const { return at<1>().as_int32(); }
+  bool has_dst_id() const { return at<2>().valid(); }
+  int32_t dst_id() const { return at<2>().as_int32(); }
+  bool has_pid() const { return at<3>().valid(); }
+  int32_t pid() const { return at<3>().as_int32(); }
+  bool has_comm() const { return at<4>().valid(); }
+  ::protozero::ConstChars comm() const { return at<4>().as_string(); }
+  bool has_cname() const { return at<5>().valid(); }
+  ::protozero::ConstChars cname() const { return at<5>().as_string(); }
+  bool has_dst_level() const { return at<6>().valid(); }
+  int32_t dst_level() const { return at<6>().as_int32(); }
+  bool has_dst_path() const { return at<7>().valid(); }
+  ::protozero::ConstChars dst_path() const { return at<7>().as_string(); }
+};
+
+class CgroupTransferTasksFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CgroupTransferTasksFtraceEvent_Decoder;
+  enum : int32_t {
+    kDstRootFieldNumber = 1,
+    kDstIdFieldNumber = 2,
+    kPidFieldNumber = 3,
+    kCommFieldNumber = 4,
+    kCnameFieldNumber = 5,
+    kDstLevelFieldNumber = 6,
+    kDstPathFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CgroupTransferTasksFtraceEvent"; }
+
+
+  using FieldMetadata_DstRoot =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupTransferTasksFtraceEvent>;
+
+  static constexpr FieldMetadata_DstRoot kDstRoot{};
+  void set_dst_root(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DstRoot::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_DstId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupTransferTasksFtraceEvent>;
+
+  static constexpr FieldMetadata_DstId kDstId{};
+  void set_dst_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DstId::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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupTransferTasksFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CgroupTransferTasksFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::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_Cname =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CgroupTransferTasksFtraceEvent>;
+
+  static constexpr FieldMetadata_Cname kCname{};
+  void set_cname(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cname::kFieldId, data, size);
+  }
+  void set_cname(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Cname::kFieldId, chars.data, chars.size);
+  }
+  void set_cname(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cname::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_DstLevel =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupTransferTasksFtraceEvent>;
+
+  static constexpr FieldMetadata_DstLevel kDstLevel{};
+  void set_dst_level(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DstLevel::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_DstPath =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CgroupTransferTasksFtraceEvent>;
+
+  static constexpr FieldMetadata_DstPath kDstPath{};
+  void set_dst_path(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DstPath::kFieldId, data, size);
+  }
+  void set_dst_path(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_DstPath::kFieldId, chars.data, chars.size);
+  }
+  void set_dst_path(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_DstPath::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 CgroupRmdirFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CgroupRmdirFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CgroupRmdirFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CgroupRmdirFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_root() const { return at<1>().valid(); }
+  int32_t root() const { return at<1>().as_int32(); }
+  bool has_id() const { return at<2>().valid(); }
+  int32_t id() const { return at<2>().as_int32(); }
+  bool has_cname() const { return at<3>().valid(); }
+  ::protozero::ConstChars cname() const { return at<3>().as_string(); }
+  bool has_level() const { return at<4>().valid(); }
+  int32_t level() const { return at<4>().as_int32(); }
+  bool has_path() const { return at<5>().valid(); }
+  ::protozero::ConstChars path() const { return at<5>().as_string(); }
+};
+
+class CgroupRmdirFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CgroupRmdirFtraceEvent_Decoder;
+  enum : int32_t {
+    kRootFieldNumber = 1,
+    kIdFieldNumber = 2,
+    kCnameFieldNumber = 3,
+    kLevelFieldNumber = 4,
+    kPathFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CgroupRmdirFtraceEvent"; }
+
+
+  using FieldMetadata_Root =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupRmdirFtraceEvent>;
+
+  static constexpr FieldMetadata_Root kRoot{};
+  void set_root(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Root::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_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupRmdirFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::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_Cname =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CgroupRmdirFtraceEvent>;
+
+  static constexpr FieldMetadata_Cname kCname{};
+  void set_cname(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cname::kFieldId, data, size);
+  }
+  void set_cname(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Cname::kFieldId, chars.data, chars.size);
+  }
+  void set_cname(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cname::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_Level =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupRmdirFtraceEvent>;
+
+  static constexpr FieldMetadata_Level kLevel{};
+  void set_level(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Level::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_Path =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CgroupRmdirFtraceEvent>;
+
+  static constexpr FieldMetadata_Path kPath{};
+  void set_path(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Path::kFieldId, data, size);
+  }
+  void set_path(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Path::kFieldId, chars.data, chars.size);
+  }
+  void set_path(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Path::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 CgroupRemountFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CgroupRemountFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CgroupRemountFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CgroupRemountFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_root() const { return at<1>().valid(); }
+  int32_t root() const { return at<1>().as_int32(); }
+  bool has_ss_mask() const { return at<2>().valid(); }
+  uint32_t ss_mask() const { return at<2>().as_uint32(); }
+  bool has_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars name() const { return at<3>().as_string(); }
+};
+
+class CgroupRemountFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CgroupRemountFtraceEvent_Decoder;
+  enum : int32_t {
+    kRootFieldNumber = 1,
+    kSsMaskFieldNumber = 2,
+    kNameFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CgroupRemountFtraceEvent"; }
+
+
+  using FieldMetadata_Root =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupRemountFtraceEvent>;
+
+  static constexpr FieldMetadata_Root kRoot{};
+  void set_root(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Root::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_SsMask =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CgroupRemountFtraceEvent>;
+
+  static constexpr FieldMetadata_SsMask kSsMask{};
+  void set_ss_mask(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SsMask::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CgroupRemountFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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);
+  }
+};
+
+class CgroupMkdirFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CgroupMkdirFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CgroupMkdirFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CgroupMkdirFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_root() const { return at<1>().valid(); }
+  int32_t root() const { return at<1>().as_int32(); }
+  bool has_id() const { return at<2>().valid(); }
+  int32_t id() const { return at<2>().as_int32(); }
+  bool has_cname() const { return at<3>().valid(); }
+  ::protozero::ConstChars cname() const { return at<3>().as_string(); }
+  bool has_level() const { return at<4>().valid(); }
+  int32_t level() const { return at<4>().as_int32(); }
+  bool has_path() const { return at<5>().valid(); }
+  ::protozero::ConstChars path() const { return at<5>().as_string(); }
+};
+
+class CgroupMkdirFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CgroupMkdirFtraceEvent_Decoder;
+  enum : int32_t {
+    kRootFieldNumber = 1,
+    kIdFieldNumber = 2,
+    kCnameFieldNumber = 3,
+    kLevelFieldNumber = 4,
+    kPathFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CgroupMkdirFtraceEvent"; }
+
+
+  using FieldMetadata_Root =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupMkdirFtraceEvent>;
+
+  static constexpr FieldMetadata_Root kRoot{};
+  void set_root(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Root::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_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupMkdirFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::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_Cname =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CgroupMkdirFtraceEvent>;
+
+  static constexpr FieldMetadata_Cname kCname{};
+  void set_cname(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cname::kFieldId, data, size);
+  }
+  void set_cname(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Cname::kFieldId, chars.data, chars.size);
+  }
+  void set_cname(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cname::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_Level =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupMkdirFtraceEvent>;
+
+  static constexpr FieldMetadata_Level kLevel{};
+  void set_level(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Level::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_Path =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CgroupMkdirFtraceEvent>;
+
+  static constexpr FieldMetadata_Path kPath{};
+  void set_path(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Path::kFieldId, data, size);
+  }
+  void set_path(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Path::kFieldId, chars.data, chars.size);
+  }
+  void set_path(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Path::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 CgroupAttachTaskFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CgroupAttachTaskFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CgroupAttachTaskFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CgroupAttachTaskFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dst_root() const { return at<1>().valid(); }
+  int32_t dst_root() const { return at<1>().as_int32(); }
+  bool has_dst_id() const { return at<2>().valid(); }
+  int32_t dst_id() const { return at<2>().as_int32(); }
+  bool has_pid() const { return at<3>().valid(); }
+  int32_t pid() const { return at<3>().as_int32(); }
+  bool has_comm() const { return at<4>().valid(); }
+  ::protozero::ConstChars comm() const { return at<4>().as_string(); }
+  bool has_cname() const { return at<5>().valid(); }
+  ::protozero::ConstChars cname() const { return at<5>().as_string(); }
+  bool has_dst_level() const { return at<6>().valid(); }
+  int32_t dst_level() const { return at<6>().as_int32(); }
+  bool has_dst_path() const { return at<7>().valid(); }
+  ::protozero::ConstChars dst_path() const { return at<7>().as_string(); }
+};
+
+class CgroupAttachTaskFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CgroupAttachTaskFtraceEvent_Decoder;
+  enum : int32_t {
+    kDstRootFieldNumber = 1,
+    kDstIdFieldNumber = 2,
+    kPidFieldNumber = 3,
+    kCommFieldNumber = 4,
+    kCnameFieldNumber = 5,
+    kDstLevelFieldNumber = 6,
+    kDstPathFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CgroupAttachTaskFtraceEvent"; }
+
+
+  using FieldMetadata_DstRoot =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupAttachTaskFtraceEvent>;
+
+  static constexpr FieldMetadata_DstRoot kDstRoot{};
+  void set_dst_root(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DstRoot::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_DstId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupAttachTaskFtraceEvent>;
+
+  static constexpr FieldMetadata_DstId kDstId{};
+  void set_dst_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DstId::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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupAttachTaskFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CgroupAttachTaskFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::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_Cname =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CgroupAttachTaskFtraceEvent>;
+
+  static constexpr FieldMetadata_Cname kCname{};
+  void set_cname(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cname::kFieldId, data, size);
+  }
+  void set_cname(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Cname::kFieldId, chars.data, chars.size);
+  }
+  void set_cname(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cname::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_DstLevel =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupAttachTaskFtraceEvent>;
+
+  static constexpr FieldMetadata_DstLevel kDstLevel{};
+  void set_dst_level(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DstLevel::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_DstPath =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CgroupAttachTaskFtraceEvent>;
+
+  static constexpr FieldMetadata_DstPath kDstPath{};
+  void set_dst_path(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DstPath::kFieldId, data, size);
+  }
+  void set_dst_path(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_DstPath::kFieldId, chars.data, chars.size);
+  }
+  void set_dst_path(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_DstPath::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/clk.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_CLK_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_CLK_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class ClkSetRateFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ClkSetRateFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ClkSetRateFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ClkSetRateFtraceEvent_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_rate() const { return at<2>().valid(); }
+  uint64_t rate() const { return at<2>().as_uint64(); }
+};
+
+class ClkSetRateFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = ClkSetRateFtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kRateFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ClkSetRateFtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ClkSetRateFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Rate =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ClkSetRateFtraceEvent>;
+
+  static constexpr FieldMetadata_Rate kRate{};
+  void set_rate(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rate::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 ClkDisableFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ClkDisableFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ClkDisableFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ClkDisableFtraceEvent_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(); }
+};
+
+class ClkDisableFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = ClkDisableFtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ClkDisableFtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ClkDisableFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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);
+  }
+};
+
+class ClkEnableFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ClkEnableFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ClkEnableFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ClkEnableFtraceEvent_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(); }
+};
+
+class ClkEnableFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = ClkEnableFtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ClkEnableFtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ClkEnableFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/cma.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_CMA_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_CMA_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class CmaAllocInfoFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/10, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CmaAllocInfoFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CmaAllocInfoFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CmaAllocInfoFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_align() const { return at<1>().valid(); }
+  uint32_t align() const { return at<1>().as_uint32(); }
+  bool has_count() const { return at<2>().valid(); }
+  uint32_t count() const { return at<2>().as_uint32(); }
+  bool has_err_iso() const { return at<3>().valid(); }
+  uint32_t err_iso() const { return at<3>().as_uint32(); }
+  bool has_err_mig() const { return at<4>().valid(); }
+  uint32_t err_mig() const { return at<4>().as_uint32(); }
+  bool has_err_test() const { return at<5>().valid(); }
+  uint32_t err_test() const { return at<5>().as_uint32(); }
+  bool has_name() const { return at<6>().valid(); }
+  ::protozero::ConstChars name() const { return at<6>().as_string(); }
+  bool has_nr_mapped() const { return at<7>().valid(); }
+  uint64_t nr_mapped() const { return at<7>().as_uint64(); }
+  bool has_nr_migrated() const { return at<8>().valid(); }
+  uint64_t nr_migrated() const { return at<8>().as_uint64(); }
+  bool has_nr_reclaimed() const { return at<9>().valid(); }
+  uint64_t nr_reclaimed() const { return at<9>().as_uint64(); }
+  bool has_pfn() const { return at<10>().valid(); }
+  uint64_t pfn() const { return at<10>().as_uint64(); }
+};
+
+class CmaAllocInfoFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CmaAllocInfoFtraceEvent_Decoder;
+  enum : int32_t {
+    kAlignFieldNumber = 1,
+    kCountFieldNumber = 2,
+    kErrIsoFieldNumber = 3,
+    kErrMigFieldNumber = 4,
+    kErrTestFieldNumber = 5,
+    kNameFieldNumber = 6,
+    kNrMappedFieldNumber = 7,
+    kNrMigratedFieldNumber = 8,
+    kNrReclaimedFieldNumber = 9,
+    kPfnFieldNumber = 10,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CmaAllocInfoFtraceEvent"; }
+
+
+  using FieldMetadata_Align =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CmaAllocInfoFtraceEvent>;
+
+  static constexpr FieldMetadata_Align kAlign{};
+  void set_align(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Align::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_Count =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CmaAllocInfoFtraceEvent>;
+
+  static constexpr FieldMetadata_Count kCount{};
+  void set_count(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Count::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_ErrIso =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CmaAllocInfoFtraceEvent>;
+
+  static constexpr FieldMetadata_ErrIso kErrIso{};
+  void set_err_iso(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ErrIso::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_ErrMig =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CmaAllocInfoFtraceEvent>;
+
+  static constexpr FieldMetadata_ErrMig kErrMig{};
+  void set_err_mig(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ErrMig::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_ErrTest =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CmaAllocInfoFtraceEvent>;
+
+  static constexpr FieldMetadata_ErrTest kErrTest{};
+  void set_err_test(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ErrTest::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CmaAllocInfoFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_NrMapped =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      CmaAllocInfoFtraceEvent>;
+
+  static constexpr FieldMetadata_NrMapped kNrMapped{};
+  void set_nr_mapped(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrMapped::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_NrMigrated =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      CmaAllocInfoFtraceEvent>;
+
+  static constexpr FieldMetadata_NrMigrated kNrMigrated{};
+  void set_nr_migrated(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrMigrated::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_NrReclaimed =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      CmaAllocInfoFtraceEvent>;
+
+  static constexpr FieldMetadata_NrReclaimed kNrReclaimed{};
+  void set_nr_reclaimed(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrReclaimed::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_Pfn =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      CmaAllocInfoFtraceEvent>;
+
+  static constexpr FieldMetadata_Pfn kPfn{};
+  void set_pfn(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pfn::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 CmaAllocStartFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CmaAllocStartFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CmaAllocStartFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CmaAllocStartFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_align() const { return at<1>().valid(); }
+  uint32_t align() const { return at<1>().as_uint32(); }
+  bool has_count() const { return at<2>().valid(); }
+  uint32_t count() const { return at<2>().as_uint32(); }
+  bool has_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars name() const { return at<3>().as_string(); }
+};
+
+class CmaAllocStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CmaAllocStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kAlignFieldNumber = 1,
+    kCountFieldNumber = 2,
+    kNameFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CmaAllocStartFtraceEvent"; }
+
+
+  using FieldMetadata_Align =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CmaAllocStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Align kAlign{};
+  void set_align(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Align::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_Count =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CmaAllocStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Count kCount{};
+  void set_count(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Count::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CmaAllocStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/compaction.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_COMPACTION_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_COMPACTION_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class MmCompactionWakeupKcompactdFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmCompactionWakeupKcompactdFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmCompactionWakeupKcompactdFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmCompactionWakeupKcompactdFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_nid() const { return at<1>().valid(); }
+  int32_t nid() const { return at<1>().as_int32(); }
+  bool has_order() const { return at<2>().valid(); }
+  int32_t order() const { return at<2>().as_int32(); }
+  bool has_classzone_idx() const { return at<3>().valid(); }
+  uint32_t classzone_idx() const { return at<3>().as_uint32(); }
+  bool has_highest_zoneidx() const { return at<4>().valid(); }
+  uint32_t highest_zoneidx() const { return at<4>().as_uint32(); }
+};
+
+class MmCompactionWakeupKcompactdFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmCompactionWakeupKcompactdFtraceEvent_Decoder;
+  enum : int32_t {
+    kNidFieldNumber = 1,
+    kOrderFieldNumber = 2,
+    kClasszoneIdxFieldNumber = 3,
+    kHighestZoneidxFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmCompactionWakeupKcompactdFtraceEvent"; }
+
+
+  using FieldMetadata_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionWakeupKcompactdFtraceEvent>;
+
+  static constexpr FieldMetadata_Nid kNid{};
+  void set_nid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nid::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_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionWakeupKcompactdFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::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_ClasszoneIdx =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionWakeupKcompactdFtraceEvent>;
+
+  static constexpr FieldMetadata_ClasszoneIdx kClasszoneIdx{};
+  void set_classzone_idx(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ClasszoneIdx::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_HighestZoneidx =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionWakeupKcompactdFtraceEvent>;
+
+  static constexpr FieldMetadata_HighestZoneidx kHighestZoneidx{};
+  void set_highest_zoneidx(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_HighestZoneidx::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 MmCompactionTryToCompactPagesFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmCompactionTryToCompactPagesFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmCompactionTryToCompactPagesFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmCompactionTryToCompactPagesFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_order() const { return at<1>().valid(); }
+  int32_t order() const { return at<1>().as_int32(); }
+  bool has_gfp_mask() const { return at<2>().valid(); }
+  uint32_t gfp_mask() const { return at<2>().as_uint32(); }
+  bool has_mode() const { return at<3>().valid(); }
+  uint32_t mode() const { return at<3>().as_uint32(); }
+  bool has_prio() const { return at<4>().valid(); }
+  int32_t prio() const { return at<4>().as_int32(); }
+};
+
+class MmCompactionTryToCompactPagesFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmCompactionTryToCompactPagesFtraceEvent_Decoder;
+  enum : int32_t {
+    kOrderFieldNumber = 1,
+    kGfpMaskFieldNumber = 2,
+    kModeFieldNumber = 3,
+    kPrioFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmCompactionTryToCompactPagesFtraceEvent"; }
+
+
+  using FieldMetadata_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionTryToCompactPagesFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::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_GfpMask =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionTryToCompactPagesFtraceEvent>;
+
+  static constexpr FieldMetadata_GfpMask kGfpMask{};
+  void set_gfp_mask(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GfpMask::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_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionTryToCompactPagesFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::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_Prio =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionTryToCompactPagesFtraceEvent>;
+
+  static constexpr FieldMetadata_Prio kPrio{};
+  void set_prio(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Prio::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);
+  }
+};
+
+class MmCompactionSuitableFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmCompactionSuitableFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmCompactionSuitableFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmCompactionSuitableFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_nid() const { return at<1>().valid(); }
+  int32_t nid() const { return at<1>().as_int32(); }
+  bool has_idx() const { return at<2>().valid(); }
+  uint32_t idx() const { return at<2>().as_uint32(); }
+  bool has_order() const { return at<3>().valid(); }
+  int32_t order() const { return at<3>().as_int32(); }
+  bool has_ret() const { return at<4>().valid(); }
+  int32_t ret() const { return at<4>().as_int32(); }
+};
+
+class MmCompactionSuitableFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmCompactionSuitableFtraceEvent_Decoder;
+  enum : int32_t {
+    kNidFieldNumber = 1,
+    kIdxFieldNumber = 2,
+    kOrderFieldNumber = 3,
+    kRetFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmCompactionSuitableFtraceEvent"; }
+
+
+  using FieldMetadata_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionSuitableFtraceEvent>;
+
+  static constexpr FieldMetadata_Nid kNid{};
+  void set_nid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nid::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_Idx =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionSuitableFtraceEvent>;
+
+  static constexpr FieldMetadata_Idx kIdx{};
+  void set_idx(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Idx::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_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionSuitableFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::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_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionSuitableFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::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);
+  }
+};
+
+class MmCompactionMigratepagesFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmCompactionMigratepagesFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmCompactionMigratepagesFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmCompactionMigratepagesFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_nr_migrated() const { return at<1>().valid(); }
+  uint64_t nr_migrated() const { return at<1>().as_uint64(); }
+  bool has_nr_failed() const { return at<2>().valid(); }
+  uint64_t nr_failed() const { return at<2>().as_uint64(); }
+};
+
+class MmCompactionMigratepagesFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmCompactionMigratepagesFtraceEvent_Decoder;
+  enum : int32_t {
+    kNrMigratedFieldNumber = 1,
+    kNrFailedFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmCompactionMigratepagesFtraceEvent"; }
+
+
+  using FieldMetadata_NrMigrated =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionMigratepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_NrMigrated kNrMigrated{};
+  void set_nr_migrated(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrMigrated::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_NrFailed =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionMigratepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_NrFailed kNrFailed{};
+  void set_nr_failed(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrFailed::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 MmCompactionKcompactdWakeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmCompactionKcompactdWakeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmCompactionKcompactdWakeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmCompactionKcompactdWakeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_nid() const { return at<1>().valid(); }
+  int32_t nid() const { return at<1>().as_int32(); }
+  bool has_order() const { return at<2>().valid(); }
+  int32_t order() const { return at<2>().as_int32(); }
+  bool has_classzone_idx() const { return at<3>().valid(); }
+  uint32_t classzone_idx() const { return at<3>().as_uint32(); }
+  bool has_highest_zoneidx() const { return at<4>().valid(); }
+  uint32_t highest_zoneidx() const { return at<4>().as_uint32(); }
+};
+
+class MmCompactionKcompactdWakeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmCompactionKcompactdWakeFtraceEvent_Decoder;
+  enum : int32_t {
+    kNidFieldNumber = 1,
+    kOrderFieldNumber = 2,
+    kClasszoneIdxFieldNumber = 3,
+    kHighestZoneidxFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmCompactionKcompactdWakeFtraceEvent"; }
+
+
+  using FieldMetadata_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionKcompactdWakeFtraceEvent>;
+
+  static constexpr FieldMetadata_Nid kNid{};
+  void set_nid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nid::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_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionKcompactdWakeFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::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_ClasszoneIdx =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionKcompactdWakeFtraceEvent>;
+
+  static constexpr FieldMetadata_ClasszoneIdx kClasszoneIdx{};
+  void set_classzone_idx(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ClasszoneIdx::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_HighestZoneidx =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionKcompactdWakeFtraceEvent>;
+
+  static constexpr FieldMetadata_HighestZoneidx kHighestZoneidx{};
+  void set_highest_zoneidx(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_HighestZoneidx::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 MmCompactionKcompactdSleepFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmCompactionKcompactdSleepFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmCompactionKcompactdSleepFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmCompactionKcompactdSleepFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_nid() const { return at<1>().valid(); }
+  int32_t nid() const { return at<1>().as_int32(); }
+};
+
+class MmCompactionKcompactdSleepFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmCompactionKcompactdSleepFtraceEvent_Decoder;
+  enum : int32_t {
+    kNidFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmCompactionKcompactdSleepFtraceEvent"; }
+
+
+  using FieldMetadata_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionKcompactdSleepFtraceEvent>;
+
+  static constexpr FieldMetadata_Nid kNid{};
+  void set_nid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nid::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);
+  }
+};
+
+class MmCompactionIsolateMigratepagesFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmCompactionIsolateMigratepagesFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmCompactionIsolateMigratepagesFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmCompactionIsolateMigratepagesFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_start_pfn() const { return at<1>().valid(); }
+  uint64_t start_pfn() const { return at<1>().as_uint64(); }
+  bool has_end_pfn() const { return at<2>().valid(); }
+  uint64_t end_pfn() const { return at<2>().as_uint64(); }
+  bool has_nr_scanned() const { return at<3>().valid(); }
+  uint64_t nr_scanned() const { return at<3>().as_uint64(); }
+  bool has_nr_taken() const { return at<4>().valid(); }
+  uint64_t nr_taken() const { return at<4>().as_uint64(); }
+};
+
+class MmCompactionIsolateMigratepagesFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmCompactionIsolateMigratepagesFtraceEvent_Decoder;
+  enum : int32_t {
+    kStartPfnFieldNumber = 1,
+    kEndPfnFieldNumber = 2,
+    kNrScannedFieldNumber = 3,
+    kNrTakenFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmCompactionIsolateMigratepagesFtraceEvent"; }
+
+
+  using FieldMetadata_StartPfn =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionIsolateMigratepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_StartPfn kStartPfn{};
+  void set_start_pfn(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StartPfn::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_EndPfn =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionIsolateMigratepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_EndPfn kEndPfn{};
+  void set_end_pfn(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EndPfn::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_NrScanned =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionIsolateMigratepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_NrScanned kNrScanned{};
+  void set_nr_scanned(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrScanned::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_NrTaken =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionIsolateMigratepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_NrTaken kNrTaken{};
+  void set_nr_taken(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrTaken::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 MmCompactionIsolateFreepagesFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmCompactionIsolateFreepagesFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmCompactionIsolateFreepagesFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmCompactionIsolateFreepagesFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_start_pfn() const { return at<1>().valid(); }
+  uint64_t start_pfn() const { return at<1>().as_uint64(); }
+  bool has_end_pfn() const { return at<2>().valid(); }
+  uint64_t end_pfn() const { return at<2>().as_uint64(); }
+  bool has_nr_scanned() const { return at<3>().valid(); }
+  uint64_t nr_scanned() const { return at<3>().as_uint64(); }
+  bool has_nr_taken() const { return at<4>().valid(); }
+  uint64_t nr_taken() const { return at<4>().as_uint64(); }
+};
+
+class MmCompactionIsolateFreepagesFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmCompactionIsolateFreepagesFtraceEvent_Decoder;
+  enum : int32_t {
+    kStartPfnFieldNumber = 1,
+    kEndPfnFieldNumber = 2,
+    kNrScannedFieldNumber = 3,
+    kNrTakenFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmCompactionIsolateFreepagesFtraceEvent"; }
+
+
+  using FieldMetadata_StartPfn =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionIsolateFreepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_StartPfn kStartPfn{};
+  void set_start_pfn(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StartPfn::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_EndPfn =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionIsolateFreepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_EndPfn kEndPfn{};
+  void set_end_pfn(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EndPfn::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_NrScanned =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionIsolateFreepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_NrScanned kNrScanned{};
+  void set_nr_scanned(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrScanned::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_NrTaken =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionIsolateFreepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_NrTaken kNrTaken{};
+  void set_nr_taken(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrTaken::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 MmCompactionFinishedFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmCompactionFinishedFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmCompactionFinishedFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmCompactionFinishedFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_nid() const { return at<1>().valid(); }
+  int32_t nid() const { return at<1>().as_int32(); }
+  bool has_idx() const { return at<2>().valid(); }
+  uint32_t idx() const { return at<2>().as_uint32(); }
+  bool has_order() const { return at<3>().valid(); }
+  int32_t order() const { return at<3>().as_int32(); }
+  bool has_ret() const { return at<4>().valid(); }
+  int32_t ret() const { return at<4>().as_int32(); }
+};
+
+class MmCompactionFinishedFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmCompactionFinishedFtraceEvent_Decoder;
+  enum : int32_t {
+    kNidFieldNumber = 1,
+    kIdxFieldNumber = 2,
+    kOrderFieldNumber = 3,
+    kRetFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmCompactionFinishedFtraceEvent"; }
+
+
+  using FieldMetadata_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionFinishedFtraceEvent>;
+
+  static constexpr FieldMetadata_Nid kNid{};
+  void set_nid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nid::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_Idx =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionFinishedFtraceEvent>;
+
+  static constexpr FieldMetadata_Idx kIdx{};
+  void set_idx(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Idx::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_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionFinishedFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::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_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionFinishedFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::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);
+  }
+};
+
+class MmCompactionEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmCompactionEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmCompactionEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmCompactionEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_zone_start() const { return at<1>().valid(); }
+  uint64_t zone_start() const { return at<1>().as_uint64(); }
+  bool has_migrate_pfn() const { return at<2>().valid(); }
+  uint64_t migrate_pfn() const { return at<2>().as_uint64(); }
+  bool has_free_pfn() const { return at<3>().valid(); }
+  uint64_t free_pfn() const { return at<3>().as_uint64(); }
+  bool has_zone_end() const { return at<4>().valid(); }
+  uint64_t zone_end() const { return at<4>().as_uint64(); }
+  bool has_sync() const { return at<5>().valid(); }
+  uint32_t sync() const { return at<5>().as_uint32(); }
+  bool has_status() const { return at<6>().valid(); }
+  int32_t status() const { return at<6>().as_int32(); }
+};
+
+class MmCompactionEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmCompactionEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kZoneStartFieldNumber = 1,
+    kMigratePfnFieldNumber = 2,
+    kFreePfnFieldNumber = 3,
+    kZoneEndFieldNumber = 4,
+    kSyncFieldNumber = 5,
+    kStatusFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmCompactionEndFtraceEvent"; }
+
+
+  using FieldMetadata_ZoneStart =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionEndFtraceEvent>;
+
+  static constexpr FieldMetadata_ZoneStart kZoneStart{};
+  void set_zone_start(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ZoneStart::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_MigratePfn =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionEndFtraceEvent>;
+
+  static constexpr FieldMetadata_MigratePfn kMigratePfn{};
+  void set_migrate_pfn(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MigratePfn::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_FreePfn =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionEndFtraceEvent>;
+
+  static constexpr FieldMetadata_FreePfn kFreePfn{};
+  void set_free_pfn(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FreePfn::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_ZoneEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionEndFtraceEvent>;
+
+  static constexpr FieldMetadata_ZoneEnd kZoneEnd{};
+  void set_zone_end(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ZoneEnd::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_Sync =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Sync kSync{};
+  void set_sync(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sync::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_Status =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Status kStatus{};
+  void set_status(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Status::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);
+  }
+};
+
+class MmCompactionDeferResetFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmCompactionDeferResetFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmCompactionDeferResetFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmCompactionDeferResetFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_nid() const { return at<1>().valid(); }
+  int32_t nid() const { return at<1>().as_int32(); }
+  bool has_idx() const { return at<2>().valid(); }
+  uint32_t idx() const { return at<2>().as_uint32(); }
+  bool has_order() const { return at<3>().valid(); }
+  int32_t order() const { return at<3>().as_int32(); }
+  bool has_considered() const { return at<4>().valid(); }
+  uint32_t considered() const { return at<4>().as_uint32(); }
+  bool has_defer_shift() const { return at<5>().valid(); }
+  uint32_t defer_shift() const { return at<5>().as_uint32(); }
+  bool has_order_failed() const { return at<6>().valid(); }
+  int32_t order_failed() const { return at<6>().as_int32(); }
+};
+
+class MmCompactionDeferResetFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmCompactionDeferResetFtraceEvent_Decoder;
+  enum : int32_t {
+    kNidFieldNumber = 1,
+    kIdxFieldNumber = 2,
+    kOrderFieldNumber = 3,
+    kConsideredFieldNumber = 4,
+    kDeferShiftFieldNumber = 5,
+    kOrderFailedFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmCompactionDeferResetFtraceEvent"; }
+
+
+  using FieldMetadata_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionDeferResetFtraceEvent>;
+
+  static constexpr FieldMetadata_Nid kNid{};
+  void set_nid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nid::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_Idx =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionDeferResetFtraceEvent>;
+
+  static constexpr FieldMetadata_Idx kIdx{};
+  void set_idx(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Idx::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_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionDeferResetFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::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_Considered =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionDeferResetFtraceEvent>;
+
+  static constexpr FieldMetadata_Considered kConsidered{};
+  void set_considered(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Considered::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_DeferShift =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionDeferResetFtraceEvent>;
+
+  static constexpr FieldMetadata_DeferShift kDeferShift{};
+  void set_defer_shift(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DeferShift::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_OrderFailed =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionDeferResetFtraceEvent>;
+
+  static constexpr FieldMetadata_OrderFailed kOrderFailed{};
+  void set_order_failed(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OrderFailed::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);
+  }
+};
+
+class MmCompactionDeferredFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmCompactionDeferredFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmCompactionDeferredFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmCompactionDeferredFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_nid() const { return at<1>().valid(); }
+  int32_t nid() const { return at<1>().as_int32(); }
+  bool has_idx() const { return at<2>().valid(); }
+  uint32_t idx() const { return at<2>().as_uint32(); }
+  bool has_order() const { return at<3>().valid(); }
+  int32_t order() const { return at<3>().as_int32(); }
+  bool has_considered() const { return at<4>().valid(); }
+  uint32_t considered() const { return at<4>().as_uint32(); }
+  bool has_defer_shift() const { return at<5>().valid(); }
+  uint32_t defer_shift() const { return at<5>().as_uint32(); }
+  bool has_order_failed() const { return at<6>().valid(); }
+  int32_t order_failed() const { return at<6>().as_int32(); }
+};
+
+class MmCompactionDeferredFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmCompactionDeferredFtraceEvent_Decoder;
+  enum : int32_t {
+    kNidFieldNumber = 1,
+    kIdxFieldNumber = 2,
+    kOrderFieldNumber = 3,
+    kConsideredFieldNumber = 4,
+    kDeferShiftFieldNumber = 5,
+    kOrderFailedFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmCompactionDeferredFtraceEvent"; }
+
+
+  using FieldMetadata_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionDeferredFtraceEvent>;
+
+  static constexpr FieldMetadata_Nid kNid{};
+  void set_nid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nid::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_Idx =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionDeferredFtraceEvent>;
+
+  static constexpr FieldMetadata_Idx kIdx{};
+  void set_idx(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Idx::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_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionDeferredFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::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_Considered =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionDeferredFtraceEvent>;
+
+  static constexpr FieldMetadata_Considered kConsidered{};
+  void set_considered(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Considered::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_DeferShift =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionDeferredFtraceEvent>;
+
+  static constexpr FieldMetadata_DeferShift kDeferShift{};
+  void set_defer_shift(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DeferShift::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_OrderFailed =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionDeferredFtraceEvent>;
+
+  static constexpr FieldMetadata_OrderFailed kOrderFailed{};
+  void set_order_failed(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OrderFailed::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);
+  }
+};
+
+class MmCompactionDeferCompactionFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmCompactionDeferCompactionFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmCompactionDeferCompactionFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmCompactionDeferCompactionFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_nid() const { return at<1>().valid(); }
+  int32_t nid() const { return at<1>().as_int32(); }
+  bool has_idx() const { return at<2>().valid(); }
+  uint32_t idx() const { return at<2>().as_uint32(); }
+  bool has_order() const { return at<3>().valid(); }
+  int32_t order() const { return at<3>().as_int32(); }
+  bool has_considered() const { return at<4>().valid(); }
+  uint32_t considered() const { return at<4>().as_uint32(); }
+  bool has_defer_shift() const { return at<5>().valid(); }
+  uint32_t defer_shift() const { return at<5>().as_uint32(); }
+  bool has_order_failed() const { return at<6>().valid(); }
+  int32_t order_failed() const { return at<6>().as_int32(); }
+};
+
+class MmCompactionDeferCompactionFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmCompactionDeferCompactionFtraceEvent_Decoder;
+  enum : int32_t {
+    kNidFieldNumber = 1,
+    kIdxFieldNumber = 2,
+    kOrderFieldNumber = 3,
+    kConsideredFieldNumber = 4,
+    kDeferShiftFieldNumber = 5,
+    kOrderFailedFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmCompactionDeferCompactionFtraceEvent"; }
+
+
+  using FieldMetadata_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionDeferCompactionFtraceEvent>;
+
+  static constexpr FieldMetadata_Nid kNid{};
+  void set_nid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nid::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_Idx =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionDeferCompactionFtraceEvent>;
+
+  static constexpr FieldMetadata_Idx kIdx{};
+  void set_idx(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Idx::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_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionDeferCompactionFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::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_Considered =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionDeferCompactionFtraceEvent>;
+
+  static constexpr FieldMetadata_Considered kConsidered{};
+  void set_considered(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Considered::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_DeferShift =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionDeferCompactionFtraceEvent>;
+
+  static constexpr FieldMetadata_DeferShift kDeferShift{};
+  void set_defer_shift(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DeferShift::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_OrderFailed =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionDeferCompactionFtraceEvent>;
+
+  static constexpr FieldMetadata_OrderFailed kOrderFailed{};
+  void set_order_failed(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OrderFailed::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);
+  }
+};
+
+class MmCompactionBeginFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmCompactionBeginFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmCompactionBeginFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmCompactionBeginFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_zone_start() const { return at<1>().valid(); }
+  uint64_t zone_start() const { return at<1>().as_uint64(); }
+  bool has_migrate_pfn() const { return at<2>().valid(); }
+  uint64_t migrate_pfn() const { return at<2>().as_uint64(); }
+  bool has_free_pfn() const { return at<3>().valid(); }
+  uint64_t free_pfn() const { return at<3>().as_uint64(); }
+  bool has_zone_end() const { return at<4>().valid(); }
+  uint64_t zone_end() const { return at<4>().as_uint64(); }
+  bool has_sync() const { return at<5>().valid(); }
+  uint32_t sync() const { return at<5>().as_uint32(); }
+};
+
+class MmCompactionBeginFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmCompactionBeginFtraceEvent_Decoder;
+  enum : int32_t {
+    kZoneStartFieldNumber = 1,
+    kMigratePfnFieldNumber = 2,
+    kFreePfnFieldNumber = 3,
+    kZoneEndFieldNumber = 4,
+    kSyncFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmCompactionBeginFtraceEvent"; }
+
+
+  using FieldMetadata_ZoneStart =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_ZoneStart kZoneStart{};
+  void set_zone_start(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ZoneStart::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_MigratePfn =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_MigratePfn kMigratePfn{};
+  void set_migrate_pfn(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MigratePfn::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_FreePfn =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_FreePfn kFreePfn{};
+  void set_free_pfn(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FreePfn::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_ZoneEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_ZoneEnd kZoneEnd{};
+  void set_zone_end(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ZoneEnd::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_Sync =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_Sync kSync{};
+  void set_sync(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sync::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/cpuhp.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_CPUHP_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_CPUHP_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class CpuhpPauseFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CpuhpPauseFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CpuhpPauseFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CpuhpPauseFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_active_cpus() const { return at<1>().valid(); }
+  uint32_t active_cpus() const { return at<1>().as_uint32(); }
+  bool has_cpus() const { return at<2>().valid(); }
+  uint32_t cpus() const { return at<2>().as_uint32(); }
+  bool has_pause() const { return at<3>().valid(); }
+  uint32_t pause() const { return at<3>().as_uint32(); }
+  bool has_time() const { return at<4>().valid(); }
+  uint32_t time() const { return at<4>().as_uint32(); }
+};
+
+class CpuhpPauseFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CpuhpPauseFtraceEvent_Decoder;
+  enum : int32_t {
+    kActiveCpusFieldNumber = 1,
+    kCpusFieldNumber = 2,
+    kPauseFieldNumber = 3,
+    kTimeFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CpuhpPauseFtraceEvent"; }
+
+
+  using FieldMetadata_ActiveCpus =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuhpPauseFtraceEvent>;
+
+  static constexpr FieldMetadata_ActiveCpus kActiveCpus{};
+  void set_active_cpus(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ActiveCpus::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_Cpus =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuhpPauseFtraceEvent>;
+
+  static constexpr FieldMetadata_Cpus kCpus{};
+  void set_cpus(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cpus::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_Pause =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuhpPauseFtraceEvent>;
+
+  static constexpr FieldMetadata_Pause kPause{};
+  void set_pause(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pause::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_Time =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuhpPauseFtraceEvent>;
+
+  static constexpr FieldMetadata_Time kTime{};
+  void set_time(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Time::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 CpuhpLatencyFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CpuhpLatencyFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CpuhpLatencyFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CpuhpLatencyFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cpu() const { return at<1>().valid(); }
+  uint32_t cpu() const { return at<1>().as_uint32(); }
+  bool has_ret() const { return at<2>().valid(); }
+  int32_t ret() const { return at<2>().as_int32(); }
+  bool has_state() const { return at<3>().valid(); }
+  uint32_t state() const { return at<3>().as_uint32(); }
+  bool has_time() const { return at<4>().valid(); }
+  uint64_t time() const { return at<4>().as_uint64(); }
+};
+
+class CpuhpLatencyFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CpuhpLatencyFtraceEvent_Decoder;
+  enum : int32_t {
+    kCpuFieldNumber = 1,
+    kRetFieldNumber = 2,
+    kStateFieldNumber = 3,
+    kTimeFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CpuhpLatencyFtraceEvent"; }
+
+
+  using FieldMetadata_Cpu =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuhpLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_Cpu kCpu{};
+  void set_cpu(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cpu::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_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CpuhpLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::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_State =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuhpLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::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_Time =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      CpuhpLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_Time kTime{};
+  void set_time(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Time::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 CpuhpEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CpuhpEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CpuhpEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CpuhpEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cpu() const { return at<1>().valid(); }
+  uint32_t cpu() const { return at<1>().as_uint32(); }
+  bool has_fun() const { return at<2>().valid(); }
+  uint64_t fun() const { return at<2>().as_uint64(); }
+  bool has_idx() const { return at<3>().valid(); }
+  int32_t idx() const { return at<3>().as_int32(); }
+  bool has_target() const { return at<4>().valid(); }
+  int32_t target() const { return at<4>().as_int32(); }
+};
+
+class CpuhpEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CpuhpEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kCpuFieldNumber = 1,
+    kFunFieldNumber = 2,
+    kIdxFieldNumber = 3,
+    kTargetFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CpuhpEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Cpu =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuhpEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Cpu kCpu{};
+  void set_cpu(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cpu::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_Fun =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      CpuhpEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Fun kFun{};
+  void set_fun(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Fun::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_Idx =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CpuhpEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Idx kIdx{};
+  void set_idx(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Idx::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_Target =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CpuhpEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Target kTarget{};
+  void set_target(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Target::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);
+  }
+};
+
+class CpuhpMultiEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CpuhpMultiEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CpuhpMultiEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CpuhpMultiEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cpu() const { return at<1>().valid(); }
+  uint32_t cpu() const { return at<1>().as_uint32(); }
+  bool has_fun() const { return at<2>().valid(); }
+  uint64_t fun() const { return at<2>().as_uint64(); }
+  bool has_idx() const { return at<3>().valid(); }
+  int32_t idx() const { return at<3>().as_int32(); }
+  bool has_target() const { return at<4>().valid(); }
+  int32_t target() const { return at<4>().as_int32(); }
+};
+
+class CpuhpMultiEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CpuhpMultiEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kCpuFieldNumber = 1,
+    kFunFieldNumber = 2,
+    kIdxFieldNumber = 3,
+    kTargetFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CpuhpMultiEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Cpu =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuhpMultiEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Cpu kCpu{};
+  void set_cpu(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cpu::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_Fun =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      CpuhpMultiEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Fun kFun{};
+  void set_fun(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Fun::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_Idx =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CpuhpMultiEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Idx kIdx{};
+  void set_idx(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Idx::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_Target =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CpuhpMultiEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Target kTarget{};
+  void set_target(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Target::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);
+  }
+};
+
+class CpuhpExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CpuhpExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CpuhpExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CpuhpExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cpu() const { return at<1>().valid(); }
+  uint32_t cpu() const { return at<1>().as_uint32(); }
+  bool has_idx() const { return at<2>().valid(); }
+  int32_t idx() const { return at<2>().as_int32(); }
+  bool has_ret() const { return at<3>().valid(); }
+  int32_t ret() const { return at<3>().as_int32(); }
+  bool has_state() const { return at<4>().valid(); }
+  int32_t state() const { return at<4>().as_int32(); }
+};
+
+class CpuhpExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CpuhpExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kCpuFieldNumber = 1,
+    kIdxFieldNumber = 2,
+    kRetFieldNumber = 3,
+    kStateFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CpuhpExitFtraceEvent"; }
+
+
+  using FieldMetadata_Cpu =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuhpExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Cpu kCpu{};
+  void set_cpu(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cpu::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_Idx =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CpuhpExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Idx kIdx{};
+  void set_idx(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Idx::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_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CpuhpExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::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_State =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CpuhpExitFtraceEvent>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/cros_ec.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_CROS_EC_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_CROS_EC_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class CrosEcSensorhubDataFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CrosEcSensorhubDataFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CrosEcSensorhubDataFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CrosEcSensorhubDataFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_current_time() const { return at<1>().valid(); }
+  int64_t current_time() const { return at<1>().as_int64(); }
+  bool has_current_timestamp() const { return at<2>().valid(); }
+  int64_t current_timestamp() const { return at<2>().as_int64(); }
+  bool has_delta() const { return at<3>().valid(); }
+  int64_t delta() const { return at<3>().as_int64(); }
+  bool has_ec_fifo_timestamp() const { return at<4>().valid(); }
+  uint32_t ec_fifo_timestamp() const { return at<4>().as_uint32(); }
+  bool has_ec_sensor_num() const { return at<5>().valid(); }
+  uint32_t ec_sensor_num() const { return at<5>().as_uint32(); }
+  bool has_fifo_timestamp() const { return at<6>().valid(); }
+  int64_t fifo_timestamp() const { return at<6>().as_int64(); }
+};
+
+class CrosEcSensorhubDataFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CrosEcSensorhubDataFtraceEvent_Decoder;
+  enum : int32_t {
+    kCurrentTimeFieldNumber = 1,
+    kCurrentTimestampFieldNumber = 2,
+    kDeltaFieldNumber = 3,
+    kEcFifoTimestampFieldNumber = 4,
+    kEcSensorNumFieldNumber = 5,
+    kFifoTimestampFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CrosEcSensorhubDataFtraceEvent"; }
+
+
+  using FieldMetadata_CurrentTime =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      CrosEcSensorhubDataFtraceEvent>;
+
+  static constexpr FieldMetadata_CurrentTime kCurrentTime{};
+  void set_current_time(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CurrentTime::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_CurrentTimestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      CrosEcSensorhubDataFtraceEvent>;
+
+  static constexpr FieldMetadata_CurrentTimestamp kCurrentTimestamp{};
+  void set_current_timestamp(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CurrentTimestamp::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_Delta =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      CrosEcSensorhubDataFtraceEvent>;
+
+  static constexpr FieldMetadata_Delta kDelta{};
+  void set_delta(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Delta::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_EcFifoTimestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CrosEcSensorhubDataFtraceEvent>;
+
+  static constexpr FieldMetadata_EcFifoTimestamp kEcFifoTimestamp{};
+  void set_ec_fifo_timestamp(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EcFifoTimestamp::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_EcSensorNum =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CrosEcSensorhubDataFtraceEvent>;
+
+  static constexpr FieldMetadata_EcSensorNum kEcSensorNum{};
+  void set_ec_sensor_num(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EcSensorNum::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_FifoTimestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      CrosEcSensorhubDataFtraceEvent>;
+
+  static constexpr FieldMetadata_FifoTimestamp kFifoTimestamp{};
+  void set_fifo_timestamp(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FifoTimestamp::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/dma_fence.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_DMA_FENCE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_DMA_FENCE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class DmaFenceWaitEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DmaFenceWaitEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DmaFenceWaitEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DmaFenceWaitEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_context() const { return at<1>().valid(); }
+  uint32_t context() const { return at<1>().as_uint32(); }
+  bool has_driver() const { return at<2>().valid(); }
+  ::protozero::ConstChars driver() const { return at<2>().as_string(); }
+  bool has_seqno() const { return at<3>().valid(); }
+  uint32_t seqno() const { return at<3>().as_uint32(); }
+  bool has_timeline() const { return at<4>().valid(); }
+  ::protozero::ConstChars timeline() const { return at<4>().as_string(); }
+};
+
+class DmaFenceWaitEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = DmaFenceWaitEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kContextFieldNumber = 1,
+    kDriverFieldNumber = 2,
+    kSeqnoFieldNumber = 3,
+    kTimelineFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DmaFenceWaitEndFtraceEvent"; }
+
+
+  using FieldMetadata_Context =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DmaFenceWaitEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Context kContext{};
+  void set_context(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Context::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_Driver =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DmaFenceWaitEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Driver kDriver{};
+  void set_driver(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, data, size);
+  }
+  void set_driver(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, chars.data, chars.size);
+  }
+  void set_driver(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Driver::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_Seqno =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DmaFenceWaitEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Seqno kSeqno{};
+  void set_seqno(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Seqno::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_Timeline =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DmaFenceWaitEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Timeline kTimeline{};
+  void set_timeline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, data, size);
+  }
+  void set_timeline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, chars.data, chars.size);
+  }
+  void set_timeline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timeline::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 DmaFenceWaitStartFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DmaFenceWaitStartFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DmaFenceWaitStartFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DmaFenceWaitStartFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_context() const { return at<1>().valid(); }
+  uint32_t context() const { return at<1>().as_uint32(); }
+  bool has_driver() const { return at<2>().valid(); }
+  ::protozero::ConstChars driver() const { return at<2>().as_string(); }
+  bool has_seqno() const { return at<3>().valid(); }
+  uint32_t seqno() const { return at<3>().as_uint32(); }
+  bool has_timeline() const { return at<4>().valid(); }
+  ::protozero::ConstChars timeline() const { return at<4>().as_string(); }
+};
+
+class DmaFenceWaitStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = DmaFenceWaitStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kContextFieldNumber = 1,
+    kDriverFieldNumber = 2,
+    kSeqnoFieldNumber = 3,
+    kTimelineFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DmaFenceWaitStartFtraceEvent"; }
+
+
+  using FieldMetadata_Context =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DmaFenceWaitStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Context kContext{};
+  void set_context(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Context::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_Driver =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DmaFenceWaitStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Driver kDriver{};
+  void set_driver(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, data, size);
+  }
+  void set_driver(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, chars.data, chars.size);
+  }
+  void set_driver(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Driver::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_Seqno =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DmaFenceWaitStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Seqno kSeqno{};
+  void set_seqno(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Seqno::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_Timeline =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DmaFenceWaitStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Timeline kTimeline{};
+  void set_timeline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, data, size);
+  }
+  void set_timeline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, chars.data, chars.size);
+  }
+  void set_timeline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timeline::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 DmaFenceSignaledFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DmaFenceSignaledFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DmaFenceSignaledFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DmaFenceSignaledFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_context() const { return at<1>().valid(); }
+  uint32_t context() const { return at<1>().as_uint32(); }
+  bool has_driver() const { return at<2>().valid(); }
+  ::protozero::ConstChars driver() const { return at<2>().as_string(); }
+  bool has_seqno() const { return at<3>().valid(); }
+  uint32_t seqno() const { return at<3>().as_uint32(); }
+  bool has_timeline() const { return at<4>().valid(); }
+  ::protozero::ConstChars timeline() const { return at<4>().as_string(); }
+};
+
+class DmaFenceSignaledFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = DmaFenceSignaledFtraceEvent_Decoder;
+  enum : int32_t {
+    kContextFieldNumber = 1,
+    kDriverFieldNumber = 2,
+    kSeqnoFieldNumber = 3,
+    kTimelineFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DmaFenceSignaledFtraceEvent"; }
+
+
+  using FieldMetadata_Context =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DmaFenceSignaledFtraceEvent>;
+
+  static constexpr FieldMetadata_Context kContext{};
+  void set_context(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Context::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_Driver =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DmaFenceSignaledFtraceEvent>;
+
+  static constexpr FieldMetadata_Driver kDriver{};
+  void set_driver(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, data, size);
+  }
+  void set_driver(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, chars.data, chars.size);
+  }
+  void set_driver(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Driver::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_Seqno =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DmaFenceSignaledFtraceEvent>;
+
+  static constexpr FieldMetadata_Seqno kSeqno{};
+  void set_seqno(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Seqno::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_Timeline =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DmaFenceSignaledFtraceEvent>;
+
+  static constexpr FieldMetadata_Timeline kTimeline{};
+  void set_timeline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, data, size);
+  }
+  void set_timeline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, chars.data, chars.size);
+  }
+  void set_timeline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timeline::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 DmaFenceEmitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DmaFenceEmitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DmaFenceEmitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DmaFenceEmitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_context() const { return at<1>().valid(); }
+  uint32_t context() const { return at<1>().as_uint32(); }
+  bool has_driver() const { return at<2>().valid(); }
+  ::protozero::ConstChars driver() const { return at<2>().as_string(); }
+  bool has_seqno() const { return at<3>().valid(); }
+  uint32_t seqno() const { return at<3>().as_uint32(); }
+  bool has_timeline() const { return at<4>().valid(); }
+  ::protozero::ConstChars timeline() const { return at<4>().as_string(); }
+};
+
+class DmaFenceEmitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = DmaFenceEmitFtraceEvent_Decoder;
+  enum : int32_t {
+    kContextFieldNumber = 1,
+    kDriverFieldNumber = 2,
+    kSeqnoFieldNumber = 3,
+    kTimelineFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DmaFenceEmitFtraceEvent"; }
+
+
+  using FieldMetadata_Context =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DmaFenceEmitFtraceEvent>;
+
+  static constexpr FieldMetadata_Context kContext{};
+  void set_context(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Context::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_Driver =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DmaFenceEmitFtraceEvent>;
+
+  static constexpr FieldMetadata_Driver kDriver{};
+  void set_driver(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, data, size);
+  }
+  void set_driver(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, chars.data, chars.size);
+  }
+  void set_driver(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Driver::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_Seqno =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DmaFenceEmitFtraceEvent>;
+
+  static constexpr FieldMetadata_Seqno kSeqno{};
+  void set_seqno(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Seqno::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_Timeline =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DmaFenceEmitFtraceEvent>;
+
+  static constexpr FieldMetadata_Timeline kTimeline{};
+  void set_timeline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, data, size);
+  }
+  void set_timeline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, chars.data, chars.size);
+  }
+  void set_timeline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timeline::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 DmaFenceInitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DmaFenceInitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DmaFenceInitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DmaFenceInitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_context() const { return at<1>().valid(); }
+  uint32_t context() const { return at<1>().as_uint32(); }
+  bool has_driver() const { return at<2>().valid(); }
+  ::protozero::ConstChars driver() const { return at<2>().as_string(); }
+  bool has_seqno() const { return at<3>().valid(); }
+  uint32_t seqno() const { return at<3>().as_uint32(); }
+  bool has_timeline() const { return at<4>().valid(); }
+  ::protozero::ConstChars timeline() const { return at<4>().as_string(); }
+};
+
+class DmaFenceInitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = DmaFenceInitFtraceEvent_Decoder;
+  enum : int32_t {
+    kContextFieldNumber = 1,
+    kDriverFieldNumber = 2,
+    kSeqnoFieldNumber = 3,
+    kTimelineFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DmaFenceInitFtraceEvent"; }
+
+
+  using FieldMetadata_Context =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DmaFenceInitFtraceEvent>;
+
+  static constexpr FieldMetadata_Context kContext{};
+  void set_context(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Context::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_Driver =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DmaFenceInitFtraceEvent>;
+
+  static constexpr FieldMetadata_Driver kDriver{};
+  void set_driver(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, data, size);
+  }
+  void set_driver(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, chars.data, chars.size);
+  }
+  void set_driver(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Driver::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_Seqno =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DmaFenceInitFtraceEvent>;
+
+  static constexpr FieldMetadata_Seqno kSeqno{};
+  void set_seqno(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Seqno::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_Timeline =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DmaFenceInitFtraceEvent>;
+
+  static constexpr FieldMetadata_Timeline kTimeline{};
+  void set_timeline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, data, size);
+  }
+  void set_timeline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, chars.data, chars.size);
+  }
+  void set_timeline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timeline::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/dmabuf_heap.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_DMABUF_HEAP_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_DMABUF_HEAP_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class DmaHeapStatFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DmaHeapStatFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DmaHeapStatFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DmaHeapStatFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_inode() const { return at<1>().valid(); }
+  uint64_t inode() const { return at<1>().as_uint64(); }
+  bool has_len() const { return at<2>().valid(); }
+  int64_t len() const { return at<2>().as_int64(); }
+  bool has_total_allocated() const { return at<3>().valid(); }
+  uint64_t total_allocated() const { return at<3>().as_uint64(); }
+};
+
+class DmaHeapStatFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = DmaHeapStatFtraceEvent_Decoder;
+  enum : int32_t {
+    kInodeFieldNumber = 1,
+    kLenFieldNumber = 2,
+    kTotalAllocatedFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DmaHeapStatFtraceEvent"; }
+
+
+  using FieldMetadata_Inode =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DmaHeapStatFtraceEvent>;
+
+  static constexpr FieldMetadata_Inode kInode{};
+  void set_inode(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Inode::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      DmaHeapStatFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_TotalAllocated =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DmaHeapStatFtraceEvent>;
+
+  static constexpr FieldMetadata_TotalAllocated kTotalAllocated{};
+  void set_total_allocated(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TotalAllocated::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/dpu.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_DPU_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_DPU_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class DpuDsiTxFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DpuDsiTxFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DpuDsiTxFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DpuDsiTxFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_type() const { return at<1>().valid(); }
+  uint32_t type() const { return at<1>().as_uint32(); }
+  bool has_tx_buf() const { return at<2>().valid(); }
+  uint32_t tx_buf() const { return at<2>().as_uint32(); }
+  bool has_last() const { return at<3>().valid(); }
+  uint32_t last() const { return at<3>().as_uint32(); }
+  bool has_delay_ms() const { return at<4>().valid(); }
+  uint32_t delay_ms() const { return at<4>().as_uint32(); }
+};
+
+class DpuDsiTxFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = DpuDsiTxFtraceEvent_Decoder;
+  enum : int32_t {
+    kTypeFieldNumber = 1,
+    kTxBufFieldNumber = 2,
+    kLastFieldNumber = 3,
+    kDelayMsFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DpuDsiTxFtraceEvent"; }
+
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DpuDsiTxFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::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_TxBuf =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DpuDsiTxFtraceEvent>;
+
+  static constexpr FieldMetadata_TxBuf kTxBuf{};
+  void set_tx_buf(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TxBuf::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_Last =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DpuDsiTxFtraceEvent>;
+
+  static constexpr FieldMetadata_Last kLast{};
+  void set_last(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Last::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_DelayMs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DpuDsiTxFtraceEvent>;
+
+  static constexpr FieldMetadata_DelayMs kDelayMs{};
+  void set_delay_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DelayMs::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 DpuDsiRxFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DpuDsiRxFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DpuDsiRxFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DpuDsiRxFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cmd() const { return at<1>().valid(); }
+  uint32_t cmd() const { return at<1>().as_uint32(); }
+  bool has_rx_buf() const { return at<2>().valid(); }
+  uint32_t rx_buf() const { return at<2>().as_uint32(); }
+};
+
+class DpuDsiRxFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = DpuDsiRxFtraceEvent_Decoder;
+  enum : int32_t {
+    kCmdFieldNumber = 1,
+    kRxBufFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DpuDsiRxFtraceEvent"; }
+
+
+  using FieldMetadata_Cmd =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DpuDsiRxFtraceEvent>;
+
+  static constexpr FieldMetadata_Cmd kCmd{};
+  void set_cmd(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cmd::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_RxBuf =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DpuDsiRxFtraceEvent>;
+
+  static constexpr FieldMetadata_RxBuf kRxBuf{};
+  void set_rx_buf(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RxBuf::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 DpuDsiCmdFifoStatusFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DpuDsiCmdFifoStatusFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DpuDsiCmdFifoStatusFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DpuDsiCmdFifoStatusFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_header() const { return at<1>().valid(); }
+  uint32_t header() const { return at<1>().as_uint32(); }
+  bool has_payload() const { return at<2>().valid(); }
+  uint32_t payload() const { return at<2>().as_uint32(); }
+};
+
+class DpuDsiCmdFifoStatusFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = DpuDsiCmdFifoStatusFtraceEvent_Decoder;
+  enum : int32_t {
+    kHeaderFieldNumber = 1,
+    kPayloadFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DpuDsiCmdFifoStatusFtraceEvent"; }
+
+
+  using FieldMetadata_Header =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DpuDsiCmdFifoStatusFtraceEvent>;
+
+  static constexpr FieldMetadata_Header kHeader{};
+  void set_header(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Header::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_Payload =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DpuDsiCmdFifoStatusFtraceEvent>;
+
+  static constexpr FieldMetadata_Payload kPayload{};
+  void set_payload(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Payload::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 DpuTracingMarkWriteFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DpuTracingMarkWriteFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DpuTracingMarkWriteFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DpuTracingMarkWriteFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  int32_t pid() const { return at<1>().as_int32(); }
+  bool has_trace_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars trace_name() const { return at<2>().as_string(); }
+  bool has_trace_begin() const { return at<3>().valid(); }
+  uint32_t trace_begin() const { return at<3>().as_uint32(); }
+  bool has_name() const { return at<4>().valid(); }
+  ::protozero::ConstChars name() const { return at<4>().as_string(); }
+  bool has_type() const { return at<5>().valid(); }
+  uint32_t type() const { return at<5>().as_uint32(); }
+  bool has_value() const { return at<6>().valid(); }
+  int32_t value() const { return at<6>().as_int32(); }
+};
+
+class DpuTracingMarkWriteFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = DpuTracingMarkWriteFtraceEvent_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kTraceNameFieldNumber = 2,
+    kTraceBeginFieldNumber = 3,
+    kNameFieldNumber = 4,
+    kTypeFieldNumber = 5,
+    kValueFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DpuTracingMarkWriteFtraceEvent"; }
+
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      DpuTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_TraceName =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DpuTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_TraceName kTraceName{};
+  void set_trace_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TraceName::kFieldId, data, size);
+  }
+  void set_trace_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_TraceName::kFieldId, chars.data, chars.size);
+  }
+  void set_trace_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_TraceName::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_TraceBegin =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DpuTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_TraceBegin kTraceBegin{};
+  void set_trace_begin(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TraceBegin::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DpuTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DpuTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::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_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      DpuTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/drm.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_DRM_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_DRM_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class DrmVblankEventDeliveredFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DrmVblankEventDeliveredFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DrmVblankEventDeliveredFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DrmVblankEventDeliveredFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_crtc() const { return at<1>().valid(); }
+  int32_t crtc() const { return at<1>().as_int32(); }
+  bool has_file() const { return at<2>().valid(); }
+  uint64_t file() const { return at<2>().as_uint64(); }
+  bool has_seq() const { return at<3>().valid(); }
+  uint32_t seq() const { return at<3>().as_uint32(); }
+};
+
+class DrmVblankEventDeliveredFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = DrmVblankEventDeliveredFtraceEvent_Decoder;
+  enum : int32_t {
+    kCrtcFieldNumber = 1,
+    kFileFieldNumber = 2,
+    kSeqFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DrmVblankEventDeliveredFtraceEvent"; }
+
+
+  using FieldMetadata_Crtc =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      DrmVblankEventDeliveredFtraceEvent>;
+
+  static constexpr FieldMetadata_Crtc kCrtc{};
+  void set_crtc(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Crtc::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_File =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DrmVblankEventDeliveredFtraceEvent>;
+
+  static constexpr FieldMetadata_File kFile{};
+  void set_file(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_File::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_Seq =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DrmVblankEventDeliveredFtraceEvent>;
+
+  static constexpr FieldMetadata_Seq kSeq{};
+  void set_seq(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Seq::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 DrmVblankEventFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DrmVblankEventFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DrmVblankEventFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DrmVblankEventFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_crtc() const { return at<1>().valid(); }
+  int32_t crtc() const { return at<1>().as_int32(); }
+  bool has_high_prec() const { return at<2>().valid(); }
+  uint32_t high_prec() const { return at<2>().as_uint32(); }
+  bool has_seq() const { return at<3>().valid(); }
+  uint32_t seq() const { return at<3>().as_uint32(); }
+  bool has_time() const { return at<4>().valid(); }
+  int64_t time() const { return at<4>().as_int64(); }
+};
+
+class DrmVblankEventFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = DrmVblankEventFtraceEvent_Decoder;
+  enum : int32_t {
+    kCrtcFieldNumber = 1,
+    kHighPrecFieldNumber = 2,
+    kSeqFieldNumber = 3,
+    kTimeFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DrmVblankEventFtraceEvent"; }
+
+
+  using FieldMetadata_Crtc =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      DrmVblankEventFtraceEvent>;
+
+  static constexpr FieldMetadata_Crtc kCrtc{};
+  void set_crtc(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Crtc::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_HighPrec =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DrmVblankEventFtraceEvent>;
+
+  static constexpr FieldMetadata_HighPrec kHighPrec{};
+  void set_high_prec(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_HighPrec::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_Seq =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DrmVblankEventFtraceEvent>;
+
+  static constexpr FieldMetadata_Seq kSeq{};
+  void set_seq(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Seq::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_Time =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      DrmVblankEventFtraceEvent>;
+
+  static constexpr FieldMetadata_Time kTime{};
+  void set_time(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Time::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/ext4.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_EXT4_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_EXT4_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class Ext4ZeroRangeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4ZeroRangeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4ZeroRangeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4ZeroRangeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_offset() const { return at<3>().valid(); }
+  int64_t offset() const { return at<3>().as_int64(); }
+  bool has_len() const { return at<4>().valid(); }
+  int64_t len() const { return at<4>().as_int64(); }
+  bool has_mode() const { return at<5>().valid(); }
+  int32_t mode() const { return at<5>().as_int32(); }
+};
+
+class Ext4ZeroRangeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4ZeroRangeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kOffsetFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kModeFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4ZeroRangeFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ZeroRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ZeroRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Offset =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4ZeroRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Offset kOffset{};
+  void set_offset(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Offset::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4ZeroRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4ZeroRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::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);
+  }
+};
+
+class Ext4WritepagesResultFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4WritepagesResultFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4WritepagesResultFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4WritepagesResultFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_ret() const { return at<3>().valid(); }
+  int32_t ret() const { return at<3>().as_int32(); }
+  bool has_pages_written() const { return at<4>().valid(); }
+  int32_t pages_written() const { return at<4>().as_int32(); }
+  bool has_pages_skipped() const { return at<5>().valid(); }
+  int64_t pages_skipped() const { return at<5>().as_int64(); }
+  bool has_writeback_index() const { return at<6>().valid(); }
+  uint64_t writeback_index() const { return at<6>().as_uint64(); }
+  bool has_sync_mode() const { return at<7>().valid(); }
+  int32_t sync_mode() const { return at<7>().as_int32(); }
+};
+
+class Ext4WritepagesResultFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4WritepagesResultFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kRetFieldNumber = 3,
+    kPagesWrittenFieldNumber = 4,
+    kPagesSkippedFieldNumber = 5,
+    kWritebackIndexFieldNumber = 6,
+    kSyncModeFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4WritepagesResultFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4WritepagesResultFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4WritepagesResultFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4WritepagesResultFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::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_PagesWritten =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4WritepagesResultFtraceEvent>;
+
+  static constexpr FieldMetadata_PagesWritten kPagesWritten{};
+  void set_pages_written(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PagesWritten::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_PagesSkipped =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4WritepagesResultFtraceEvent>;
+
+  static constexpr FieldMetadata_PagesSkipped kPagesSkipped{};
+  void set_pages_skipped(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PagesSkipped::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_WritebackIndex =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4WritepagesResultFtraceEvent>;
+
+  static constexpr FieldMetadata_WritebackIndex kWritebackIndex{};
+  void set_writeback_index(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_WritebackIndex::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_SyncMode =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4WritepagesResultFtraceEvent>;
+
+  static constexpr FieldMetadata_SyncMode kSyncMode{};
+  void set_sync_mode(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SyncMode::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);
+  }
+};
+
+class Ext4WritepagesFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/10, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4WritepagesFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4WritepagesFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4WritepagesFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_nr_to_write() const { return at<3>().valid(); }
+  int64_t nr_to_write() const { return at<3>().as_int64(); }
+  bool has_pages_skipped() const { return at<4>().valid(); }
+  int64_t pages_skipped() const { return at<4>().as_int64(); }
+  bool has_range_start() const { return at<5>().valid(); }
+  int64_t range_start() const { return at<5>().as_int64(); }
+  bool has_range_end() const { return at<6>().valid(); }
+  int64_t range_end() const { return at<6>().as_int64(); }
+  bool has_writeback_index() const { return at<7>().valid(); }
+  uint64_t writeback_index() const { return at<7>().as_uint64(); }
+  bool has_sync_mode() const { return at<8>().valid(); }
+  int32_t sync_mode() const { return at<8>().as_int32(); }
+  bool has_for_kupdate() const { return at<9>().valid(); }
+  uint32_t for_kupdate() const { return at<9>().as_uint32(); }
+  bool has_range_cyclic() const { return at<10>().valid(); }
+  uint32_t range_cyclic() const { return at<10>().as_uint32(); }
+};
+
+class Ext4WritepagesFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4WritepagesFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kNrToWriteFieldNumber = 3,
+    kPagesSkippedFieldNumber = 4,
+    kRangeStartFieldNumber = 5,
+    kRangeEndFieldNumber = 6,
+    kWritebackIndexFieldNumber = 7,
+    kSyncModeFieldNumber = 8,
+    kForKupdateFieldNumber = 9,
+    kRangeCyclicFieldNumber = 10,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4WritepagesFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4WritepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4WritepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_NrToWrite =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4WritepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_NrToWrite kNrToWrite{};
+  void set_nr_to_write(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrToWrite::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_PagesSkipped =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4WritepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_PagesSkipped kPagesSkipped{};
+  void set_pages_skipped(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PagesSkipped::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_RangeStart =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4WritepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_RangeStart kRangeStart{};
+  void set_range_start(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RangeStart::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_RangeEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4WritepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_RangeEnd kRangeEnd{};
+  void set_range_end(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RangeEnd::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_WritebackIndex =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4WritepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_WritebackIndex kWritebackIndex{};
+  void set_writeback_index(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_WritebackIndex::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_SyncMode =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4WritepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_SyncMode kSyncMode{};
+  void set_sync_mode(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SyncMode::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_ForKupdate =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4WritepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_ForKupdate kForKupdate{};
+  void set_for_kupdate(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ForKupdate::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_RangeCyclic =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4WritepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_RangeCyclic kRangeCyclic{};
+  void set_range_cyclic(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RangeCyclic::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 Ext4WritepageFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4WritepageFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4WritepageFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4WritepageFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_index() const { return at<3>().valid(); }
+  uint64_t index() const { return at<3>().as_uint64(); }
+};
+
+class Ext4WritepageFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4WritepageFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kIndexFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4WritepageFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4WritepageFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4WritepageFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4WritepageFtraceEvent>;
+
+  static constexpr FieldMetadata_Index kIndex{};
+  void set_index(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Index::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 Ext4WriteEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4WriteEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4WriteEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4WriteEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pos() const { return at<3>().valid(); }
+  int64_t pos() const { return at<3>().as_int64(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint32_t len() const { return at<4>().as_uint32(); }
+  bool has_copied() const { return at<5>().valid(); }
+  uint32_t copied() const { return at<5>().as_uint32(); }
+};
+
+class Ext4WriteEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4WriteEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPosFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kCopiedFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4WriteEndFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4WriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4WriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Pos =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4WriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Pos kPos{};
+  void set_pos(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pos::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4WriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Copied =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4WriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Copied kCopied{};
+  void set_copied(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Copied::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 Ext4WriteBeginFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4WriteBeginFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4WriteBeginFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4WriteBeginFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pos() const { return at<3>().valid(); }
+  int64_t pos() const { return at<3>().as_int64(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint32_t len() const { return at<4>().as_uint32(); }
+  bool has_flags() const { return at<5>().valid(); }
+  uint32_t flags() const { return at<5>().as_uint32(); }
+};
+
+class Ext4WriteBeginFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4WriteBeginFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPosFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kFlagsFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4WriteBeginFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4WriteBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4WriteBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Pos =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4WriteBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_Pos kPos{};
+  void set_pos(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pos::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4WriteBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4WriteBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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 Ext4UnlinkExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4UnlinkExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4UnlinkExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4UnlinkExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_ret() const { return at<3>().valid(); }
+  int32_t ret() const { return at<3>().as_int32(); }
+};
+
+class Ext4UnlinkExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4UnlinkExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kRetFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4UnlinkExitFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4UnlinkExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4UnlinkExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4UnlinkExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::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);
+  }
+};
+
+class Ext4UnlinkEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4UnlinkEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4UnlinkEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4UnlinkEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_parent() const { return at<3>().valid(); }
+  uint64_t parent() const { return at<3>().as_uint64(); }
+  bool has_size() const { return at<4>().valid(); }
+  int64_t size() const { return at<4>().as_int64(); }
+};
+
+class Ext4UnlinkEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4UnlinkEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kParentFieldNumber = 3,
+    kSizeFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4UnlinkEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4UnlinkEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4UnlinkEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Parent =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4UnlinkEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Parent kParent{};
+  void set_parent(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Parent::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_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4UnlinkEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void set_size(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::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 Ext4TruncateExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4TruncateExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4TruncateExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4TruncateExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_blocks() const { return at<3>().valid(); }
+  uint64_t blocks() const { return at<3>().as_uint64(); }
+};
+
+class Ext4TruncateExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4TruncateExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kBlocksFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4TruncateExitFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4TruncateExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4TruncateExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Blocks =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4TruncateExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Blocks kBlocks{};
+  void set_blocks(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Blocks::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 Ext4TruncateEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4TruncateEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4TruncateEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4TruncateEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_blocks() const { return at<3>().valid(); }
+  uint64_t blocks() const { return at<3>().as_uint64(); }
+};
+
+class Ext4TruncateEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4TruncateEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kBlocksFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4TruncateEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4TruncateEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4TruncateEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Blocks =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4TruncateEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Blocks kBlocks{};
+  void set_blocks(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Blocks::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 Ext4TrimExtentFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4TrimExtentFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4TrimExtentFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4TrimExtentFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev_major() const { return at<1>().valid(); }
+  int32_t dev_major() const { return at<1>().as_int32(); }
+  bool has_dev_minor() const { return at<2>().valid(); }
+  int32_t dev_minor() const { return at<2>().as_int32(); }
+  bool has_group() const { return at<3>().valid(); }
+  uint32_t group() const { return at<3>().as_uint32(); }
+  bool has_start() const { return at<4>().valid(); }
+  int32_t start() const { return at<4>().as_int32(); }
+  bool has_len() const { return at<5>().valid(); }
+  int32_t len() const { return at<5>().as_int32(); }
+};
+
+class Ext4TrimExtentFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4TrimExtentFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevMajorFieldNumber = 1,
+    kDevMinorFieldNumber = 2,
+    kGroupFieldNumber = 3,
+    kStartFieldNumber = 4,
+    kLenFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4TrimExtentFtraceEvent"; }
+
+
+  using FieldMetadata_DevMajor =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4TrimExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_DevMajor kDevMajor{};
+  void set_dev_major(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DevMajor::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_DevMinor =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4TrimExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_DevMinor kDevMinor{};
+  void set_dev_minor(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DevMinor::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_Group =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4TrimExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Group kGroup{};
+  void set_group(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Group::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_Start =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4TrimExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Start kStart{};
+  void set_start(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Start::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4TrimExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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);
+  }
+};
+
+class Ext4TrimAllFreeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4TrimAllFreeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4TrimAllFreeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4TrimAllFreeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev_major() const { return at<1>().valid(); }
+  int32_t dev_major() const { return at<1>().as_int32(); }
+  bool has_dev_minor() const { return at<2>().valid(); }
+  int32_t dev_minor() const { return at<2>().as_int32(); }
+  bool has_group() const { return at<3>().valid(); }
+  uint32_t group() const { return at<3>().as_uint32(); }
+  bool has_start() const { return at<4>().valid(); }
+  int32_t start() const { return at<4>().as_int32(); }
+  bool has_len() const { return at<5>().valid(); }
+  int32_t len() const { return at<5>().as_int32(); }
+};
+
+class Ext4TrimAllFreeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4TrimAllFreeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevMajorFieldNumber = 1,
+    kDevMinorFieldNumber = 2,
+    kGroupFieldNumber = 3,
+    kStartFieldNumber = 4,
+    kLenFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4TrimAllFreeFtraceEvent"; }
+
+
+  using FieldMetadata_DevMajor =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4TrimAllFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_DevMajor kDevMajor{};
+  void set_dev_major(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DevMajor::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_DevMinor =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4TrimAllFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_DevMinor kDevMinor{};
+  void set_dev_minor(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DevMinor::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_Group =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4TrimAllFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_Group kGroup{};
+  void set_group(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Group::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_Start =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4TrimAllFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_Start kStart{};
+  void set_start(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Start::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4TrimAllFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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);
+  }
+};
+
+class Ext4SyncFsFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4SyncFsFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4SyncFsFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4SyncFsFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_wait() const { return at<2>().valid(); }
+  int32_t wait() const { return at<2>().as_int32(); }
+};
+
+class Ext4SyncFsFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4SyncFsFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kWaitFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4SyncFsFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4SyncFsFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Wait =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4SyncFsFtraceEvent>;
+
+  static constexpr FieldMetadata_Wait kWait{};
+  void set_wait(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Wait::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);
+  }
+};
+
+class Ext4RequestInodeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4RequestInodeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4RequestInodeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4RequestInodeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_dir() const { return at<2>().valid(); }
+  uint64_t dir() const { return at<2>().as_uint64(); }
+  bool has_mode() const { return at<3>().valid(); }
+  uint32_t mode() const { return at<3>().as_uint32(); }
+};
+
+class Ext4RequestInodeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4RequestInodeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kDirFieldNumber = 2,
+    kModeFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4RequestInodeFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4RequestInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Dir =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4RequestInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dir kDir{};
+  void set_dir(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dir::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_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4RequestInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::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 Ext4RequestBlocksFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/10, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4RequestBlocksFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4RequestBlocksFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4RequestBlocksFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_len() const { return at<3>().valid(); }
+  uint32_t len() const { return at<3>().as_uint32(); }
+  bool has_logical() const { return at<4>().valid(); }
+  uint32_t logical() const { return at<4>().as_uint32(); }
+  bool has_lleft() const { return at<5>().valid(); }
+  uint32_t lleft() const { return at<5>().as_uint32(); }
+  bool has_lright() const { return at<6>().valid(); }
+  uint32_t lright() const { return at<6>().as_uint32(); }
+  bool has_goal() const { return at<7>().valid(); }
+  uint64_t goal() const { return at<7>().as_uint64(); }
+  bool has_pleft() const { return at<8>().valid(); }
+  uint64_t pleft() const { return at<8>().as_uint64(); }
+  bool has_pright() const { return at<9>().valid(); }
+  uint64_t pright() const { return at<9>().as_uint64(); }
+  bool has_flags() const { return at<10>().valid(); }
+  uint32_t flags() const { return at<10>().as_uint32(); }
+};
+
+class Ext4RequestBlocksFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4RequestBlocksFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kLenFieldNumber = 3,
+    kLogicalFieldNumber = 4,
+    kLleftFieldNumber = 5,
+    kLrightFieldNumber = 6,
+    kGoalFieldNumber = 7,
+    kPleftFieldNumber = 8,
+    kPrightFieldNumber = 9,
+    kFlagsFieldNumber = 10,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4RequestBlocksFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4RequestBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4RequestBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4RequestBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Logical =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4RequestBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Logical kLogical{};
+  void set_logical(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Logical::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_Lleft =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4RequestBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Lleft kLleft{};
+  void set_lleft(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lleft::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_Lright =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4RequestBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Lright kLright{};
+  void set_lright(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lright::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_Goal =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4RequestBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Goal kGoal{};
+  void set_goal(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Goal::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_Pleft =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4RequestBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Pleft kPleft{};
+  void set_pleft(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pleft::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_Pright =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4RequestBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Pright kPright{};
+  void set_pright(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pright::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4RequestBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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 Ext4RemoveBlocksFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/11, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4RemoveBlocksFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4RemoveBlocksFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4RemoveBlocksFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_from() const { return at<3>().valid(); }
+  uint32_t from() const { return at<3>().as_uint32(); }
+  bool has_to() const { return at<4>().valid(); }
+  uint32_t to() const { return at<4>().as_uint32(); }
+  bool has_partial() const { return at<5>().valid(); }
+  int64_t partial() const { return at<5>().as_int64(); }
+  bool has_ee_pblk() const { return at<6>().valid(); }
+  uint64_t ee_pblk() const { return at<6>().as_uint64(); }
+  bool has_ee_lblk() const { return at<7>().valid(); }
+  uint32_t ee_lblk() const { return at<7>().as_uint32(); }
+  bool has_ee_len() const { return at<8>().valid(); }
+  uint32_t ee_len() const { return at<8>().as_uint32(); }
+  bool has_pc_lblk() const { return at<9>().valid(); }
+  uint32_t pc_lblk() const { return at<9>().as_uint32(); }
+  bool has_pc_pclu() const { return at<10>().valid(); }
+  uint64_t pc_pclu() const { return at<10>().as_uint64(); }
+  bool has_pc_state() const { return at<11>().valid(); }
+  int32_t pc_state() const { return at<11>().as_int32(); }
+};
+
+class Ext4RemoveBlocksFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4RemoveBlocksFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kFromFieldNumber = 3,
+    kToFieldNumber = 4,
+    kPartialFieldNumber = 5,
+    kEePblkFieldNumber = 6,
+    kEeLblkFieldNumber = 7,
+    kEeLenFieldNumber = 8,
+    kPcLblkFieldNumber = 9,
+    kPcPcluFieldNumber = 10,
+    kPcStateFieldNumber = 11,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4RemoveBlocksFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4RemoveBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4RemoveBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_From =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4RemoveBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_From kFrom{};
+  void set_from(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_From::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_To =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4RemoveBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_To kTo{};
+  void set_to(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_To::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_Partial =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4RemoveBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Partial kPartial{};
+  void set_partial(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Partial::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_EePblk =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4RemoveBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_EePblk kEePblk{};
+  void set_ee_pblk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EePblk::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_EeLblk =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4RemoveBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_EeLblk kEeLblk{};
+  void set_ee_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EeLblk::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_EeLen =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4RemoveBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_EeLen kEeLen{};
+  void set_ee_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EeLen::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_PcLblk =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4RemoveBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_PcLblk kPcLblk{};
+  void set_pc_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PcLblk::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_PcPclu =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4RemoveBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_PcPclu kPcPclu{};
+  void set_pc_pclu(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PcPclu::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_PcState =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4RemoveBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_PcState kPcState{};
+  void set_pc_state(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PcState::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);
+  }
+};
+
+class Ext4ReleasepageFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4ReleasepageFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4ReleasepageFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4ReleasepageFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_index() const { return at<3>().valid(); }
+  uint64_t index() const { return at<3>().as_uint64(); }
+};
+
+class Ext4ReleasepageFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4ReleasepageFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kIndexFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4ReleasepageFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ReleasepageFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ReleasepageFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ReleasepageFtraceEvent>;
+
+  static constexpr FieldMetadata_Index kIndex{};
+  void set_index(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Index::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 Ext4ReadpageFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4ReadpageFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4ReadpageFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4ReadpageFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_index() const { return at<3>().valid(); }
+  uint64_t index() const { return at<3>().as_uint64(); }
+};
+
+class Ext4ReadpageFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4ReadpageFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kIndexFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4ReadpageFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ReadpageFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ReadpageFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ReadpageFtraceEvent>;
+
+  static constexpr FieldMetadata_Index kIndex{};
+  void set_index(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Index::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 Ext4ReadBlockBitmapLoadFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4ReadBlockBitmapLoadFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4ReadBlockBitmapLoadFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4ReadBlockBitmapLoadFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_group() const { return at<2>().valid(); }
+  uint32_t group() const { return at<2>().as_uint32(); }
+  bool has_prefetch() const { return at<3>().valid(); }
+  uint32_t prefetch() const { return at<3>().as_uint32(); }
+};
+
+class Ext4ReadBlockBitmapLoadFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4ReadBlockBitmapLoadFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kGroupFieldNumber = 2,
+    kPrefetchFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4ReadBlockBitmapLoadFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ReadBlockBitmapLoadFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Group =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ReadBlockBitmapLoadFtraceEvent>;
+
+  static constexpr FieldMetadata_Group kGroup{};
+  void set_group(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Group::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_Prefetch =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ReadBlockBitmapLoadFtraceEvent>;
+
+  static constexpr FieldMetadata_Prefetch kPrefetch{};
+  void set_prefetch(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Prefetch::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 Ext4PunchHoleFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4PunchHoleFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4PunchHoleFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4PunchHoleFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_offset() const { return at<3>().valid(); }
+  int64_t offset() const { return at<3>().as_int64(); }
+  bool has_len() const { return at<4>().valid(); }
+  int64_t len() const { return at<4>().as_int64(); }
+  bool has_mode() const { return at<5>().valid(); }
+  int32_t mode() const { return at<5>().as_int32(); }
+};
+
+class Ext4PunchHoleFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4PunchHoleFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kOffsetFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kModeFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4PunchHoleFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4PunchHoleFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4PunchHoleFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Offset =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4PunchHoleFtraceEvent>;
+
+  static constexpr FieldMetadata_Offset kOffset{};
+  void set_offset(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Offset::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4PunchHoleFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4PunchHoleFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::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);
+  }
+};
+
+class Ext4OtherInodeUpdateTimeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4OtherInodeUpdateTimeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4OtherInodeUpdateTimeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4OtherInodeUpdateTimeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_orig_ino() const { return at<3>().valid(); }
+  uint64_t orig_ino() const { return at<3>().as_uint64(); }
+  bool has_uid() const { return at<4>().valid(); }
+  uint32_t uid() const { return at<4>().as_uint32(); }
+  bool has_gid() const { return at<5>().valid(); }
+  uint32_t gid() const { return at<5>().as_uint32(); }
+  bool has_mode() const { return at<6>().valid(); }
+  uint32_t mode() const { return at<6>().as_uint32(); }
+};
+
+class Ext4OtherInodeUpdateTimeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4OtherInodeUpdateTimeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kOrigInoFieldNumber = 3,
+    kUidFieldNumber = 4,
+    kGidFieldNumber = 5,
+    kModeFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4OtherInodeUpdateTimeFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4OtherInodeUpdateTimeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4OtherInodeUpdateTimeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_OrigIno =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4OtherInodeUpdateTimeFtraceEvent>;
+
+  static constexpr FieldMetadata_OrigIno kOrigIno{};
+  void set_orig_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OrigIno::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_Uid =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4OtherInodeUpdateTimeFtraceEvent>;
+
+  static constexpr FieldMetadata_Uid kUid{};
+  void set_uid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Uid::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_Gid =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4OtherInodeUpdateTimeFtraceEvent>;
+
+  static constexpr FieldMetadata_Gid kGid{};
+  void set_gid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Gid::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_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4OtherInodeUpdateTimeFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::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 Ext4MballocPreallocFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/10, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4MballocPreallocFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4MballocPreallocFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4MballocPreallocFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_orig_logical() const { return at<3>().valid(); }
+  uint32_t orig_logical() const { return at<3>().as_uint32(); }
+  bool has_orig_start() const { return at<4>().valid(); }
+  int32_t orig_start() const { return at<4>().as_int32(); }
+  bool has_orig_group() const { return at<5>().valid(); }
+  uint32_t orig_group() const { return at<5>().as_uint32(); }
+  bool has_orig_len() const { return at<6>().valid(); }
+  int32_t orig_len() const { return at<6>().as_int32(); }
+  bool has_result_logical() const { return at<7>().valid(); }
+  uint32_t result_logical() const { return at<7>().as_uint32(); }
+  bool has_result_start() const { return at<8>().valid(); }
+  int32_t result_start() const { return at<8>().as_int32(); }
+  bool has_result_group() const { return at<9>().valid(); }
+  uint32_t result_group() const { return at<9>().as_uint32(); }
+  bool has_result_len() const { return at<10>().valid(); }
+  int32_t result_len() const { return at<10>().as_int32(); }
+};
+
+class Ext4MballocPreallocFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4MballocPreallocFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kOrigLogicalFieldNumber = 3,
+    kOrigStartFieldNumber = 4,
+    kOrigGroupFieldNumber = 5,
+    kOrigLenFieldNumber = 6,
+    kResultLogicalFieldNumber = 7,
+    kResultStartFieldNumber = 8,
+    kResultGroupFieldNumber = 9,
+    kResultLenFieldNumber = 10,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4MballocPreallocFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MballocPreallocFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MballocPreallocFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_OrigLogical =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MballocPreallocFtraceEvent>;
+
+  static constexpr FieldMetadata_OrigLogical kOrigLogical{};
+  void set_orig_logical(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OrigLogical::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_OrigStart =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4MballocPreallocFtraceEvent>;
+
+  static constexpr FieldMetadata_OrigStart kOrigStart{};
+  void set_orig_start(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OrigStart::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_OrigGroup =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MballocPreallocFtraceEvent>;
+
+  static constexpr FieldMetadata_OrigGroup kOrigGroup{};
+  void set_orig_group(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OrigGroup::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_OrigLen =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4MballocPreallocFtraceEvent>;
+
+  static constexpr FieldMetadata_OrigLen kOrigLen{};
+  void set_orig_len(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OrigLen::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_ResultLogical =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MballocPreallocFtraceEvent>;
+
+  static constexpr FieldMetadata_ResultLogical kResultLogical{};
+  void set_result_logical(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResultLogical::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_ResultStart =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4MballocPreallocFtraceEvent>;
+
+  static constexpr FieldMetadata_ResultStart kResultStart{};
+  void set_result_start(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResultStart::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_ResultGroup =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MballocPreallocFtraceEvent>;
+
+  static constexpr FieldMetadata_ResultGroup kResultGroup{};
+  void set_result_group(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResultGroup::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_ResultLen =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4MballocPreallocFtraceEvent>;
+
+  static constexpr FieldMetadata_ResultLen kResultLen{};
+  void set_result_len(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResultLen::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);
+  }
+};
+
+class Ext4MballocFreeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4MballocFreeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4MballocFreeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4MballocFreeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_result_start() const { return at<3>().valid(); }
+  int32_t result_start() const { return at<3>().as_int32(); }
+  bool has_result_group() const { return at<4>().valid(); }
+  uint32_t result_group() const { return at<4>().as_uint32(); }
+  bool has_result_len() const { return at<5>().valid(); }
+  int32_t result_len() const { return at<5>().as_int32(); }
+};
+
+class Ext4MballocFreeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4MballocFreeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kResultStartFieldNumber = 3,
+    kResultGroupFieldNumber = 4,
+    kResultLenFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4MballocFreeFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MballocFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MballocFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_ResultStart =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4MballocFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_ResultStart kResultStart{};
+  void set_result_start(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResultStart::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_ResultGroup =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MballocFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_ResultGroup kResultGroup{};
+  void set_result_group(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResultGroup::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_ResultLen =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4MballocFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_ResultLen kResultLen{};
+  void set_result_len(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResultLen::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);
+  }
+};
+
+class Ext4MballocDiscardFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4MballocDiscardFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4MballocDiscardFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4MballocDiscardFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_result_start() const { return at<3>().valid(); }
+  int32_t result_start() const { return at<3>().as_int32(); }
+  bool has_result_group() const { return at<4>().valid(); }
+  uint32_t result_group() const { return at<4>().as_uint32(); }
+  bool has_result_len() const { return at<5>().valid(); }
+  int32_t result_len() const { return at<5>().as_int32(); }
+};
+
+class Ext4MballocDiscardFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4MballocDiscardFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kResultStartFieldNumber = 3,
+    kResultGroupFieldNumber = 4,
+    kResultLenFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4MballocDiscardFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MballocDiscardFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MballocDiscardFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_ResultStart =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4MballocDiscardFtraceEvent>;
+
+  static constexpr FieldMetadata_ResultStart kResultStart{};
+  void set_result_start(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResultStart::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_ResultGroup =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MballocDiscardFtraceEvent>;
+
+  static constexpr FieldMetadata_ResultGroup kResultGroup{};
+  void set_result_group(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResultGroup::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_ResultLen =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4MballocDiscardFtraceEvent>;
+
+  static constexpr FieldMetadata_ResultLen kResultLen{};
+  void set_result_len(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResultLen::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);
+  }
+};
+
+class Ext4MballocAllocFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/20, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4MballocAllocFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4MballocAllocFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4MballocAllocFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_orig_logical() const { return at<3>().valid(); }
+  uint32_t orig_logical() const { return at<3>().as_uint32(); }
+  bool has_orig_start() const { return at<4>().valid(); }
+  int32_t orig_start() const { return at<4>().as_int32(); }
+  bool has_orig_group() const { return at<5>().valid(); }
+  uint32_t orig_group() const { return at<5>().as_uint32(); }
+  bool has_orig_len() const { return at<6>().valid(); }
+  int32_t orig_len() const { return at<6>().as_int32(); }
+  bool has_goal_logical() const { return at<7>().valid(); }
+  uint32_t goal_logical() const { return at<7>().as_uint32(); }
+  bool has_goal_start() const { return at<8>().valid(); }
+  int32_t goal_start() const { return at<8>().as_int32(); }
+  bool has_goal_group() const { return at<9>().valid(); }
+  uint32_t goal_group() const { return at<9>().as_uint32(); }
+  bool has_goal_len() const { return at<10>().valid(); }
+  int32_t goal_len() const { return at<10>().as_int32(); }
+  bool has_result_logical() const { return at<11>().valid(); }
+  uint32_t result_logical() const { return at<11>().as_uint32(); }
+  bool has_result_start() const { return at<12>().valid(); }
+  int32_t result_start() const { return at<12>().as_int32(); }
+  bool has_result_group() const { return at<13>().valid(); }
+  uint32_t result_group() const { return at<13>().as_uint32(); }
+  bool has_result_len() const { return at<14>().valid(); }
+  int32_t result_len() const { return at<14>().as_int32(); }
+  bool has_found() const { return at<15>().valid(); }
+  uint32_t found() const { return at<15>().as_uint32(); }
+  bool has_groups() const { return at<16>().valid(); }
+  uint32_t groups() const { return at<16>().as_uint32(); }
+  bool has_buddy() const { return at<17>().valid(); }
+  uint32_t buddy() const { return at<17>().as_uint32(); }
+  bool has_flags() const { return at<18>().valid(); }
+  uint32_t flags() const { return at<18>().as_uint32(); }
+  bool has_tail() const { return at<19>().valid(); }
+  uint32_t tail() const { return at<19>().as_uint32(); }
+  bool has_cr() const { return at<20>().valid(); }
+  uint32_t cr() const { return at<20>().as_uint32(); }
+};
+
+class Ext4MballocAllocFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4MballocAllocFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kOrigLogicalFieldNumber = 3,
+    kOrigStartFieldNumber = 4,
+    kOrigGroupFieldNumber = 5,
+    kOrigLenFieldNumber = 6,
+    kGoalLogicalFieldNumber = 7,
+    kGoalStartFieldNumber = 8,
+    kGoalGroupFieldNumber = 9,
+    kGoalLenFieldNumber = 10,
+    kResultLogicalFieldNumber = 11,
+    kResultStartFieldNumber = 12,
+    kResultGroupFieldNumber = 13,
+    kResultLenFieldNumber = 14,
+    kFoundFieldNumber = 15,
+    kGroupsFieldNumber = 16,
+    kBuddyFieldNumber = 17,
+    kFlagsFieldNumber = 18,
+    kTailFieldNumber = 19,
+    kCrFieldNumber = 20,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4MballocAllocFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_OrigLogical =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_OrigLogical kOrigLogical{};
+  void set_orig_logical(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OrigLogical::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_OrigStart =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_OrigStart kOrigStart{};
+  void set_orig_start(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OrigStart::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_OrigGroup =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_OrigGroup kOrigGroup{};
+  void set_orig_group(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OrigGroup::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_OrigLen =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_OrigLen kOrigLen{};
+  void set_orig_len(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OrigLen::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_GoalLogical =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_GoalLogical kGoalLogical{};
+  void set_goal_logical(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GoalLogical::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_GoalStart =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_GoalStart kGoalStart{};
+  void set_goal_start(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GoalStart::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_GoalGroup =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_GoalGroup kGoalGroup{};
+  void set_goal_group(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GoalGroup::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_GoalLen =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_GoalLen kGoalLen{};
+  void set_goal_len(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GoalLen::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_ResultLogical =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_ResultLogical kResultLogical{};
+  void set_result_logical(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResultLogical::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_ResultStart =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_ResultStart kResultStart{};
+  void set_result_start(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResultStart::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_ResultGroup =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_ResultGroup kResultGroup{};
+  void set_result_group(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResultGroup::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_ResultLen =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_ResultLen kResultLen{};
+  void set_result_len(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResultLen::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_Found =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Found kFound{};
+  void set_found(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Found::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_Groups =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Groups kGroups{};
+  void set_groups(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Groups::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_Buddy =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Buddy kBuddy{};
+  void set_buddy(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Buddy::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_Tail =
+    ::protozero::proto_utils::FieldMetadata<
+      19,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Tail kTail{};
+  void set_tail(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tail::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_Cr =
+    ::protozero::proto_utils::FieldMetadata<
+      20,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Cr kCr{};
+  void set_cr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cr::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 Ext4MbReleaseInodePaFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4MbReleaseInodePaFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4MbReleaseInodePaFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4MbReleaseInodePaFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_block() const { return at<3>().valid(); }
+  uint64_t block() const { return at<3>().as_uint64(); }
+  bool has_count() const { return at<4>().valid(); }
+  uint32_t count() const { return at<4>().as_uint32(); }
+};
+
+class Ext4MbReleaseInodePaFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4MbReleaseInodePaFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kBlockFieldNumber = 3,
+    kCountFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4MbReleaseInodePaFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbReleaseInodePaFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbReleaseInodePaFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Block =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbReleaseInodePaFtraceEvent>;
+
+  static constexpr FieldMetadata_Block kBlock{};
+  void set_block(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Block::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_Count =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MbReleaseInodePaFtraceEvent>;
+
+  static constexpr FieldMetadata_Count kCount{};
+  void set_count(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Count::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 Ext4MbReleaseGroupPaFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4MbReleaseGroupPaFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4MbReleaseGroupPaFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4MbReleaseGroupPaFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_pa_pstart() const { return at<2>().valid(); }
+  uint64_t pa_pstart() const { return at<2>().as_uint64(); }
+  bool has_pa_len() const { return at<3>().valid(); }
+  uint32_t pa_len() const { return at<3>().as_uint32(); }
+};
+
+class Ext4MbReleaseGroupPaFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4MbReleaseGroupPaFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kPaPstartFieldNumber = 2,
+    kPaLenFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4MbReleaseGroupPaFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbReleaseGroupPaFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_PaPstart =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbReleaseGroupPaFtraceEvent>;
+
+  static constexpr FieldMetadata_PaPstart kPaPstart{};
+  void set_pa_pstart(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PaPstart::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_PaLen =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MbReleaseGroupPaFtraceEvent>;
+
+  static constexpr FieldMetadata_PaLen kPaLen{};
+  void set_pa_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PaLen::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 Ext4MbNewInodePaFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4MbNewInodePaFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4MbNewInodePaFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4MbNewInodePaFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pa_pstart() const { return at<3>().valid(); }
+  uint64_t pa_pstart() const { return at<3>().as_uint64(); }
+  bool has_pa_lstart() const { return at<4>().valid(); }
+  uint64_t pa_lstart() const { return at<4>().as_uint64(); }
+  bool has_pa_len() const { return at<5>().valid(); }
+  uint32_t pa_len() const { return at<5>().as_uint32(); }
+};
+
+class Ext4MbNewInodePaFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4MbNewInodePaFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPaPstartFieldNumber = 3,
+    kPaLstartFieldNumber = 4,
+    kPaLenFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4MbNewInodePaFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbNewInodePaFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbNewInodePaFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_PaPstart =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbNewInodePaFtraceEvent>;
+
+  static constexpr FieldMetadata_PaPstart kPaPstart{};
+  void set_pa_pstart(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PaPstart::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_PaLstart =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbNewInodePaFtraceEvent>;
+
+  static constexpr FieldMetadata_PaLstart kPaLstart{};
+  void set_pa_lstart(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PaLstart::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_PaLen =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MbNewInodePaFtraceEvent>;
+
+  static constexpr FieldMetadata_PaLen kPaLen{};
+  void set_pa_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PaLen::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 Ext4MbNewGroupPaFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4MbNewGroupPaFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4MbNewGroupPaFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4MbNewGroupPaFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pa_pstart() const { return at<3>().valid(); }
+  uint64_t pa_pstart() const { return at<3>().as_uint64(); }
+  bool has_pa_lstart() const { return at<4>().valid(); }
+  uint64_t pa_lstart() const { return at<4>().as_uint64(); }
+  bool has_pa_len() const { return at<5>().valid(); }
+  uint32_t pa_len() const { return at<5>().as_uint32(); }
+};
+
+class Ext4MbNewGroupPaFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4MbNewGroupPaFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPaPstartFieldNumber = 3,
+    kPaLstartFieldNumber = 4,
+    kPaLenFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4MbNewGroupPaFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbNewGroupPaFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbNewGroupPaFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_PaPstart =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbNewGroupPaFtraceEvent>;
+
+  static constexpr FieldMetadata_PaPstart kPaPstart{};
+  void set_pa_pstart(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PaPstart::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_PaLstart =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbNewGroupPaFtraceEvent>;
+
+  static constexpr FieldMetadata_PaLstart kPaLstart{};
+  void set_pa_lstart(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PaLstart::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_PaLen =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MbNewGroupPaFtraceEvent>;
+
+  static constexpr FieldMetadata_PaLen kPaLen{};
+  void set_pa_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PaLen::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 Ext4MbDiscardPreallocationsFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4MbDiscardPreallocationsFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4MbDiscardPreallocationsFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4MbDiscardPreallocationsFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_needed() const { return at<2>().valid(); }
+  int32_t needed() const { return at<2>().as_int32(); }
+};
+
+class Ext4MbDiscardPreallocationsFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4MbDiscardPreallocationsFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kNeededFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4MbDiscardPreallocationsFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbDiscardPreallocationsFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Needed =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4MbDiscardPreallocationsFtraceEvent>;
+
+  static constexpr FieldMetadata_Needed kNeeded{};
+  void set_needed(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Needed::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);
+  }
+};
+
+class Ext4MbBuddyBitmapLoadFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4MbBuddyBitmapLoadFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4MbBuddyBitmapLoadFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4MbBuddyBitmapLoadFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_group() const { return at<2>().valid(); }
+  uint32_t group() const { return at<2>().as_uint32(); }
+};
+
+class Ext4MbBuddyBitmapLoadFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4MbBuddyBitmapLoadFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kGroupFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4MbBuddyBitmapLoadFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbBuddyBitmapLoadFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Group =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MbBuddyBitmapLoadFtraceEvent>;
+
+  static constexpr FieldMetadata_Group kGroup{};
+  void set_group(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Group::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 Ext4MbBitmapLoadFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4MbBitmapLoadFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4MbBitmapLoadFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4MbBitmapLoadFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_group() const { return at<2>().valid(); }
+  uint32_t group() const { return at<2>().as_uint32(); }
+};
+
+class Ext4MbBitmapLoadFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4MbBitmapLoadFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kGroupFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4MbBitmapLoadFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbBitmapLoadFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Group =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MbBitmapLoadFtraceEvent>;
+
+  static constexpr FieldMetadata_Group kGroup{};
+  void set_group(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Group::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 Ext4MarkInodeDirtyFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4MarkInodeDirtyFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4MarkInodeDirtyFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4MarkInodeDirtyFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_ip() const { return at<3>().valid(); }
+  uint64_t ip() const { return at<3>().as_uint64(); }
+};
+
+class Ext4MarkInodeDirtyFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4MarkInodeDirtyFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kIpFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4MarkInodeDirtyFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MarkInodeDirtyFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MarkInodeDirtyFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Ip =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MarkInodeDirtyFtraceEvent>;
+
+  static constexpr FieldMetadata_Ip kIp{};
+  void set_ip(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ip::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 Ext4LoadInodeBitmapFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4LoadInodeBitmapFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4LoadInodeBitmapFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4LoadInodeBitmapFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_group() const { return at<2>().valid(); }
+  uint32_t group() const { return at<2>().as_uint32(); }
+};
+
+class Ext4LoadInodeBitmapFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4LoadInodeBitmapFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kGroupFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4LoadInodeBitmapFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4LoadInodeBitmapFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Group =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4LoadInodeBitmapFtraceEvent>;
+
+  static constexpr FieldMetadata_Group kGroup{};
+  void set_group(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Group::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 Ext4LoadInodeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4LoadInodeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4LoadInodeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4LoadInodeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+};
+
+class Ext4LoadInodeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4LoadInodeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4LoadInodeFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4LoadInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4LoadInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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 Ext4JournalledWriteEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4JournalledWriteEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4JournalledWriteEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4JournalledWriteEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pos() const { return at<3>().valid(); }
+  int64_t pos() const { return at<3>().as_int64(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint32_t len() const { return at<4>().as_uint32(); }
+  bool has_copied() const { return at<5>().valid(); }
+  uint32_t copied() const { return at<5>().as_uint32(); }
+};
+
+class Ext4JournalledWriteEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4JournalledWriteEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPosFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kCopiedFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4JournalledWriteEndFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4JournalledWriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4JournalledWriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Pos =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4JournalledWriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Pos kPos{};
+  void set_pos(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pos::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4JournalledWriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Copied =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4JournalledWriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Copied kCopied{};
+  void set_copied(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Copied::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 Ext4JournalledInvalidatepageFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4JournalledInvalidatepageFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4JournalledInvalidatepageFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4JournalledInvalidatepageFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_index() const { return at<3>().valid(); }
+  uint64_t index() const { return at<3>().as_uint64(); }
+  bool has_offset() const { return at<4>().valid(); }
+  uint64_t offset() const { return at<4>().as_uint64(); }
+  bool has_length() const { return at<5>().valid(); }
+  uint32_t length() const { return at<5>().as_uint32(); }
+};
+
+class Ext4JournalledInvalidatepageFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4JournalledInvalidatepageFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kIndexFieldNumber = 3,
+    kOffsetFieldNumber = 4,
+    kLengthFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4JournalledInvalidatepageFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4JournalledInvalidatepageFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4JournalledInvalidatepageFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4JournalledInvalidatepageFtraceEvent>;
+
+  static constexpr FieldMetadata_Index kIndex{};
+  void set_index(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Index::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_Offset =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4JournalledInvalidatepageFtraceEvent>;
+
+  static constexpr FieldMetadata_Offset kOffset{};
+  void set_offset(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Offset::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_Length =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4JournalledInvalidatepageFtraceEvent>;
+
+  static constexpr FieldMetadata_Length kLength{};
+  void set_length(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Length::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 Ext4JournalStartReservedFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4JournalStartReservedFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4JournalStartReservedFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4JournalStartReservedFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ip() const { return at<2>().valid(); }
+  uint64_t ip() const { return at<2>().as_uint64(); }
+  bool has_blocks() const { return at<3>().valid(); }
+  int32_t blocks() const { return at<3>().as_int32(); }
+};
+
+class Ext4JournalStartReservedFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4JournalStartReservedFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kIpFieldNumber = 2,
+    kBlocksFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4JournalStartReservedFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4JournalStartReservedFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ip =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4JournalStartReservedFtraceEvent>;
+
+  static constexpr FieldMetadata_Ip kIp{};
+  void set_ip(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ip::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_Blocks =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4JournalStartReservedFtraceEvent>;
+
+  static constexpr FieldMetadata_Blocks kBlocks{};
+  void set_blocks(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Blocks::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);
+  }
+};
+
+class Ext4JournalStartFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4JournalStartFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4JournalStartFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4JournalStartFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ip() const { return at<2>().valid(); }
+  uint64_t ip() const { return at<2>().as_uint64(); }
+  bool has_blocks() const { return at<3>().valid(); }
+  int32_t blocks() const { return at<3>().as_int32(); }
+  bool has_rsv_blocks() const { return at<4>().valid(); }
+  int32_t rsv_blocks() const { return at<4>().as_int32(); }
+  bool has_nblocks() const { return at<5>().valid(); }
+  int32_t nblocks() const { return at<5>().as_int32(); }
+  bool has_revoke_creds() const { return at<6>().valid(); }
+  int32_t revoke_creds() const { return at<6>().as_int32(); }
+};
+
+class Ext4JournalStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4JournalStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kIpFieldNumber = 2,
+    kBlocksFieldNumber = 3,
+    kRsvBlocksFieldNumber = 4,
+    kNblocksFieldNumber = 5,
+    kRevokeCredsFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4JournalStartFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4JournalStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ip =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4JournalStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Ip kIp{};
+  void set_ip(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ip::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_Blocks =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4JournalStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Blocks kBlocks{};
+  void set_blocks(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Blocks::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_RsvBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4JournalStartFtraceEvent>;
+
+  static constexpr FieldMetadata_RsvBlocks kRsvBlocks{};
+  void set_rsv_blocks(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RsvBlocks::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_Nblocks =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4JournalStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Nblocks kNblocks{};
+  void set_nblocks(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nblocks::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_RevokeCreds =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4JournalStartFtraceEvent>;
+
+  static constexpr FieldMetadata_RevokeCreds kRevokeCreds{};
+  void set_revoke_creds(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RevokeCreds::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);
+  }
+};
+
+class Ext4InvalidatepageFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4InvalidatepageFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4InvalidatepageFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4InvalidatepageFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_index() const { return at<3>().valid(); }
+  uint64_t index() const { return at<3>().as_uint64(); }
+  bool has_offset() const { return at<4>().valid(); }
+  uint64_t offset() const { return at<4>().as_uint64(); }
+  bool has_length() const { return at<5>().valid(); }
+  uint32_t length() const { return at<5>().as_uint32(); }
+};
+
+class Ext4InvalidatepageFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4InvalidatepageFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kIndexFieldNumber = 3,
+    kOffsetFieldNumber = 4,
+    kLengthFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4InvalidatepageFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4InvalidatepageFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4InvalidatepageFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4InvalidatepageFtraceEvent>;
+
+  static constexpr FieldMetadata_Index kIndex{};
+  void set_index(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Index::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_Offset =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4InvalidatepageFtraceEvent>;
+
+  static constexpr FieldMetadata_Offset kOffset{};
+  void set_offset(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Offset::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_Length =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4InvalidatepageFtraceEvent>;
+
+  static constexpr FieldMetadata_Length kLength{};
+  void set_length(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Length::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 Ext4InsertRangeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4InsertRangeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4InsertRangeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4InsertRangeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_offset() const { return at<3>().valid(); }
+  int64_t offset() const { return at<3>().as_int64(); }
+  bool has_len() const { return at<4>().valid(); }
+  int64_t len() const { return at<4>().as_int64(); }
+};
+
+class Ext4InsertRangeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4InsertRangeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kOffsetFieldNumber = 3,
+    kLenFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4InsertRangeFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4InsertRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4InsertRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Offset =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4InsertRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Offset kOffset{};
+  void set_offset(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Offset::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4InsertRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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 Ext4IndMapBlocksExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4IndMapBlocksExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4IndMapBlocksExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4IndMapBlocksExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_flags() const { return at<3>().valid(); }
+  uint32_t flags() const { return at<3>().as_uint32(); }
+  bool has_pblk() const { return at<4>().valid(); }
+  uint64_t pblk() const { return at<4>().as_uint64(); }
+  bool has_lblk() const { return at<5>().valid(); }
+  uint32_t lblk() const { return at<5>().as_uint32(); }
+  bool has_len() const { return at<6>().valid(); }
+  uint32_t len() const { return at<6>().as_uint32(); }
+  bool has_mflags() const { return at<7>().valid(); }
+  uint32_t mflags() const { return at<7>().as_uint32(); }
+  bool has_ret() const { return at<8>().valid(); }
+  int32_t ret() const { return at<8>().as_int32(); }
+};
+
+class Ext4IndMapBlocksExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4IndMapBlocksExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kFlagsFieldNumber = 3,
+    kPblkFieldNumber = 4,
+    kLblkFieldNumber = 5,
+    kLenFieldNumber = 6,
+    kMflagsFieldNumber = 7,
+    kRetFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4IndMapBlocksExitFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4IndMapBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4IndMapBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4IndMapBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_Pblk =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4IndMapBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Pblk kPblk{};
+  void set_pblk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pblk::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_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4IndMapBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4IndMapBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Mflags =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4IndMapBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Mflags kMflags{};
+  void set_mflags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mflags::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_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4IndMapBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::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);
+  }
+};
+
+class Ext4IndMapBlocksEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4IndMapBlocksEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4IndMapBlocksEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4IndMapBlocksEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_lblk() const { return at<3>().valid(); }
+  uint32_t lblk() const { return at<3>().as_uint32(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint32_t len() const { return at<4>().as_uint32(); }
+  bool has_flags() const { return at<5>().valid(); }
+  uint32_t flags() const { return at<5>().as_uint32(); }
+};
+
+class Ext4IndMapBlocksEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4IndMapBlocksEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kLblkFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kFlagsFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4IndMapBlocksEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4IndMapBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4IndMapBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4IndMapBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4IndMapBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4IndMapBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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 Ext4GetReservedClusterAllocFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4GetReservedClusterAllocFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4GetReservedClusterAllocFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4GetReservedClusterAllocFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_lblk() const { return at<3>().valid(); }
+  uint32_t lblk() const { return at<3>().as_uint32(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint32_t len() const { return at<4>().as_uint32(); }
+};
+
+class Ext4GetReservedClusterAllocFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4GetReservedClusterAllocFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kLblkFieldNumber = 3,
+    kLenFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4GetReservedClusterAllocFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4GetReservedClusterAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4GetReservedClusterAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4GetReservedClusterAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4GetReservedClusterAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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 Ext4GetImpliedClusterAllocExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4GetImpliedClusterAllocExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4GetImpliedClusterAllocExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4GetImpliedClusterAllocExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_flags() const { return at<2>().valid(); }
+  uint32_t flags() const { return at<2>().as_uint32(); }
+  bool has_lblk() const { return at<3>().valid(); }
+  uint32_t lblk() const { return at<3>().as_uint32(); }
+  bool has_pblk() const { return at<4>().valid(); }
+  uint64_t pblk() const { return at<4>().as_uint64(); }
+  bool has_len() const { return at<5>().valid(); }
+  uint32_t len() const { return at<5>().as_uint32(); }
+  bool has_ret() const { return at<6>().valid(); }
+  int32_t ret() const { return at<6>().as_int32(); }
+};
+
+class Ext4GetImpliedClusterAllocExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4GetImpliedClusterAllocExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kFlagsFieldNumber = 2,
+    kLblkFieldNumber = 3,
+    kPblkFieldNumber = 4,
+    kLenFieldNumber = 5,
+    kRetFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4GetImpliedClusterAllocExitFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4GetImpliedClusterAllocExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4GetImpliedClusterAllocExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4GetImpliedClusterAllocExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::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_Pblk =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4GetImpliedClusterAllocExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Pblk kPblk{};
+  void set_pblk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pblk::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4GetImpliedClusterAllocExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4GetImpliedClusterAllocExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::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);
+  }
+};
+
+class Ext4FreeInodeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4FreeInodeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4FreeInodeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4FreeInodeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_uid() const { return at<3>().valid(); }
+  uint32_t uid() const { return at<3>().as_uint32(); }
+  bool has_gid() const { return at<4>().valid(); }
+  uint32_t gid() const { return at<4>().as_uint32(); }
+  bool has_blocks() const { return at<5>().valid(); }
+  uint64_t blocks() const { return at<5>().as_uint64(); }
+  bool has_mode() const { return at<6>().valid(); }
+  uint32_t mode() const { return at<6>().as_uint32(); }
+};
+
+class Ext4FreeInodeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4FreeInodeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kUidFieldNumber = 3,
+    kGidFieldNumber = 4,
+    kBlocksFieldNumber = 5,
+    kModeFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4FreeInodeFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4FreeInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4FreeInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Uid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4FreeInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Uid kUid{};
+  void set_uid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Uid::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_Gid =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4FreeInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Gid kGid{};
+  void set_gid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Gid::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_Blocks =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4FreeInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Blocks kBlocks{};
+  void set_blocks(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Blocks::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_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4FreeInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::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 Ext4FreeBlocksFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4FreeBlocksFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4FreeBlocksFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4FreeBlocksFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_block() const { return at<3>().valid(); }
+  uint64_t block() const { return at<3>().as_uint64(); }
+  bool has_count() const { return at<4>().valid(); }
+  uint64_t count() const { return at<4>().as_uint64(); }
+  bool has_flags() const { return at<5>().valid(); }
+  int32_t flags() const { return at<5>().as_int32(); }
+  bool has_mode() const { return at<6>().valid(); }
+  uint32_t mode() const { return at<6>().as_uint32(); }
+};
+
+class Ext4FreeBlocksFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4FreeBlocksFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kBlockFieldNumber = 3,
+    kCountFieldNumber = 4,
+    kFlagsFieldNumber = 5,
+    kModeFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4FreeBlocksFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4FreeBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4FreeBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Block =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4FreeBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Block kBlock{};
+  void set_block(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Block::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_Count =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4FreeBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Count kCount{};
+  void set_count(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Count::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4FreeBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4FreeBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::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 Ext4ForgetFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4ForgetFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4ForgetFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4ForgetFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_block() const { return at<3>().valid(); }
+  uint64_t block() const { return at<3>().as_uint64(); }
+  bool has_is_metadata() const { return at<4>().valid(); }
+  int32_t is_metadata() const { return at<4>().as_int32(); }
+  bool has_mode() const { return at<5>().valid(); }
+  uint32_t mode() const { return at<5>().as_uint32(); }
+};
+
+class Ext4ForgetFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4ForgetFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kBlockFieldNumber = 3,
+    kIsMetadataFieldNumber = 4,
+    kModeFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4ForgetFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ForgetFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ForgetFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Block =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ForgetFtraceEvent>;
+
+  static constexpr FieldMetadata_Block kBlock{};
+  void set_block(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Block::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_IsMetadata =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4ForgetFtraceEvent>;
+
+  static constexpr FieldMetadata_IsMetadata kIsMetadata{};
+  void set_is_metadata(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsMetadata::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_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ForgetFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::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 Ext4FindDelallocRangeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4FindDelallocRangeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4FindDelallocRangeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4FindDelallocRangeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_from() const { return at<3>().valid(); }
+  uint32_t from() const { return at<3>().as_uint32(); }
+  bool has_to() const { return at<4>().valid(); }
+  uint32_t to() const { return at<4>().as_uint32(); }
+  bool has_reverse() const { return at<5>().valid(); }
+  int32_t reverse() const { return at<5>().as_int32(); }
+  bool has_found() const { return at<6>().valid(); }
+  int32_t found() const { return at<6>().as_int32(); }
+  bool has_found_blk() const { return at<7>().valid(); }
+  uint32_t found_blk() const { return at<7>().as_uint32(); }
+};
+
+class Ext4FindDelallocRangeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4FindDelallocRangeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kFromFieldNumber = 3,
+    kToFieldNumber = 4,
+    kReverseFieldNumber = 5,
+    kFoundFieldNumber = 6,
+    kFoundBlkFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4FindDelallocRangeFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4FindDelallocRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4FindDelallocRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_From =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4FindDelallocRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_From kFrom{};
+  void set_from(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_From::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_To =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4FindDelallocRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_To kTo{};
+  void set_to(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_To::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_Reverse =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4FindDelallocRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Reverse kReverse{};
+  void set_reverse(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Reverse::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_Found =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4FindDelallocRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Found kFound{};
+  void set_found(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Found::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_FoundBlk =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4FindDelallocRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_FoundBlk kFoundBlk{};
+  void set_found_blk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FoundBlk::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 Ext4FallocateExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4FallocateExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4FallocateExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4FallocateExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pos() const { return at<3>().valid(); }
+  int64_t pos() const { return at<3>().as_int64(); }
+  bool has_blocks() const { return at<4>().valid(); }
+  uint32_t blocks() const { return at<4>().as_uint32(); }
+  bool has_ret() const { return at<5>().valid(); }
+  int32_t ret() const { return at<5>().as_int32(); }
+};
+
+class Ext4FallocateExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4FallocateExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPosFieldNumber = 3,
+    kBlocksFieldNumber = 4,
+    kRetFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4FallocateExitFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4FallocateExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4FallocateExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Pos =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4FallocateExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Pos kPos{};
+  void set_pos(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pos::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_Blocks =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4FallocateExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Blocks kBlocks{};
+  void set_blocks(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Blocks::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_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4FallocateExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::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);
+  }
+};
+
+class Ext4FallocateEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4FallocateEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4FallocateEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4FallocateEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_offset() const { return at<3>().valid(); }
+  int64_t offset() const { return at<3>().as_int64(); }
+  bool has_len() const { return at<4>().valid(); }
+  int64_t len() const { return at<4>().as_int64(); }
+  bool has_mode() const { return at<5>().valid(); }
+  int32_t mode() const { return at<5>().as_int32(); }
+  bool has_pos() const { return at<6>().valid(); }
+  int64_t pos() const { return at<6>().as_int64(); }
+};
+
+class Ext4FallocateEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4FallocateEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kOffsetFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kModeFieldNumber = 5,
+    kPosFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4FallocateEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4FallocateEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4FallocateEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Offset =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4FallocateEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Offset kOffset{};
+  void set_offset(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Offset::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4FallocateEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4FallocateEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::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_Pos =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4FallocateEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Pos kPos{};
+  void set_pos(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pos::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 Ext4ExtShowExtentFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4ExtShowExtentFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4ExtShowExtentFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4ExtShowExtentFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pblk() const { return at<3>().valid(); }
+  uint64_t pblk() const { return at<3>().as_uint64(); }
+  bool has_lblk() const { return at<4>().valid(); }
+  uint32_t lblk() const { return at<4>().as_uint32(); }
+  bool has_len() const { return at<5>().valid(); }
+  uint32_t len() const { return at<5>().as_uint32(); }
+};
+
+class Ext4ExtShowExtentFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4ExtShowExtentFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPblkFieldNumber = 3,
+    kLblkFieldNumber = 4,
+    kLenFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4ExtShowExtentFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtShowExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtShowExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Pblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtShowExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Pblk kPblk{};
+  void set_pblk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pblk::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_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtShowExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtShowExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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 Ext4ExtRmLeafFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/10, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4ExtRmLeafFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4ExtRmLeafFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4ExtRmLeafFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_partial() const { return at<3>().valid(); }
+  int64_t partial() const { return at<3>().as_int64(); }
+  bool has_start() const { return at<4>().valid(); }
+  uint32_t start() const { return at<4>().as_uint32(); }
+  bool has_ee_lblk() const { return at<5>().valid(); }
+  uint32_t ee_lblk() const { return at<5>().as_uint32(); }
+  bool has_ee_pblk() const { return at<6>().valid(); }
+  uint64_t ee_pblk() const { return at<6>().as_uint64(); }
+  bool has_ee_len() const { return at<7>().valid(); }
+  int32_t ee_len() const { return at<7>().as_int32(); }
+  bool has_pc_lblk() const { return at<8>().valid(); }
+  uint32_t pc_lblk() const { return at<8>().as_uint32(); }
+  bool has_pc_pclu() const { return at<9>().valid(); }
+  uint64_t pc_pclu() const { return at<9>().as_uint64(); }
+  bool has_pc_state() const { return at<10>().valid(); }
+  int32_t pc_state() const { return at<10>().as_int32(); }
+};
+
+class Ext4ExtRmLeafFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4ExtRmLeafFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPartialFieldNumber = 3,
+    kStartFieldNumber = 4,
+    kEeLblkFieldNumber = 5,
+    kEePblkFieldNumber = 6,
+    kEeLenFieldNumber = 7,
+    kPcLblkFieldNumber = 8,
+    kPcPcluFieldNumber = 9,
+    kPcStateFieldNumber = 10,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4ExtRmLeafFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtRmLeafFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtRmLeafFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Partial =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4ExtRmLeafFtraceEvent>;
+
+  static constexpr FieldMetadata_Partial kPartial{};
+  void set_partial(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Partial::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_Start =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtRmLeafFtraceEvent>;
+
+  static constexpr FieldMetadata_Start kStart{};
+  void set_start(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Start::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_EeLblk =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtRmLeafFtraceEvent>;
+
+  static constexpr FieldMetadata_EeLblk kEeLblk{};
+  void set_ee_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EeLblk::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_EePblk =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtRmLeafFtraceEvent>;
+
+  static constexpr FieldMetadata_EePblk kEePblk{};
+  void set_ee_pblk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EePblk::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_EeLen =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4ExtRmLeafFtraceEvent>;
+
+  static constexpr FieldMetadata_EeLen kEeLen{};
+  void set_ee_len(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EeLen::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_PcLblk =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtRmLeafFtraceEvent>;
+
+  static constexpr FieldMetadata_PcLblk kPcLblk{};
+  void set_pc_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PcLblk::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_PcPclu =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtRmLeafFtraceEvent>;
+
+  static constexpr FieldMetadata_PcPclu kPcPclu{};
+  void set_pc_pclu(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PcPclu::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_PcState =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4ExtRmLeafFtraceEvent>;
+
+  static constexpr FieldMetadata_PcState kPcState{};
+  void set_pc_state(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PcState::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);
+  }
+};
+
+class Ext4ExtRmIdxFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4ExtRmIdxFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4ExtRmIdxFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4ExtRmIdxFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pblk() const { return at<3>().valid(); }
+  uint64_t pblk() const { return at<3>().as_uint64(); }
+};
+
+class Ext4ExtRmIdxFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4ExtRmIdxFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPblkFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4ExtRmIdxFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtRmIdxFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtRmIdxFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Pblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtRmIdxFtraceEvent>;
+
+  static constexpr FieldMetadata_Pblk kPblk{};
+  void set_pblk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pblk::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 Ext4ExtRemoveSpaceDoneFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/10, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4ExtRemoveSpaceDoneFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4ExtRemoveSpaceDoneFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4ExtRemoveSpaceDoneFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_start() const { return at<3>().valid(); }
+  uint32_t start() const { return at<3>().as_uint32(); }
+  bool has_end() const { return at<4>().valid(); }
+  uint32_t end() const { return at<4>().as_uint32(); }
+  bool has_depth() const { return at<5>().valid(); }
+  int32_t depth() const { return at<5>().as_int32(); }
+  bool has_partial() const { return at<6>().valid(); }
+  int64_t partial() const { return at<6>().as_int64(); }
+  bool has_eh_entries() const { return at<7>().valid(); }
+  uint32_t eh_entries() const { return at<7>().as_uint32(); }
+  bool has_pc_lblk() const { return at<8>().valid(); }
+  uint32_t pc_lblk() const { return at<8>().as_uint32(); }
+  bool has_pc_pclu() const { return at<9>().valid(); }
+  uint64_t pc_pclu() const { return at<9>().as_uint64(); }
+  bool has_pc_state() const { return at<10>().valid(); }
+  int32_t pc_state() const { return at<10>().as_int32(); }
+};
+
+class Ext4ExtRemoveSpaceDoneFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4ExtRemoveSpaceDoneFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kStartFieldNumber = 3,
+    kEndFieldNumber = 4,
+    kDepthFieldNumber = 5,
+    kPartialFieldNumber = 6,
+    kEhEntriesFieldNumber = 7,
+    kPcLblkFieldNumber = 8,
+    kPcPcluFieldNumber = 9,
+    kPcStateFieldNumber = 10,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4ExtRemoveSpaceDoneFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtRemoveSpaceDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtRemoveSpaceDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Start =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtRemoveSpaceDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Start kStart{};
+  void set_start(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Start::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_End =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtRemoveSpaceDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_End kEnd{};
+  void set_end(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_End::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_Depth =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4ExtRemoveSpaceDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Depth kDepth{};
+  void set_depth(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Depth::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_Partial =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4ExtRemoveSpaceDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Partial kPartial{};
+  void set_partial(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Partial::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_EhEntries =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtRemoveSpaceDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_EhEntries kEhEntries{};
+  void set_eh_entries(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EhEntries::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_PcLblk =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtRemoveSpaceDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_PcLblk kPcLblk{};
+  void set_pc_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PcLblk::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_PcPclu =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtRemoveSpaceDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_PcPclu kPcPclu{};
+  void set_pc_pclu(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PcPclu::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_PcState =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4ExtRemoveSpaceDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_PcState kPcState{};
+  void set_pc_state(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PcState::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);
+  }
+};
+
+class Ext4ExtRemoveSpaceFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4ExtRemoveSpaceFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4ExtRemoveSpaceFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4ExtRemoveSpaceFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_start() const { return at<3>().valid(); }
+  uint32_t start() const { return at<3>().as_uint32(); }
+  bool has_end() const { return at<4>().valid(); }
+  uint32_t end() const { return at<4>().as_uint32(); }
+  bool has_depth() const { return at<5>().valid(); }
+  int32_t depth() const { return at<5>().as_int32(); }
+};
+
+class Ext4ExtRemoveSpaceFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4ExtRemoveSpaceFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kStartFieldNumber = 3,
+    kEndFieldNumber = 4,
+    kDepthFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4ExtRemoveSpaceFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtRemoveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtRemoveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Start =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtRemoveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_Start kStart{};
+  void set_start(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Start::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_End =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtRemoveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_End kEnd{};
+  void set_end(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_End::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_Depth =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4ExtRemoveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_Depth kDepth{};
+  void set_depth(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Depth::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);
+  }
+};
+
+class Ext4ExtPutInCacheFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4ExtPutInCacheFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4ExtPutInCacheFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4ExtPutInCacheFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_lblk() const { return at<3>().valid(); }
+  uint32_t lblk() const { return at<3>().as_uint32(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint32_t len() const { return at<4>().as_uint32(); }
+  bool has_start() const { return at<5>().valid(); }
+  uint64_t start() const { return at<5>().as_uint64(); }
+};
+
+class Ext4ExtPutInCacheFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4ExtPutInCacheFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kLblkFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kStartFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4ExtPutInCacheFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtPutInCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtPutInCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtPutInCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtPutInCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Start =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtPutInCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_Start kStart{};
+  void set_start(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Start::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 Ext4ExtMapBlocksExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4ExtMapBlocksExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4ExtMapBlocksExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4ExtMapBlocksExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_flags() const { return at<3>().valid(); }
+  uint32_t flags() const { return at<3>().as_uint32(); }
+  bool has_pblk() const { return at<4>().valid(); }
+  uint64_t pblk() const { return at<4>().as_uint64(); }
+  bool has_lblk() const { return at<5>().valid(); }
+  uint32_t lblk() const { return at<5>().as_uint32(); }
+  bool has_len() const { return at<6>().valid(); }
+  uint32_t len() const { return at<6>().as_uint32(); }
+  bool has_mflags() const { return at<7>().valid(); }
+  uint32_t mflags() const { return at<7>().as_uint32(); }
+  bool has_ret() const { return at<8>().valid(); }
+  int32_t ret() const { return at<8>().as_int32(); }
+};
+
+class Ext4ExtMapBlocksExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4ExtMapBlocksExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kFlagsFieldNumber = 3,
+    kPblkFieldNumber = 4,
+    kLblkFieldNumber = 5,
+    kLenFieldNumber = 6,
+    kMflagsFieldNumber = 7,
+    kRetFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4ExtMapBlocksExitFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtMapBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtMapBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtMapBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_Pblk =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtMapBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Pblk kPblk{};
+  void set_pblk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pblk::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_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtMapBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtMapBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Mflags =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtMapBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Mflags kMflags{};
+  void set_mflags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mflags::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_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4ExtMapBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::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);
+  }
+};
+
+class Ext4ExtMapBlocksEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4ExtMapBlocksEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4ExtMapBlocksEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4ExtMapBlocksEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_lblk() const { return at<3>().valid(); }
+  uint32_t lblk() const { return at<3>().as_uint32(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint32_t len() const { return at<4>().as_uint32(); }
+  bool has_flags() const { return at<5>().valid(); }
+  uint32_t flags() const { return at<5>().as_uint32(); }
+};
+
+class Ext4ExtMapBlocksEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4ExtMapBlocksEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kLblkFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kFlagsFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4ExtMapBlocksEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtMapBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtMapBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtMapBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtMapBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtMapBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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 Ext4ExtLoadExtentFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4ExtLoadExtentFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4ExtLoadExtentFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4ExtLoadExtentFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pblk() const { return at<3>().valid(); }
+  uint64_t pblk() const { return at<3>().as_uint64(); }
+  bool has_lblk() const { return at<4>().valid(); }
+  uint32_t lblk() const { return at<4>().as_uint32(); }
+};
+
+class Ext4ExtLoadExtentFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4ExtLoadExtentFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPblkFieldNumber = 3,
+    kLblkFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4ExtLoadExtentFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtLoadExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtLoadExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Pblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtLoadExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Pblk kPblk{};
+  void set_pblk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pblk::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_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtLoadExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::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 Ext4ExtInCacheFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4ExtInCacheFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4ExtInCacheFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4ExtInCacheFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_lblk() const { return at<3>().valid(); }
+  uint32_t lblk() const { return at<3>().as_uint32(); }
+  bool has_ret() const { return at<4>().valid(); }
+  int32_t ret() const { return at<4>().as_int32(); }
+};
+
+class Ext4ExtInCacheFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4ExtInCacheFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kLblkFieldNumber = 3,
+    kRetFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4ExtInCacheFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtInCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtInCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtInCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::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_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4ExtInCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::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);
+  }
+};
+
+class Ext4ExtHandleUnwrittenExtentsFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4ExtHandleUnwrittenExtentsFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4ExtHandleUnwrittenExtentsFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4ExtHandleUnwrittenExtentsFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_flags() const { return at<3>().valid(); }
+  int32_t flags() const { return at<3>().as_int32(); }
+  bool has_lblk() const { return at<4>().valid(); }
+  uint32_t lblk() const { return at<4>().as_uint32(); }
+  bool has_pblk() const { return at<5>().valid(); }
+  uint64_t pblk() const { return at<5>().as_uint64(); }
+  bool has_len() const { return at<6>().valid(); }
+  uint32_t len() const { return at<6>().as_uint32(); }
+  bool has_allocated() const { return at<7>().valid(); }
+  uint32_t allocated() const { return at<7>().as_uint32(); }
+  bool has_newblk() const { return at<8>().valid(); }
+  uint64_t newblk() const { return at<8>().as_uint64(); }
+};
+
+class Ext4ExtHandleUnwrittenExtentsFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4ExtHandleUnwrittenExtentsFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kFlagsFieldNumber = 3,
+    kLblkFieldNumber = 4,
+    kPblkFieldNumber = 5,
+    kLenFieldNumber = 6,
+    kAllocatedFieldNumber = 7,
+    kNewblkFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4ExtHandleUnwrittenExtentsFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtHandleUnwrittenExtentsFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtHandleUnwrittenExtentsFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4ExtHandleUnwrittenExtentsFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtHandleUnwrittenExtentsFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::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_Pblk =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtHandleUnwrittenExtentsFtraceEvent>;
+
+  static constexpr FieldMetadata_Pblk kPblk{};
+  void set_pblk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pblk::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtHandleUnwrittenExtentsFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Allocated =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtHandleUnwrittenExtentsFtraceEvent>;
+
+  static constexpr FieldMetadata_Allocated kAllocated{};
+  void set_allocated(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Allocated::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_Newblk =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtHandleUnwrittenExtentsFtraceEvent>;
+
+  static constexpr FieldMetadata_Newblk kNewblk{};
+  void set_newblk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Newblk::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 Ext4ExtConvertToInitializedFastpathFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/10, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4ExtConvertToInitializedFastpathFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4ExtConvertToInitializedFastpathFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4ExtConvertToInitializedFastpathFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_m_lblk() const { return at<3>().valid(); }
+  uint32_t m_lblk() const { return at<3>().as_uint32(); }
+  bool has_m_len() const { return at<4>().valid(); }
+  uint32_t m_len() const { return at<4>().as_uint32(); }
+  bool has_u_lblk() const { return at<5>().valid(); }
+  uint32_t u_lblk() const { return at<5>().as_uint32(); }
+  bool has_u_len() const { return at<6>().valid(); }
+  uint32_t u_len() const { return at<6>().as_uint32(); }
+  bool has_u_pblk() const { return at<7>().valid(); }
+  uint64_t u_pblk() const { return at<7>().as_uint64(); }
+  bool has_i_lblk() const { return at<8>().valid(); }
+  uint32_t i_lblk() const { return at<8>().as_uint32(); }
+  bool has_i_len() const { return at<9>().valid(); }
+  uint32_t i_len() const { return at<9>().as_uint32(); }
+  bool has_i_pblk() const { return at<10>().valid(); }
+  uint64_t i_pblk() const { return at<10>().as_uint64(); }
+};
+
+class Ext4ExtConvertToInitializedFastpathFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4ExtConvertToInitializedFastpathFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kMLblkFieldNumber = 3,
+    kMLenFieldNumber = 4,
+    kULblkFieldNumber = 5,
+    kULenFieldNumber = 6,
+    kUPblkFieldNumber = 7,
+    kILblkFieldNumber = 8,
+    kILenFieldNumber = 9,
+    kIPblkFieldNumber = 10,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4ExtConvertToInitializedFastpathFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtConvertToInitializedFastpathFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtConvertToInitializedFastpathFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_MLblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtConvertToInitializedFastpathFtraceEvent>;
+
+  static constexpr FieldMetadata_MLblk kMLblk{};
+  void set_m_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MLblk::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_MLen =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtConvertToInitializedFastpathFtraceEvent>;
+
+  static constexpr FieldMetadata_MLen kMLen{};
+  void set_m_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MLen::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_ULblk =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtConvertToInitializedFastpathFtraceEvent>;
+
+  static constexpr FieldMetadata_ULblk kULblk{};
+  void set_u_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ULblk::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_ULen =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtConvertToInitializedFastpathFtraceEvent>;
+
+  static constexpr FieldMetadata_ULen kULen{};
+  void set_u_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ULen::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_UPblk =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtConvertToInitializedFastpathFtraceEvent>;
+
+  static constexpr FieldMetadata_UPblk kUPblk{};
+  void set_u_pblk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UPblk::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_ILblk =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtConvertToInitializedFastpathFtraceEvent>;
+
+  static constexpr FieldMetadata_ILblk kILblk{};
+  void set_i_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ILblk::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_ILen =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtConvertToInitializedFastpathFtraceEvent>;
+
+  static constexpr FieldMetadata_ILen kILen{};
+  void set_i_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ILen::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_IPblk =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtConvertToInitializedFastpathFtraceEvent>;
+
+  static constexpr FieldMetadata_IPblk kIPblk{};
+  void set_i_pblk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IPblk::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 Ext4ExtConvertToInitializedEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4ExtConvertToInitializedEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4ExtConvertToInitializedEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4ExtConvertToInitializedEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_m_lblk() const { return at<3>().valid(); }
+  uint32_t m_lblk() const { return at<3>().as_uint32(); }
+  bool has_m_len() const { return at<4>().valid(); }
+  uint32_t m_len() const { return at<4>().as_uint32(); }
+  bool has_u_lblk() const { return at<5>().valid(); }
+  uint32_t u_lblk() const { return at<5>().as_uint32(); }
+  bool has_u_len() const { return at<6>().valid(); }
+  uint32_t u_len() const { return at<6>().as_uint32(); }
+  bool has_u_pblk() const { return at<7>().valid(); }
+  uint64_t u_pblk() const { return at<7>().as_uint64(); }
+};
+
+class Ext4ExtConvertToInitializedEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4ExtConvertToInitializedEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kMLblkFieldNumber = 3,
+    kMLenFieldNumber = 4,
+    kULblkFieldNumber = 5,
+    kULenFieldNumber = 6,
+    kUPblkFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4ExtConvertToInitializedEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtConvertToInitializedEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtConvertToInitializedEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_MLblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtConvertToInitializedEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_MLblk kMLblk{};
+  void set_m_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MLblk::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_MLen =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtConvertToInitializedEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_MLen kMLen{};
+  void set_m_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MLen::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_ULblk =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtConvertToInitializedEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_ULblk kULblk{};
+  void set_u_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ULblk::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_ULen =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtConvertToInitializedEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_ULen kULen{};
+  void set_u_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ULen::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_UPblk =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtConvertToInitializedEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_UPblk kUPblk{};
+  void set_u_pblk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UPblk::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 Ext4EvictInodeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4EvictInodeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4EvictInodeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4EvictInodeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_nlink() const { return at<3>().valid(); }
+  int32_t nlink() const { return at<3>().as_int32(); }
+};
+
+class Ext4EvictInodeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4EvictInodeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kNlinkFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4EvictInodeFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EvictInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EvictInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Nlink =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4EvictInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Nlink kNlink{};
+  void set_nlink(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nlink::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);
+  }
+};
+
+class Ext4EsShrinkScanExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4EsShrinkScanExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4EsShrinkScanExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4EsShrinkScanExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_nr_shrunk() const { return at<2>().valid(); }
+  int32_t nr_shrunk() const { return at<2>().as_int32(); }
+  bool has_cache_cnt() const { return at<3>().valid(); }
+  int32_t cache_cnt() const { return at<3>().as_int32(); }
+};
+
+class Ext4EsShrinkScanExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4EsShrinkScanExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kNrShrunkFieldNumber = 2,
+    kCacheCntFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4EsShrinkScanExitFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsShrinkScanExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_NrShrunk =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4EsShrinkScanExitFtraceEvent>;
+
+  static constexpr FieldMetadata_NrShrunk kNrShrunk{};
+  void set_nr_shrunk(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrShrunk::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_CacheCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4EsShrinkScanExitFtraceEvent>;
+
+  static constexpr FieldMetadata_CacheCnt kCacheCnt{};
+  void set_cache_cnt(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CacheCnt::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);
+  }
+};
+
+class Ext4EsShrinkScanEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4EsShrinkScanEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4EsShrinkScanEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4EsShrinkScanEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_nr_to_scan() const { return at<2>().valid(); }
+  int32_t nr_to_scan() const { return at<2>().as_int32(); }
+  bool has_cache_cnt() const { return at<3>().valid(); }
+  int32_t cache_cnt() const { return at<3>().as_int32(); }
+};
+
+class Ext4EsShrinkScanEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4EsShrinkScanEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kNrToScanFieldNumber = 2,
+    kCacheCntFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4EsShrinkScanEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsShrinkScanEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_NrToScan =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4EsShrinkScanEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_NrToScan kNrToScan{};
+  void set_nr_to_scan(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrToScan::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_CacheCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4EsShrinkScanEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_CacheCnt kCacheCnt{};
+  void set_cache_cnt(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CacheCnt::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);
+  }
+};
+
+class Ext4EsShrinkCountFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4EsShrinkCountFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4EsShrinkCountFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4EsShrinkCountFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_nr_to_scan() const { return at<2>().valid(); }
+  int32_t nr_to_scan() const { return at<2>().as_int32(); }
+  bool has_cache_cnt() const { return at<3>().valid(); }
+  int32_t cache_cnt() const { return at<3>().as_int32(); }
+};
+
+class Ext4EsShrinkCountFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4EsShrinkCountFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kNrToScanFieldNumber = 2,
+    kCacheCntFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4EsShrinkCountFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsShrinkCountFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_NrToScan =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4EsShrinkCountFtraceEvent>;
+
+  static constexpr FieldMetadata_NrToScan kNrToScan{};
+  void set_nr_to_scan(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrToScan::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_CacheCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4EsShrinkCountFtraceEvent>;
+
+  static constexpr FieldMetadata_CacheCnt kCacheCnt{};
+  void set_cache_cnt(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CacheCnt::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);
+  }
+};
+
+class Ext4EsShrinkFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4EsShrinkFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4EsShrinkFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4EsShrinkFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_nr_shrunk() const { return at<2>().valid(); }
+  int32_t nr_shrunk() const { return at<2>().as_int32(); }
+  bool has_scan_time() const { return at<3>().valid(); }
+  uint64_t scan_time() const { return at<3>().as_uint64(); }
+  bool has_nr_skipped() const { return at<4>().valid(); }
+  int32_t nr_skipped() const { return at<4>().as_int32(); }
+  bool has_retried() const { return at<5>().valid(); }
+  int32_t retried() const { return at<5>().as_int32(); }
+};
+
+class Ext4EsShrinkFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4EsShrinkFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kNrShrunkFieldNumber = 2,
+    kScanTimeFieldNumber = 3,
+    kNrSkippedFieldNumber = 4,
+    kRetriedFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4EsShrinkFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsShrinkFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_NrShrunk =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4EsShrinkFtraceEvent>;
+
+  static constexpr FieldMetadata_NrShrunk kNrShrunk{};
+  void set_nr_shrunk(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrShrunk::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_ScanTime =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsShrinkFtraceEvent>;
+
+  static constexpr FieldMetadata_ScanTime kScanTime{};
+  void set_scan_time(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ScanTime::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_NrSkipped =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4EsShrinkFtraceEvent>;
+
+  static constexpr FieldMetadata_NrSkipped kNrSkipped{};
+  void set_nr_skipped(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrSkipped::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_Retried =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4EsShrinkFtraceEvent>;
+
+  static constexpr FieldMetadata_Retried kRetried{};
+  void set_retried(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Retried::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);
+  }
+};
+
+class Ext4EsRemoveExtentFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4EsRemoveExtentFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4EsRemoveExtentFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4EsRemoveExtentFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_lblk() const { return at<3>().valid(); }
+  int64_t lblk() const { return at<3>().as_int64(); }
+  bool has_len() const { return at<4>().valid(); }
+  int64_t len() const { return at<4>().as_int64(); }
+};
+
+class Ext4EsRemoveExtentFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4EsRemoveExtentFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kLblkFieldNumber = 3,
+    kLenFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4EsRemoveExtentFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsRemoveExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsRemoveExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4EsRemoveExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4EsRemoveExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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 Ext4EsLookupExtentExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4EsLookupExtentExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4EsLookupExtentExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4EsLookupExtentExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_lblk() const { return at<3>().valid(); }
+  uint32_t lblk() const { return at<3>().as_uint32(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint32_t len() const { return at<4>().as_uint32(); }
+  bool has_pblk() const { return at<5>().valid(); }
+  uint64_t pblk() const { return at<5>().as_uint64(); }
+  bool has_status() const { return at<6>().valid(); }
+  uint64_t status() const { return at<6>().as_uint64(); }
+  bool has_found() const { return at<7>().valid(); }
+  int32_t found() const { return at<7>().as_int32(); }
+};
+
+class Ext4EsLookupExtentExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4EsLookupExtentExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kLblkFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kPblkFieldNumber = 5,
+    kStatusFieldNumber = 6,
+    kFoundFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4EsLookupExtentExitFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsLookupExtentExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsLookupExtentExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4EsLookupExtentExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4EsLookupExtentExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Pblk =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsLookupExtentExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Pblk kPblk{};
+  void set_pblk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pblk::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_Status =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsLookupExtentExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Status kStatus{};
+  void set_status(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Status::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_Found =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4EsLookupExtentExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Found kFound{};
+  void set_found(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Found::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);
+  }
+};
+
+class Ext4EsLookupExtentEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4EsLookupExtentEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4EsLookupExtentEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4EsLookupExtentEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_lblk() const { return at<3>().valid(); }
+  uint32_t lblk() const { return at<3>().as_uint32(); }
+};
+
+class Ext4EsLookupExtentEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4EsLookupExtentEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kLblkFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4EsLookupExtentEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsLookupExtentEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsLookupExtentEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4EsLookupExtentEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::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 Ext4EsInsertExtentFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4EsInsertExtentFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4EsInsertExtentFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4EsInsertExtentFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_lblk() const { return at<3>().valid(); }
+  uint32_t lblk() const { return at<3>().as_uint32(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint32_t len() const { return at<4>().as_uint32(); }
+  bool has_pblk() const { return at<5>().valid(); }
+  uint64_t pblk() const { return at<5>().as_uint64(); }
+  bool has_status() const { return at<6>().valid(); }
+  uint64_t status() const { return at<6>().as_uint64(); }
+};
+
+class Ext4EsInsertExtentFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4EsInsertExtentFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kLblkFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kPblkFieldNumber = 5,
+    kStatusFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4EsInsertExtentFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsInsertExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsInsertExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4EsInsertExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4EsInsertExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Pblk =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsInsertExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Pblk kPblk{};
+  void set_pblk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pblk::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_Status =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsInsertExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Status kStatus{};
+  void set_status(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Status::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 Ext4EsFindDelayedExtentRangeExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4EsFindDelayedExtentRangeExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4EsFindDelayedExtentRangeExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4EsFindDelayedExtentRangeExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_lblk() const { return at<3>().valid(); }
+  uint32_t lblk() const { return at<3>().as_uint32(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint32_t len() const { return at<4>().as_uint32(); }
+  bool has_pblk() const { return at<5>().valid(); }
+  uint64_t pblk() const { return at<5>().as_uint64(); }
+  bool has_status() const { return at<6>().valid(); }
+  uint64_t status() const { return at<6>().as_uint64(); }
+};
+
+class Ext4EsFindDelayedExtentRangeExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4EsFindDelayedExtentRangeExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kLblkFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kPblkFieldNumber = 5,
+    kStatusFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4EsFindDelayedExtentRangeExitFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsFindDelayedExtentRangeExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsFindDelayedExtentRangeExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4EsFindDelayedExtentRangeExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4EsFindDelayedExtentRangeExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Pblk =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsFindDelayedExtentRangeExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Pblk kPblk{};
+  void set_pblk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pblk::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_Status =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsFindDelayedExtentRangeExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Status kStatus{};
+  void set_status(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Status::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 Ext4EsFindDelayedExtentRangeEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4EsFindDelayedExtentRangeEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4EsFindDelayedExtentRangeEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4EsFindDelayedExtentRangeEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_lblk() const { return at<3>().valid(); }
+  uint32_t lblk() const { return at<3>().as_uint32(); }
+};
+
+class Ext4EsFindDelayedExtentRangeEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4EsFindDelayedExtentRangeEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kLblkFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4EsFindDelayedExtentRangeEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsFindDelayedExtentRangeEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsFindDelayedExtentRangeEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4EsFindDelayedExtentRangeEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::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 Ext4EsCacheExtentFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4EsCacheExtentFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4EsCacheExtentFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4EsCacheExtentFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_lblk() const { return at<3>().valid(); }
+  uint32_t lblk() const { return at<3>().as_uint32(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint32_t len() const { return at<4>().as_uint32(); }
+  bool has_pblk() const { return at<5>().valid(); }
+  uint64_t pblk() const { return at<5>().as_uint64(); }
+  bool has_status() const { return at<6>().valid(); }
+  uint32_t status() const { return at<6>().as_uint32(); }
+};
+
+class Ext4EsCacheExtentFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4EsCacheExtentFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kLblkFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kPblkFieldNumber = 5,
+    kStatusFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4EsCacheExtentFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsCacheExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsCacheExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4EsCacheExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4EsCacheExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Pblk =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsCacheExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Pblk kPblk{};
+  void set_pblk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pblk::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_Status =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4EsCacheExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Status kStatus{};
+  void set_status(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Status::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 Ext4DropInodeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4DropInodeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4DropInodeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4DropInodeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_drop() const { return at<3>().valid(); }
+  int32_t drop() const { return at<3>().as_int32(); }
+};
+
+class Ext4DropInodeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4DropInodeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kDropFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4DropInodeFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DropInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DropInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Drop =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DropInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Drop kDrop{};
+  void set_drop(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Drop::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);
+  }
+};
+
+class Ext4DiscardPreallocationsFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4DiscardPreallocationsFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4DiscardPreallocationsFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4DiscardPreallocationsFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_len() const { return at<3>().valid(); }
+  uint32_t len() const { return at<3>().as_uint32(); }
+  bool has_needed() const { return at<4>().valid(); }
+  uint32_t needed() const { return at<4>().as_uint32(); }
+};
+
+class Ext4DiscardPreallocationsFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4DiscardPreallocationsFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kLenFieldNumber = 3,
+    kNeededFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4DiscardPreallocationsFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DiscardPreallocationsFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DiscardPreallocationsFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4DiscardPreallocationsFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Needed =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4DiscardPreallocationsFtraceEvent>;
+
+  static constexpr FieldMetadata_Needed kNeeded{};
+  void set_needed(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Needed::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 Ext4DiscardBlocksFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4DiscardBlocksFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4DiscardBlocksFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4DiscardBlocksFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_blk() const { return at<2>().valid(); }
+  uint64_t blk() const { return at<2>().as_uint64(); }
+  bool has_count() const { return at<3>().valid(); }
+  uint64_t count() const { return at<3>().as_uint64(); }
+};
+
+class Ext4DiscardBlocksFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4DiscardBlocksFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kBlkFieldNumber = 2,
+    kCountFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4DiscardBlocksFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DiscardBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Blk =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DiscardBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Blk kBlk{};
+  void set_blk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Blk::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_Count =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DiscardBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Count kCount{};
+  void set_count(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Count::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 Ext4DirectIOExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4DirectIOExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4DirectIOExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4DirectIOExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pos() const { return at<3>().valid(); }
+  int64_t pos() const { return at<3>().as_int64(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint64_t len() const { return at<4>().as_uint64(); }
+  bool has_rw() const { return at<5>().valid(); }
+  int32_t rw() const { return at<5>().as_int32(); }
+  bool has_ret() const { return at<6>().valid(); }
+  int32_t ret() const { return at<6>().as_int32(); }
+};
+
+class Ext4DirectIOExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4DirectIOExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPosFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kRwFieldNumber = 5,
+    kRetFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4DirectIOExitFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DirectIOExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DirectIOExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Pos =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4DirectIOExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Pos kPos{};
+  void set_pos(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pos::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DirectIOExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Rw =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DirectIOExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Rw kRw{};
+  void set_rw(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rw::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_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DirectIOExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::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);
+  }
+};
+
+class Ext4DirectIOEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4DirectIOEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4DirectIOEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4DirectIOEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pos() const { return at<3>().valid(); }
+  int64_t pos() const { return at<3>().as_int64(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint64_t len() const { return at<4>().as_uint64(); }
+  bool has_rw() const { return at<5>().valid(); }
+  int32_t rw() const { return at<5>().as_int32(); }
+};
+
+class Ext4DirectIOEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4DirectIOEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPosFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kRwFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4DirectIOEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DirectIOEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DirectIOEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Pos =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4DirectIOEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Pos kPos{};
+  void set_pos(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pos::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DirectIOEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Rw =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DirectIOEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Rw kRw{};
+  void set_rw(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rw::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);
+  }
+};
+
+class Ext4DaWritePagesExtentFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4DaWritePagesExtentFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4DaWritePagesExtentFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4DaWritePagesExtentFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_lblk() const { return at<3>().valid(); }
+  uint64_t lblk() const { return at<3>().as_uint64(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint32_t len() const { return at<4>().as_uint32(); }
+  bool has_flags() const { return at<5>().valid(); }
+  uint32_t flags() const { return at<5>().as_uint32(); }
+};
+
+class Ext4DaWritePagesExtentFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4DaWritePagesExtentFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kLblkFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kFlagsFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4DaWritePagesExtentFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaWritePagesExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaWritePagesExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaWritePagesExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4DaWritePagesExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4DaWritePagesExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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 Ext4DaWritePagesFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/10, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4DaWritePagesFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4DaWritePagesFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4DaWritePagesFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_first_page() const { return at<3>().valid(); }
+  uint64_t first_page() const { return at<3>().as_uint64(); }
+  bool has_nr_to_write() const { return at<4>().valid(); }
+  int64_t nr_to_write() const { return at<4>().as_int64(); }
+  bool has_sync_mode() const { return at<5>().valid(); }
+  int32_t sync_mode() const { return at<5>().as_int32(); }
+  bool has_b_blocknr() const { return at<6>().valid(); }
+  uint64_t b_blocknr() const { return at<6>().as_uint64(); }
+  bool has_b_size() const { return at<7>().valid(); }
+  uint32_t b_size() const { return at<7>().as_uint32(); }
+  bool has_b_state() const { return at<8>().valid(); }
+  uint32_t b_state() const { return at<8>().as_uint32(); }
+  bool has_io_done() const { return at<9>().valid(); }
+  int32_t io_done() const { return at<9>().as_int32(); }
+  bool has_pages_written() const { return at<10>().valid(); }
+  int32_t pages_written() const { return at<10>().as_int32(); }
+};
+
+class Ext4DaWritePagesFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4DaWritePagesFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kFirstPageFieldNumber = 3,
+    kNrToWriteFieldNumber = 4,
+    kSyncModeFieldNumber = 5,
+    kBBlocknrFieldNumber = 6,
+    kBSizeFieldNumber = 7,
+    kBStateFieldNumber = 8,
+    kIoDoneFieldNumber = 9,
+    kPagesWrittenFieldNumber = 10,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4DaWritePagesFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaWritePagesFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaWritePagesFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_FirstPage =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaWritePagesFtraceEvent>;
+
+  static constexpr FieldMetadata_FirstPage kFirstPage{};
+  void set_first_page(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FirstPage::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_NrToWrite =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4DaWritePagesFtraceEvent>;
+
+  static constexpr FieldMetadata_NrToWrite kNrToWrite{};
+  void set_nr_to_write(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrToWrite::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_SyncMode =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DaWritePagesFtraceEvent>;
+
+  static constexpr FieldMetadata_SyncMode kSyncMode{};
+  void set_sync_mode(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SyncMode::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_BBlocknr =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaWritePagesFtraceEvent>;
+
+  static constexpr FieldMetadata_BBlocknr kBBlocknr{};
+  void set_b_blocknr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BBlocknr::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_BSize =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4DaWritePagesFtraceEvent>;
+
+  static constexpr FieldMetadata_BSize kBSize{};
+  void set_b_size(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BSize::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_BState =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4DaWritePagesFtraceEvent>;
+
+  static constexpr FieldMetadata_BState kBState{};
+  void set_b_state(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BState::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_IoDone =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DaWritePagesFtraceEvent>;
+
+  static constexpr FieldMetadata_IoDone kIoDone{};
+  void set_io_done(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IoDone::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_PagesWritten =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DaWritePagesFtraceEvent>;
+
+  static constexpr FieldMetadata_PagesWritten kPagesWritten{};
+  void set_pages_written(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PagesWritten::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);
+  }
+};
+
+class Ext4DaUpdateReserveSpaceFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4DaUpdateReserveSpaceFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4DaUpdateReserveSpaceFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4DaUpdateReserveSpaceFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_i_blocks() const { return at<3>().valid(); }
+  uint64_t i_blocks() const { return at<3>().as_uint64(); }
+  bool has_used_blocks() const { return at<4>().valid(); }
+  int32_t used_blocks() const { return at<4>().as_int32(); }
+  bool has_reserved_data_blocks() const { return at<5>().valid(); }
+  int32_t reserved_data_blocks() const { return at<5>().as_int32(); }
+  bool has_reserved_meta_blocks() const { return at<6>().valid(); }
+  int32_t reserved_meta_blocks() const { return at<6>().as_int32(); }
+  bool has_allocated_meta_blocks() const { return at<7>().valid(); }
+  int32_t allocated_meta_blocks() const { return at<7>().as_int32(); }
+  bool has_quota_claim() const { return at<8>().valid(); }
+  int32_t quota_claim() const { return at<8>().as_int32(); }
+  bool has_mode() const { return at<9>().valid(); }
+  uint32_t mode() const { return at<9>().as_uint32(); }
+};
+
+class Ext4DaUpdateReserveSpaceFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4DaUpdateReserveSpaceFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kIBlocksFieldNumber = 3,
+    kUsedBlocksFieldNumber = 4,
+    kReservedDataBlocksFieldNumber = 5,
+    kReservedMetaBlocksFieldNumber = 6,
+    kAllocatedMetaBlocksFieldNumber = 7,
+    kQuotaClaimFieldNumber = 8,
+    kModeFieldNumber = 9,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4DaUpdateReserveSpaceFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaUpdateReserveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaUpdateReserveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_IBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaUpdateReserveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_IBlocks kIBlocks{};
+  void set_i_blocks(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IBlocks::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_UsedBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DaUpdateReserveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_UsedBlocks kUsedBlocks{};
+  void set_used_blocks(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UsedBlocks::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_ReservedDataBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DaUpdateReserveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_ReservedDataBlocks kReservedDataBlocks{};
+  void set_reserved_data_blocks(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReservedDataBlocks::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_ReservedMetaBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DaUpdateReserveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_ReservedMetaBlocks kReservedMetaBlocks{};
+  void set_reserved_meta_blocks(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReservedMetaBlocks::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_AllocatedMetaBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DaUpdateReserveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_AllocatedMetaBlocks kAllocatedMetaBlocks{};
+  void set_allocated_meta_blocks(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AllocatedMetaBlocks::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_QuotaClaim =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DaUpdateReserveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_QuotaClaim kQuotaClaim{};
+  void set_quota_claim(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_QuotaClaim::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_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4DaUpdateReserveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::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 Ext4DaReserveSpaceFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4DaReserveSpaceFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4DaReserveSpaceFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4DaReserveSpaceFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_i_blocks() const { return at<3>().valid(); }
+  uint64_t i_blocks() const { return at<3>().as_uint64(); }
+  bool has_reserved_data_blocks() const { return at<4>().valid(); }
+  int32_t reserved_data_blocks() const { return at<4>().as_int32(); }
+  bool has_reserved_meta_blocks() const { return at<5>().valid(); }
+  int32_t reserved_meta_blocks() const { return at<5>().as_int32(); }
+  bool has_mode() const { return at<6>().valid(); }
+  uint32_t mode() const { return at<6>().as_uint32(); }
+  bool has_md_needed() const { return at<7>().valid(); }
+  int32_t md_needed() const { return at<7>().as_int32(); }
+};
+
+class Ext4DaReserveSpaceFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4DaReserveSpaceFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kIBlocksFieldNumber = 3,
+    kReservedDataBlocksFieldNumber = 4,
+    kReservedMetaBlocksFieldNumber = 5,
+    kModeFieldNumber = 6,
+    kMdNeededFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4DaReserveSpaceFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaReserveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaReserveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_IBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaReserveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_IBlocks kIBlocks{};
+  void set_i_blocks(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IBlocks::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_ReservedDataBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DaReserveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_ReservedDataBlocks kReservedDataBlocks{};
+  void set_reserved_data_blocks(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReservedDataBlocks::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_ReservedMetaBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DaReserveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_ReservedMetaBlocks kReservedMetaBlocks{};
+  void set_reserved_meta_blocks(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReservedMetaBlocks::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_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4DaReserveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::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_MdNeeded =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DaReserveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_MdNeeded kMdNeeded{};
+  void set_md_needed(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MdNeeded::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);
+  }
+};
+
+class Ext4DaReleaseSpaceFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4DaReleaseSpaceFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4DaReleaseSpaceFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4DaReleaseSpaceFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_i_blocks() const { return at<3>().valid(); }
+  uint64_t i_blocks() const { return at<3>().as_uint64(); }
+  bool has_freed_blocks() const { return at<4>().valid(); }
+  int32_t freed_blocks() const { return at<4>().as_int32(); }
+  bool has_reserved_data_blocks() const { return at<5>().valid(); }
+  int32_t reserved_data_blocks() const { return at<5>().as_int32(); }
+  bool has_reserved_meta_blocks() const { return at<6>().valid(); }
+  int32_t reserved_meta_blocks() const { return at<6>().as_int32(); }
+  bool has_allocated_meta_blocks() const { return at<7>().valid(); }
+  int32_t allocated_meta_blocks() const { return at<7>().as_int32(); }
+  bool has_mode() const { return at<8>().valid(); }
+  uint32_t mode() const { return at<8>().as_uint32(); }
+};
+
+class Ext4DaReleaseSpaceFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4DaReleaseSpaceFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kIBlocksFieldNumber = 3,
+    kFreedBlocksFieldNumber = 4,
+    kReservedDataBlocksFieldNumber = 5,
+    kReservedMetaBlocksFieldNumber = 6,
+    kAllocatedMetaBlocksFieldNumber = 7,
+    kModeFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4DaReleaseSpaceFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaReleaseSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaReleaseSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_IBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaReleaseSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_IBlocks kIBlocks{};
+  void set_i_blocks(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IBlocks::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_FreedBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DaReleaseSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_FreedBlocks kFreedBlocks{};
+  void set_freed_blocks(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FreedBlocks::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_ReservedDataBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DaReleaseSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_ReservedDataBlocks kReservedDataBlocks{};
+  void set_reserved_data_blocks(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReservedDataBlocks::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_ReservedMetaBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DaReleaseSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_ReservedMetaBlocks kReservedMetaBlocks{};
+  void set_reserved_meta_blocks(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReservedMetaBlocks::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_AllocatedMetaBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DaReleaseSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_AllocatedMetaBlocks kAllocatedMetaBlocks{};
+  void set_allocated_meta_blocks(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AllocatedMetaBlocks::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_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4DaReleaseSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::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 Ext4CollapseRangeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4CollapseRangeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4CollapseRangeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4CollapseRangeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_offset() const { return at<3>().valid(); }
+  int64_t offset() const { return at<3>().as_int64(); }
+  bool has_len() const { return at<4>().valid(); }
+  int64_t len() const { return at<4>().as_int64(); }
+};
+
+class Ext4CollapseRangeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4CollapseRangeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kOffsetFieldNumber = 3,
+    kLenFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4CollapseRangeFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4CollapseRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4CollapseRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Offset =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4CollapseRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Offset kOffset{};
+  void set_offset(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Offset::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4CollapseRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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 Ext4BeginOrderedTruncateFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4BeginOrderedTruncateFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4BeginOrderedTruncateFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4BeginOrderedTruncateFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_new_size() const { return at<3>().valid(); }
+  int64_t new_size() const { return at<3>().as_int64(); }
+};
+
+class Ext4BeginOrderedTruncateFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4BeginOrderedTruncateFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kNewSizeFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4BeginOrderedTruncateFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4BeginOrderedTruncateFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4BeginOrderedTruncateFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_NewSize =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4BeginOrderedTruncateFtraceEvent>;
+
+  static constexpr FieldMetadata_NewSize kNewSize{};
+  void set_new_size(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NewSize::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 Ext4AllocateInodeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4AllocateInodeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4AllocateInodeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4AllocateInodeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_dir() const { return at<3>().valid(); }
+  uint64_t dir() const { return at<3>().as_uint64(); }
+  bool has_mode() const { return at<4>().valid(); }
+  uint32_t mode() const { return at<4>().as_uint32(); }
+};
+
+class Ext4AllocateInodeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4AllocateInodeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kDirFieldNumber = 3,
+    kModeFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4AllocateInodeFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4AllocateInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4AllocateInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Dir =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4AllocateInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dir kDir{};
+  void set_dir(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dir::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_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4AllocateInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::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 Ext4AllocateBlocksFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/11, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4AllocateBlocksFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4AllocateBlocksFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4AllocateBlocksFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_block() const { return at<3>().valid(); }
+  uint64_t block() const { return at<3>().as_uint64(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint32_t len() const { return at<4>().as_uint32(); }
+  bool has_logical() const { return at<5>().valid(); }
+  uint32_t logical() const { return at<5>().as_uint32(); }
+  bool has_lleft() const { return at<6>().valid(); }
+  uint32_t lleft() const { return at<6>().as_uint32(); }
+  bool has_lright() const { return at<7>().valid(); }
+  uint32_t lright() const { return at<7>().as_uint32(); }
+  bool has_goal() const { return at<8>().valid(); }
+  uint64_t goal() const { return at<8>().as_uint64(); }
+  bool has_pleft() const { return at<9>().valid(); }
+  uint64_t pleft() const { return at<9>().as_uint64(); }
+  bool has_pright() const { return at<10>().valid(); }
+  uint64_t pright() const { return at<10>().as_uint64(); }
+  bool has_flags() const { return at<11>().valid(); }
+  uint32_t flags() const { return at<11>().as_uint32(); }
+};
+
+class Ext4AllocateBlocksFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4AllocateBlocksFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kBlockFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kLogicalFieldNumber = 5,
+    kLleftFieldNumber = 6,
+    kLrightFieldNumber = 7,
+    kGoalFieldNumber = 8,
+    kPleftFieldNumber = 9,
+    kPrightFieldNumber = 10,
+    kFlagsFieldNumber = 11,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4AllocateBlocksFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4AllocateBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4AllocateBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Block =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4AllocateBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Block kBlock{};
+  void set_block(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Block::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4AllocateBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Logical =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4AllocateBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Logical kLogical{};
+  void set_logical(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Logical::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_Lleft =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4AllocateBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Lleft kLleft{};
+  void set_lleft(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lleft::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_Lright =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4AllocateBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Lright kLright{};
+  void set_lright(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lright::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_Goal =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4AllocateBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Goal kGoal{};
+  void set_goal(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Goal::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_Pleft =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4AllocateBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Pleft kPleft{};
+  void set_pleft(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pleft::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_Pright =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4AllocateBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Pright kPright{};
+  void set_pright(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pright::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4AllocateBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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 Ext4AllocDaBlocksFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4AllocDaBlocksFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4AllocDaBlocksFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4AllocDaBlocksFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_data_blocks() const { return at<3>().valid(); }
+  uint32_t data_blocks() const { return at<3>().as_uint32(); }
+  bool has_meta_blocks() const { return at<4>().valid(); }
+  uint32_t meta_blocks() const { return at<4>().as_uint32(); }
+};
+
+class Ext4AllocDaBlocksFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4AllocDaBlocksFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kDataBlocksFieldNumber = 3,
+    kMetaBlocksFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4AllocDaBlocksFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4AllocDaBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4AllocDaBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_DataBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4AllocDaBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_DataBlocks kDataBlocks{};
+  void set_data_blocks(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DataBlocks::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_MetaBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4AllocDaBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_MetaBlocks kMetaBlocks{};
+  void set_meta_blocks(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MetaBlocks::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 Ext4SyncFileExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4SyncFileExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4SyncFileExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4SyncFileExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_ret() const { return at<3>().valid(); }
+  int32_t ret() const { return at<3>().as_int32(); }
+};
+
+class Ext4SyncFileExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4SyncFileExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kRetFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4SyncFileExitFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4SyncFileExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4SyncFileExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4SyncFileExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::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);
+  }
+};
+
+class Ext4SyncFileEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4SyncFileEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4SyncFileEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4SyncFileEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_parent() const { return at<3>().valid(); }
+  uint64_t parent() const { return at<3>().as_uint64(); }
+  bool has_datasync() const { return at<4>().valid(); }
+  int32_t datasync() const { return at<4>().as_int32(); }
+};
+
+class Ext4SyncFileEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4SyncFileEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kParentFieldNumber = 3,
+    kDatasyncFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4SyncFileEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4SyncFileEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4SyncFileEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Parent =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4SyncFileEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Parent kParent{};
+  void set_parent(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Parent::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_Datasync =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4SyncFileEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Datasync kDatasync{};
+  void set_datasync(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Datasync::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);
+  }
+};
+
+class Ext4DaWriteEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4DaWriteEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4DaWriteEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4DaWriteEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pos() const { return at<3>().valid(); }
+  int64_t pos() const { return at<3>().as_int64(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint32_t len() const { return at<4>().as_uint32(); }
+  bool has_copied() const { return at<5>().valid(); }
+  uint32_t copied() const { return at<5>().as_uint32(); }
+};
+
+class Ext4DaWriteEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4DaWriteEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPosFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kCopiedFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4DaWriteEndFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaWriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaWriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Pos =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4DaWriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Pos kPos{};
+  void set_pos(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pos::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4DaWriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Copied =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4DaWriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Copied kCopied{};
+  void set_copied(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Copied::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 Ext4DaWriteBeginFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4DaWriteBeginFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4DaWriteBeginFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4DaWriteBeginFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pos() const { return at<3>().valid(); }
+  int64_t pos() const { return at<3>().as_int64(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint32_t len() const { return at<4>().as_uint32(); }
+  bool has_flags() const { return at<5>().valid(); }
+  uint32_t flags() const { return at<5>().as_uint32(); }
+};
+
+class Ext4DaWriteBeginFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4DaWriteBeginFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPosFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kFlagsFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4DaWriteBeginFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaWriteBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaWriteBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Pos =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4DaWriteBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_Pos kPos{};
+  void set_pos(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pos::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4DaWriteBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4DaWriteBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/f2fs.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_F2FS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_F2FS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class F2fsGcEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/11, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsGcEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsGcEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsGcEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ret() const { return at<2>().valid(); }
+  int32_t ret() const { return at<2>().as_int32(); }
+  bool has_seg_freed() const { return at<3>().valid(); }
+  int32_t seg_freed() const { return at<3>().as_int32(); }
+  bool has_sec_freed() const { return at<4>().valid(); }
+  int32_t sec_freed() const { return at<4>().as_int32(); }
+  bool has_dirty_nodes() const { return at<5>().valid(); }
+  int64_t dirty_nodes() const { return at<5>().as_int64(); }
+  bool has_dirty_dents() const { return at<6>().valid(); }
+  int64_t dirty_dents() const { return at<6>().as_int64(); }
+  bool has_dirty_imeta() const { return at<7>().valid(); }
+  int64_t dirty_imeta() const { return at<7>().as_int64(); }
+  bool has_free_sec() const { return at<8>().valid(); }
+  uint32_t free_sec() const { return at<8>().as_uint32(); }
+  bool has_free_seg() const { return at<9>().valid(); }
+  uint32_t free_seg() const { return at<9>().as_uint32(); }
+  bool has_reserved_seg() const { return at<10>().valid(); }
+  int32_t reserved_seg() const { return at<10>().as_int32(); }
+  bool has_prefree_seg() const { return at<11>().valid(); }
+  uint32_t prefree_seg() const { return at<11>().as_uint32(); }
+};
+
+class F2fsGcEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsGcEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kRetFieldNumber = 2,
+    kSegFreedFieldNumber = 3,
+    kSecFreedFieldNumber = 4,
+    kDirtyNodesFieldNumber = 5,
+    kDirtyDentsFieldNumber = 6,
+    kDirtyImetaFieldNumber = 7,
+    kFreeSecFieldNumber = 8,
+    kFreeSegFieldNumber = 9,
+    kReservedSegFieldNumber = 10,
+    kPrefreeSegFieldNumber = 11,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsGcEndFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsGcEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsGcEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::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_SegFreed =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsGcEndFtraceEvent>;
+
+  static constexpr FieldMetadata_SegFreed kSegFreed{};
+  void set_seg_freed(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SegFreed::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_SecFreed =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsGcEndFtraceEvent>;
+
+  static constexpr FieldMetadata_SecFreed kSecFreed{};
+  void set_sec_freed(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SecFreed::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_DirtyNodes =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      F2fsGcEndFtraceEvent>;
+
+  static constexpr FieldMetadata_DirtyNodes kDirtyNodes{};
+  void set_dirty_nodes(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DirtyNodes::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_DirtyDents =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      F2fsGcEndFtraceEvent>;
+
+  static constexpr FieldMetadata_DirtyDents kDirtyDents{};
+  void set_dirty_dents(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DirtyDents::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_DirtyImeta =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      F2fsGcEndFtraceEvent>;
+
+  static constexpr FieldMetadata_DirtyImeta kDirtyImeta{};
+  void set_dirty_imeta(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DirtyImeta::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_FreeSec =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsGcEndFtraceEvent>;
+
+  static constexpr FieldMetadata_FreeSec kFreeSec{};
+  void set_free_sec(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FreeSec::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_FreeSeg =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsGcEndFtraceEvent>;
+
+  static constexpr FieldMetadata_FreeSeg kFreeSeg{};
+  void set_free_seg(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FreeSeg::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_ReservedSeg =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsGcEndFtraceEvent>;
+
+  static constexpr FieldMetadata_ReservedSeg kReservedSeg{};
+  void set_reserved_seg(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReservedSeg::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_PrefreeSeg =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsGcEndFtraceEvent>;
+
+  static constexpr FieldMetadata_PrefreeSeg kPrefreeSeg{};
+  void set_prefree_seg(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PrefreeSeg::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 F2fsGcBeginFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/13, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsGcBeginFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsGcBeginFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsGcBeginFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_sync() const { return at<2>().valid(); }
+  uint32_t sync() const { return at<2>().as_uint32(); }
+  bool has_background() const { return at<3>().valid(); }
+  uint32_t background() const { return at<3>().as_uint32(); }
+  bool has_dirty_nodes() const { return at<4>().valid(); }
+  int64_t dirty_nodes() const { return at<4>().as_int64(); }
+  bool has_dirty_dents() const { return at<5>().valid(); }
+  int64_t dirty_dents() const { return at<5>().as_int64(); }
+  bool has_dirty_imeta() const { return at<6>().valid(); }
+  int64_t dirty_imeta() const { return at<6>().as_int64(); }
+  bool has_free_sec() const { return at<7>().valid(); }
+  uint32_t free_sec() const { return at<7>().as_uint32(); }
+  bool has_free_seg() const { return at<8>().valid(); }
+  uint32_t free_seg() const { return at<8>().as_uint32(); }
+  bool has_reserved_seg() const { return at<9>().valid(); }
+  int32_t reserved_seg() const { return at<9>().as_int32(); }
+  bool has_prefree_seg() const { return at<10>().valid(); }
+  uint32_t prefree_seg() const { return at<10>().as_uint32(); }
+  bool has_gc_type() const { return at<11>().valid(); }
+  int32_t gc_type() const { return at<11>().as_int32(); }
+  bool has_no_bg_gc() const { return at<12>().valid(); }
+  uint32_t no_bg_gc() const { return at<12>().as_uint32(); }
+  bool has_nr_free_secs() const { return at<13>().valid(); }
+  uint32_t nr_free_secs() const { return at<13>().as_uint32(); }
+};
+
+class F2fsGcBeginFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsGcBeginFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kSyncFieldNumber = 2,
+    kBackgroundFieldNumber = 3,
+    kDirtyNodesFieldNumber = 4,
+    kDirtyDentsFieldNumber = 5,
+    kDirtyImetaFieldNumber = 6,
+    kFreeSecFieldNumber = 7,
+    kFreeSegFieldNumber = 8,
+    kReservedSegFieldNumber = 9,
+    kPrefreeSegFieldNumber = 10,
+    kGcTypeFieldNumber = 11,
+    kNoBgGcFieldNumber = 12,
+    kNrFreeSecsFieldNumber = 13,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsGcBeginFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsGcBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Sync =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsGcBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_Sync kSync{};
+  void set_sync(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sync::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_Background =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsGcBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_Background kBackground{};
+  void set_background(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Background::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_DirtyNodes =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      F2fsGcBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_DirtyNodes kDirtyNodes{};
+  void set_dirty_nodes(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DirtyNodes::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_DirtyDents =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      F2fsGcBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_DirtyDents kDirtyDents{};
+  void set_dirty_dents(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DirtyDents::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_DirtyImeta =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      F2fsGcBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_DirtyImeta kDirtyImeta{};
+  void set_dirty_imeta(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DirtyImeta::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_FreeSec =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsGcBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_FreeSec kFreeSec{};
+  void set_free_sec(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FreeSec::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_FreeSeg =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsGcBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_FreeSeg kFreeSeg{};
+  void set_free_seg(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FreeSeg::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_ReservedSeg =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsGcBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_ReservedSeg kReservedSeg{};
+  void set_reserved_seg(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReservedSeg::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_PrefreeSeg =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsGcBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_PrefreeSeg kPrefreeSeg{};
+  void set_prefree_seg(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PrefreeSeg::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_GcType =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsGcBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_GcType kGcType{};
+  void set_gc_type(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GcType::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_NoBgGc =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsGcBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_NoBgGc kNoBgGc{};
+  void set_no_bg_gc(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NoBgGc::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_NrFreeSecs =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsGcBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_NrFreeSecs kNrFreeSecs{};
+  void set_nr_free_secs(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrFreeSecs::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 F2fsBackgroundGcFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsBackgroundGcFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsBackgroundGcFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsBackgroundGcFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_wait_ms() const { return at<2>().valid(); }
+  uint32_t wait_ms() const { return at<2>().as_uint32(); }
+  bool has_prefree() const { return at<3>().valid(); }
+  uint32_t prefree() const { return at<3>().as_uint32(); }
+  bool has_free() const { return at<4>().valid(); }
+  uint32_t free() const { return at<4>().as_uint32(); }
+};
+
+class F2fsBackgroundGcFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsBackgroundGcFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kWaitMsFieldNumber = 2,
+    kPrefreeFieldNumber = 3,
+    kFreeFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsBackgroundGcFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsBackgroundGcFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_WaitMs =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsBackgroundGcFtraceEvent>;
+
+  static constexpr FieldMetadata_WaitMs kWaitMs{};
+  void set_wait_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_WaitMs::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_Prefree =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsBackgroundGcFtraceEvent>;
+
+  static constexpr FieldMetadata_Prefree kPrefree{};
+  void set_prefree(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Prefree::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_Free =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsBackgroundGcFtraceEvent>;
+
+  static constexpr FieldMetadata_Free kFree{};
+  void set_free(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Free::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 F2fsIostatLatencyFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/28, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsIostatLatencyFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsIostatLatencyFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsIostatLatencyFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_d_rd_avg() const { return at<1>().valid(); }
+  uint32_t d_rd_avg() const { return at<1>().as_uint32(); }
+  bool has_d_rd_cnt() const { return at<2>().valid(); }
+  uint32_t d_rd_cnt() const { return at<2>().as_uint32(); }
+  bool has_d_rd_peak() const { return at<3>().valid(); }
+  uint32_t d_rd_peak() const { return at<3>().as_uint32(); }
+  bool has_d_wr_as_avg() const { return at<4>().valid(); }
+  uint32_t d_wr_as_avg() const { return at<4>().as_uint32(); }
+  bool has_d_wr_as_cnt() const { return at<5>().valid(); }
+  uint32_t d_wr_as_cnt() const { return at<5>().as_uint32(); }
+  bool has_d_wr_as_peak() const { return at<6>().valid(); }
+  uint32_t d_wr_as_peak() const { return at<6>().as_uint32(); }
+  bool has_d_wr_s_avg() const { return at<7>().valid(); }
+  uint32_t d_wr_s_avg() const { return at<7>().as_uint32(); }
+  bool has_d_wr_s_cnt() const { return at<8>().valid(); }
+  uint32_t d_wr_s_cnt() const { return at<8>().as_uint32(); }
+  bool has_d_wr_s_peak() const { return at<9>().valid(); }
+  uint32_t d_wr_s_peak() const { return at<9>().as_uint32(); }
+  bool has_dev() const { return at<10>().valid(); }
+  uint64_t dev() const { return at<10>().as_uint64(); }
+  bool has_m_rd_avg() const { return at<11>().valid(); }
+  uint32_t m_rd_avg() const { return at<11>().as_uint32(); }
+  bool has_m_rd_cnt() const { return at<12>().valid(); }
+  uint32_t m_rd_cnt() const { return at<12>().as_uint32(); }
+  bool has_m_rd_peak() const { return at<13>().valid(); }
+  uint32_t m_rd_peak() const { return at<13>().as_uint32(); }
+  bool has_m_wr_as_avg() const { return at<14>().valid(); }
+  uint32_t m_wr_as_avg() const { return at<14>().as_uint32(); }
+  bool has_m_wr_as_cnt() const { return at<15>().valid(); }
+  uint32_t m_wr_as_cnt() const { return at<15>().as_uint32(); }
+  bool has_m_wr_as_peak() const { return at<16>().valid(); }
+  uint32_t m_wr_as_peak() const { return at<16>().as_uint32(); }
+  bool has_m_wr_s_avg() const { return at<17>().valid(); }
+  uint32_t m_wr_s_avg() const { return at<17>().as_uint32(); }
+  bool has_m_wr_s_cnt() const { return at<18>().valid(); }
+  uint32_t m_wr_s_cnt() const { return at<18>().as_uint32(); }
+  bool has_m_wr_s_peak() const { return at<19>().valid(); }
+  uint32_t m_wr_s_peak() const { return at<19>().as_uint32(); }
+  bool has_n_rd_avg() const { return at<20>().valid(); }
+  uint32_t n_rd_avg() const { return at<20>().as_uint32(); }
+  bool has_n_rd_cnt() const { return at<21>().valid(); }
+  uint32_t n_rd_cnt() const { return at<21>().as_uint32(); }
+  bool has_n_rd_peak() const { return at<22>().valid(); }
+  uint32_t n_rd_peak() const { return at<22>().as_uint32(); }
+  bool has_n_wr_as_avg() const { return at<23>().valid(); }
+  uint32_t n_wr_as_avg() const { return at<23>().as_uint32(); }
+  bool has_n_wr_as_cnt() const { return at<24>().valid(); }
+  uint32_t n_wr_as_cnt() const { return at<24>().as_uint32(); }
+  bool has_n_wr_as_peak() const { return at<25>().valid(); }
+  uint32_t n_wr_as_peak() const { return at<25>().as_uint32(); }
+  bool has_n_wr_s_avg() const { return at<26>().valid(); }
+  uint32_t n_wr_s_avg() const { return at<26>().as_uint32(); }
+  bool has_n_wr_s_cnt() const { return at<27>().valid(); }
+  uint32_t n_wr_s_cnt() const { return at<27>().as_uint32(); }
+  bool has_n_wr_s_peak() const { return at<28>().valid(); }
+  uint32_t n_wr_s_peak() const { return at<28>().as_uint32(); }
+};
+
+class F2fsIostatLatencyFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsIostatLatencyFtraceEvent_Decoder;
+  enum : int32_t {
+    kDRdAvgFieldNumber = 1,
+    kDRdCntFieldNumber = 2,
+    kDRdPeakFieldNumber = 3,
+    kDWrAsAvgFieldNumber = 4,
+    kDWrAsCntFieldNumber = 5,
+    kDWrAsPeakFieldNumber = 6,
+    kDWrSAvgFieldNumber = 7,
+    kDWrSCntFieldNumber = 8,
+    kDWrSPeakFieldNumber = 9,
+    kDevFieldNumber = 10,
+    kMRdAvgFieldNumber = 11,
+    kMRdCntFieldNumber = 12,
+    kMRdPeakFieldNumber = 13,
+    kMWrAsAvgFieldNumber = 14,
+    kMWrAsCntFieldNumber = 15,
+    kMWrAsPeakFieldNumber = 16,
+    kMWrSAvgFieldNumber = 17,
+    kMWrSCntFieldNumber = 18,
+    kMWrSPeakFieldNumber = 19,
+    kNRdAvgFieldNumber = 20,
+    kNRdCntFieldNumber = 21,
+    kNRdPeakFieldNumber = 22,
+    kNWrAsAvgFieldNumber = 23,
+    kNWrAsCntFieldNumber = 24,
+    kNWrAsPeakFieldNumber = 25,
+    kNWrSAvgFieldNumber = 26,
+    kNWrSCntFieldNumber = 27,
+    kNWrSPeakFieldNumber = 28,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsIostatLatencyFtraceEvent"; }
+
+
+  using FieldMetadata_DRdAvg =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_DRdAvg kDRdAvg{};
+  void set_d_rd_avg(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DRdAvg::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_DRdCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_DRdCnt kDRdCnt{};
+  void set_d_rd_cnt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DRdCnt::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_DRdPeak =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_DRdPeak kDRdPeak{};
+  void set_d_rd_peak(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DRdPeak::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_DWrAsAvg =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_DWrAsAvg kDWrAsAvg{};
+  void set_d_wr_as_avg(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DWrAsAvg::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_DWrAsCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_DWrAsCnt kDWrAsCnt{};
+  void set_d_wr_as_cnt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DWrAsCnt::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_DWrAsPeak =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_DWrAsPeak kDWrAsPeak{};
+  void set_d_wr_as_peak(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DWrAsPeak::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_DWrSAvg =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_DWrSAvg kDWrSAvg{};
+  void set_d_wr_s_avg(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DWrSAvg::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_DWrSCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_DWrSCnt kDWrSCnt{};
+  void set_d_wr_s_cnt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DWrSCnt::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_DWrSPeak =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_DWrSPeak kDWrSPeak{};
+  void set_d_wr_s_peak(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DWrSPeak::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_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_MRdAvg =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_MRdAvg kMRdAvg{};
+  void set_m_rd_avg(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MRdAvg::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_MRdCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_MRdCnt kMRdCnt{};
+  void set_m_rd_cnt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MRdCnt::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_MRdPeak =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_MRdPeak kMRdPeak{};
+  void set_m_rd_peak(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MRdPeak::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_MWrAsAvg =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_MWrAsAvg kMWrAsAvg{};
+  void set_m_wr_as_avg(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MWrAsAvg::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_MWrAsCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_MWrAsCnt kMWrAsCnt{};
+  void set_m_wr_as_cnt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MWrAsCnt::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_MWrAsPeak =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_MWrAsPeak kMWrAsPeak{};
+  void set_m_wr_as_peak(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MWrAsPeak::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_MWrSAvg =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_MWrSAvg kMWrSAvg{};
+  void set_m_wr_s_avg(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MWrSAvg::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_MWrSCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_MWrSCnt kMWrSCnt{};
+  void set_m_wr_s_cnt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MWrSCnt::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_MWrSPeak =
+    ::protozero::proto_utils::FieldMetadata<
+      19,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_MWrSPeak kMWrSPeak{};
+  void set_m_wr_s_peak(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MWrSPeak::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_NRdAvg =
+    ::protozero::proto_utils::FieldMetadata<
+      20,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_NRdAvg kNRdAvg{};
+  void set_n_rd_avg(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NRdAvg::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_NRdCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      21,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_NRdCnt kNRdCnt{};
+  void set_n_rd_cnt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NRdCnt::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_NRdPeak =
+    ::protozero::proto_utils::FieldMetadata<
+      22,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_NRdPeak kNRdPeak{};
+  void set_n_rd_peak(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NRdPeak::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_NWrAsAvg =
+    ::protozero::proto_utils::FieldMetadata<
+      23,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_NWrAsAvg kNWrAsAvg{};
+  void set_n_wr_as_avg(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NWrAsAvg::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_NWrAsCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      24,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_NWrAsCnt kNWrAsCnt{};
+  void set_n_wr_as_cnt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NWrAsCnt::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_NWrAsPeak =
+    ::protozero::proto_utils::FieldMetadata<
+      25,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_NWrAsPeak kNWrAsPeak{};
+  void set_n_wr_as_peak(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NWrAsPeak::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_NWrSAvg =
+    ::protozero::proto_utils::FieldMetadata<
+      26,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_NWrSAvg kNWrSAvg{};
+  void set_n_wr_s_avg(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NWrSAvg::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_NWrSCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      27,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_NWrSCnt kNWrSCnt{};
+  void set_n_wr_s_cnt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NWrSCnt::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_NWrSPeak =
+    ::protozero::proto_utils::FieldMetadata<
+      28,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_NWrSPeak kNWrSPeak{};
+  void set_n_wr_s_peak(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NWrSPeak::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 F2fsIostatFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/23, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsIostatFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsIostatFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsIostatFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_app_bio() const { return at<1>().valid(); }
+  uint64_t app_bio() const { return at<1>().as_uint64(); }
+  bool has_app_brio() const { return at<2>().valid(); }
+  uint64_t app_brio() const { return at<2>().as_uint64(); }
+  bool has_app_dio() const { return at<3>().valid(); }
+  uint64_t app_dio() const { return at<3>().as_uint64(); }
+  bool has_app_drio() const { return at<4>().valid(); }
+  uint64_t app_drio() const { return at<4>().as_uint64(); }
+  bool has_app_mio() const { return at<5>().valid(); }
+  uint64_t app_mio() const { return at<5>().as_uint64(); }
+  bool has_app_mrio() const { return at<6>().valid(); }
+  uint64_t app_mrio() const { return at<6>().as_uint64(); }
+  bool has_app_rio() const { return at<7>().valid(); }
+  uint64_t app_rio() const { return at<7>().as_uint64(); }
+  bool has_app_wio() const { return at<8>().valid(); }
+  uint64_t app_wio() const { return at<8>().as_uint64(); }
+  bool has_dev() const { return at<9>().valid(); }
+  uint64_t dev() const { return at<9>().as_uint64(); }
+  bool has_fs_cdrio() const { return at<10>().valid(); }
+  uint64_t fs_cdrio() const { return at<10>().as_uint64(); }
+  bool has_fs_cp_dio() const { return at<11>().valid(); }
+  uint64_t fs_cp_dio() const { return at<11>().as_uint64(); }
+  bool has_fs_cp_mio() const { return at<12>().valid(); }
+  uint64_t fs_cp_mio() const { return at<12>().as_uint64(); }
+  bool has_fs_cp_nio() const { return at<13>().valid(); }
+  uint64_t fs_cp_nio() const { return at<13>().as_uint64(); }
+  bool has_fs_dio() const { return at<14>().valid(); }
+  uint64_t fs_dio() const { return at<14>().as_uint64(); }
+  bool has_fs_discard() const { return at<15>().valid(); }
+  uint64_t fs_discard() const { return at<15>().as_uint64(); }
+  bool has_fs_drio() const { return at<16>().valid(); }
+  uint64_t fs_drio() const { return at<16>().as_uint64(); }
+  bool has_fs_gc_dio() const { return at<17>().valid(); }
+  uint64_t fs_gc_dio() const { return at<17>().as_uint64(); }
+  bool has_fs_gc_nio() const { return at<18>().valid(); }
+  uint64_t fs_gc_nio() const { return at<18>().as_uint64(); }
+  bool has_fs_gdrio() const { return at<19>().valid(); }
+  uint64_t fs_gdrio() const { return at<19>().as_uint64(); }
+  bool has_fs_mio() const { return at<20>().valid(); }
+  uint64_t fs_mio() const { return at<20>().as_uint64(); }
+  bool has_fs_mrio() const { return at<21>().valid(); }
+  uint64_t fs_mrio() const { return at<21>().as_uint64(); }
+  bool has_fs_nio() const { return at<22>().valid(); }
+  uint64_t fs_nio() const { return at<22>().as_uint64(); }
+  bool has_fs_nrio() const { return at<23>().valid(); }
+  uint64_t fs_nrio() const { return at<23>().as_uint64(); }
+};
+
+class F2fsIostatFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsIostatFtraceEvent_Decoder;
+  enum : int32_t {
+    kAppBioFieldNumber = 1,
+    kAppBrioFieldNumber = 2,
+    kAppDioFieldNumber = 3,
+    kAppDrioFieldNumber = 4,
+    kAppMioFieldNumber = 5,
+    kAppMrioFieldNumber = 6,
+    kAppRioFieldNumber = 7,
+    kAppWioFieldNumber = 8,
+    kDevFieldNumber = 9,
+    kFsCdrioFieldNumber = 10,
+    kFsCpDioFieldNumber = 11,
+    kFsCpMioFieldNumber = 12,
+    kFsCpNioFieldNumber = 13,
+    kFsDioFieldNumber = 14,
+    kFsDiscardFieldNumber = 15,
+    kFsDrioFieldNumber = 16,
+    kFsGcDioFieldNumber = 17,
+    kFsGcNioFieldNumber = 18,
+    kFsGdrioFieldNumber = 19,
+    kFsMioFieldNumber = 20,
+    kFsMrioFieldNumber = 21,
+    kFsNioFieldNumber = 22,
+    kFsNrioFieldNumber = 23,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsIostatFtraceEvent"; }
+
+
+  using FieldMetadata_AppBio =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_AppBio kAppBio{};
+  void set_app_bio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AppBio::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_AppBrio =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_AppBrio kAppBrio{};
+  void set_app_brio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AppBrio::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_AppDio =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_AppDio kAppDio{};
+  void set_app_dio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AppDio::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_AppDrio =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_AppDrio kAppDrio{};
+  void set_app_drio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AppDrio::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_AppMio =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_AppMio kAppMio{};
+  void set_app_mio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AppMio::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_AppMrio =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_AppMrio kAppMrio{};
+  void set_app_mrio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AppMrio::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_AppRio =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_AppRio kAppRio{};
+  void set_app_rio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AppRio::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_AppWio =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_AppWio kAppWio{};
+  void set_app_wio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AppWio::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_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_FsCdrio =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_FsCdrio kFsCdrio{};
+  void set_fs_cdrio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FsCdrio::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_FsCpDio =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_FsCpDio kFsCpDio{};
+  void set_fs_cp_dio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FsCpDio::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_FsCpMio =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_FsCpMio kFsCpMio{};
+  void set_fs_cp_mio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FsCpMio::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_FsCpNio =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_FsCpNio kFsCpNio{};
+  void set_fs_cp_nio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FsCpNio::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_FsDio =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_FsDio kFsDio{};
+  void set_fs_dio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FsDio::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_FsDiscard =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_FsDiscard kFsDiscard{};
+  void set_fs_discard(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FsDiscard::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_FsDrio =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_FsDrio kFsDrio{};
+  void set_fs_drio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FsDrio::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_FsGcDio =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_FsGcDio kFsGcDio{};
+  void set_fs_gc_dio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FsGcDio::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_FsGcNio =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_FsGcNio kFsGcNio{};
+  void set_fs_gc_nio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FsGcNio::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_FsGdrio =
+    ::protozero::proto_utils::FieldMetadata<
+      19,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_FsGdrio kFsGdrio{};
+  void set_fs_gdrio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FsGdrio::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_FsMio =
+    ::protozero::proto_utils::FieldMetadata<
+      20,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_FsMio kFsMio{};
+  void set_fs_mio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FsMio::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_FsMrio =
+    ::protozero::proto_utils::FieldMetadata<
+      21,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_FsMrio kFsMrio{};
+  void set_fs_mrio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FsMrio::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_FsNio =
+    ::protozero::proto_utils::FieldMetadata<
+      22,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_FsNio kFsNio{};
+  void set_fs_nio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FsNio::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_FsNrio =
+    ::protozero::proto_utils::FieldMetadata<
+      23,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_FsNrio kFsNrio{};
+  void set_fs_nrio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FsNrio::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 F2fsWriteEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsWriteEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsWriteEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsWriteEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pos() const { return at<3>().valid(); }
+  int64_t pos() const { return at<3>().as_int64(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint32_t len() const { return at<4>().as_uint32(); }
+  bool has_copied() const { return at<5>().valid(); }
+  uint32_t copied() const { return at<5>().as_uint32(); }
+};
+
+class F2fsWriteEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsWriteEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPosFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kCopiedFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsWriteEndFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsWriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsWriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Pos =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      F2fsWriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Pos kPos{};
+  void set_pos(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pos::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsWriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Copied =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsWriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Copied kCopied{};
+  void set_copied(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Copied::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 F2fsWriteCheckpointFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsWriteCheckpointFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsWriteCheckpointFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsWriteCheckpointFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_is_umount() const { return at<2>().valid(); }
+  uint32_t is_umount() const { return at<2>().as_uint32(); }
+  bool has_msg() const { return at<3>().valid(); }
+  ::protozero::ConstChars msg() const { return at<3>().as_string(); }
+  bool has_reason() const { return at<4>().valid(); }
+  int32_t reason() const { return at<4>().as_int32(); }
+};
+
+class F2fsWriteCheckpointFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsWriteCheckpointFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kIsUmountFieldNumber = 2,
+    kMsgFieldNumber = 3,
+    kReasonFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsWriteCheckpointFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsWriteCheckpointFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_IsUmount =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsWriteCheckpointFtraceEvent>;
+
+  static constexpr FieldMetadata_IsUmount kIsUmount{};
+  void set_is_umount(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsUmount::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_Msg =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      F2fsWriteCheckpointFtraceEvent>;
+
+  static constexpr FieldMetadata_Msg kMsg{};
+  void set_msg(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Msg::kFieldId, data, size);
+  }
+  void set_msg(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Msg::kFieldId, chars.data, chars.size);
+  }
+  void set_msg(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Msg::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_Reason =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsWriteCheckpointFtraceEvent>;
+
+  static constexpr FieldMetadata_Reason kReason{};
+  void set_reason(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Reason::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);
+  }
+};
+
+class F2fsWriteBeginFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsWriteBeginFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsWriteBeginFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsWriteBeginFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pos() const { return at<3>().valid(); }
+  int64_t pos() const { return at<3>().as_int64(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint32_t len() const { return at<4>().as_uint32(); }
+  bool has_flags() const { return at<5>().valid(); }
+  uint32_t flags() const { return at<5>().as_uint32(); }
+};
+
+class F2fsWriteBeginFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsWriteBeginFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPosFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kFlagsFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsWriteBeginFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsWriteBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsWriteBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Pos =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      F2fsWriteBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_Pos kPos{};
+  void set_pos(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pos::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsWriteBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsWriteBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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 F2fsVmPageMkwriteFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsVmPageMkwriteFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsVmPageMkwriteFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsVmPageMkwriteFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_type() const { return at<3>().valid(); }
+  int32_t type() const { return at<3>().as_int32(); }
+  bool has_dir() const { return at<4>().valid(); }
+  int32_t dir() const { return at<4>().as_int32(); }
+  bool has_index() const { return at<5>().valid(); }
+  uint64_t index() const { return at<5>().as_uint64(); }
+  bool has_dirty() const { return at<6>().valid(); }
+  int32_t dirty() const { return at<6>().as_int32(); }
+  bool has_uptodate() const { return at<7>().valid(); }
+  int32_t uptodate() const { return at<7>().as_int32(); }
+};
+
+class F2fsVmPageMkwriteFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsVmPageMkwriteFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kTypeFieldNumber = 3,
+    kDirFieldNumber = 4,
+    kIndexFieldNumber = 5,
+    kDirtyFieldNumber = 6,
+    kUptodateFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsVmPageMkwriteFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsVmPageMkwriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsVmPageMkwriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsVmPageMkwriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::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_Dir =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsVmPageMkwriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Dir kDir{};
+  void set_dir(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dir::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_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsVmPageMkwriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Index kIndex{};
+  void set_index(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Index::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_Dirty =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsVmPageMkwriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Dirty kDirty{};
+  void set_dirty(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dirty::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_Uptodate =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsVmPageMkwriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Uptodate kUptodate{};
+  void set_uptodate(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Uptodate::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);
+  }
+};
+
+class F2fsUnlinkExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsUnlinkExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsUnlinkExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsUnlinkExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_ret() const { return at<3>().valid(); }
+  int32_t ret() const { return at<3>().as_int32(); }
+};
+
+class F2fsUnlinkExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsUnlinkExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kRetFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsUnlinkExitFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsUnlinkExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsUnlinkExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsUnlinkExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::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);
+  }
+};
+
+class F2fsUnlinkEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsUnlinkEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsUnlinkEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsUnlinkEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_size() const { return at<3>().valid(); }
+  int64_t size() const { return at<3>().as_int64(); }
+  bool has_blocks() const { return at<4>().valid(); }
+  uint64_t blocks() const { return at<4>().as_uint64(); }
+  bool has_name() const { return at<5>().valid(); }
+  ::protozero::ConstChars name() const { return at<5>().as_string(); }
+};
+
+class F2fsUnlinkEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsUnlinkEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kSizeFieldNumber = 3,
+    kBlocksFieldNumber = 4,
+    kNameFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsUnlinkEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsUnlinkEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsUnlinkEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      F2fsUnlinkEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void set_size(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::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_Blocks =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsUnlinkEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Blocks kBlocks{};
+  void set_blocks(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Blocks::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      F2fsUnlinkEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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);
+  }
+};
+
+class F2fsTruncatePartialNodesFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsTruncatePartialNodesFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsTruncatePartialNodesFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsTruncatePartialNodesFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_nid() const { return at<3>().valid(); }
+  uint32_t nid() const { return at<3>().as_uint32(); }
+  bool has_depth() const { return at<4>().valid(); }
+  int32_t depth() const { return at<4>().as_int32(); }
+  bool has_err() const { return at<5>().valid(); }
+  int32_t err() const { return at<5>().as_int32(); }
+};
+
+class F2fsTruncatePartialNodesFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsTruncatePartialNodesFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kNidFieldNumber = 3,
+    kDepthFieldNumber = 4,
+    kErrFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsTruncatePartialNodesFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncatePartialNodesFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncatePartialNodesFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsTruncatePartialNodesFtraceEvent>;
+
+  static constexpr FieldMetadata_Nid kNid{};
+  void set_nid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nid::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_Depth =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsTruncatePartialNodesFtraceEvent>;
+
+  static constexpr FieldMetadata_Depth kDepth{};
+  void set_depth(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Depth::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_Err =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsTruncatePartialNodesFtraceEvent>;
+
+  static constexpr FieldMetadata_Err kErr{};
+  void set_err(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Err::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);
+  }
+};
+
+class F2fsTruncateNodesExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsTruncateNodesExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsTruncateNodesExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsTruncateNodesExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_ret() const { return at<3>().valid(); }
+  int32_t ret() const { return at<3>().as_int32(); }
+};
+
+class F2fsTruncateNodesExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsTruncateNodesExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kRetFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsTruncateNodesExitFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateNodesExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateNodesExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsTruncateNodesExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::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);
+  }
+};
+
+class F2fsTruncateNodesEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsTruncateNodesEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsTruncateNodesEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsTruncateNodesEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_nid() const { return at<3>().valid(); }
+  uint32_t nid() const { return at<3>().as_uint32(); }
+  bool has_blk_addr() const { return at<4>().valid(); }
+  uint32_t blk_addr() const { return at<4>().as_uint32(); }
+};
+
+class F2fsTruncateNodesEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsTruncateNodesEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kNidFieldNumber = 3,
+    kBlkAddrFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsTruncateNodesEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateNodesEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateNodesEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsTruncateNodesEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Nid kNid{};
+  void set_nid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nid::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_BlkAddr =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsTruncateNodesEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_BlkAddr kBlkAddr{};
+  void set_blk_addr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BlkAddr::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 F2fsTruncateNodeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsTruncateNodeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsTruncateNodeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsTruncateNodeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_nid() const { return at<3>().valid(); }
+  uint32_t nid() const { return at<3>().as_uint32(); }
+  bool has_blk_addr() const { return at<4>().valid(); }
+  uint32_t blk_addr() const { return at<4>().as_uint32(); }
+};
+
+class F2fsTruncateNodeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsTruncateNodeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kNidFieldNumber = 3,
+    kBlkAddrFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsTruncateNodeFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateNodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateNodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsTruncateNodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Nid kNid{};
+  void set_nid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nid::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_BlkAddr =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsTruncateNodeFtraceEvent>;
+
+  static constexpr FieldMetadata_BlkAddr kBlkAddr{};
+  void set_blk_addr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BlkAddr::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 F2fsTruncateInodeBlocksExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsTruncateInodeBlocksExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsTruncateInodeBlocksExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsTruncateInodeBlocksExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_ret() const { return at<3>().valid(); }
+  int32_t ret() const { return at<3>().as_int32(); }
+};
+
+class F2fsTruncateInodeBlocksExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsTruncateInodeBlocksExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kRetFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsTruncateInodeBlocksExitFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateInodeBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateInodeBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsTruncateInodeBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::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);
+  }
+};
+
+class F2fsTruncateInodeBlocksEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsTruncateInodeBlocksEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsTruncateInodeBlocksEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsTruncateInodeBlocksEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_size() const { return at<3>().valid(); }
+  int64_t size() const { return at<3>().as_int64(); }
+  bool has_blocks() const { return at<4>().valid(); }
+  uint64_t blocks() const { return at<4>().as_uint64(); }
+  bool has_from() const { return at<5>().valid(); }
+  uint64_t from() const { return at<5>().as_uint64(); }
+};
+
+class F2fsTruncateInodeBlocksEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsTruncateInodeBlocksEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kSizeFieldNumber = 3,
+    kBlocksFieldNumber = 4,
+    kFromFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsTruncateInodeBlocksEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateInodeBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateInodeBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      F2fsTruncateInodeBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void set_size(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::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_Blocks =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateInodeBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Blocks kBlocks{};
+  void set_blocks(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Blocks::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_From =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateInodeBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_From kFrom{};
+  void set_from(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_From::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 F2fsTruncateDataBlocksRangeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsTruncateDataBlocksRangeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsTruncateDataBlocksRangeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsTruncateDataBlocksRangeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_nid() const { return at<3>().valid(); }
+  uint32_t nid() const { return at<3>().as_uint32(); }
+  bool has_ofs() const { return at<4>().valid(); }
+  uint32_t ofs() const { return at<4>().as_uint32(); }
+  bool has_free() const { return at<5>().valid(); }
+  int32_t free() const { return at<5>().as_int32(); }
+};
+
+class F2fsTruncateDataBlocksRangeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsTruncateDataBlocksRangeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kNidFieldNumber = 3,
+    kOfsFieldNumber = 4,
+    kFreeFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsTruncateDataBlocksRangeFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateDataBlocksRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateDataBlocksRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsTruncateDataBlocksRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Nid kNid{};
+  void set_nid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nid::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_Ofs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsTruncateDataBlocksRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ofs kOfs{};
+  void set_ofs(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ofs::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_Free =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsTruncateDataBlocksRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Free kFree{};
+  void set_free(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Free::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);
+  }
+};
+
+class F2fsTruncateBlocksExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsTruncateBlocksExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsTruncateBlocksExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsTruncateBlocksExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_ret() const { return at<3>().valid(); }
+  int32_t ret() const { return at<3>().as_int32(); }
+};
+
+class F2fsTruncateBlocksExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsTruncateBlocksExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kRetFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsTruncateBlocksExitFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsTruncateBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::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);
+  }
+};
+
+class F2fsTruncateBlocksEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsTruncateBlocksEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsTruncateBlocksEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsTruncateBlocksEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_size() const { return at<3>().valid(); }
+  int64_t size() const { return at<3>().as_int64(); }
+  bool has_blocks() const { return at<4>().valid(); }
+  uint64_t blocks() const { return at<4>().as_uint64(); }
+  bool has_from() const { return at<5>().valid(); }
+  uint64_t from() const { return at<5>().as_uint64(); }
+};
+
+class F2fsTruncateBlocksEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsTruncateBlocksEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kSizeFieldNumber = 3,
+    kBlocksFieldNumber = 4,
+    kFromFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsTruncateBlocksEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      F2fsTruncateBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void set_size(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::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_Blocks =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Blocks kBlocks{};
+  void set_blocks(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Blocks::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_From =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_From kFrom{};
+  void set_from(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_From::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 F2fsTruncateFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsTruncateFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsTruncateFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsTruncateFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pino() const { return at<3>().valid(); }
+  uint64_t pino() const { return at<3>().as_uint64(); }
+  bool has_mode() const { return at<4>().valid(); }
+  uint32_t mode() const { return at<4>().as_uint32(); }
+  bool has_size() const { return at<5>().valid(); }
+  int64_t size() const { return at<5>().as_int64(); }
+  bool has_nlink() const { return at<6>().valid(); }
+  uint32_t nlink() const { return at<6>().as_uint32(); }
+  bool has_blocks() const { return at<7>().valid(); }
+  uint64_t blocks() const { return at<7>().as_uint64(); }
+  bool has_advise() const { return at<8>().valid(); }
+  uint32_t advise() const { return at<8>().as_uint32(); }
+};
+
+class F2fsTruncateFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsTruncateFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPinoFieldNumber = 3,
+    kModeFieldNumber = 4,
+    kSizeFieldNumber = 5,
+    kNlinkFieldNumber = 6,
+    kBlocksFieldNumber = 7,
+    kAdviseFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsTruncateFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Pino =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateFtraceEvent>;
+
+  static constexpr FieldMetadata_Pino kPino{};
+  void set_pino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pino::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_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsTruncateFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::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_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      F2fsTruncateFtraceEvent>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void set_size(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::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_Nlink =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsTruncateFtraceEvent>;
+
+  static constexpr FieldMetadata_Nlink kNlink{};
+  void set_nlink(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nlink::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_Blocks =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateFtraceEvent>;
+
+  static constexpr FieldMetadata_Blocks kBlocks{};
+  void set_blocks(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Blocks::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_Advise =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsTruncateFtraceEvent>;
+
+  static constexpr FieldMetadata_Advise kAdvise{};
+  void set_advise(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Advise::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 F2fsSyncFsFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsSyncFsFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsSyncFsFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsSyncFsFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_dirty() const { return at<2>().valid(); }
+  int32_t dirty() const { return at<2>().as_int32(); }
+  bool has_wait() const { return at<3>().valid(); }
+  int32_t wait() const { return at<3>().as_int32(); }
+};
+
+class F2fsSyncFsFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsSyncFsFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kDirtyFieldNumber = 2,
+    kWaitFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsSyncFsFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsSyncFsFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Dirty =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsSyncFsFtraceEvent>;
+
+  static constexpr FieldMetadata_Dirty kDirty{};
+  void set_dirty(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dirty::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_Wait =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsSyncFsFtraceEvent>;
+
+  static constexpr FieldMetadata_Wait kWait{};
+  void set_wait(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Wait::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);
+  }
+};
+
+class F2fsSyncFileExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsSyncFileExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsSyncFileExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsSyncFileExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_need_cp() const { return at<3>().valid(); }
+  uint32_t need_cp() const { return at<3>().as_uint32(); }
+  bool has_datasync() const { return at<4>().valid(); }
+  int32_t datasync() const { return at<4>().as_int32(); }
+  bool has_ret() const { return at<5>().valid(); }
+  int32_t ret() const { return at<5>().as_int32(); }
+  bool has_cp_reason() const { return at<6>().valid(); }
+  int32_t cp_reason() const { return at<6>().as_int32(); }
+};
+
+class F2fsSyncFileExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsSyncFileExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kNeedCpFieldNumber = 3,
+    kDatasyncFieldNumber = 4,
+    kRetFieldNumber = 5,
+    kCpReasonFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsSyncFileExitFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsSyncFileExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsSyncFileExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_NeedCp =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsSyncFileExitFtraceEvent>;
+
+  static constexpr FieldMetadata_NeedCp kNeedCp{};
+  void set_need_cp(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NeedCp::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_Datasync =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsSyncFileExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Datasync kDatasync{};
+  void set_datasync(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Datasync::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_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsSyncFileExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::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_CpReason =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsSyncFileExitFtraceEvent>;
+
+  static constexpr FieldMetadata_CpReason kCpReason{};
+  void set_cp_reason(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CpReason::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);
+  }
+};
+
+class F2fsSyncFileEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsSyncFileEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsSyncFileEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsSyncFileEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pino() const { return at<3>().valid(); }
+  uint64_t pino() const { return at<3>().as_uint64(); }
+  bool has_mode() const { return at<4>().valid(); }
+  uint32_t mode() const { return at<4>().as_uint32(); }
+  bool has_size() const { return at<5>().valid(); }
+  int64_t size() const { return at<5>().as_int64(); }
+  bool has_nlink() const { return at<6>().valid(); }
+  uint32_t nlink() const { return at<6>().as_uint32(); }
+  bool has_blocks() const { return at<7>().valid(); }
+  uint64_t blocks() const { return at<7>().as_uint64(); }
+  bool has_advise() const { return at<8>().valid(); }
+  uint32_t advise() const { return at<8>().as_uint32(); }
+};
+
+class F2fsSyncFileEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsSyncFileEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPinoFieldNumber = 3,
+    kModeFieldNumber = 4,
+    kSizeFieldNumber = 5,
+    kNlinkFieldNumber = 6,
+    kBlocksFieldNumber = 7,
+    kAdviseFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsSyncFileEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsSyncFileEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsSyncFileEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Pino =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsSyncFileEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Pino kPino{};
+  void set_pino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pino::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_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsSyncFileEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::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_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      F2fsSyncFileEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void set_size(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::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_Nlink =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsSyncFileEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Nlink kNlink{};
+  void set_nlink(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nlink::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_Blocks =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsSyncFileEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Blocks kBlocks{};
+  void set_blocks(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Blocks::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_Advise =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsSyncFileEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Advise kAdvise{};
+  void set_advise(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Advise::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 F2fsSubmitWritePageFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsSubmitWritePageFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsSubmitWritePageFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsSubmitWritePageFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_type() const { return at<3>().valid(); }
+  int32_t type() const { return at<3>().as_int32(); }
+  bool has_index() const { return at<4>().valid(); }
+  uint64_t index() const { return at<4>().as_uint64(); }
+  bool has_block() const { return at<5>().valid(); }
+  uint32_t block() const { return at<5>().as_uint32(); }
+};
+
+class F2fsSubmitWritePageFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsSubmitWritePageFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kTypeFieldNumber = 3,
+    kIndexFieldNumber = 4,
+    kBlockFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsSubmitWritePageFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsSubmitWritePageFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsSubmitWritePageFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsSubmitWritePageFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::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_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsSubmitWritePageFtraceEvent>;
+
+  static constexpr FieldMetadata_Index kIndex{};
+  void set_index(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Index::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_Block =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsSubmitWritePageFtraceEvent>;
+
+  static constexpr FieldMetadata_Block kBlock{};
+  void set_block(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Block::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 F2fsSetPageDirtyFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsSetPageDirtyFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsSetPageDirtyFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsSetPageDirtyFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_type() const { return at<3>().valid(); }
+  int32_t type() const { return at<3>().as_int32(); }
+  bool has_dir() const { return at<4>().valid(); }
+  int32_t dir() const { return at<4>().as_int32(); }
+  bool has_index() const { return at<5>().valid(); }
+  uint64_t index() const { return at<5>().as_uint64(); }
+  bool has_dirty() const { return at<6>().valid(); }
+  int32_t dirty() const { return at<6>().as_int32(); }
+  bool has_uptodate() const { return at<7>().valid(); }
+  int32_t uptodate() const { return at<7>().as_int32(); }
+};
+
+class F2fsSetPageDirtyFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsSetPageDirtyFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kTypeFieldNumber = 3,
+    kDirFieldNumber = 4,
+    kIndexFieldNumber = 5,
+    kDirtyFieldNumber = 6,
+    kUptodateFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsSetPageDirtyFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsSetPageDirtyFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsSetPageDirtyFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsSetPageDirtyFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::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_Dir =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsSetPageDirtyFtraceEvent>;
+
+  static constexpr FieldMetadata_Dir kDir{};
+  void set_dir(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dir::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_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsSetPageDirtyFtraceEvent>;
+
+  static constexpr FieldMetadata_Index kIndex{};
+  void set_index(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Index::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_Dirty =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsSetPageDirtyFtraceEvent>;
+
+  static constexpr FieldMetadata_Dirty kDirty{};
+  void set_dirty(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dirty::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_Uptodate =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsSetPageDirtyFtraceEvent>;
+
+  static constexpr FieldMetadata_Uptodate kUptodate{};
+  void set_uptodate(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Uptodate::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);
+  }
+};
+
+class F2fsReserveNewBlockFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsReserveNewBlockFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsReserveNewBlockFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsReserveNewBlockFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_nid() const { return at<2>().valid(); }
+  uint32_t nid() const { return at<2>().as_uint32(); }
+  bool has_ofs_in_node() const { return at<3>().valid(); }
+  uint32_t ofs_in_node() const { return at<3>().as_uint32(); }
+};
+
+class F2fsReserveNewBlockFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsReserveNewBlockFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kNidFieldNumber = 2,
+    kOfsInNodeFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsReserveNewBlockFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsReserveNewBlockFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsReserveNewBlockFtraceEvent>;
+
+  static constexpr FieldMetadata_Nid kNid{};
+  void set_nid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nid::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_OfsInNode =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsReserveNewBlockFtraceEvent>;
+
+  static constexpr FieldMetadata_OfsInNode kOfsInNode{};
+  void set_ofs_in_node(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OfsInNode::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 F2fsReadpageFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsReadpageFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsReadpageFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsReadpageFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_index() const { return at<3>().valid(); }
+  uint64_t index() const { return at<3>().as_uint64(); }
+  bool has_blkaddr() const { return at<4>().valid(); }
+  uint64_t blkaddr() const { return at<4>().as_uint64(); }
+  bool has_type() const { return at<5>().valid(); }
+  int32_t type() const { return at<5>().as_int32(); }
+  bool has_dir() const { return at<6>().valid(); }
+  int32_t dir() const { return at<6>().as_int32(); }
+  bool has_dirty() const { return at<7>().valid(); }
+  int32_t dirty() const { return at<7>().as_int32(); }
+  bool has_uptodate() const { return at<8>().valid(); }
+  int32_t uptodate() const { return at<8>().as_int32(); }
+};
+
+class F2fsReadpageFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsReadpageFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kIndexFieldNumber = 3,
+    kBlkaddrFieldNumber = 4,
+    kTypeFieldNumber = 5,
+    kDirFieldNumber = 6,
+    kDirtyFieldNumber = 7,
+    kUptodateFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsReadpageFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsReadpageFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsReadpageFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsReadpageFtraceEvent>;
+
+  static constexpr FieldMetadata_Index kIndex{};
+  void set_index(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Index::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_Blkaddr =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsReadpageFtraceEvent>;
+
+  static constexpr FieldMetadata_Blkaddr kBlkaddr{};
+  void set_blkaddr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Blkaddr::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_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsReadpageFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::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_Dir =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsReadpageFtraceEvent>;
+
+  static constexpr FieldMetadata_Dir kDir{};
+  void set_dir(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dir::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_Dirty =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsReadpageFtraceEvent>;
+
+  static constexpr FieldMetadata_Dirty kDirty{};
+  void set_dirty(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dirty::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_Uptodate =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsReadpageFtraceEvent>;
+
+  static constexpr FieldMetadata_Uptodate kUptodate{};
+  void set_uptodate(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Uptodate::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);
+  }
+};
+
+class F2fsNewInodeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsNewInodeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsNewInodeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsNewInodeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_ret() const { return at<3>().valid(); }
+  int32_t ret() const { return at<3>().as_int32(); }
+};
+
+class F2fsNewInodeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsNewInodeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kRetFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsNewInodeFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsNewInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsNewInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsNewInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::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);
+  }
+};
+
+class F2fsIgetExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsIgetExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsIgetExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsIgetExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_ret() const { return at<3>().valid(); }
+  int32_t ret() const { return at<3>().as_int32(); }
+};
+
+class F2fsIgetExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsIgetExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kRetFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsIgetExitFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIgetExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIgetExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsIgetExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::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);
+  }
+};
+
+class F2fsIgetFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsIgetFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsIgetFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsIgetFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pino() const { return at<3>().valid(); }
+  uint64_t pino() const { return at<3>().as_uint64(); }
+  bool has_mode() const { return at<4>().valid(); }
+  uint32_t mode() const { return at<4>().as_uint32(); }
+  bool has_size() const { return at<5>().valid(); }
+  int64_t size() const { return at<5>().as_int64(); }
+  bool has_nlink() const { return at<6>().valid(); }
+  uint32_t nlink() const { return at<6>().as_uint32(); }
+  bool has_blocks() const { return at<7>().valid(); }
+  uint64_t blocks() const { return at<7>().as_uint64(); }
+  bool has_advise() const { return at<8>().valid(); }
+  uint32_t advise() const { return at<8>().as_uint32(); }
+};
+
+class F2fsIgetFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsIgetFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPinoFieldNumber = 3,
+    kModeFieldNumber = 4,
+    kSizeFieldNumber = 5,
+    kNlinkFieldNumber = 6,
+    kBlocksFieldNumber = 7,
+    kAdviseFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsIgetFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIgetFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIgetFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Pino =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIgetFtraceEvent>;
+
+  static constexpr FieldMetadata_Pino kPino{};
+  void set_pino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pino::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_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIgetFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::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_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      F2fsIgetFtraceEvent>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void set_size(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::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_Nlink =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIgetFtraceEvent>;
+
+  static constexpr FieldMetadata_Nlink kNlink{};
+  void set_nlink(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nlink::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_Blocks =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIgetFtraceEvent>;
+
+  static constexpr FieldMetadata_Blocks kBlocks{};
+  void set_blocks(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Blocks::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_Advise =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIgetFtraceEvent>;
+
+  static constexpr FieldMetadata_Advise kAdvise{};
+  void set_advise(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Advise::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 F2fsGetVictimFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/11, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsGetVictimFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsGetVictimFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsGetVictimFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_type() const { return at<2>().valid(); }
+  int32_t type() const { return at<2>().as_int32(); }
+  bool has_gc_type() const { return at<3>().valid(); }
+  int32_t gc_type() const { return at<3>().as_int32(); }
+  bool has_alloc_mode() const { return at<4>().valid(); }
+  int32_t alloc_mode() const { return at<4>().as_int32(); }
+  bool has_gc_mode() const { return at<5>().valid(); }
+  int32_t gc_mode() const { return at<5>().as_int32(); }
+  bool has_victim() const { return at<6>().valid(); }
+  uint32_t victim() const { return at<6>().as_uint32(); }
+  bool has_ofs_unit() const { return at<7>().valid(); }
+  uint32_t ofs_unit() const { return at<7>().as_uint32(); }
+  bool has_pre_victim() const { return at<8>().valid(); }
+  uint32_t pre_victim() const { return at<8>().as_uint32(); }
+  bool has_prefree() const { return at<9>().valid(); }
+  uint32_t prefree() const { return at<9>().as_uint32(); }
+  bool has_free() const { return at<10>().valid(); }
+  uint32_t free() const { return at<10>().as_uint32(); }
+  bool has_cost() const { return at<11>().valid(); }
+  uint32_t cost() const { return at<11>().as_uint32(); }
+};
+
+class F2fsGetVictimFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsGetVictimFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kTypeFieldNumber = 2,
+    kGcTypeFieldNumber = 3,
+    kAllocModeFieldNumber = 4,
+    kGcModeFieldNumber = 5,
+    kVictimFieldNumber = 6,
+    kOfsUnitFieldNumber = 7,
+    kPreVictimFieldNumber = 8,
+    kPrefreeFieldNumber = 9,
+    kFreeFieldNumber = 10,
+    kCostFieldNumber = 11,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsGetVictimFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsGetVictimFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsGetVictimFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::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_GcType =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsGetVictimFtraceEvent>;
+
+  static constexpr FieldMetadata_GcType kGcType{};
+  void set_gc_type(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GcType::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_AllocMode =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsGetVictimFtraceEvent>;
+
+  static constexpr FieldMetadata_AllocMode kAllocMode{};
+  void set_alloc_mode(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AllocMode::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_GcMode =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsGetVictimFtraceEvent>;
+
+  static constexpr FieldMetadata_GcMode kGcMode{};
+  void set_gc_mode(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GcMode::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_Victim =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsGetVictimFtraceEvent>;
+
+  static constexpr FieldMetadata_Victim kVictim{};
+  void set_victim(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Victim::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_OfsUnit =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsGetVictimFtraceEvent>;
+
+  static constexpr FieldMetadata_OfsUnit kOfsUnit{};
+  void set_ofs_unit(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OfsUnit::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_PreVictim =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsGetVictimFtraceEvent>;
+
+  static constexpr FieldMetadata_PreVictim kPreVictim{};
+  void set_pre_victim(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PreVictim::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_Prefree =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsGetVictimFtraceEvent>;
+
+  static constexpr FieldMetadata_Prefree kPrefree{};
+  void set_prefree(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Prefree::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_Free =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsGetVictimFtraceEvent>;
+
+  static constexpr FieldMetadata_Free kFree{};
+  void set_free(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Free::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_Cost =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsGetVictimFtraceEvent>;
+
+  static constexpr FieldMetadata_Cost kCost{};
+  void set_cost(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cost::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 F2fsGetDataBlockFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsGetDataBlockFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsGetDataBlockFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsGetDataBlockFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_iblock() const { return at<3>().valid(); }
+  uint64_t iblock() const { return at<3>().as_uint64(); }
+  bool has_bh_start() const { return at<4>().valid(); }
+  uint64_t bh_start() const { return at<4>().as_uint64(); }
+  bool has_bh_size() const { return at<5>().valid(); }
+  uint64_t bh_size() const { return at<5>().as_uint64(); }
+  bool has_ret() const { return at<6>().valid(); }
+  int32_t ret() const { return at<6>().as_int32(); }
+};
+
+class F2fsGetDataBlockFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsGetDataBlockFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kIblockFieldNumber = 3,
+    kBhStartFieldNumber = 4,
+    kBhSizeFieldNumber = 5,
+    kRetFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsGetDataBlockFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsGetDataBlockFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsGetDataBlockFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Iblock =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsGetDataBlockFtraceEvent>;
+
+  static constexpr FieldMetadata_Iblock kIblock{};
+  void set_iblock(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iblock::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_BhStart =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsGetDataBlockFtraceEvent>;
+
+  static constexpr FieldMetadata_BhStart kBhStart{};
+  void set_bh_start(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BhStart::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_BhSize =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsGetDataBlockFtraceEvent>;
+
+  static constexpr FieldMetadata_BhSize kBhSize{};
+  void set_bh_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BhSize::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_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsGetDataBlockFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::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);
+  }
+};
+
+class F2fsFallocateFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsFallocateFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsFallocateFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsFallocateFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_mode() const { return at<3>().valid(); }
+  int32_t mode() const { return at<3>().as_int32(); }
+  bool has_offset() const { return at<4>().valid(); }
+  int64_t offset() const { return at<4>().as_int64(); }
+  bool has_len() const { return at<5>().valid(); }
+  int64_t len() const { return at<5>().as_int64(); }
+  bool has_size() const { return at<6>().valid(); }
+  int64_t size() const { return at<6>().as_int64(); }
+  bool has_blocks() const { return at<7>().valid(); }
+  uint64_t blocks() const { return at<7>().as_uint64(); }
+  bool has_ret() const { return at<8>().valid(); }
+  int32_t ret() const { return at<8>().as_int32(); }
+};
+
+class F2fsFallocateFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsFallocateFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kModeFieldNumber = 3,
+    kOffsetFieldNumber = 4,
+    kLenFieldNumber = 5,
+    kSizeFieldNumber = 6,
+    kBlocksFieldNumber = 7,
+    kRetFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsFallocateFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsFallocateFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsFallocateFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsFallocateFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::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_Offset =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      F2fsFallocateFtraceEvent>;
+
+  static constexpr FieldMetadata_Offset kOffset{};
+  void set_offset(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Offset::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      F2fsFallocateFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      F2fsFallocateFtraceEvent>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void set_size(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::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_Blocks =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsFallocateFtraceEvent>;
+
+  static constexpr FieldMetadata_Blocks kBlocks{};
+  void set_blocks(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Blocks::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_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsFallocateFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::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);
+  }
+};
+
+class F2fsEvictInodeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsEvictInodeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsEvictInodeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsEvictInodeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pino() const { return at<3>().valid(); }
+  uint64_t pino() const { return at<3>().as_uint64(); }
+  bool has_mode() const { return at<4>().valid(); }
+  uint32_t mode() const { return at<4>().as_uint32(); }
+  bool has_size() const { return at<5>().valid(); }
+  int64_t size() const { return at<5>().as_int64(); }
+  bool has_nlink() const { return at<6>().valid(); }
+  uint32_t nlink() const { return at<6>().as_uint32(); }
+  bool has_blocks() const { return at<7>().valid(); }
+  uint64_t blocks() const { return at<7>().as_uint64(); }
+  bool has_advise() const { return at<8>().valid(); }
+  uint32_t advise() const { return at<8>().as_uint32(); }
+};
+
+class F2fsEvictInodeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsEvictInodeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPinoFieldNumber = 3,
+    kModeFieldNumber = 4,
+    kSizeFieldNumber = 5,
+    kNlinkFieldNumber = 6,
+    kBlocksFieldNumber = 7,
+    kAdviseFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsEvictInodeFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsEvictInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsEvictInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::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_Pino =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsEvictInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Pino kPino{};
+  void set_pino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pino::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_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsEvictInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::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_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      F2fsEvictInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void set_size(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::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_Nlink =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsEvictInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Nlink kNlink{};
+  void set_nlink(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nlink::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_Blocks =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsEvictInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Blocks kBlocks{};
+  void set_blocks(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Blocks::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_Advise =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsEvictInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Advise kAdvise{};
+  void set_advise(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Advise::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 F2fsDoSubmitBioFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsDoSubmitBioFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsDoSubmitBioFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsDoSubmitBioFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_btype() const { return at<2>().valid(); }
+  int32_t btype() const { return at<2>().as_int32(); }
+  bool has_sync() const { return at<3>().valid(); }
+  uint32_t sync() const { return at<3>().as_uint32(); }
+  bool has_sector() const { return at<4>().valid(); }
+  uint64_t sector() const { return at<4>().as_uint64(); }
+  bool has_size() const { return at<5>().valid(); }
+  uint32_t size() const { return at<5>().as_uint32(); }
+};
+
+class F2fsDoSubmitBioFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsDoSubmitBioFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kBtypeFieldNumber = 2,
+    kSyncFieldNumber = 3,
+    kSectorFieldNumber = 4,
+    kSizeFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsDoSubmitBioFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsDoSubmitBioFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_Btype =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsDoSubmitBioFtraceEvent>;
+
+  static constexpr FieldMetadata_Btype kBtype{};
+  void set_btype(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Btype::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_Sync =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsDoSubmitBioFtraceEvent>;
+
+  static constexpr FieldMetadata_Sync kSync{};
+  void set_sync(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sync::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_Sector =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsDoSubmitBioFtraceEvent>;
+
+  static constexpr FieldMetadata_Sector kSector{};
+  void set_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sector::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_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsDoSubmitBioFtraceEvent>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void set_size(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/fastrpc.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_FASTRPC_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_FASTRPC_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class FastrpcDmaMapFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FastrpcDmaMapFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FastrpcDmaMapFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FastrpcDmaMapFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cid() const { return at<1>().valid(); }
+  int32_t cid() const { return at<1>().as_int32(); }
+  bool has_fd() const { return at<2>().valid(); }
+  int32_t fd() const { return at<2>().as_int32(); }
+  bool has_phys() const { return at<3>().valid(); }
+  uint64_t phys() const { return at<3>().as_uint64(); }
+  bool has_size() const { return at<4>().valid(); }
+  uint64_t size() const { return at<4>().as_uint64(); }
+  bool has_len() const { return at<5>().valid(); }
+  uint64_t len() const { return at<5>().as_uint64(); }
+  bool has_attr() const { return at<6>().valid(); }
+  uint32_t attr() const { return at<6>().as_uint32(); }
+  bool has_mflags() const { return at<7>().valid(); }
+  int32_t mflags() const { return at<7>().as_int32(); }
+};
+
+class FastrpcDmaMapFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = FastrpcDmaMapFtraceEvent_Decoder;
+  enum : int32_t {
+    kCidFieldNumber = 1,
+    kFdFieldNumber = 2,
+    kPhysFieldNumber = 3,
+    kSizeFieldNumber = 4,
+    kLenFieldNumber = 5,
+    kAttrFieldNumber = 6,
+    kMflagsFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FastrpcDmaMapFtraceEvent"; }
+
+
+  using FieldMetadata_Cid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FastrpcDmaMapFtraceEvent>;
+
+  static constexpr FieldMetadata_Cid kCid{};
+  void set_cid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cid::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_Fd =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FastrpcDmaMapFtraceEvent>;
+
+  static constexpr FieldMetadata_Fd kFd{};
+  void set_fd(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Fd::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_Phys =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FastrpcDmaMapFtraceEvent>;
+
+  static constexpr FieldMetadata_Phys kPhys{};
+  void set_phys(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Phys::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_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FastrpcDmaMapFtraceEvent>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void set_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FastrpcDmaMapFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Attr =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FastrpcDmaMapFtraceEvent>;
+
+  static constexpr FieldMetadata_Attr kAttr{};
+  void set_attr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Attr::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_Mflags =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FastrpcDmaMapFtraceEvent>;
+
+  static constexpr FieldMetadata_Mflags kMflags{};
+  void set_mflags(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mflags::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);
+  }
+};
+
+class FastrpcDmaUnmapFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FastrpcDmaUnmapFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FastrpcDmaUnmapFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FastrpcDmaUnmapFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cid() const { return at<1>().valid(); }
+  int32_t cid() const { return at<1>().as_int32(); }
+  bool has_phys() const { return at<2>().valid(); }
+  uint64_t phys() const { return at<2>().as_uint64(); }
+  bool has_size() const { return at<3>().valid(); }
+  uint64_t size() const { return at<3>().as_uint64(); }
+};
+
+class FastrpcDmaUnmapFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = FastrpcDmaUnmapFtraceEvent_Decoder;
+  enum : int32_t {
+    kCidFieldNumber = 1,
+    kPhysFieldNumber = 2,
+    kSizeFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FastrpcDmaUnmapFtraceEvent"; }
+
+
+  using FieldMetadata_Cid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FastrpcDmaUnmapFtraceEvent>;
+
+  static constexpr FieldMetadata_Cid kCid{};
+  void set_cid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cid::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_Phys =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FastrpcDmaUnmapFtraceEvent>;
+
+  static constexpr FieldMetadata_Phys kPhys{};
+  void set_phys(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Phys::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_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FastrpcDmaUnmapFtraceEvent>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void set_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::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 FastrpcDmaAllocFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FastrpcDmaAllocFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FastrpcDmaAllocFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FastrpcDmaAllocFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cid() const { return at<1>().valid(); }
+  int32_t cid() const { return at<1>().as_int32(); }
+  bool has_phys() const { return at<2>().valid(); }
+  uint64_t phys() const { return at<2>().as_uint64(); }
+  bool has_size() const { return at<3>().valid(); }
+  uint64_t size() const { return at<3>().as_uint64(); }
+  bool has_attr() const { return at<4>().valid(); }
+  uint64_t attr() const { return at<4>().as_uint64(); }
+  bool has_mflags() const { return at<5>().valid(); }
+  int32_t mflags() const { return at<5>().as_int32(); }
+};
+
+class FastrpcDmaAllocFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = FastrpcDmaAllocFtraceEvent_Decoder;
+  enum : int32_t {
+    kCidFieldNumber = 1,
+    kPhysFieldNumber = 2,
+    kSizeFieldNumber = 3,
+    kAttrFieldNumber = 4,
+    kMflagsFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FastrpcDmaAllocFtraceEvent"; }
+
+
+  using FieldMetadata_Cid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FastrpcDmaAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Cid kCid{};
+  void set_cid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cid::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_Phys =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FastrpcDmaAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Phys kPhys{};
+  void set_phys(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Phys::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_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FastrpcDmaAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void set_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::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_Attr =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FastrpcDmaAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Attr kAttr{};
+  void set_attr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Attr::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_Mflags =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FastrpcDmaAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Mflags kMflags{};
+  void set_mflags(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mflags::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);
+  }
+};
+
+class FastrpcDmaFreeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FastrpcDmaFreeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FastrpcDmaFreeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FastrpcDmaFreeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cid() const { return at<1>().valid(); }
+  int32_t cid() const { return at<1>().as_int32(); }
+  bool has_phys() const { return at<2>().valid(); }
+  uint64_t phys() const { return at<2>().as_uint64(); }
+  bool has_size() const { return at<3>().valid(); }
+  uint64_t size() const { return at<3>().as_uint64(); }
+};
+
+class FastrpcDmaFreeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = FastrpcDmaFreeFtraceEvent_Decoder;
+  enum : int32_t {
+    kCidFieldNumber = 1,
+    kPhysFieldNumber = 2,
+    kSizeFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FastrpcDmaFreeFtraceEvent"; }
+
+
+  using FieldMetadata_Cid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FastrpcDmaFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_Cid kCid{};
+  void set_cid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cid::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_Phys =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FastrpcDmaFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_Phys kPhys{};
+  void set_phys(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Phys::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_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FastrpcDmaFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void set_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::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 FastrpcDmaStatFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FastrpcDmaStatFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FastrpcDmaStatFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FastrpcDmaStatFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cid() const { return at<1>().valid(); }
+  int32_t cid() const { return at<1>().as_int32(); }
+  bool has_len() const { return at<2>().valid(); }
+  int64_t len() const { return at<2>().as_int64(); }
+  bool has_total_allocated() const { return at<3>().valid(); }
+  uint64_t total_allocated() const { return at<3>().as_uint64(); }
+};
+
+class FastrpcDmaStatFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = FastrpcDmaStatFtraceEvent_Decoder;
+  enum : int32_t {
+    kCidFieldNumber = 1,
+    kLenFieldNumber = 2,
+    kTotalAllocatedFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FastrpcDmaStatFtraceEvent"; }
+
+
+  using FieldMetadata_Cid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FastrpcDmaStatFtraceEvent>;
+
+  static constexpr FieldMetadata_Cid kCid{};
+  void set_cid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cid::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      FastrpcDmaStatFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_TotalAllocated =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FastrpcDmaStatFtraceEvent>;
+
+  static constexpr FieldMetadata_TotalAllocated kTotalAllocated{};
+  void set_total_allocated(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TotalAllocated::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/fence.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_FENCE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_FENCE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class FenceSignaledFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FenceSignaledFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FenceSignaledFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FenceSignaledFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_context() const { return at<1>().valid(); }
+  uint32_t context() const { return at<1>().as_uint32(); }
+  bool has_driver() const { return at<2>().valid(); }
+  ::protozero::ConstChars driver() const { return at<2>().as_string(); }
+  bool has_seqno() const { return at<3>().valid(); }
+  uint32_t seqno() const { return at<3>().as_uint32(); }
+  bool has_timeline() const { return at<4>().valid(); }
+  ::protozero::ConstChars timeline() const { return at<4>().as_string(); }
+};
+
+class FenceSignaledFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = FenceSignaledFtraceEvent_Decoder;
+  enum : int32_t {
+    kContextFieldNumber = 1,
+    kDriverFieldNumber = 2,
+    kSeqnoFieldNumber = 3,
+    kTimelineFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FenceSignaledFtraceEvent"; }
+
+
+  using FieldMetadata_Context =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FenceSignaledFtraceEvent>;
+
+  static constexpr FieldMetadata_Context kContext{};
+  void set_context(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Context::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_Driver =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FenceSignaledFtraceEvent>;
+
+  static constexpr FieldMetadata_Driver kDriver{};
+  void set_driver(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, data, size);
+  }
+  void set_driver(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, chars.data, chars.size);
+  }
+  void set_driver(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Driver::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_Seqno =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FenceSignaledFtraceEvent>;
+
+  static constexpr FieldMetadata_Seqno kSeqno{};
+  void set_seqno(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Seqno::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_Timeline =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FenceSignaledFtraceEvent>;
+
+  static constexpr FieldMetadata_Timeline kTimeline{};
+  void set_timeline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, data, size);
+  }
+  void set_timeline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, chars.data, chars.size);
+  }
+  void set_timeline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timeline::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 FenceEnableSignalFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FenceEnableSignalFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FenceEnableSignalFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FenceEnableSignalFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_context() const { return at<1>().valid(); }
+  uint32_t context() const { return at<1>().as_uint32(); }
+  bool has_driver() const { return at<2>().valid(); }
+  ::protozero::ConstChars driver() const { return at<2>().as_string(); }
+  bool has_seqno() const { return at<3>().valid(); }
+  uint32_t seqno() const { return at<3>().as_uint32(); }
+  bool has_timeline() const { return at<4>().valid(); }
+  ::protozero::ConstChars timeline() const { return at<4>().as_string(); }
+};
+
+class FenceEnableSignalFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = FenceEnableSignalFtraceEvent_Decoder;
+  enum : int32_t {
+    kContextFieldNumber = 1,
+    kDriverFieldNumber = 2,
+    kSeqnoFieldNumber = 3,
+    kTimelineFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FenceEnableSignalFtraceEvent"; }
+
+
+  using FieldMetadata_Context =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FenceEnableSignalFtraceEvent>;
+
+  static constexpr FieldMetadata_Context kContext{};
+  void set_context(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Context::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_Driver =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FenceEnableSignalFtraceEvent>;
+
+  static constexpr FieldMetadata_Driver kDriver{};
+  void set_driver(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, data, size);
+  }
+  void set_driver(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, chars.data, chars.size);
+  }
+  void set_driver(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Driver::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_Seqno =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FenceEnableSignalFtraceEvent>;
+
+  static constexpr FieldMetadata_Seqno kSeqno{};
+  void set_seqno(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Seqno::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_Timeline =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FenceEnableSignalFtraceEvent>;
+
+  static constexpr FieldMetadata_Timeline kTimeline{};
+  void set_timeline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, data, size);
+  }
+  void set_timeline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, chars.data, chars.size);
+  }
+  void set_timeline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timeline::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 FenceDestroyFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FenceDestroyFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FenceDestroyFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FenceDestroyFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_context() const { return at<1>().valid(); }
+  uint32_t context() const { return at<1>().as_uint32(); }
+  bool has_driver() const { return at<2>().valid(); }
+  ::protozero::ConstChars driver() const { return at<2>().as_string(); }
+  bool has_seqno() const { return at<3>().valid(); }
+  uint32_t seqno() const { return at<3>().as_uint32(); }
+  bool has_timeline() const { return at<4>().valid(); }
+  ::protozero::ConstChars timeline() const { return at<4>().as_string(); }
+};
+
+class FenceDestroyFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = FenceDestroyFtraceEvent_Decoder;
+  enum : int32_t {
+    kContextFieldNumber = 1,
+    kDriverFieldNumber = 2,
+    kSeqnoFieldNumber = 3,
+    kTimelineFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FenceDestroyFtraceEvent"; }
+
+
+  using FieldMetadata_Context =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FenceDestroyFtraceEvent>;
+
+  static constexpr FieldMetadata_Context kContext{};
+  void set_context(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Context::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_Driver =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FenceDestroyFtraceEvent>;
+
+  static constexpr FieldMetadata_Driver kDriver{};
+  void set_driver(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, data, size);
+  }
+  void set_driver(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, chars.data, chars.size);
+  }
+  void set_driver(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Driver::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_Seqno =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FenceDestroyFtraceEvent>;
+
+  static constexpr FieldMetadata_Seqno kSeqno{};
+  void set_seqno(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Seqno::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_Timeline =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FenceDestroyFtraceEvent>;
+
+  static constexpr FieldMetadata_Timeline kTimeline{};
+  void set_timeline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, data, size);
+  }
+  void set_timeline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, chars.data, chars.size);
+  }
+  void set_timeline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timeline::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 FenceInitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FenceInitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FenceInitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FenceInitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_context() const { return at<1>().valid(); }
+  uint32_t context() const { return at<1>().as_uint32(); }
+  bool has_driver() const { return at<2>().valid(); }
+  ::protozero::ConstChars driver() const { return at<2>().as_string(); }
+  bool has_seqno() const { return at<3>().valid(); }
+  uint32_t seqno() const { return at<3>().as_uint32(); }
+  bool has_timeline() const { return at<4>().valid(); }
+  ::protozero::ConstChars timeline() const { return at<4>().as_string(); }
+};
+
+class FenceInitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = FenceInitFtraceEvent_Decoder;
+  enum : int32_t {
+    kContextFieldNumber = 1,
+    kDriverFieldNumber = 2,
+    kSeqnoFieldNumber = 3,
+    kTimelineFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FenceInitFtraceEvent"; }
+
+
+  using FieldMetadata_Context =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FenceInitFtraceEvent>;
+
+  static constexpr FieldMetadata_Context kContext{};
+  void set_context(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Context::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_Driver =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FenceInitFtraceEvent>;
+
+  static constexpr FieldMetadata_Driver kDriver{};
+  void set_driver(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, data, size);
+  }
+  void set_driver(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, chars.data, chars.size);
+  }
+  void set_driver(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Driver::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_Seqno =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FenceInitFtraceEvent>;
+
+  static constexpr FieldMetadata_Seqno kSeqno{};
+  void set_seqno(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Seqno::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_Timeline =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FenceInitFtraceEvent>;
+
+  static constexpr FieldMetadata_Timeline kTimeline{};
+  void set_timeline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, data, size);
+  }
+  void set_timeline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, chars.data, chars.size);
+  }
+  void set_timeline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timeline::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/filemap.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_FILEMAP_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_FILEMAP_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class MmFilemapDeleteFromPageCacheFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmFilemapDeleteFromPageCacheFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmFilemapDeleteFromPageCacheFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmFilemapDeleteFromPageCacheFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pfn() const { return at<1>().valid(); }
+  uint64_t pfn() const { return at<1>().as_uint64(); }
+  bool has_i_ino() const { return at<2>().valid(); }
+  uint64_t i_ino() const { return at<2>().as_uint64(); }
+  bool has_index() const { return at<3>().valid(); }
+  uint64_t index() const { return at<3>().as_uint64(); }
+  bool has_s_dev() const { return at<4>().valid(); }
+  uint64_t s_dev() const { return at<4>().as_uint64(); }
+  bool has_page() const { return at<5>().valid(); }
+  uint64_t page() const { return at<5>().as_uint64(); }
+};
+
+class MmFilemapDeleteFromPageCacheFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmFilemapDeleteFromPageCacheFtraceEvent_Decoder;
+  enum : int32_t {
+    kPfnFieldNumber = 1,
+    kIInoFieldNumber = 2,
+    kIndexFieldNumber = 3,
+    kSDevFieldNumber = 4,
+    kPageFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmFilemapDeleteFromPageCacheFtraceEvent"; }
+
+
+  using FieldMetadata_Pfn =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmFilemapDeleteFromPageCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_Pfn kPfn{};
+  void set_pfn(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pfn::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_IIno =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmFilemapDeleteFromPageCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_IIno kIIno{};
+  void set_i_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IIno::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_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmFilemapDeleteFromPageCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_Index kIndex{};
+  void set_index(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Index::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_SDev =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmFilemapDeleteFromPageCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_SDev kSDev{};
+  void set_s_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SDev::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_Page =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmFilemapDeleteFromPageCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_Page kPage{};
+  void set_page(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Page::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 MmFilemapAddToPageCacheFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmFilemapAddToPageCacheFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmFilemapAddToPageCacheFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmFilemapAddToPageCacheFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pfn() const { return at<1>().valid(); }
+  uint64_t pfn() const { return at<1>().as_uint64(); }
+  bool has_i_ino() const { return at<2>().valid(); }
+  uint64_t i_ino() const { return at<2>().as_uint64(); }
+  bool has_index() const { return at<3>().valid(); }
+  uint64_t index() const { return at<3>().as_uint64(); }
+  bool has_s_dev() const { return at<4>().valid(); }
+  uint64_t s_dev() const { return at<4>().as_uint64(); }
+  bool has_page() const { return at<5>().valid(); }
+  uint64_t page() const { return at<5>().as_uint64(); }
+};
+
+class MmFilemapAddToPageCacheFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmFilemapAddToPageCacheFtraceEvent_Decoder;
+  enum : int32_t {
+    kPfnFieldNumber = 1,
+    kIInoFieldNumber = 2,
+    kIndexFieldNumber = 3,
+    kSDevFieldNumber = 4,
+    kPageFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmFilemapAddToPageCacheFtraceEvent"; }
+
+
+  using FieldMetadata_Pfn =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmFilemapAddToPageCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_Pfn kPfn{};
+  void set_pfn(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pfn::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_IIno =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmFilemapAddToPageCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_IIno kIIno{};
+  void set_i_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IIno::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_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmFilemapAddToPageCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_Index kIndex{};
+  void set_index(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Index::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_SDev =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmFilemapAddToPageCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_SDev kSDev{};
+  void set_s_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SDev::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_Page =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmFilemapAddToPageCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_Page kPage{};
+  void set_page(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Page::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/ftrace.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_FTRACE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_FTRACE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class FuncgraphExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FuncgraphExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FuncgraphExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FuncgraphExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_calltime() const { return at<1>().valid(); }
+  uint64_t calltime() const { return at<1>().as_uint64(); }
+  bool has_depth() const { return at<2>().valid(); }
+  int32_t depth() const { return at<2>().as_int32(); }
+  bool has_func() const { return at<3>().valid(); }
+  uint64_t func() const { return at<3>().as_uint64(); }
+  bool has_overrun() const { return at<4>().valid(); }
+  uint64_t overrun() const { return at<4>().as_uint64(); }
+  bool has_rettime() const { return at<5>().valid(); }
+  uint64_t rettime() const { return at<5>().as_uint64(); }
+};
+
+class FuncgraphExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = FuncgraphExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kCalltimeFieldNumber = 1,
+    kDepthFieldNumber = 2,
+    kFuncFieldNumber = 3,
+    kOverrunFieldNumber = 4,
+    kRettimeFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FuncgraphExitFtraceEvent"; }
+
+
+  using FieldMetadata_Calltime =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FuncgraphExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Calltime kCalltime{};
+  void set_calltime(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Calltime::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_Depth =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FuncgraphExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Depth kDepth{};
+  void set_depth(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Depth::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_Func =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FuncgraphExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Func kFunc{};
+  void set_func(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Func::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_Overrun =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FuncgraphExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Overrun kOverrun{};
+  void set_overrun(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Overrun::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_Rettime =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FuncgraphExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Rettime kRettime{};
+  void set_rettime(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rettime::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 FuncgraphEntryFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FuncgraphEntryFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FuncgraphEntryFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FuncgraphEntryFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_depth() const { return at<1>().valid(); }
+  int32_t depth() const { return at<1>().as_int32(); }
+  bool has_func() const { return at<2>().valid(); }
+  uint64_t func() const { return at<2>().as_uint64(); }
+};
+
+class FuncgraphEntryFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = FuncgraphEntryFtraceEvent_Decoder;
+  enum : int32_t {
+    kDepthFieldNumber = 1,
+    kFuncFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FuncgraphEntryFtraceEvent"; }
+
+
+  using FieldMetadata_Depth =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FuncgraphEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_Depth kDepth{};
+  void set_depth(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Depth::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_Func =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FuncgraphEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_Func kFunc{};
+  void set_func(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Func::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 PrintFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  PrintFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PrintFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PrintFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ip() const { return at<1>().valid(); }
+  uint64_t ip() const { return at<1>().as_uint64(); }
+  bool has_buf() const { return at<2>().valid(); }
+  ::protozero::ConstChars buf() const { return at<2>().as_string(); }
+};
+
+class PrintFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = PrintFtraceEvent_Decoder;
+  enum : int32_t {
+    kIpFieldNumber = 1,
+    kBufFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PrintFtraceEvent"; }
+
+
+  using FieldMetadata_Ip =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PrintFtraceEvent>;
+
+  static constexpr FieldMetadata_Ip kIp{};
+  void set_ip(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ip::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_Buf =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PrintFtraceEvent>;
+
+  static constexpr FieldMetadata_Buf kBuf{};
+  void set_buf(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Buf::kFieldId, data, size);
+  }
+  void set_buf(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Buf::kFieldId, chars.data, chars.size);
+  }
+  void set_buf(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Buf::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/g2d.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_G2D_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_G2D_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class G2dTracingMarkWriteFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  G2dTracingMarkWriteFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit G2dTracingMarkWriteFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit G2dTracingMarkWriteFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  int32_t pid() const { return at<1>().as_int32(); }
+  bool has_name() const { return at<4>().valid(); }
+  ::protozero::ConstChars name() const { return at<4>().as_string(); }
+  bool has_type() const { return at<5>().valid(); }
+  uint32_t type() const { return at<5>().as_uint32(); }
+  bool has_value() const { return at<6>().valid(); }
+  int32_t value() const { return at<6>().as_int32(); }
+};
+
+class G2dTracingMarkWriteFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = G2dTracingMarkWriteFtraceEvent_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kNameFieldNumber = 4,
+    kTypeFieldNumber = 5,
+    kValueFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.G2dTracingMarkWriteFtraceEvent"; }
+
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      G2dTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      G2dTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      G2dTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::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_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      G2dTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/google_icc_trace.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_GOOGLE_ICC_TRACE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_GOOGLE_ICC_TRACE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class GoogleIccEventFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  GoogleIccEventFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GoogleIccEventFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GoogleIccEventFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_event() const { return at<1>().valid(); }
+  ::protozero::ConstChars event() const { return at<1>().as_string(); }
+  bool has_timestamp() const { return at<2>().valid(); }
+  uint64_t timestamp() const { return at<2>().as_uint64(); }
+};
+
+class GoogleIccEventFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = GoogleIccEventFtraceEvent_Decoder;
+  enum : int32_t {
+    kEventFieldNumber = 1,
+    kTimestampFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GoogleIccEventFtraceEvent"; }
+
+
+  using FieldMetadata_Event =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      GoogleIccEventFtraceEvent>;
+
+  static constexpr FieldMetadata_Event kEvent{};
+  void set_event(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Event::kFieldId, data, size);
+  }
+  void set_event(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Event::kFieldId, chars.data, chars.size);
+  }
+  void set_event(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Event::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_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GoogleIccEventFtraceEvent>;
+
+  static constexpr FieldMetadata_Timestamp kTimestamp{};
+  void set_timestamp(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timestamp::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/google_irm_trace.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_GOOGLE_IRM_TRACE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_GOOGLE_IRM_TRACE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class GoogleIrmEventFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  GoogleIrmEventFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GoogleIrmEventFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GoogleIrmEventFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_event() const { return at<1>().valid(); }
+  ::protozero::ConstChars event() const { return at<1>().as_string(); }
+  bool has_timestamp() const { return at<2>().valid(); }
+  uint64_t timestamp() const { return at<2>().as_uint64(); }
+};
+
+class GoogleIrmEventFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = GoogleIrmEventFtraceEvent_Decoder;
+  enum : int32_t {
+    kEventFieldNumber = 1,
+    kTimestampFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GoogleIrmEventFtraceEvent"; }
+
+
+  using FieldMetadata_Event =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      GoogleIrmEventFtraceEvent>;
+
+  static constexpr FieldMetadata_Event kEvent{};
+  void set_event(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Event::kFieldId, data, size);
+  }
+  void set_event(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Event::kFieldId, chars.data, chars.size);
+  }
+  void set_event(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Event::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_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GoogleIrmEventFtraceEvent>;
+
+  static constexpr FieldMetadata_Timestamp kTimestamp{};
+  void set_timestamp(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timestamp::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/gpu_mem.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_GPU_MEM_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_GPU_MEM_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class GpuMemTotalFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  GpuMemTotalFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GpuMemTotalFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GpuMemTotalFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_gpu_id() const { return at<1>().valid(); }
+  uint32_t gpu_id() const { return at<1>().as_uint32(); }
+  bool has_pid() const { return at<2>().valid(); }
+  uint32_t pid() const { return at<2>().as_uint32(); }
+  bool has_size() const { return at<3>().valid(); }
+  uint64_t size() const { return at<3>().as_uint64(); }
+};
+
+class GpuMemTotalFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = GpuMemTotalFtraceEvent_Decoder;
+  enum : int32_t {
+    kGpuIdFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kSizeFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GpuMemTotalFtraceEvent"; }
+
+
+  using FieldMetadata_GpuId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GpuMemTotalFtraceEvent>;
+
+  static constexpr FieldMetadata_GpuId kGpuId{};
+  void set_gpu_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GpuId::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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GpuMemTotalFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuMemTotalFtraceEvent>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void set_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/gpu_scheduler.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_GPU_SCHEDULER_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_GPU_SCHEDULER_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class DrmSchedProcessJobFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DrmSchedProcessJobFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DrmSchedProcessJobFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DrmSchedProcessJobFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_fence() const { return at<1>().valid(); }
+  uint64_t fence() const { return at<1>().as_uint64(); }
+};
+
+class DrmSchedProcessJobFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = DrmSchedProcessJobFtraceEvent_Decoder;
+  enum : int32_t {
+    kFenceFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DrmSchedProcessJobFtraceEvent"; }
+
+
+  using FieldMetadata_Fence =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DrmSchedProcessJobFtraceEvent>;
+
+  static constexpr FieldMetadata_Fence kFence{};
+  void set_fence(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Fence::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 DrmRunJobFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DrmRunJobFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DrmRunJobFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DrmRunJobFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_entity() const { return at<1>().valid(); }
+  uint64_t entity() const { return at<1>().as_uint64(); }
+  bool has_fence() const { return at<2>().valid(); }
+  uint64_t fence() const { return at<2>().as_uint64(); }
+  bool has_hw_job_count() const { return at<3>().valid(); }
+  int32_t hw_job_count() const { return at<3>().as_int32(); }
+  bool has_id() const { return at<4>().valid(); }
+  uint64_t id() const { return at<4>().as_uint64(); }
+  bool has_job_count() const { return at<5>().valid(); }
+  uint32_t job_count() const { return at<5>().as_uint32(); }
+  bool has_name() const { return at<6>().valid(); }
+  ::protozero::ConstChars name() const { return at<6>().as_string(); }
+};
+
+class DrmRunJobFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = DrmRunJobFtraceEvent_Decoder;
+  enum : int32_t {
+    kEntityFieldNumber = 1,
+    kFenceFieldNumber = 2,
+    kHwJobCountFieldNumber = 3,
+    kIdFieldNumber = 4,
+    kJobCountFieldNumber = 5,
+    kNameFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DrmRunJobFtraceEvent"; }
+
+
+  using FieldMetadata_Entity =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DrmRunJobFtraceEvent>;
+
+  static constexpr FieldMetadata_Entity kEntity{};
+  void set_entity(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Entity::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_Fence =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DrmRunJobFtraceEvent>;
+
+  static constexpr FieldMetadata_Fence kFence{};
+  void set_fence(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Fence::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_HwJobCount =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      DrmRunJobFtraceEvent>;
+
+  static constexpr FieldMetadata_HwJobCount kHwJobCount{};
+  void set_hw_job_count(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_HwJobCount::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_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DrmRunJobFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::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_JobCount =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DrmRunJobFtraceEvent>;
+
+  static constexpr FieldMetadata_JobCount kJobCount{};
+  void set_job_count(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_JobCount::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DrmRunJobFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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);
+  }
+};
+
+class DrmSchedJobFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DrmSchedJobFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DrmSchedJobFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DrmSchedJobFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_entity() const { return at<1>().valid(); }
+  uint64_t entity() const { return at<1>().as_uint64(); }
+  bool has_fence() const { return at<2>().valid(); }
+  uint64_t fence() const { return at<2>().as_uint64(); }
+  bool has_hw_job_count() const { return at<3>().valid(); }
+  int32_t hw_job_count() const { return at<3>().as_int32(); }
+  bool has_id() const { return at<4>().valid(); }
+  uint64_t id() const { return at<4>().as_uint64(); }
+  bool has_job_count() const { return at<5>().valid(); }
+  uint32_t job_count() const { return at<5>().as_uint32(); }
+  bool has_name() const { return at<6>().valid(); }
+  ::protozero::ConstChars name() const { return at<6>().as_string(); }
+};
+
+class DrmSchedJobFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = DrmSchedJobFtraceEvent_Decoder;
+  enum : int32_t {
+    kEntityFieldNumber = 1,
+    kFenceFieldNumber = 2,
+    kHwJobCountFieldNumber = 3,
+    kIdFieldNumber = 4,
+    kJobCountFieldNumber = 5,
+    kNameFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DrmSchedJobFtraceEvent"; }
+
+
+  using FieldMetadata_Entity =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DrmSchedJobFtraceEvent>;
+
+  static constexpr FieldMetadata_Entity kEntity{};
+  void set_entity(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Entity::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_Fence =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DrmSchedJobFtraceEvent>;
+
+  static constexpr FieldMetadata_Fence kFence{};
+  void set_fence(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Fence::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_HwJobCount =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      DrmSchedJobFtraceEvent>;
+
+  static constexpr FieldMetadata_HwJobCount kHwJobCount{};
+  void set_hw_job_count(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_HwJobCount::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_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DrmSchedJobFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::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_JobCount =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DrmSchedJobFtraceEvent>;
+
+  static constexpr FieldMetadata_JobCount kJobCount{};
+  void set_job_count(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_JobCount::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DrmSchedJobFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/hyp.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_HYP_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_HYP_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class HostMemAbortFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  HostMemAbortFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit HostMemAbortFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit HostMemAbortFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_esr() const { return at<1>().valid(); }
+  uint64_t esr() const { return at<1>().as_uint64(); }
+  bool has_addr() const { return at<2>().valid(); }
+  uint64_t addr() const { return at<2>().as_uint64(); }
+};
+
+class HostMemAbortFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = HostMemAbortFtraceEvent_Decoder;
+  enum : int32_t {
+    kEsrFieldNumber = 1,
+    kAddrFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.HostMemAbortFtraceEvent"; }
+
+
+  using FieldMetadata_Esr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HostMemAbortFtraceEvent>;
+
+  static constexpr FieldMetadata_Esr kEsr{};
+  void set_esr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Esr::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_Addr =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HostMemAbortFtraceEvent>;
+
+  static constexpr FieldMetadata_Addr kAddr{};
+  void set_addr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Addr::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 HostSmcFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  HostSmcFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit HostSmcFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit HostSmcFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  uint64_t id() const { return at<1>().as_uint64(); }
+  bool has_forwarded() const { return at<2>().valid(); }
+  uint32_t forwarded() const { return at<2>().as_uint32(); }
+};
+
+class HostSmcFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = HostSmcFtraceEvent_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kForwardedFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.HostSmcFtraceEvent"; }
+
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HostSmcFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::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_Forwarded =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      HostSmcFtraceEvent>;
+
+  static constexpr FieldMetadata_Forwarded kForwarded{};
+  void set_forwarded(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Forwarded::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 HostHcallFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  HostHcallFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit HostHcallFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit HostHcallFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  uint32_t id() const { return at<1>().as_uint32(); }
+  bool has_invalid() const { return at<2>().valid(); }
+  uint32_t invalid() const { return at<2>().as_uint32(); }
+};
+
+class HostHcallFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = HostHcallFtraceEvent_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kInvalidFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.HostHcallFtraceEvent"; }
+
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      HostHcallFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::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_Invalid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      HostHcallFtraceEvent>;
+
+  static constexpr FieldMetadata_Invalid kInvalid{};
+  void set_invalid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Invalid::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 HypExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/0, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  HypExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit HypExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit HypExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+};
+
+class HypExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = HypExitFtraceEvent_Decoder;
+  static constexpr const char* GetName() { return ".perfetto.protos.HypExitFtraceEvent"; }
+
+};
+
+class HypEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/0, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  HypEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit HypEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit HypEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+};
+
+class HypEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = HypEnterFtraceEvent_Decoder;
+  static constexpr const char* GetName() { return ".perfetto.protos.HypEnterFtraceEvent"; }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/i2c.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_I2C_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_I2C_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class SmbusReplyFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SmbusReplyFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SmbusReplyFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SmbusReplyFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_adapter_nr() const { return at<1>().valid(); }
+  int32_t adapter_nr() const { return at<1>().as_int32(); }
+  bool has_addr() const { return at<2>().valid(); }
+  uint32_t addr() const { return at<2>().as_uint32(); }
+  bool has_flags() const { return at<3>().valid(); }
+  uint32_t flags() const { return at<3>().as_uint32(); }
+  bool has_command() const { return at<4>().valid(); }
+  uint32_t command() const { return at<4>().as_uint32(); }
+  bool has_len() const { return at<5>().valid(); }
+  uint32_t len() const { return at<5>().as_uint32(); }
+  bool has_protocol() const { return at<6>().valid(); }
+  uint32_t protocol() const { return at<6>().as_uint32(); }
+};
+
+class SmbusReplyFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SmbusReplyFtraceEvent_Decoder;
+  enum : int32_t {
+    kAdapterNrFieldNumber = 1,
+    kAddrFieldNumber = 2,
+    kFlagsFieldNumber = 3,
+    kCommandFieldNumber = 4,
+    kLenFieldNumber = 5,
+    kProtocolFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SmbusReplyFtraceEvent"; }
+
+
+  using FieldMetadata_AdapterNr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SmbusReplyFtraceEvent>;
+
+  static constexpr FieldMetadata_AdapterNr kAdapterNr{};
+  void set_adapter_nr(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AdapterNr::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_Addr =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusReplyFtraceEvent>;
+
+  static constexpr FieldMetadata_Addr kAddr{};
+  void set_addr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Addr::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusReplyFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_Command =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusReplyFtraceEvent>;
+
+  static constexpr FieldMetadata_Command kCommand{};
+  void set_command(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Command::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusReplyFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Protocol =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusReplyFtraceEvent>;
+
+  static constexpr FieldMetadata_Protocol kProtocol{};
+  void set_protocol(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Protocol::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 SmbusResultFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SmbusResultFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SmbusResultFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SmbusResultFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_adapter_nr() const { return at<1>().valid(); }
+  int32_t adapter_nr() const { return at<1>().as_int32(); }
+  bool has_addr() const { return at<2>().valid(); }
+  uint32_t addr() const { return at<2>().as_uint32(); }
+  bool has_flags() const { return at<3>().valid(); }
+  uint32_t flags() const { return at<3>().as_uint32(); }
+  bool has_read_write() const { return at<4>().valid(); }
+  uint32_t read_write() const { return at<4>().as_uint32(); }
+  bool has_command() const { return at<5>().valid(); }
+  uint32_t command() const { return at<5>().as_uint32(); }
+  bool has_res() const { return at<6>().valid(); }
+  int32_t res() const { return at<6>().as_int32(); }
+  bool has_protocol() const { return at<7>().valid(); }
+  uint32_t protocol() const { return at<7>().as_uint32(); }
+};
+
+class SmbusResultFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SmbusResultFtraceEvent_Decoder;
+  enum : int32_t {
+    kAdapterNrFieldNumber = 1,
+    kAddrFieldNumber = 2,
+    kFlagsFieldNumber = 3,
+    kReadWriteFieldNumber = 4,
+    kCommandFieldNumber = 5,
+    kResFieldNumber = 6,
+    kProtocolFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SmbusResultFtraceEvent"; }
+
+
+  using FieldMetadata_AdapterNr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SmbusResultFtraceEvent>;
+
+  static constexpr FieldMetadata_AdapterNr kAdapterNr{};
+  void set_adapter_nr(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AdapterNr::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_Addr =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusResultFtraceEvent>;
+
+  static constexpr FieldMetadata_Addr kAddr{};
+  void set_addr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Addr::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusResultFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_ReadWrite =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusResultFtraceEvent>;
+
+  static constexpr FieldMetadata_ReadWrite kReadWrite{};
+  void set_read_write(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReadWrite::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_Command =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusResultFtraceEvent>;
+
+  static constexpr FieldMetadata_Command kCommand{};
+  void set_command(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Command::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_Res =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SmbusResultFtraceEvent>;
+
+  static constexpr FieldMetadata_Res kRes{};
+  void set_res(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Res::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_Protocol =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusResultFtraceEvent>;
+
+  static constexpr FieldMetadata_Protocol kProtocol{};
+  void set_protocol(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Protocol::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 SmbusWriteFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SmbusWriteFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SmbusWriteFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SmbusWriteFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_adapter_nr() const { return at<1>().valid(); }
+  int32_t adapter_nr() const { return at<1>().as_int32(); }
+  bool has_addr() const { return at<2>().valid(); }
+  uint32_t addr() const { return at<2>().as_uint32(); }
+  bool has_flags() const { return at<3>().valid(); }
+  uint32_t flags() const { return at<3>().as_uint32(); }
+  bool has_command() const { return at<4>().valid(); }
+  uint32_t command() const { return at<4>().as_uint32(); }
+  bool has_len() const { return at<5>().valid(); }
+  uint32_t len() const { return at<5>().as_uint32(); }
+  bool has_protocol() const { return at<6>().valid(); }
+  uint32_t protocol() const { return at<6>().as_uint32(); }
+};
+
+class SmbusWriteFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SmbusWriteFtraceEvent_Decoder;
+  enum : int32_t {
+    kAdapterNrFieldNumber = 1,
+    kAddrFieldNumber = 2,
+    kFlagsFieldNumber = 3,
+    kCommandFieldNumber = 4,
+    kLenFieldNumber = 5,
+    kProtocolFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SmbusWriteFtraceEvent"; }
+
+
+  using FieldMetadata_AdapterNr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SmbusWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_AdapterNr kAdapterNr{};
+  void set_adapter_nr(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AdapterNr::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_Addr =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Addr kAddr{};
+  void set_addr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Addr::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_Command =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Command kCommand{};
+  void set_command(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Command::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Protocol =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Protocol kProtocol{};
+  void set_protocol(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Protocol::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 SmbusReadFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SmbusReadFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SmbusReadFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SmbusReadFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_adapter_nr() const { return at<1>().valid(); }
+  int32_t adapter_nr() const { return at<1>().as_int32(); }
+  bool has_flags() const { return at<2>().valid(); }
+  uint32_t flags() const { return at<2>().as_uint32(); }
+  bool has_addr() const { return at<3>().valid(); }
+  uint32_t addr() const { return at<3>().as_uint32(); }
+  bool has_command() const { return at<4>().valid(); }
+  uint32_t command() const { return at<4>().as_uint32(); }
+  bool has_protocol() const { return at<5>().valid(); }
+  uint32_t protocol() const { return at<5>().as_uint32(); }
+};
+
+class SmbusReadFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SmbusReadFtraceEvent_Decoder;
+  enum : int32_t {
+    kAdapterNrFieldNumber = 1,
+    kFlagsFieldNumber = 2,
+    kAddrFieldNumber = 3,
+    kCommandFieldNumber = 4,
+    kProtocolFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SmbusReadFtraceEvent"; }
+
+
+  using FieldMetadata_AdapterNr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SmbusReadFtraceEvent>;
+
+  static constexpr FieldMetadata_AdapterNr kAdapterNr{};
+  void set_adapter_nr(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AdapterNr::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusReadFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_Addr =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusReadFtraceEvent>;
+
+  static constexpr FieldMetadata_Addr kAddr{};
+  void set_addr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Addr::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_Command =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusReadFtraceEvent>;
+
+  static constexpr FieldMetadata_Command kCommand{};
+  void set_command(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Command::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_Protocol =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusReadFtraceEvent>;
+
+  static constexpr FieldMetadata_Protocol kProtocol{};
+  void set_protocol(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Protocol::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 I2cReplyFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  I2cReplyFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit I2cReplyFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit I2cReplyFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_adapter_nr() const { return at<1>().valid(); }
+  int32_t adapter_nr() const { return at<1>().as_int32(); }
+  bool has_msg_nr() const { return at<2>().valid(); }
+  uint32_t msg_nr() const { return at<2>().as_uint32(); }
+  bool has_addr() const { return at<3>().valid(); }
+  uint32_t addr() const { return at<3>().as_uint32(); }
+  bool has_flags() const { return at<4>().valid(); }
+  uint32_t flags() const { return at<4>().as_uint32(); }
+  bool has_len() const { return at<5>().valid(); }
+  uint32_t len() const { return at<5>().as_uint32(); }
+  bool has_buf() const { return at<6>().valid(); }
+  uint32_t buf() const { return at<6>().as_uint32(); }
+};
+
+class I2cReplyFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = I2cReplyFtraceEvent_Decoder;
+  enum : int32_t {
+    kAdapterNrFieldNumber = 1,
+    kMsgNrFieldNumber = 2,
+    kAddrFieldNumber = 3,
+    kFlagsFieldNumber = 4,
+    kLenFieldNumber = 5,
+    kBufFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.I2cReplyFtraceEvent"; }
+
+
+  using FieldMetadata_AdapterNr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      I2cReplyFtraceEvent>;
+
+  static constexpr FieldMetadata_AdapterNr kAdapterNr{};
+  void set_adapter_nr(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AdapterNr::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_MsgNr =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      I2cReplyFtraceEvent>;
+
+  static constexpr FieldMetadata_MsgNr kMsgNr{};
+  void set_msg_nr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MsgNr::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_Addr =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      I2cReplyFtraceEvent>;
+
+  static constexpr FieldMetadata_Addr kAddr{};
+  void set_addr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Addr::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      I2cReplyFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      I2cReplyFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Buf =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      I2cReplyFtraceEvent>;
+
+  static constexpr FieldMetadata_Buf kBuf{};
+  void set_buf(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Buf::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 I2cResultFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  I2cResultFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit I2cResultFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit I2cResultFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_adapter_nr() const { return at<1>().valid(); }
+  int32_t adapter_nr() const { return at<1>().as_int32(); }
+  bool has_nr_msgs() const { return at<2>().valid(); }
+  uint32_t nr_msgs() const { return at<2>().as_uint32(); }
+  bool has_ret() const { return at<3>().valid(); }
+  int32_t ret() const { return at<3>().as_int32(); }
+};
+
+class I2cResultFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = I2cResultFtraceEvent_Decoder;
+  enum : int32_t {
+    kAdapterNrFieldNumber = 1,
+    kNrMsgsFieldNumber = 2,
+    kRetFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.I2cResultFtraceEvent"; }
+
+
+  using FieldMetadata_AdapterNr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      I2cResultFtraceEvent>;
+
+  static constexpr FieldMetadata_AdapterNr kAdapterNr{};
+  void set_adapter_nr(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AdapterNr::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_NrMsgs =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      I2cResultFtraceEvent>;
+
+  static constexpr FieldMetadata_NrMsgs kNrMsgs{};
+  void set_nr_msgs(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrMsgs::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_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      I2cResultFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::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);
+  }
+};
+
+class I2cWriteFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  I2cWriteFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit I2cWriteFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit I2cWriteFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_adapter_nr() const { return at<1>().valid(); }
+  int32_t adapter_nr() const { return at<1>().as_int32(); }
+  bool has_msg_nr() const { return at<2>().valid(); }
+  uint32_t msg_nr() const { return at<2>().as_uint32(); }
+  bool has_addr() const { return at<3>().valid(); }
+  uint32_t addr() const { return at<3>().as_uint32(); }
+  bool has_flags() const { return at<4>().valid(); }
+  uint32_t flags() const { return at<4>().as_uint32(); }
+  bool has_len() const { return at<5>().valid(); }
+  uint32_t len() const { return at<5>().as_uint32(); }
+  bool has_buf() const { return at<6>().valid(); }
+  uint32_t buf() const { return at<6>().as_uint32(); }
+};
+
+class I2cWriteFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = I2cWriteFtraceEvent_Decoder;
+  enum : int32_t {
+    kAdapterNrFieldNumber = 1,
+    kMsgNrFieldNumber = 2,
+    kAddrFieldNumber = 3,
+    kFlagsFieldNumber = 4,
+    kLenFieldNumber = 5,
+    kBufFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.I2cWriteFtraceEvent"; }
+
+
+  using FieldMetadata_AdapterNr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      I2cWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_AdapterNr kAdapterNr{};
+  void set_adapter_nr(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AdapterNr::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_MsgNr =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      I2cWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_MsgNr kMsgNr{};
+  void set_msg_nr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MsgNr::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_Addr =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      I2cWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Addr kAddr{};
+  void set_addr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Addr::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      I2cWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      I2cWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Buf =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      I2cWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Buf kBuf{};
+  void set_buf(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Buf::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 I2cReadFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  I2cReadFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit I2cReadFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit I2cReadFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_adapter_nr() const { return at<1>().valid(); }
+  int32_t adapter_nr() const { return at<1>().as_int32(); }
+  bool has_msg_nr() const { return at<2>().valid(); }
+  uint32_t msg_nr() const { return at<2>().as_uint32(); }
+  bool has_addr() const { return at<3>().valid(); }
+  uint32_t addr() const { return at<3>().as_uint32(); }
+  bool has_flags() const { return at<4>().valid(); }
+  uint32_t flags() const { return at<4>().as_uint32(); }
+  bool has_len() const { return at<5>().valid(); }
+  uint32_t len() const { return at<5>().as_uint32(); }
+};
+
+class I2cReadFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = I2cReadFtraceEvent_Decoder;
+  enum : int32_t {
+    kAdapterNrFieldNumber = 1,
+    kMsgNrFieldNumber = 2,
+    kAddrFieldNumber = 3,
+    kFlagsFieldNumber = 4,
+    kLenFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.I2cReadFtraceEvent"; }
+
+
+  using FieldMetadata_AdapterNr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      I2cReadFtraceEvent>;
+
+  static constexpr FieldMetadata_AdapterNr kAdapterNr{};
+  void set_adapter_nr(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AdapterNr::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_MsgNr =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      I2cReadFtraceEvent>;
+
+  static constexpr FieldMetadata_MsgNr kMsgNr{};
+  void set_msg_nr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MsgNr::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_Addr =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      I2cReadFtraceEvent>;
+
+  static constexpr FieldMetadata_Addr kAddr{};
+  void set_addr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Addr::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      I2cReadFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      I2cReadFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/ion.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_ION_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_ION_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class IonStatFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonStatFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonStatFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonStatFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_buffer_id() const { return at<1>().valid(); }
+  uint32_t buffer_id() const { return at<1>().as_uint32(); }
+  bool has_len() const { return at<2>().valid(); }
+  int64_t len() const { return at<2>().as_int64(); }
+  bool has_total_allocated() const { return at<3>().valid(); }
+  uint64_t total_allocated() const { return at<3>().as_uint64(); }
+};
+
+class IonStatFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonStatFtraceEvent_Decoder;
+  enum : int32_t {
+    kBufferIdFieldNumber = 1,
+    kLenFieldNumber = 2,
+    kTotalAllocatedFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonStatFtraceEvent"; }
+
+
+  using FieldMetadata_BufferId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      IonStatFtraceEvent>;
+
+  static constexpr FieldMetadata_BufferId kBufferId{};
+  void set_buffer_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BufferId::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      IonStatFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_TotalAllocated =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonStatFtraceEvent>;
+
+  static constexpr FieldMetadata_TotalAllocated kTotalAllocated{};
+  void set_total_allocated(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TotalAllocated::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/ipi.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_IPI_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_IPI_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class IpiRaiseFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IpiRaiseFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IpiRaiseFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IpiRaiseFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_target_cpus() const { return at<1>().valid(); }
+  uint32_t target_cpus() const { return at<1>().as_uint32(); }
+  bool has_reason() const { return at<2>().valid(); }
+  ::protozero::ConstChars reason() const { return at<2>().as_string(); }
+};
+
+class IpiRaiseFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IpiRaiseFtraceEvent_Decoder;
+  enum : int32_t {
+    kTargetCpusFieldNumber = 1,
+    kReasonFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IpiRaiseFtraceEvent"; }
+
+
+  using FieldMetadata_TargetCpus =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      IpiRaiseFtraceEvent>;
+
+  static constexpr FieldMetadata_TargetCpus kTargetCpus{};
+  void set_target_cpus(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TargetCpus::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_Reason =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IpiRaiseFtraceEvent>;
+
+  static constexpr FieldMetadata_Reason kReason{};
+  void set_reason(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Reason::kFieldId, data, size);
+  }
+  void set_reason(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Reason::kFieldId, chars.data, chars.size);
+  }
+  void set_reason(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Reason::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 IpiExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IpiExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IpiExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IpiExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_reason() const { return at<1>().valid(); }
+  ::protozero::ConstChars reason() const { return at<1>().as_string(); }
+};
+
+class IpiExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IpiExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kReasonFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IpiExitFtraceEvent"; }
+
+
+  using FieldMetadata_Reason =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IpiExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Reason kReason{};
+  void set_reason(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Reason::kFieldId, data, size);
+  }
+  void set_reason(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Reason::kFieldId, chars.data, chars.size);
+  }
+  void set_reason(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Reason::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 IpiEntryFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IpiEntryFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IpiEntryFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IpiEntryFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_reason() const { return at<1>().valid(); }
+  ::protozero::ConstChars reason() const { return at<1>().as_string(); }
+};
+
+class IpiEntryFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IpiEntryFtraceEvent_Decoder;
+  enum : int32_t {
+    kReasonFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IpiEntryFtraceEvent"; }
+
+
+  using FieldMetadata_Reason =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IpiEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_Reason kReason{};
+  void set_reason(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Reason::kFieldId, data, size);
+  }
+  void set_reason(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Reason::kFieldId, chars.data, chars.size);
+  }
+  void set_reason(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Reason::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/irq.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_IRQ_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_IRQ_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class IrqHandlerExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IrqHandlerExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IrqHandlerExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IrqHandlerExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_irq() const { return at<1>().valid(); }
+  int32_t irq() const { return at<1>().as_int32(); }
+  bool has_ret() const { return at<2>().valid(); }
+  int32_t ret() const { return at<2>().as_int32(); }
+};
+
+class IrqHandlerExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IrqHandlerExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kIrqFieldNumber = 1,
+    kRetFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IrqHandlerExitFtraceEvent"; }
+
+
+  using FieldMetadata_Irq =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      IrqHandlerExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Irq kIrq{};
+  void set_irq(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Irq::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_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      IrqHandlerExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::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);
+  }
+};
+
+class IrqHandlerEntryFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IrqHandlerEntryFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IrqHandlerEntryFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IrqHandlerEntryFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_irq() const { return at<1>().valid(); }
+  int32_t irq() const { return at<1>().as_int32(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+  bool has_handler() const { return at<3>().valid(); }
+  uint32_t handler() const { return at<3>().as_uint32(); }
+};
+
+class IrqHandlerEntryFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IrqHandlerEntryFtraceEvent_Decoder;
+  enum : int32_t {
+    kIrqFieldNumber = 1,
+    kNameFieldNumber = 2,
+    kHandlerFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IrqHandlerEntryFtraceEvent"; }
+
+
+  using FieldMetadata_Irq =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      IrqHandlerEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_Irq kIrq{};
+  void set_irq(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Irq::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IrqHandlerEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Handler =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      IrqHandlerEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_Handler kHandler{};
+  void set_handler(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Handler::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 SoftirqRaiseFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SoftirqRaiseFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SoftirqRaiseFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SoftirqRaiseFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_vec() const { return at<1>().valid(); }
+  uint32_t vec() const { return at<1>().as_uint32(); }
+};
+
+class SoftirqRaiseFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SoftirqRaiseFtraceEvent_Decoder;
+  enum : int32_t {
+    kVecFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SoftirqRaiseFtraceEvent"; }
+
+
+  using FieldMetadata_Vec =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SoftirqRaiseFtraceEvent>;
+
+  static constexpr FieldMetadata_Vec kVec{};
+  void set_vec(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Vec::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 SoftirqExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SoftirqExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SoftirqExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SoftirqExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_vec() const { return at<1>().valid(); }
+  uint32_t vec() const { return at<1>().as_uint32(); }
+};
+
+class SoftirqExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SoftirqExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kVecFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SoftirqExitFtraceEvent"; }
+
+
+  using FieldMetadata_Vec =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SoftirqExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Vec kVec{};
+  void set_vec(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Vec::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 SoftirqEntryFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SoftirqEntryFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SoftirqEntryFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SoftirqEntryFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_vec() const { return at<1>().valid(); }
+  uint32_t vec() const { return at<1>().as_uint32(); }
+};
+
+class SoftirqEntryFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SoftirqEntryFtraceEvent_Decoder;
+  enum : int32_t {
+    kVecFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SoftirqEntryFtraceEvent"; }
+
+
+  using FieldMetadata_Vec =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SoftirqEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_Vec kVec{};
+  void set_vec(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Vec::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/kmem.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_KMEM_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_KMEM_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class IonBufferDestroyFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonBufferDestroyFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonBufferDestroyFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonBufferDestroyFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_addr() const { return at<1>().valid(); }
+  uint64_t addr() const { return at<1>().as_uint64(); }
+  bool has_len() const { return at<2>().valid(); }
+  uint64_t len() const { return at<2>().as_uint64(); }
+};
+
+class IonBufferDestroyFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonBufferDestroyFtraceEvent_Decoder;
+  enum : int32_t {
+    kAddrFieldNumber = 1,
+    kLenFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonBufferDestroyFtraceEvent"; }
+
+
+  using FieldMetadata_Addr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonBufferDestroyFtraceEvent>;
+
+  static constexpr FieldMetadata_Addr kAddr{};
+  void set_addr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Addr::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonBufferDestroyFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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 IonBufferCreateFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonBufferCreateFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonBufferCreateFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonBufferCreateFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_addr() const { return at<1>().valid(); }
+  uint64_t addr() const { return at<1>().as_uint64(); }
+  bool has_len() const { return at<2>().valid(); }
+  uint64_t len() const { return at<2>().as_uint64(); }
+};
+
+class IonBufferCreateFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonBufferCreateFtraceEvent_Decoder;
+  enum : int32_t {
+    kAddrFieldNumber = 1,
+    kLenFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonBufferCreateFtraceEvent"; }
+
+
+  using FieldMetadata_Addr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonBufferCreateFtraceEvent>;
+
+  static constexpr FieldMetadata_Addr kAddr{};
+  void set_addr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Addr::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonBufferCreateFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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 IonHeapGrowFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonHeapGrowFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonHeapGrowFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonHeapGrowFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_heap_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars heap_name() const { return at<1>().as_string(); }
+  bool has_len() const { return at<2>().valid(); }
+  uint64_t len() const { return at<2>().as_uint64(); }
+  bool has_total_allocated() const { return at<3>().valid(); }
+  int64_t total_allocated() const { return at<3>().as_int64(); }
+};
+
+class IonHeapGrowFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonHeapGrowFtraceEvent_Decoder;
+  enum : int32_t {
+    kHeapNameFieldNumber = 1,
+    kLenFieldNumber = 2,
+    kTotalAllocatedFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonHeapGrowFtraceEvent"; }
+
+
+  using FieldMetadata_HeapName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IonHeapGrowFtraceEvent>;
+
+  static constexpr FieldMetadata_HeapName kHeapName{};
+  void set_heap_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, data, size);
+  }
+  void set_heap_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, chars.data, chars.size);
+  }
+  void set_heap_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_HeapName::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonHeapGrowFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_TotalAllocated =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      IonHeapGrowFtraceEvent>;
+
+  static constexpr FieldMetadata_TotalAllocated kTotalAllocated{};
+  void set_total_allocated(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TotalAllocated::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 IonHeapShrinkFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonHeapShrinkFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonHeapShrinkFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonHeapShrinkFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_heap_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars heap_name() const { return at<1>().as_string(); }
+  bool has_len() const { return at<2>().valid(); }
+  uint64_t len() const { return at<2>().as_uint64(); }
+  bool has_total_allocated() const { return at<3>().valid(); }
+  int64_t total_allocated() const { return at<3>().as_int64(); }
+};
+
+class IonHeapShrinkFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonHeapShrinkFtraceEvent_Decoder;
+  enum : int32_t {
+    kHeapNameFieldNumber = 1,
+    kLenFieldNumber = 2,
+    kTotalAllocatedFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonHeapShrinkFtraceEvent"; }
+
+
+  using FieldMetadata_HeapName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IonHeapShrinkFtraceEvent>;
+
+  static constexpr FieldMetadata_HeapName kHeapName{};
+  void set_heap_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, data, size);
+  }
+  void set_heap_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, chars.data, chars.size);
+  }
+  void set_heap_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_HeapName::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonHeapShrinkFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_TotalAllocated =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      IonHeapShrinkFtraceEvent>;
+
+  static constexpr FieldMetadata_TotalAllocated kTotalAllocated{};
+  void set_total_allocated(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TotalAllocated::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 RssStatFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  RssStatFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit RssStatFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit RssStatFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_member() const { return at<1>().valid(); }
+  int32_t member() const { return at<1>().as_int32(); }
+  bool has_size() const { return at<2>().valid(); }
+  int64_t size() const { return at<2>().as_int64(); }
+  bool has_curr() const { return at<3>().valid(); }
+  uint32_t curr() const { return at<3>().as_uint32(); }
+  bool has_mm_id() const { return at<4>().valid(); }
+  uint32_t mm_id() const { return at<4>().as_uint32(); }
+};
+
+class RssStatFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = RssStatFtraceEvent_Decoder;
+  enum : int32_t {
+    kMemberFieldNumber = 1,
+    kSizeFieldNumber = 2,
+    kCurrFieldNumber = 3,
+    kMmIdFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.RssStatFtraceEvent"; }
+
+
+  using FieldMetadata_Member =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      RssStatFtraceEvent>;
+
+  static constexpr FieldMetadata_Member kMember{};
+  void set_member(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Member::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_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      RssStatFtraceEvent>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void set_size(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::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_Curr =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      RssStatFtraceEvent>;
+
+  static constexpr FieldMetadata_Curr kCurr{};
+  void set_curr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Curr::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_MmId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      RssStatFtraceEvent>;
+
+  static constexpr FieldMetadata_MmId kMmId{};
+  void set_mm_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MmId::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 MmPagePcpuDrainFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmPagePcpuDrainFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmPagePcpuDrainFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmPagePcpuDrainFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_migratetype() const { return at<1>().valid(); }
+  int32_t migratetype() const { return at<1>().as_int32(); }
+  bool has_order() const { return at<2>().valid(); }
+  uint32_t order() const { return at<2>().as_uint32(); }
+  bool has_page() const { return at<3>().valid(); }
+  uint64_t page() const { return at<3>().as_uint64(); }
+  bool has_pfn() const { return at<4>().valid(); }
+  uint64_t pfn() const { return at<4>().as_uint64(); }
+};
+
+class MmPagePcpuDrainFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmPagePcpuDrainFtraceEvent_Decoder;
+  enum : int32_t {
+    kMigratetypeFieldNumber = 1,
+    kOrderFieldNumber = 2,
+    kPageFieldNumber = 3,
+    kPfnFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmPagePcpuDrainFtraceEvent"; }
+
+
+  using FieldMetadata_Migratetype =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmPagePcpuDrainFtraceEvent>;
+
+  static constexpr FieldMetadata_Migratetype kMigratetype{};
+  void set_migratetype(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Migratetype::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_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmPagePcpuDrainFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::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_Page =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmPagePcpuDrainFtraceEvent>;
+
+  static constexpr FieldMetadata_Page kPage{};
+  void set_page(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Page::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_Pfn =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmPagePcpuDrainFtraceEvent>;
+
+  static constexpr FieldMetadata_Pfn kPfn{};
+  void set_pfn(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pfn::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 MmPageFreeBatchedFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmPageFreeBatchedFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmPageFreeBatchedFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmPageFreeBatchedFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cold() const { return at<1>().valid(); }
+  int32_t cold() const { return at<1>().as_int32(); }
+  bool has_page() const { return at<2>().valid(); }
+  uint64_t page() const { return at<2>().as_uint64(); }
+  bool has_pfn() const { return at<3>().valid(); }
+  uint64_t pfn() const { return at<3>().as_uint64(); }
+};
+
+class MmPageFreeBatchedFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmPageFreeBatchedFtraceEvent_Decoder;
+  enum : int32_t {
+    kColdFieldNumber = 1,
+    kPageFieldNumber = 2,
+    kPfnFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmPageFreeBatchedFtraceEvent"; }
+
+
+  using FieldMetadata_Cold =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmPageFreeBatchedFtraceEvent>;
+
+  static constexpr FieldMetadata_Cold kCold{};
+  void set_cold(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cold::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_Page =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmPageFreeBatchedFtraceEvent>;
+
+  static constexpr FieldMetadata_Page kPage{};
+  void set_page(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Page::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_Pfn =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmPageFreeBatchedFtraceEvent>;
+
+  static constexpr FieldMetadata_Pfn kPfn{};
+  void set_pfn(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pfn::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 MmPageFreeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmPageFreeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmPageFreeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmPageFreeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_order() const { return at<1>().valid(); }
+  uint32_t order() const { return at<1>().as_uint32(); }
+  bool has_page() const { return at<2>().valid(); }
+  uint64_t page() const { return at<2>().as_uint64(); }
+  bool has_pfn() const { return at<3>().valid(); }
+  uint64_t pfn() const { return at<3>().as_uint64(); }
+};
+
+class MmPageFreeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmPageFreeFtraceEvent_Decoder;
+  enum : int32_t {
+    kOrderFieldNumber = 1,
+    kPageFieldNumber = 2,
+    kPfnFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmPageFreeFtraceEvent"; }
+
+
+  using FieldMetadata_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmPageFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::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_Page =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmPageFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_Page kPage{};
+  void set_page(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Page::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_Pfn =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmPageFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_Pfn kPfn{};
+  void set_pfn(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pfn::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 MmPageAllocZoneLockedFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmPageAllocZoneLockedFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmPageAllocZoneLockedFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmPageAllocZoneLockedFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_migratetype() const { return at<1>().valid(); }
+  int32_t migratetype() const { return at<1>().as_int32(); }
+  bool has_order() const { return at<2>().valid(); }
+  uint32_t order() const { return at<2>().as_uint32(); }
+  bool has_page() const { return at<3>().valid(); }
+  uint64_t page() const { return at<3>().as_uint64(); }
+  bool has_pfn() const { return at<4>().valid(); }
+  uint64_t pfn() const { return at<4>().as_uint64(); }
+};
+
+class MmPageAllocZoneLockedFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmPageAllocZoneLockedFtraceEvent_Decoder;
+  enum : int32_t {
+    kMigratetypeFieldNumber = 1,
+    kOrderFieldNumber = 2,
+    kPageFieldNumber = 3,
+    kPfnFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmPageAllocZoneLockedFtraceEvent"; }
+
+
+  using FieldMetadata_Migratetype =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmPageAllocZoneLockedFtraceEvent>;
+
+  static constexpr FieldMetadata_Migratetype kMigratetype{};
+  void set_migratetype(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Migratetype::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_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmPageAllocZoneLockedFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::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_Page =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmPageAllocZoneLockedFtraceEvent>;
+
+  static constexpr FieldMetadata_Page kPage{};
+  void set_page(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Page::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_Pfn =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmPageAllocZoneLockedFtraceEvent>;
+
+  static constexpr FieldMetadata_Pfn kPfn{};
+  void set_pfn(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pfn::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 MmPageAllocExtfragFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmPageAllocExtfragFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmPageAllocExtfragFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmPageAllocExtfragFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_alloc_migratetype() const { return at<1>().valid(); }
+  int32_t alloc_migratetype() const { return at<1>().as_int32(); }
+  bool has_alloc_order() const { return at<2>().valid(); }
+  int32_t alloc_order() const { return at<2>().as_int32(); }
+  bool has_fallback_migratetype() const { return at<3>().valid(); }
+  int32_t fallback_migratetype() const { return at<3>().as_int32(); }
+  bool has_fallback_order() const { return at<4>().valid(); }
+  int32_t fallback_order() const { return at<4>().as_int32(); }
+  bool has_page() const { return at<5>().valid(); }
+  uint64_t page() const { return at<5>().as_uint64(); }
+  bool has_change_ownership() const { return at<6>().valid(); }
+  int32_t change_ownership() const { return at<6>().as_int32(); }
+  bool has_pfn() const { return at<7>().valid(); }
+  uint64_t pfn() const { return at<7>().as_uint64(); }
+};
+
+class MmPageAllocExtfragFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmPageAllocExtfragFtraceEvent_Decoder;
+  enum : int32_t {
+    kAllocMigratetypeFieldNumber = 1,
+    kAllocOrderFieldNumber = 2,
+    kFallbackMigratetypeFieldNumber = 3,
+    kFallbackOrderFieldNumber = 4,
+    kPageFieldNumber = 5,
+    kChangeOwnershipFieldNumber = 6,
+    kPfnFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmPageAllocExtfragFtraceEvent"; }
+
+
+  using FieldMetadata_AllocMigratetype =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmPageAllocExtfragFtraceEvent>;
+
+  static constexpr FieldMetadata_AllocMigratetype kAllocMigratetype{};
+  void set_alloc_migratetype(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AllocMigratetype::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_AllocOrder =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmPageAllocExtfragFtraceEvent>;
+
+  static constexpr FieldMetadata_AllocOrder kAllocOrder{};
+  void set_alloc_order(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AllocOrder::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_FallbackMigratetype =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmPageAllocExtfragFtraceEvent>;
+
+  static constexpr FieldMetadata_FallbackMigratetype kFallbackMigratetype{};
+  void set_fallback_migratetype(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FallbackMigratetype::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_FallbackOrder =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmPageAllocExtfragFtraceEvent>;
+
+  static constexpr FieldMetadata_FallbackOrder kFallbackOrder{};
+  void set_fallback_order(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FallbackOrder::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_Page =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmPageAllocExtfragFtraceEvent>;
+
+  static constexpr FieldMetadata_Page kPage{};
+  void set_page(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Page::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_ChangeOwnership =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmPageAllocExtfragFtraceEvent>;
+
+  static constexpr FieldMetadata_ChangeOwnership kChangeOwnership{};
+  void set_change_ownership(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChangeOwnership::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_Pfn =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmPageAllocExtfragFtraceEvent>;
+
+  static constexpr FieldMetadata_Pfn kPfn{};
+  void set_pfn(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pfn::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 MmPageAllocFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmPageAllocFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmPageAllocFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmPageAllocFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_gfp_flags() const { return at<1>().valid(); }
+  uint32_t gfp_flags() const { return at<1>().as_uint32(); }
+  bool has_migratetype() const { return at<2>().valid(); }
+  int32_t migratetype() const { return at<2>().as_int32(); }
+  bool has_order() const { return at<3>().valid(); }
+  uint32_t order() const { return at<3>().as_uint32(); }
+  bool has_page() const { return at<4>().valid(); }
+  uint64_t page() const { return at<4>().as_uint64(); }
+  bool has_pfn() const { return at<5>().valid(); }
+  uint64_t pfn() const { return at<5>().as_uint64(); }
+};
+
+class MmPageAllocFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmPageAllocFtraceEvent_Decoder;
+  enum : int32_t {
+    kGfpFlagsFieldNumber = 1,
+    kMigratetypeFieldNumber = 2,
+    kOrderFieldNumber = 3,
+    kPageFieldNumber = 4,
+    kPfnFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmPageAllocFtraceEvent"; }
+
+
+  using FieldMetadata_GfpFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmPageAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_GfpFlags kGfpFlags{};
+  void set_gfp_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GfpFlags::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_Migratetype =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmPageAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Migratetype kMigratetype{};
+  void set_migratetype(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Migratetype::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_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmPageAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::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_Page =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmPageAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Page kPage{};
+  void set_page(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Page::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_Pfn =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmPageAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Pfn kPfn{};
+  void set_pfn(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pfn::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 MigrateRetryFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MigrateRetryFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MigrateRetryFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MigrateRetryFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_tries() const { return at<1>().valid(); }
+  int32_t tries() const { return at<1>().as_int32(); }
+};
+
+class MigrateRetryFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MigrateRetryFtraceEvent_Decoder;
+  enum : int32_t {
+    kTriesFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MigrateRetryFtraceEvent"; }
+
+
+  using FieldMetadata_Tries =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MigrateRetryFtraceEvent>;
+
+  static constexpr FieldMetadata_Tries kTries{};
+  void set_tries(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tries::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);
+  }
+};
+
+class MigratePagesStartFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MigratePagesStartFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MigratePagesStartFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MigratePagesStartFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_mode() const { return at<1>().valid(); }
+  int32_t mode() const { return at<1>().as_int32(); }
+};
+
+class MigratePagesStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MigratePagesStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kModeFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MigratePagesStartFtraceEvent"; }
+
+
+  using FieldMetadata_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MigratePagesStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::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);
+  }
+};
+
+class MigratePagesEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MigratePagesEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MigratePagesEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MigratePagesEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_mode() const { return at<1>().valid(); }
+  int32_t mode() const { return at<1>().as_int32(); }
+};
+
+class MigratePagesEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MigratePagesEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kModeFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MigratePagesEndFtraceEvent"; }
+
+
+  using FieldMetadata_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MigratePagesEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::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);
+  }
+};
+
+class KmemCacheFreeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KmemCacheFreeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KmemCacheFreeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KmemCacheFreeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_call_site() const { return at<1>().valid(); }
+  uint64_t call_site() const { return at<1>().as_uint64(); }
+  bool has_ptr() const { return at<2>().valid(); }
+  uint64_t ptr() const { return at<2>().as_uint64(); }
+};
+
+class KmemCacheFreeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KmemCacheFreeFtraceEvent_Decoder;
+  enum : int32_t {
+    kCallSiteFieldNumber = 1,
+    kPtrFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KmemCacheFreeFtraceEvent"; }
+
+
+  using FieldMetadata_CallSite =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmemCacheFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_CallSite kCallSite{};
+  void set_call_site(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CallSite::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_Ptr =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmemCacheFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ptr kPtr{};
+  void set_ptr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ptr::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 KmemCacheAllocNodeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KmemCacheAllocNodeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KmemCacheAllocNodeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KmemCacheAllocNodeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_bytes_alloc() const { return at<1>().valid(); }
+  uint64_t bytes_alloc() const { return at<1>().as_uint64(); }
+  bool has_bytes_req() const { return at<2>().valid(); }
+  uint64_t bytes_req() const { return at<2>().as_uint64(); }
+  bool has_call_site() const { return at<3>().valid(); }
+  uint64_t call_site() const { return at<3>().as_uint64(); }
+  bool has_gfp_flags() const { return at<4>().valid(); }
+  uint32_t gfp_flags() const { return at<4>().as_uint32(); }
+  bool has_node() const { return at<5>().valid(); }
+  int32_t node() const { return at<5>().as_int32(); }
+  bool has_ptr() const { return at<6>().valid(); }
+  uint64_t ptr() const { return at<6>().as_uint64(); }
+};
+
+class KmemCacheAllocNodeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KmemCacheAllocNodeFtraceEvent_Decoder;
+  enum : int32_t {
+    kBytesAllocFieldNumber = 1,
+    kBytesReqFieldNumber = 2,
+    kCallSiteFieldNumber = 3,
+    kGfpFlagsFieldNumber = 4,
+    kNodeFieldNumber = 5,
+    kPtrFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KmemCacheAllocNodeFtraceEvent"; }
+
+
+  using FieldMetadata_BytesAlloc =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmemCacheAllocNodeFtraceEvent>;
+
+  static constexpr FieldMetadata_BytesAlloc kBytesAlloc{};
+  void set_bytes_alloc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BytesAlloc::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_BytesReq =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmemCacheAllocNodeFtraceEvent>;
+
+  static constexpr FieldMetadata_BytesReq kBytesReq{};
+  void set_bytes_req(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BytesReq::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_CallSite =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmemCacheAllocNodeFtraceEvent>;
+
+  static constexpr FieldMetadata_CallSite kCallSite{};
+  void set_call_site(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CallSite::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_GfpFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KmemCacheAllocNodeFtraceEvent>;
+
+  static constexpr FieldMetadata_GfpFlags kGfpFlags{};
+  void set_gfp_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GfpFlags::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_Node =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      KmemCacheAllocNodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Node kNode{};
+  void set_node(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Node::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_Ptr =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmemCacheAllocNodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ptr kPtr{};
+  void set_ptr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ptr::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 KmemCacheAllocFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KmemCacheAllocFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KmemCacheAllocFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KmemCacheAllocFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_bytes_alloc() const { return at<1>().valid(); }
+  uint64_t bytes_alloc() const { return at<1>().as_uint64(); }
+  bool has_bytes_req() const { return at<2>().valid(); }
+  uint64_t bytes_req() const { return at<2>().as_uint64(); }
+  bool has_call_site() const { return at<3>().valid(); }
+  uint64_t call_site() const { return at<3>().as_uint64(); }
+  bool has_gfp_flags() const { return at<4>().valid(); }
+  uint32_t gfp_flags() const { return at<4>().as_uint32(); }
+  bool has_ptr() const { return at<5>().valid(); }
+  uint64_t ptr() const { return at<5>().as_uint64(); }
+};
+
+class KmemCacheAllocFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KmemCacheAllocFtraceEvent_Decoder;
+  enum : int32_t {
+    kBytesAllocFieldNumber = 1,
+    kBytesReqFieldNumber = 2,
+    kCallSiteFieldNumber = 3,
+    kGfpFlagsFieldNumber = 4,
+    kPtrFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KmemCacheAllocFtraceEvent"; }
+
+
+  using FieldMetadata_BytesAlloc =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmemCacheAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_BytesAlloc kBytesAlloc{};
+  void set_bytes_alloc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BytesAlloc::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_BytesReq =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmemCacheAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_BytesReq kBytesReq{};
+  void set_bytes_req(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BytesReq::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_CallSite =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmemCacheAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_CallSite kCallSite{};
+  void set_call_site(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CallSite::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_GfpFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KmemCacheAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_GfpFlags kGfpFlags{};
+  void set_gfp_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GfpFlags::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_Ptr =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmemCacheAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Ptr kPtr{};
+  void set_ptr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ptr::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 KmallocNodeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KmallocNodeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KmallocNodeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KmallocNodeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_bytes_alloc() const { return at<1>().valid(); }
+  uint64_t bytes_alloc() const { return at<1>().as_uint64(); }
+  bool has_bytes_req() const { return at<2>().valid(); }
+  uint64_t bytes_req() const { return at<2>().as_uint64(); }
+  bool has_call_site() const { return at<3>().valid(); }
+  uint64_t call_site() const { return at<3>().as_uint64(); }
+  bool has_gfp_flags() const { return at<4>().valid(); }
+  uint32_t gfp_flags() const { return at<4>().as_uint32(); }
+  bool has_node() const { return at<5>().valid(); }
+  int32_t node() const { return at<5>().as_int32(); }
+  bool has_ptr() const { return at<6>().valid(); }
+  uint64_t ptr() const { return at<6>().as_uint64(); }
+};
+
+class KmallocNodeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KmallocNodeFtraceEvent_Decoder;
+  enum : int32_t {
+    kBytesAllocFieldNumber = 1,
+    kBytesReqFieldNumber = 2,
+    kCallSiteFieldNumber = 3,
+    kGfpFlagsFieldNumber = 4,
+    kNodeFieldNumber = 5,
+    kPtrFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KmallocNodeFtraceEvent"; }
+
+
+  using FieldMetadata_BytesAlloc =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmallocNodeFtraceEvent>;
+
+  static constexpr FieldMetadata_BytesAlloc kBytesAlloc{};
+  void set_bytes_alloc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BytesAlloc::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_BytesReq =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmallocNodeFtraceEvent>;
+
+  static constexpr FieldMetadata_BytesReq kBytesReq{};
+  void set_bytes_req(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BytesReq::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_CallSite =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmallocNodeFtraceEvent>;
+
+  static constexpr FieldMetadata_CallSite kCallSite{};
+  void set_call_site(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CallSite::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_GfpFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KmallocNodeFtraceEvent>;
+
+  static constexpr FieldMetadata_GfpFlags kGfpFlags{};
+  void set_gfp_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GfpFlags::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_Node =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      KmallocNodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Node kNode{};
+  void set_node(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Node::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_Ptr =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmallocNodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ptr kPtr{};
+  void set_ptr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ptr::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 KmallocFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KmallocFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KmallocFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KmallocFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_bytes_alloc() const { return at<1>().valid(); }
+  uint64_t bytes_alloc() const { return at<1>().as_uint64(); }
+  bool has_bytes_req() const { return at<2>().valid(); }
+  uint64_t bytes_req() const { return at<2>().as_uint64(); }
+  bool has_call_site() const { return at<3>().valid(); }
+  uint64_t call_site() const { return at<3>().as_uint64(); }
+  bool has_gfp_flags() const { return at<4>().valid(); }
+  uint32_t gfp_flags() const { return at<4>().as_uint32(); }
+  bool has_ptr() const { return at<5>().valid(); }
+  uint64_t ptr() const { return at<5>().as_uint64(); }
+};
+
+class KmallocFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KmallocFtraceEvent_Decoder;
+  enum : int32_t {
+    kBytesAllocFieldNumber = 1,
+    kBytesReqFieldNumber = 2,
+    kCallSiteFieldNumber = 3,
+    kGfpFlagsFieldNumber = 4,
+    kPtrFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KmallocFtraceEvent"; }
+
+
+  using FieldMetadata_BytesAlloc =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmallocFtraceEvent>;
+
+  static constexpr FieldMetadata_BytesAlloc kBytesAlloc{};
+  void set_bytes_alloc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BytesAlloc::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_BytesReq =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmallocFtraceEvent>;
+
+  static constexpr FieldMetadata_BytesReq kBytesReq{};
+  void set_bytes_req(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BytesReq::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_CallSite =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmallocFtraceEvent>;
+
+  static constexpr FieldMetadata_CallSite kCallSite{};
+  void set_call_site(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CallSite::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_GfpFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KmallocFtraceEvent>;
+
+  static constexpr FieldMetadata_GfpFlags kGfpFlags{};
+  void set_gfp_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GfpFlags::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_Ptr =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmallocFtraceEvent>;
+
+  static constexpr FieldMetadata_Ptr kPtr{};
+  void set_ptr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ptr::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 KfreeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KfreeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KfreeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KfreeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_call_site() const { return at<1>().valid(); }
+  uint64_t call_site() const { return at<1>().as_uint64(); }
+  bool has_ptr() const { return at<2>().valid(); }
+  uint64_t ptr() const { return at<2>().as_uint64(); }
+};
+
+class KfreeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KfreeFtraceEvent_Decoder;
+  enum : int32_t {
+    kCallSiteFieldNumber = 1,
+    kPtrFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KfreeFtraceEvent"; }
+
+
+  using FieldMetadata_CallSite =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KfreeFtraceEvent>;
+
+  static constexpr FieldMetadata_CallSite kCallSite{};
+  void set_call_site(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CallSite::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_Ptr =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KfreeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ptr kPtr{};
+  void set_ptr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ptr::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 IonSecureCmaShrinkPoolStartFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonSecureCmaShrinkPoolStartFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonSecureCmaShrinkPoolStartFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonSecureCmaShrinkPoolStartFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_drained_size() const { return at<1>().valid(); }
+  uint64_t drained_size() const { return at<1>().as_uint64(); }
+  bool has_skipped_size() const { return at<2>().valid(); }
+  uint64_t skipped_size() const { return at<2>().as_uint64(); }
+};
+
+class IonSecureCmaShrinkPoolStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonSecureCmaShrinkPoolStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kDrainedSizeFieldNumber = 1,
+    kSkippedSizeFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonSecureCmaShrinkPoolStartFtraceEvent"; }
+
+
+  using FieldMetadata_DrainedSize =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonSecureCmaShrinkPoolStartFtraceEvent>;
+
+  static constexpr FieldMetadata_DrainedSize kDrainedSize{};
+  void set_drained_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DrainedSize::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_SkippedSize =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonSecureCmaShrinkPoolStartFtraceEvent>;
+
+  static constexpr FieldMetadata_SkippedSize kSkippedSize{};
+  void set_skipped_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SkippedSize::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 IonSecureCmaShrinkPoolEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonSecureCmaShrinkPoolEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonSecureCmaShrinkPoolEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonSecureCmaShrinkPoolEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_drained_size() const { return at<1>().valid(); }
+  uint64_t drained_size() const { return at<1>().as_uint64(); }
+  bool has_skipped_size() const { return at<2>().valid(); }
+  uint64_t skipped_size() const { return at<2>().as_uint64(); }
+};
+
+class IonSecureCmaShrinkPoolEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonSecureCmaShrinkPoolEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kDrainedSizeFieldNumber = 1,
+    kSkippedSizeFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonSecureCmaShrinkPoolEndFtraceEvent"; }
+
+
+  using FieldMetadata_DrainedSize =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonSecureCmaShrinkPoolEndFtraceEvent>;
+
+  static constexpr FieldMetadata_DrainedSize kDrainedSize{};
+  void set_drained_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DrainedSize::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_SkippedSize =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonSecureCmaShrinkPoolEndFtraceEvent>;
+
+  static constexpr FieldMetadata_SkippedSize kSkippedSize{};
+  void set_skipped_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SkippedSize::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 IonSecureCmaAllocateStartFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonSecureCmaAllocateStartFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonSecureCmaAllocateStartFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonSecureCmaAllocateStartFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_align() const { return at<1>().valid(); }
+  uint64_t align() const { return at<1>().as_uint64(); }
+  bool has_flags() const { return at<2>().valid(); }
+  uint64_t flags() const { return at<2>().as_uint64(); }
+  bool has_heap_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars heap_name() const { return at<3>().as_string(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint64_t len() const { return at<4>().as_uint64(); }
+};
+
+class IonSecureCmaAllocateStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonSecureCmaAllocateStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kAlignFieldNumber = 1,
+    kFlagsFieldNumber = 2,
+    kHeapNameFieldNumber = 3,
+    kLenFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonSecureCmaAllocateStartFtraceEvent"; }
+
+
+  using FieldMetadata_Align =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonSecureCmaAllocateStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Align kAlign{};
+  void set_align(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Align::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonSecureCmaAllocateStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_HeapName =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IonSecureCmaAllocateStartFtraceEvent>;
+
+  static constexpr FieldMetadata_HeapName kHeapName{};
+  void set_heap_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, data, size);
+  }
+  void set_heap_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, chars.data, chars.size);
+  }
+  void set_heap_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_HeapName::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonSecureCmaAllocateStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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 IonSecureCmaAllocateEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonSecureCmaAllocateEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonSecureCmaAllocateEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonSecureCmaAllocateEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_align() const { return at<1>().valid(); }
+  uint64_t align() const { return at<1>().as_uint64(); }
+  bool has_flags() const { return at<2>().valid(); }
+  uint64_t flags() const { return at<2>().as_uint64(); }
+  bool has_heap_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars heap_name() const { return at<3>().as_string(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint64_t len() const { return at<4>().as_uint64(); }
+};
+
+class IonSecureCmaAllocateEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonSecureCmaAllocateEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kAlignFieldNumber = 1,
+    kFlagsFieldNumber = 2,
+    kHeapNameFieldNumber = 3,
+    kLenFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonSecureCmaAllocateEndFtraceEvent"; }
+
+
+  using FieldMetadata_Align =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonSecureCmaAllocateEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Align kAlign{};
+  void set_align(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Align::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonSecureCmaAllocateEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_HeapName =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IonSecureCmaAllocateEndFtraceEvent>;
+
+  static constexpr FieldMetadata_HeapName kHeapName{};
+  void set_heap_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, data, size);
+  }
+  void set_heap_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, chars.data, chars.size);
+  }
+  void set_heap_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_HeapName::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonSecureCmaAllocateEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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 IonSecureCmaAddToPoolStartFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonSecureCmaAddToPoolStartFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonSecureCmaAddToPoolStartFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonSecureCmaAddToPoolStartFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_is_prefetch() const { return at<1>().valid(); }
+  uint32_t is_prefetch() const { return at<1>().as_uint32(); }
+  bool has_len() const { return at<2>().valid(); }
+  uint64_t len() const { return at<2>().as_uint64(); }
+  bool has_pool_total() const { return at<3>().valid(); }
+  int32_t pool_total() const { return at<3>().as_int32(); }
+};
+
+class IonSecureCmaAddToPoolStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonSecureCmaAddToPoolStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kIsPrefetchFieldNumber = 1,
+    kLenFieldNumber = 2,
+    kPoolTotalFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonSecureCmaAddToPoolStartFtraceEvent"; }
+
+
+  using FieldMetadata_IsPrefetch =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      IonSecureCmaAddToPoolStartFtraceEvent>;
+
+  static constexpr FieldMetadata_IsPrefetch kIsPrefetch{};
+  void set_is_prefetch(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsPrefetch::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonSecureCmaAddToPoolStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_PoolTotal =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      IonSecureCmaAddToPoolStartFtraceEvent>;
+
+  static constexpr FieldMetadata_PoolTotal kPoolTotal{};
+  void set_pool_total(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PoolTotal::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);
+  }
+};
+
+class IonSecureCmaAddToPoolEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonSecureCmaAddToPoolEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonSecureCmaAddToPoolEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonSecureCmaAddToPoolEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_is_prefetch() const { return at<1>().valid(); }
+  uint32_t is_prefetch() const { return at<1>().as_uint32(); }
+  bool has_len() const { return at<2>().valid(); }
+  uint64_t len() const { return at<2>().as_uint64(); }
+  bool has_pool_total() const { return at<3>().valid(); }
+  int32_t pool_total() const { return at<3>().as_int32(); }
+};
+
+class IonSecureCmaAddToPoolEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonSecureCmaAddToPoolEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kIsPrefetchFieldNumber = 1,
+    kLenFieldNumber = 2,
+    kPoolTotalFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonSecureCmaAddToPoolEndFtraceEvent"; }
+
+
+  using FieldMetadata_IsPrefetch =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      IonSecureCmaAddToPoolEndFtraceEvent>;
+
+  static constexpr FieldMetadata_IsPrefetch kIsPrefetch{};
+  void set_is_prefetch(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsPrefetch::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonSecureCmaAddToPoolEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_PoolTotal =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      IonSecureCmaAddToPoolEndFtraceEvent>;
+
+  static constexpr FieldMetadata_PoolTotal kPoolTotal{};
+  void set_pool_total(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PoolTotal::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);
+  }
+};
+
+class IonPrefetchingFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonPrefetchingFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonPrefetchingFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonPrefetchingFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_len() const { return at<1>().valid(); }
+  uint64_t len() const { return at<1>().as_uint64(); }
+};
+
+class IonPrefetchingFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonPrefetchingFtraceEvent_Decoder;
+  enum : int32_t {
+    kLenFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonPrefetchingFtraceEvent"; }
+
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonPrefetchingFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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 IonCpSecureBufferStartFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonCpSecureBufferStartFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonCpSecureBufferStartFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonCpSecureBufferStartFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_align() const { return at<1>().valid(); }
+  uint64_t align() const { return at<1>().as_uint64(); }
+  bool has_flags() const { return at<2>().valid(); }
+  uint64_t flags() const { return at<2>().as_uint64(); }
+  bool has_heap_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars heap_name() const { return at<3>().as_string(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint64_t len() const { return at<4>().as_uint64(); }
+};
+
+class IonCpSecureBufferStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonCpSecureBufferStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kAlignFieldNumber = 1,
+    kFlagsFieldNumber = 2,
+    kHeapNameFieldNumber = 3,
+    kLenFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonCpSecureBufferStartFtraceEvent"; }
+
+
+  using FieldMetadata_Align =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonCpSecureBufferStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Align kAlign{};
+  void set_align(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Align::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonCpSecureBufferStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_HeapName =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IonCpSecureBufferStartFtraceEvent>;
+
+  static constexpr FieldMetadata_HeapName kHeapName{};
+  void set_heap_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, data, size);
+  }
+  void set_heap_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, chars.data, chars.size);
+  }
+  void set_heap_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_HeapName::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonCpSecureBufferStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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 IonCpSecureBufferEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonCpSecureBufferEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonCpSecureBufferEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonCpSecureBufferEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_align() const { return at<1>().valid(); }
+  uint64_t align() const { return at<1>().as_uint64(); }
+  bool has_flags() const { return at<2>().valid(); }
+  uint64_t flags() const { return at<2>().as_uint64(); }
+  bool has_heap_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars heap_name() const { return at<3>().as_string(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint64_t len() const { return at<4>().as_uint64(); }
+};
+
+class IonCpSecureBufferEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonCpSecureBufferEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kAlignFieldNumber = 1,
+    kFlagsFieldNumber = 2,
+    kHeapNameFieldNumber = 3,
+    kLenFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonCpSecureBufferEndFtraceEvent"; }
+
+
+  using FieldMetadata_Align =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonCpSecureBufferEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Align kAlign{};
+  void set_align(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Align::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonCpSecureBufferEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_HeapName =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IonCpSecureBufferEndFtraceEvent>;
+
+  static constexpr FieldMetadata_HeapName kHeapName{};
+  void set_heap_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, data, size);
+  }
+  void set_heap_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, chars.data, chars.size);
+  }
+  void set_heap_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_HeapName::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonCpSecureBufferEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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 IonCpAllocRetryFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonCpAllocRetryFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonCpAllocRetryFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonCpAllocRetryFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_tries() const { return at<1>().valid(); }
+  int32_t tries() const { return at<1>().as_int32(); }
+};
+
+class IonCpAllocRetryFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonCpAllocRetryFtraceEvent_Decoder;
+  enum : int32_t {
+    kTriesFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonCpAllocRetryFtraceEvent"; }
+
+
+  using FieldMetadata_Tries =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      IonCpAllocRetryFtraceEvent>;
+
+  static constexpr FieldMetadata_Tries kTries{};
+  void set_tries(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tries::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);
+  }
+};
+
+class IonAllocBufferStartFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonAllocBufferStartFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonAllocBufferStartFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonAllocBufferStartFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_client_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars client_name() const { return at<1>().as_string(); }
+  bool has_flags() const { return at<2>().valid(); }
+  uint32_t flags() const { return at<2>().as_uint32(); }
+  bool has_heap_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars heap_name() const { return at<3>().as_string(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint64_t len() const { return at<4>().as_uint64(); }
+  bool has_mask() const { return at<5>().valid(); }
+  uint32_t mask() const { return at<5>().as_uint32(); }
+};
+
+class IonAllocBufferStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonAllocBufferStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kClientNameFieldNumber = 1,
+    kFlagsFieldNumber = 2,
+    kHeapNameFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kMaskFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonAllocBufferStartFtraceEvent"; }
+
+
+  using FieldMetadata_ClientName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IonAllocBufferStartFtraceEvent>;
+
+  static constexpr FieldMetadata_ClientName kClientName{};
+  void set_client_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ClientName::kFieldId, data, size);
+  }
+  void set_client_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ClientName::kFieldId, chars.data, chars.size);
+  }
+  void set_client_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ClientName::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      IonAllocBufferStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_HeapName =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IonAllocBufferStartFtraceEvent>;
+
+  static constexpr FieldMetadata_HeapName kHeapName{};
+  void set_heap_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, data, size);
+  }
+  void set_heap_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, chars.data, chars.size);
+  }
+  void set_heap_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_HeapName::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonAllocBufferStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Mask =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      IonAllocBufferStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Mask kMask{};
+  void set_mask(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mask::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 IonAllocBufferFallbackFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonAllocBufferFallbackFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonAllocBufferFallbackFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonAllocBufferFallbackFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_client_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars client_name() const { return at<1>().as_string(); }
+  bool has_error() const { return at<2>().valid(); }
+  int64_t error() const { return at<2>().as_int64(); }
+  bool has_flags() const { return at<3>().valid(); }
+  uint32_t flags() const { return at<3>().as_uint32(); }
+  bool has_heap_name() const { return at<4>().valid(); }
+  ::protozero::ConstChars heap_name() const { return at<4>().as_string(); }
+  bool has_len() const { return at<5>().valid(); }
+  uint64_t len() const { return at<5>().as_uint64(); }
+  bool has_mask() const { return at<6>().valid(); }
+  uint32_t mask() const { return at<6>().as_uint32(); }
+};
+
+class IonAllocBufferFallbackFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonAllocBufferFallbackFtraceEvent_Decoder;
+  enum : int32_t {
+    kClientNameFieldNumber = 1,
+    kErrorFieldNumber = 2,
+    kFlagsFieldNumber = 3,
+    kHeapNameFieldNumber = 4,
+    kLenFieldNumber = 5,
+    kMaskFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonAllocBufferFallbackFtraceEvent"; }
+
+
+  using FieldMetadata_ClientName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IonAllocBufferFallbackFtraceEvent>;
+
+  static constexpr FieldMetadata_ClientName kClientName{};
+  void set_client_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ClientName::kFieldId, data, size);
+  }
+  void set_client_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ClientName::kFieldId, chars.data, chars.size);
+  }
+  void set_client_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ClientName::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_Error =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      IonAllocBufferFallbackFtraceEvent>;
+
+  static constexpr FieldMetadata_Error kError{};
+  void set_error(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Error::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      IonAllocBufferFallbackFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_HeapName =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IonAllocBufferFallbackFtraceEvent>;
+
+  static constexpr FieldMetadata_HeapName kHeapName{};
+  void set_heap_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, data, size);
+  }
+  void set_heap_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, chars.data, chars.size);
+  }
+  void set_heap_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_HeapName::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonAllocBufferFallbackFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Mask =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      IonAllocBufferFallbackFtraceEvent>;
+
+  static constexpr FieldMetadata_Mask kMask{};
+  void set_mask(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mask::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 IonAllocBufferFailFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonAllocBufferFailFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonAllocBufferFailFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonAllocBufferFailFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_client_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars client_name() const { return at<1>().as_string(); }
+  bool has_error() const { return at<2>().valid(); }
+  int64_t error() const { return at<2>().as_int64(); }
+  bool has_flags() const { return at<3>().valid(); }
+  uint32_t flags() const { return at<3>().as_uint32(); }
+  bool has_heap_name() const { return at<4>().valid(); }
+  ::protozero::ConstChars heap_name() const { return at<4>().as_string(); }
+  bool has_len() const { return at<5>().valid(); }
+  uint64_t len() const { return at<5>().as_uint64(); }
+  bool has_mask() const { return at<6>().valid(); }
+  uint32_t mask() const { return at<6>().as_uint32(); }
+};
+
+class IonAllocBufferFailFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonAllocBufferFailFtraceEvent_Decoder;
+  enum : int32_t {
+    kClientNameFieldNumber = 1,
+    kErrorFieldNumber = 2,
+    kFlagsFieldNumber = 3,
+    kHeapNameFieldNumber = 4,
+    kLenFieldNumber = 5,
+    kMaskFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonAllocBufferFailFtraceEvent"; }
+
+
+  using FieldMetadata_ClientName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IonAllocBufferFailFtraceEvent>;
+
+  static constexpr FieldMetadata_ClientName kClientName{};
+  void set_client_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ClientName::kFieldId, data, size);
+  }
+  void set_client_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ClientName::kFieldId, chars.data, chars.size);
+  }
+  void set_client_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ClientName::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_Error =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      IonAllocBufferFailFtraceEvent>;
+
+  static constexpr FieldMetadata_Error kError{};
+  void set_error(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Error::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      IonAllocBufferFailFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_HeapName =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IonAllocBufferFailFtraceEvent>;
+
+  static constexpr FieldMetadata_HeapName kHeapName{};
+  void set_heap_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, data, size);
+  }
+  void set_heap_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, chars.data, chars.size);
+  }
+  void set_heap_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_HeapName::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonAllocBufferFailFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Mask =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      IonAllocBufferFailFtraceEvent>;
+
+  static constexpr FieldMetadata_Mask kMask{};
+  void set_mask(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mask::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 IonAllocBufferEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonAllocBufferEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonAllocBufferEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonAllocBufferEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_client_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars client_name() const { return at<1>().as_string(); }
+  bool has_flags() const { return at<2>().valid(); }
+  uint32_t flags() const { return at<2>().as_uint32(); }
+  bool has_heap_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars heap_name() const { return at<3>().as_string(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint64_t len() const { return at<4>().as_uint64(); }
+  bool has_mask() const { return at<5>().valid(); }
+  uint32_t mask() const { return at<5>().as_uint32(); }
+};
+
+class IonAllocBufferEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonAllocBufferEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kClientNameFieldNumber = 1,
+    kFlagsFieldNumber = 2,
+    kHeapNameFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kMaskFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonAllocBufferEndFtraceEvent"; }
+
+
+  using FieldMetadata_ClientName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IonAllocBufferEndFtraceEvent>;
+
+  static constexpr FieldMetadata_ClientName kClientName{};
+  void set_client_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ClientName::kFieldId, data, size);
+  }
+  void set_client_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ClientName::kFieldId, chars.data, chars.size);
+  }
+  void set_client_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ClientName::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      IonAllocBufferEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_HeapName =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IonAllocBufferEndFtraceEvent>;
+
+  static constexpr FieldMetadata_HeapName kHeapName{};
+  void set_heap_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, data, size);
+  }
+  void set_heap_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, chars.data, chars.size);
+  }
+  void set_heap_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_HeapName::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonAllocBufferEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Mask =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      IonAllocBufferEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Mask kMask{};
+  void set_mask(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mask::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 IommuSecPtblMapRangeStartFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IommuSecPtblMapRangeStartFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IommuSecPtblMapRangeStartFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IommuSecPtblMapRangeStartFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_len() const { return at<1>().valid(); }
+  uint64_t len() const { return at<1>().as_uint64(); }
+  bool has_num() const { return at<2>().valid(); }
+  int32_t num() const { return at<2>().as_int32(); }
+  bool has_pa() const { return at<3>().valid(); }
+  uint32_t pa() const { return at<3>().as_uint32(); }
+  bool has_sec_id() const { return at<4>().valid(); }
+  int32_t sec_id() const { return at<4>().as_int32(); }
+  bool has_va() const { return at<5>().valid(); }
+  uint64_t va() const { return at<5>().as_uint64(); }
+};
+
+class IommuSecPtblMapRangeStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IommuSecPtblMapRangeStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kLenFieldNumber = 1,
+    kNumFieldNumber = 2,
+    kPaFieldNumber = 3,
+    kSecIdFieldNumber = 4,
+    kVaFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IommuSecPtblMapRangeStartFtraceEvent"; }
+
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IommuSecPtblMapRangeStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Num =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      IommuSecPtblMapRangeStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Num kNum{};
+  void set_num(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Num::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_Pa =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      IommuSecPtblMapRangeStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Pa kPa{};
+  void set_pa(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pa::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_SecId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      IommuSecPtblMapRangeStartFtraceEvent>;
+
+  static constexpr FieldMetadata_SecId kSecId{};
+  void set_sec_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SecId::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_Va =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IommuSecPtblMapRangeStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Va kVa{};
+  void set_va(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Va::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 IommuSecPtblMapRangeEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IommuSecPtblMapRangeEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IommuSecPtblMapRangeEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IommuSecPtblMapRangeEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_len() const { return at<1>().valid(); }
+  uint64_t len() const { return at<1>().as_uint64(); }
+  bool has_num() const { return at<2>().valid(); }
+  int32_t num() const { return at<2>().as_int32(); }
+  bool has_pa() const { return at<3>().valid(); }
+  uint32_t pa() const { return at<3>().as_uint32(); }
+  bool has_sec_id() const { return at<4>().valid(); }
+  int32_t sec_id() const { return at<4>().as_int32(); }
+  bool has_va() const { return at<5>().valid(); }
+  uint64_t va() const { return at<5>().as_uint64(); }
+};
+
+class IommuSecPtblMapRangeEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IommuSecPtblMapRangeEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kLenFieldNumber = 1,
+    kNumFieldNumber = 2,
+    kPaFieldNumber = 3,
+    kSecIdFieldNumber = 4,
+    kVaFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IommuSecPtblMapRangeEndFtraceEvent"; }
+
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IommuSecPtblMapRangeEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Num =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      IommuSecPtblMapRangeEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Num kNum{};
+  void set_num(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Num::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_Pa =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      IommuSecPtblMapRangeEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Pa kPa{};
+  void set_pa(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pa::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_SecId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      IommuSecPtblMapRangeEndFtraceEvent>;
+
+  static constexpr FieldMetadata_SecId kSecId{};
+  void set_sec_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SecId::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_Va =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IommuSecPtblMapRangeEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Va kVa{};
+  void set_va(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Va::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 IommuMapRangeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IommuMapRangeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IommuMapRangeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IommuMapRangeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_chunk_size() const { return at<1>().valid(); }
+  uint64_t chunk_size() const { return at<1>().as_uint64(); }
+  bool has_len() const { return at<2>().valid(); }
+  uint64_t len() const { return at<2>().as_uint64(); }
+  bool has_pa() const { return at<3>().valid(); }
+  uint64_t pa() const { return at<3>().as_uint64(); }
+  bool has_va() const { return at<4>().valid(); }
+  uint64_t va() const { return at<4>().as_uint64(); }
+};
+
+class IommuMapRangeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IommuMapRangeFtraceEvent_Decoder;
+  enum : int32_t {
+    kChunkSizeFieldNumber = 1,
+    kLenFieldNumber = 2,
+    kPaFieldNumber = 3,
+    kVaFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IommuMapRangeFtraceEvent"; }
+
+
+  using FieldMetadata_ChunkSize =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IommuMapRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_ChunkSize kChunkSize{};
+  void set_chunk_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChunkSize::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IommuMapRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Pa =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IommuMapRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Pa kPa{};
+  void set_pa(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pa::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_Va =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IommuMapRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Va kVa{};
+  void set_va(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Va::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 DmaAllocContiguousRetryFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DmaAllocContiguousRetryFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DmaAllocContiguousRetryFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DmaAllocContiguousRetryFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_tries() const { return at<1>().valid(); }
+  int32_t tries() const { return at<1>().as_int32(); }
+};
+
+class DmaAllocContiguousRetryFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = DmaAllocContiguousRetryFtraceEvent_Decoder;
+  enum : int32_t {
+    kTriesFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DmaAllocContiguousRetryFtraceEvent"; }
+
+
+  using FieldMetadata_Tries =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      DmaAllocContiguousRetryFtraceEvent>;
+
+  static constexpr FieldMetadata_Tries kTries{};
+  void set_tries(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tries::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);
+  }
+};
+
+class AllocPagesSysStartFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AllocPagesSysStartFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AllocPagesSysStartFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AllocPagesSysStartFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_gfp_flags() const { return at<1>().valid(); }
+  uint32_t gfp_flags() const { return at<1>().as_uint32(); }
+  bool has_order() const { return at<2>().valid(); }
+  uint32_t order() const { return at<2>().as_uint32(); }
+};
+
+class AllocPagesSysStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = AllocPagesSysStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kGfpFlagsFieldNumber = 1,
+    kOrderFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AllocPagesSysStartFtraceEvent"; }
+
+
+  using FieldMetadata_GfpFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AllocPagesSysStartFtraceEvent>;
+
+  static constexpr FieldMetadata_GfpFlags kGfpFlags{};
+  void set_gfp_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GfpFlags::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_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AllocPagesSysStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::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 AllocPagesSysFailFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AllocPagesSysFailFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AllocPagesSysFailFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AllocPagesSysFailFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_gfp_flags() const { return at<1>().valid(); }
+  uint32_t gfp_flags() const { return at<1>().as_uint32(); }
+  bool has_order() const { return at<2>().valid(); }
+  uint32_t order() const { return at<2>().as_uint32(); }
+};
+
+class AllocPagesSysFailFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = AllocPagesSysFailFtraceEvent_Decoder;
+  enum : int32_t {
+    kGfpFlagsFieldNumber = 1,
+    kOrderFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AllocPagesSysFailFtraceEvent"; }
+
+
+  using FieldMetadata_GfpFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AllocPagesSysFailFtraceEvent>;
+
+  static constexpr FieldMetadata_GfpFlags kGfpFlags{};
+  void set_gfp_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GfpFlags::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_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AllocPagesSysFailFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::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 AllocPagesSysEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AllocPagesSysEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AllocPagesSysEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AllocPagesSysEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_gfp_flags() const { return at<1>().valid(); }
+  uint32_t gfp_flags() const { return at<1>().as_uint32(); }
+  bool has_order() const { return at<2>().valid(); }
+  uint32_t order() const { return at<2>().as_uint32(); }
+};
+
+class AllocPagesSysEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = AllocPagesSysEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kGfpFlagsFieldNumber = 1,
+    kOrderFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AllocPagesSysEndFtraceEvent"; }
+
+
+  using FieldMetadata_GfpFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AllocPagesSysEndFtraceEvent>;
+
+  static constexpr FieldMetadata_GfpFlags kGfpFlags{};
+  void set_gfp_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GfpFlags::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_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AllocPagesSysEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::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 AllocPagesIommuStartFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AllocPagesIommuStartFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AllocPagesIommuStartFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AllocPagesIommuStartFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_gfp_flags() const { return at<1>().valid(); }
+  uint32_t gfp_flags() const { return at<1>().as_uint32(); }
+  bool has_order() const { return at<2>().valid(); }
+  uint32_t order() const { return at<2>().as_uint32(); }
+};
+
+class AllocPagesIommuStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = AllocPagesIommuStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kGfpFlagsFieldNumber = 1,
+    kOrderFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AllocPagesIommuStartFtraceEvent"; }
+
+
+  using FieldMetadata_GfpFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AllocPagesIommuStartFtraceEvent>;
+
+  static constexpr FieldMetadata_GfpFlags kGfpFlags{};
+  void set_gfp_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GfpFlags::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_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AllocPagesIommuStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::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 AllocPagesIommuFailFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AllocPagesIommuFailFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AllocPagesIommuFailFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AllocPagesIommuFailFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_gfp_flags() const { return at<1>().valid(); }
+  uint32_t gfp_flags() const { return at<1>().as_uint32(); }
+  bool has_order() const { return at<2>().valid(); }
+  uint32_t order() const { return at<2>().as_uint32(); }
+};
+
+class AllocPagesIommuFailFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = AllocPagesIommuFailFtraceEvent_Decoder;
+  enum : int32_t {
+    kGfpFlagsFieldNumber = 1,
+    kOrderFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AllocPagesIommuFailFtraceEvent"; }
+
+
+  using FieldMetadata_GfpFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AllocPagesIommuFailFtraceEvent>;
+
+  static constexpr FieldMetadata_GfpFlags kGfpFlags{};
+  void set_gfp_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GfpFlags::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_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AllocPagesIommuFailFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::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 AllocPagesIommuEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AllocPagesIommuEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AllocPagesIommuEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AllocPagesIommuEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_gfp_flags() const { return at<1>().valid(); }
+  uint32_t gfp_flags() const { return at<1>().as_uint32(); }
+  bool has_order() const { return at<2>().valid(); }
+  uint32_t order() const { return at<2>().as_uint32(); }
+};
+
+class AllocPagesIommuEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = AllocPagesIommuEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kGfpFlagsFieldNumber = 1,
+    kOrderFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AllocPagesIommuEndFtraceEvent"; }
+
+
+  using FieldMetadata_GfpFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AllocPagesIommuEndFtraceEvent>;
+
+  static constexpr FieldMetadata_GfpFlags kGfpFlags{};
+  void set_gfp_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GfpFlags::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_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AllocPagesIommuEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/kvm.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_KVM_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_KVM_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class VgicUpdateIrqPendingFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  VgicUpdateIrqPendingFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit VgicUpdateIrqPendingFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit VgicUpdateIrqPendingFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_irq() const { return at<1>().valid(); }
+  uint32_t irq() const { return at<1>().as_uint32(); }
+  bool has_level() const { return at<2>().valid(); }
+  uint32_t level() const { return at<2>().as_uint32(); }
+  bool has_vcpu_id() const { return at<3>().valid(); }
+  uint64_t vcpu_id() const { return at<3>().as_uint64(); }
+};
+
+class VgicUpdateIrqPendingFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = VgicUpdateIrqPendingFtraceEvent_Decoder;
+  enum : int32_t {
+    kIrqFieldNumber = 1,
+    kLevelFieldNumber = 2,
+    kVcpuIdFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.VgicUpdateIrqPendingFtraceEvent"; }
+
+
+  using FieldMetadata_Irq =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VgicUpdateIrqPendingFtraceEvent>;
+
+  static constexpr FieldMetadata_Irq kIrq{};
+  void set_irq(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Irq::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_Level =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VgicUpdateIrqPendingFtraceEvent>;
+
+  static constexpr FieldMetadata_Level kLevel{};
+  void set_level(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Level::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_VcpuId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      VgicUpdateIrqPendingFtraceEvent>;
+
+  static constexpr FieldMetadata_VcpuId kVcpuId{};
+  void set_vcpu_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VcpuId::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 TrapRegFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrapRegFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrapRegFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrapRegFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_fn() const { return at<1>().valid(); }
+  ::protozero::ConstChars fn() const { return at<1>().as_string(); }
+  bool has_is_write() const { return at<2>().valid(); }
+  uint32_t is_write() const { return at<2>().as_uint32(); }
+  bool has_reg() const { return at<3>().valid(); }
+  int32_t reg() const { return at<3>().as_int32(); }
+  bool has_write_value() const { return at<4>().valid(); }
+  uint64_t write_value() const { return at<4>().as_uint64(); }
+};
+
+class TrapRegFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrapRegFtraceEvent_Decoder;
+  enum : int32_t {
+    kFnFieldNumber = 1,
+    kIsWriteFieldNumber = 2,
+    kRegFieldNumber = 3,
+    kWriteValueFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrapRegFtraceEvent"; }
+
+
+  using FieldMetadata_Fn =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrapRegFtraceEvent>;
+
+  static constexpr FieldMetadata_Fn kFn{};
+  void set_fn(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Fn::kFieldId, data, size);
+  }
+  void set_fn(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Fn::kFieldId, chars.data, chars.size);
+  }
+  void set_fn(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Fn::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_IsWrite =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TrapRegFtraceEvent>;
+
+  static constexpr FieldMetadata_IsWrite kIsWrite{};
+  void set_is_write(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsWrite::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_Reg =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TrapRegFtraceEvent>;
+
+  static constexpr FieldMetadata_Reg kReg{};
+  void set_reg(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Reg::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_WriteValue =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrapRegFtraceEvent>;
+
+  static constexpr FieldMetadata_WriteValue kWriteValue{};
+  void set_write_value(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_WriteValue::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 KvmWfxArm64FtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmWfxArm64FtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmWfxArm64FtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmWfxArm64FtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_is_wfe() const { return at<1>().valid(); }
+  uint32_t is_wfe() const { return at<1>().as_uint32(); }
+  bool has_vcpu_pc() const { return at<2>().valid(); }
+  uint64_t vcpu_pc() const { return at<2>().as_uint64(); }
+};
+
+class KvmWfxArm64FtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmWfxArm64FtraceEvent_Decoder;
+  enum : int32_t {
+    kIsWfeFieldNumber = 1,
+    kVcpuPcFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmWfxArm64FtraceEvent"; }
+
+
+  using FieldMetadata_IsWfe =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmWfxArm64FtraceEvent>;
+
+  static constexpr FieldMetadata_IsWfe kIsWfe{};
+  void set_is_wfe(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsWfe::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_VcpuPc =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmWfxArm64FtraceEvent>;
+
+  static constexpr FieldMetadata_VcpuPc kVcpuPc{};
+  void set_vcpu_pc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VcpuPc::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 KvmVcpuWakeupFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmVcpuWakeupFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmVcpuWakeupFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmVcpuWakeupFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ns() const { return at<1>().valid(); }
+  uint64_t ns() const { return at<1>().as_uint64(); }
+  bool has_valid() const { return at<2>().valid(); }
+  uint32_t valid() const { return at<2>().as_uint32(); }
+  bool has_waited() const { return at<3>().valid(); }
+  uint32_t waited() const { return at<3>().as_uint32(); }
+};
+
+class KvmVcpuWakeupFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmVcpuWakeupFtraceEvent_Decoder;
+  enum : int32_t {
+    kNsFieldNumber = 1,
+    kValidFieldNumber = 2,
+    kWaitedFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmVcpuWakeupFtraceEvent"; }
+
+
+  using FieldMetadata_Ns =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmVcpuWakeupFtraceEvent>;
+
+  static constexpr FieldMetadata_Ns kNs{};
+  void set_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ns::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_Valid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmVcpuWakeupFtraceEvent>;
+
+  static constexpr FieldMetadata_Valid kValid{};
+  void set_valid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Valid::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_Waited =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmVcpuWakeupFtraceEvent>;
+
+  static constexpr FieldMetadata_Waited kWaited{};
+  void set_waited(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Waited::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 KvmUserspaceExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmUserspaceExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmUserspaceExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmUserspaceExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_reason() const { return at<1>().valid(); }
+  uint32_t reason() const { return at<1>().as_uint32(); }
+};
+
+class KvmUserspaceExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmUserspaceExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kReasonFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmUserspaceExitFtraceEvent"; }
+
+
+  using FieldMetadata_Reason =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmUserspaceExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Reason kReason{};
+  void set_reason(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Reason::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 KvmUnmapHvaRangeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmUnmapHvaRangeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmUnmapHvaRangeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmUnmapHvaRangeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_end() const { return at<1>().valid(); }
+  uint64_t end() const { return at<1>().as_uint64(); }
+  bool has_start() const { return at<2>().valid(); }
+  uint64_t start() const { return at<2>().as_uint64(); }
+};
+
+class KvmUnmapHvaRangeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmUnmapHvaRangeFtraceEvent_Decoder;
+  enum : int32_t {
+    kEndFieldNumber = 1,
+    kStartFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmUnmapHvaRangeFtraceEvent"; }
+
+
+  using FieldMetadata_End =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmUnmapHvaRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_End kEnd{};
+  void set_end(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_End::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_Start =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmUnmapHvaRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Start kStart{};
+  void set_start(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Start::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 KvmToggleCacheFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmToggleCacheFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmToggleCacheFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmToggleCacheFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_now() const { return at<1>().valid(); }
+  uint32_t now() const { return at<1>().as_uint32(); }
+  bool has_vcpu_pc() const { return at<2>().valid(); }
+  uint64_t vcpu_pc() const { return at<2>().as_uint64(); }
+  bool has_was() const { return at<3>().valid(); }
+  uint32_t was() const { return at<3>().as_uint32(); }
+};
+
+class KvmToggleCacheFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmToggleCacheFtraceEvent_Decoder;
+  enum : int32_t {
+    kNowFieldNumber = 1,
+    kVcpuPcFieldNumber = 2,
+    kWasFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmToggleCacheFtraceEvent"; }
+
+
+  using FieldMetadata_Now =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmToggleCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_Now kNow{};
+  void set_now(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Now::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_VcpuPc =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmToggleCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_VcpuPc kVcpuPc{};
+  void set_vcpu_pc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VcpuPc::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_Was =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmToggleCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_Was kWas{};
+  void set_was(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Was::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 KvmTimerUpdateIrqFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmTimerUpdateIrqFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmTimerUpdateIrqFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmTimerUpdateIrqFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_irq() const { return at<1>().valid(); }
+  uint32_t irq() const { return at<1>().as_uint32(); }
+  bool has_level() const { return at<2>().valid(); }
+  int32_t level() const { return at<2>().as_int32(); }
+  bool has_vcpu_id() const { return at<3>().valid(); }
+  uint64_t vcpu_id() const { return at<3>().as_uint64(); }
+};
+
+class KvmTimerUpdateIrqFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmTimerUpdateIrqFtraceEvent_Decoder;
+  enum : int32_t {
+    kIrqFieldNumber = 1,
+    kLevelFieldNumber = 2,
+    kVcpuIdFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmTimerUpdateIrqFtraceEvent"; }
+
+
+  using FieldMetadata_Irq =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmTimerUpdateIrqFtraceEvent>;
+
+  static constexpr FieldMetadata_Irq kIrq{};
+  void set_irq(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Irq::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_Level =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      KvmTimerUpdateIrqFtraceEvent>;
+
+  static constexpr FieldMetadata_Level kLevel{};
+  void set_level(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Level::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_VcpuId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmTimerUpdateIrqFtraceEvent>;
+
+  static constexpr FieldMetadata_VcpuId kVcpuId{};
+  void set_vcpu_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VcpuId::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 KvmTimerSaveStateFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmTimerSaveStateFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmTimerSaveStateFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmTimerSaveStateFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ctl() const { return at<1>().valid(); }
+  uint64_t ctl() const { return at<1>().as_uint64(); }
+  bool has_cval() const { return at<2>().valid(); }
+  uint64_t cval() const { return at<2>().as_uint64(); }
+  bool has_timer_idx() const { return at<3>().valid(); }
+  int32_t timer_idx() const { return at<3>().as_int32(); }
+};
+
+class KvmTimerSaveStateFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmTimerSaveStateFtraceEvent_Decoder;
+  enum : int32_t {
+    kCtlFieldNumber = 1,
+    kCvalFieldNumber = 2,
+    kTimerIdxFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmTimerSaveStateFtraceEvent"; }
+
+
+  using FieldMetadata_Ctl =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmTimerSaveStateFtraceEvent>;
+
+  static constexpr FieldMetadata_Ctl kCtl{};
+  void set_ctl(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ctl::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_Cval =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmTimerSaveStateFtraceEvent>;
+
+  static constexpr FieldMetadata_Cval kCval{};
+  void set_cval(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cval::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_TimerIdx =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      KvmTimerSaveStateFtraceEvent>;
+
+  static constexpr FieldMetadata_TimerIdx kTimerIdx{};
+  void set_timer_idx(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimerIdx::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);
+  }
+};
+
+class KvmTimerRestoreStateFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmTimerRestoreStateFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmTimerRestoreStateFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmTimerRestoreStateFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ctl() const { return at<1>().valid(); }
+  uint64_t ctl() const { return at<1>().as_uint64(); }
+  bool has_cval() const { return at<2>().valid(); }
+  uint64_t cval() const { return at<2>().as_uint64(); }
+  bool has_timer_idx() const { return at<3>().valid(); }
+  int32_t timer_idx() const { return at<3>().as_int32(); }
+};
+
+class KvmTimerRestoreStateFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmTimerRestoreStateFtraceEvent_Decoder;
+  enum : int32_t {
+    kCtlFieldNumber = 1,
+    kCvalFieldNumber = 2,
+    kTimerIdxFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmTimerRestoreStateFtraceEvent"; }
+
+
+  using FieldMetadata_Ctl =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmTimerRestoreStateFtraceEvent>;
+
+  static constexpr FieldMetadata_Ctl kCtl{};
+  void set_ctl(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ctl::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_Cval =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmTimerRestoreStateFtraceEvent>;
+
+  static constexpr FieldMetadata_Cval kCval{};
+  void set_cval(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cval::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_TimerIdx =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      KvmTimerRestoreStateFtraceEvent>;
+
+  static constexpr FieldMetadata_TimerIdx kTimerIdx{};
+  void set_timer_idx(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimerIdx::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);
+  }
+};
+
+class KvmTimerHrtimerExpireFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmTimerHrtimerExpireFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmTimerHrtimerExpireFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmTimerHrtimerExpireFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_timer_idx() const { return at<1>().valid(); }
+  int32_t timer_idx() const { return at<1>().as_int32(); }
+};
+
+class KvmTimerHrtimerExpireFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmTimerHrtimerExpireFtraceEvent_Decoder;
+  enum : int32_t {
+    kTimerIdxFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmTimerHrtimerExpireFtraceEvent"; }
+
+
+  using FieldMetadata_TimerIdx =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      KvmTimerHrtimerExpireFtraceEvent>;
+
+  static constexpr FieldMetadata_TimerIdx kTimerIdx{};
+  void set_timer_idx(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimerIdx::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);
+  }
+};
+
+class KvmTimerEmulateFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmTimerEmulateFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmTimerEmulateFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmTimerEmulateFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_should_fire() const { return at<1>().valid(); }
+  uint32_t should_fire() const { return at<1>().as_uint32(); }
+  bool has_timer_idx() const { return at<2>().valid(); }
+  int32_t timer_idx() const { return at<2>().as_int32(); }
+};
+
+class KvmTimerEmulateFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmTimerEmulateFtraceEvent_Decoder;
+  enum : int32_t {
+    kShouldFireFieldNumber = 1,
+    kTimerIdxFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmTimerEmulateFtraceEvent"; }
+
+
+  using FieldMetadata_ShouldFire =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmTimerEmulateFtraceEvent>;
+
+  static constexpr FieldMetadata_ShouldFire kShouldFire{};
+  void set_should_fire(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ShouldFire::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_TimerIdx =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      KvmTimerEmulateFtraceEvent>;
+
+  static constexpr FieldMetadata_TimerIdx kTimerIdx{};
+  void set_timer_idx(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimerIdx::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);
+  }
+};
+
+class KvmTestAgeHvaFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmTestAgeHvaFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmTestAgeHvaFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmTestAgeHvaFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_hva() const { return at<1>().valid(); }
+  uint64_t hva() const { return at<1>().as_uint64(); }
+};
+
+class KvmTestAgeHvaFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmTestAgeHvaFtraceEvent_Decoder;
+  enum : int32_t {
+    kHvaFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmTestAgeHvaFtraceEvent"; }
+
+
+  using FieldMetadata_Hva =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmTestAgeHvaFtraceEvent>;
+
+  static constexpr FieldMetadata_Hva kHva{};
+  void set_hva(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Hva::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 KvmSysAccessFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmSysAccessFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmSysAccessFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmSysAccessFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_crm() const { return at<1>().valid(); }
+  uint32_t crm() const { return at<1>().as_uint32(); }
+  bool has_crn() const { return at<2>().valid(); }
+  uint32_t crn() const { return at<2>().as_uint32(); }
+  bool has_op0() const { return at<3>().valid(); }
+  uint32_t op0() const { return at<3>().as_uint32(); }
+  bool has_op1() const { return at<4>().valid(); }
+  uint32_t op1() const { return at<4>().as_uint32(); }
+  bool has_op2() const { return at<5>().valid(); }
+  uint32_t op2() const { return at<5>().as_uint32(); }
+  bool has_is_write() const { return at<6>().valid(); }
+  uint32_t is_write() const { return at<6>().as_uint32(); }
+  bool has_name() const { return at<7>().valid(); }
+  ::protozero::ConstChars name() const { return at<7>().as_string(); }
+  bool has_vcpu_pc() const { return at<8>().valid(); }
+  uint64_t vcpu_pc() const { return at<8>().as_uint64(); }
+};
+
+class KvmSysAccessFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmSysAccessFtraceEvent_Decoder;
+  enum : int32_t {
+    kCRmFieldNumber = 1,
+    kCRnFieldNumber = 2,
+    kOp0FieldNumber = 3,
+    kOp1FieldNumber = 4,
+    kOp2FieldNumber = 5,
+    kIsWriteFieldNumber = 6,
+    kNameFieldNumber = 7,
+    kVcpuPcFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmSysAccessFtraceEvent"; }
+
+
+  using FieldMetadata_CRm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmSysAccessFtraceEvent>;
+
+  static constexpr FieldMetadata_CRm kCRm{};
+  void set_crm(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CRm::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_CRn =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmSysAccessFtraceEvent>;
+
+  static constexpr FieldMetadata_CRn kCRn{};
+  void set_crn(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CRn::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_Op0 =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmSysAccessFtraceEvent>;
+
+  static constexpr FieldMetadata_Op0 kOp0{};
+  void set_op0(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Op0::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_Op1 =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmSysAccessFtraceEvent>;
+
+  static constexpr FieldMetadata_Op1 kOp1{};
+  void set_op1(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Op1::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_Op2 =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmSysAccessFtraceEvent>;
+
+  static constexpr FieldMetadata_Op2 kOp2{};
+  void set_op2(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Op2::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_IsWrite =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmSysAccessFtraceEvent>;
+
+  static constexpr FieldMetadata_IsWrite kIsWrite{};
+  void set_is_write(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsWrite::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      KvmSysAccessFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_VcpuPc =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmSysAccessFtraceEvent>;
+
+  static constexpr FieldMetadata_VcpuPc kVcpuPc{};
+  void set_vcpu_pc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VcpuPc::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 KvmSetWayFlushFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmSetWayFlushFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmSetWayFlushFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmSetWayFlushFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cache() const { return at<1>().valid(); }
+  uint32_t cache() const { return at<1>().as_uint32(); }
+  bool has_vcpu_pc() const { return at<2>().valid(); }
+  uint64_t vcpu_pc() const { return at<2>().as_uint64(); }
+};
+
+class KvmSetWayFlushFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmSetWayFlushFtraceEvent_Decoder;
+  enum : int32_t {
+    kCacheFieldNumber = 1,
+    kVcpuPcFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmSetWayFlushFtraceEvent"; }
+
+
+  using FieldMetadata_Cache =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmSetWayFlushFtraceEvent>;
+
+  static constexpr FieldMetadata_Cache kCache{};
+  void set_cache(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cache::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_VcpuPc =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmSetWayFlushFtraceEvent>;
+
+  static constexpr FieldMetadata_VcpuPc kVcpuPc{};
+  void set_vcpu_pc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VcpuPc::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 KvmSetSpteHvaFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmSetSpteHvaFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmSetSpteHvaFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmSetSpteHvaFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_hva() const { return at<1>().valid(); }
+  uint64_t hva() const { return at<1>().as_uint64(); }
+};
+
+class KvmSetSpteHvaFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmSetSpteHvaFtraceEvent_Decoder;
+  enum : int32_t {
+    kHvaFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmSetSpteHvaFtraceEvent"; }
+
+
+  using FieldMetadata_Hva =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmSetSpteHvaFtraceEvent>;
+
+  static constexpr FieldMetadata_Hva kHva{};
+  void set_hva(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Hva::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 KvmSetIrqFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmSetIrqFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmSetIrqFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmSetIrqFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_gsi() const { return at<1>().valid(); }
+  uint32_t gsi() const { return at<1>().as_uint32(); }
+  bool has_irq_source_id() const { return at<2>().valid(); }
+  int32_t irq_source_id() const { return at<2>().as_int32(); }
+  bool has_level() const { return at<3>().valid(); }
+  int32_t level() const { return at<3>().as_int32(); }
+};
+
+class KvmSetIrqFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmSetIrqFtraceEvent_Decoder;
+  enum : int32_t {
+    kGsiFieldNumber = 1,
+    kIrqSourceIdFieldNumber = 2,
+    kLevelFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmSetIrqFtraceEvent"; }
+
+
+  using FieldMetadata_Gsi =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmSetIrqFtraceEvent>;
+
+  static constexpr FieldMetadata_Gsi kGsi{};
+  void set_gsi(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Gsi::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_IrqSourceId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      KvmSetIrqFtraceEvent>;
+
+  static constexpr FieldMetadata_IrqSourceId kIrqSourceId{};
+  void set_irq_source_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IrqSourceId::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_Level =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      KvmSetIrqFtraceEvent>;
+
+  static constexpr FieldMetadata_Level kLevel{};
+  void set_level(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Level::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);
+  }
+};
+
+class KvmSetGuestDebugFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmSetGuestDebugFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmSetGuestDebugFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmSetGuestDebugFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_guest_debug() const { return at<1>().valid(); }
+  uint32_t guest_debug() const { return at<1>().as_uint32(); }
+  bool has_vcpu() const { return at<2>().valid(); }
+  uint64_t vcpu() const { return at<2>().as_uint64(); }
+};
+
+class KvmSetGuestDebugFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmSetGuestDebugFtraceEvent_Decoder;
+  enum : int32_t {
+    kGuestDebugFieldNumber = 1,
+    kVcpuFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmSetGuestDebugFtraceEvent"; }
+
+
+  using FieldMetadata_GuestDebug =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmSetGuestDebugFtraceEvent>;
+
+  static constexpr FieldMetadata_GuestDebug kGuestDebug{};
+  void set_guest_debug(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GuestDebug::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_Vcpu =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmSetGuestDebugFtraceEvent>;
+
+  static constexpr FieldMetadata_Vcpu kVcpu{};
+  void set_vcpu(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Vcpu::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 KvmMmioEmulateFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmMmioEmulateFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmMmioEmulateFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmMmioEmulateFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cpsr() const { return at<1>().valid(); }
+  uint64_t cpsr() const { return at<1>().as_uint64(); }
+  bool has_instr() const { return at<2>().valid(); }
+  uint64_t instr() const { return at<2>().as_uint64(); }
+  bool has_vcpu_pc() const { return at<3>().valid(); }
+  uint64_t vcpu_pc() const { return at<3>().as_uint64(); }
+};
+
+class KvmMmioEmulateFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmMmioEmulateFtraceEvent_Decoder;
+  enum : int32_t {
+    kCpsrFieldNumber = 1,
+    kInstrFieldNumber = 2,
+    kVcpuPcFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmMmioEmulateFtraceEvent"; }
+
+
+  using FieldMetadata_Cpsr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmMmioEmulateFtraceEvent>;
+
+  static constexpr FieldMetadata_Cpsr kCpsr{};
+  void set_cpsr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cpsr::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_Instr =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmMmioEmulateFtraceEvent>;
+
+  static constexpr FieldMetadata_Instr kInstr{};
+  void set_instr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Instr::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_VcpuPc =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmMmioEmulateFtraceEvent>;
+
+  static constexpr FieldMetadata_VcpuPc kVcpuPc{};
+  void set_vcpu_pc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VcpuPc::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 KvmMmioFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmMmioFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmMmioFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmMmioFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_gpa() const { return at<1>().valid(); }
+  uint64_t gpa() const { return at<1>().as_uint64(); }
+  bool has_len() const { return at<2>().valid(); }
+  uint32_t len() const { return at<2>().as_uint32(); }
+  bool has_type() const { return at<3>().valid(); }
+  uint32_t type() const { return at<3>().as_uint32(); }
+  bool has_val() const { return at<4>().valid(); }
+  uint64_t val() const { return at<4>().as_uint64(); }
+};
+
+class KvmMmioFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmMmioFtraceEvent_Decoder;
+  enum : int32_t {
+    kGpaFieldNumber = 1,
+    kLenFieldNumber = 2,
+    kTypeFieldNumber = 3,
+    kValFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmMmioFtraceEvent"; }
+
+
+  using FieldMetadata_Gpa =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmMmioFtraceEvent>;
+
+  static constexpr FieldMetadata_Gpa kGpa{};
+  void set_gpa(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Gpa::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmMmioFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmMmioFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::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_Val =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmMmioFtraceEvent>;
+
+  static constexpr FieldMetadata_Val kVal{};
+  void set_val(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Val::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 KvmIrqLineFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmIrqLineFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmIrqLineFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmIrqLineFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_irq_num() const { return at<1>().valid(); }
+  int32_t irq_num() const { return at<1>().as_int32(); }
+  bool has_level() const { return at<2>().valid(); }
+  int32_t level() const { return at<2>().as_int32(); }
+  bool has_type() const { return at<3>().valid(); }
+  uint32_t type() const { return at<3>().as_uint32(); }
+  bool has_vcpu_idx() const { return at<4>().valid(); }
+  int32_t vcpu_idx() const { return at<4>().as_int32(); }
+};
+
+class KvmIrqLineFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmIrqLineFtraceEvent_Decoder;
+  enum : int32_t {
+    kIrqNumFieldNumber = 1,
+    kLevelFieldNumber = 2,
+    kTypeFieldNumber = 3,
+    kVcpuIdxFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmIrqLineFtraceEvent"; }
+
+
+  using FieldMetadata_IrqNum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      KvmIrqLineFtraceEvent>;
+
+  static constexpr FieldMetadata_IrqNum kIrqNum{};
+  void set_irq_num(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IrqNum::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_Level =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      KvmIrqLineFtraceEvent>;
+
+  static constexpr FieldMetadata_Level kLevel{};
+  void set_level(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Level::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_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmIrqLineFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::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_VcpuIdx =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      KvmIrqLineFtraceEvent>;
+
+  static constexpr FieldMetadata_VcpuIdx kVcpuIdx{};
+  void set_vcpu_idx(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VcpuIdx::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);
+  }
+};
+
+class KvmHvcArm64FtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmHvcArm64FtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmHvcArm64FtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmHvcArm64FtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_imm() const { return at<1>().valid(); }
+  uint64_t imm() const { return at<1>().as_uint64(); }
+  bool has_r0() const { return at<2>().valid(); }
+  uint64_t r0() const { return at<2>().as_uint64(); }
+  bool has_vcpu_pc() const { return at<3>().valid(); }
+  uint64_t vcpu_pc() const { return at<3>().as_uint64(); }
+};
+
+class KvmHvcArm64FtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmHvcArm64FtraceEvent_Decoder;
+  enum : int32_t {
+    kImmFieldNumber = 1,
+    kR0FieldNumber = 2,
+    kVcpuPcFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmHvcArm64FtraceEvent"; }
+
+
+  using FieldMetadata_Imm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmHvcArm64FtraceEvent>;
+
+  static constexpr FieldMetadata_Imm kImm{};
+  void set_imm(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Imm::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_R0 =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmHvcArm64FtraceEvent>;
+
+  static constexpr FieldMetadata_R0 kR0{};
+  void set_r0(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_R0::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_VcpuPc =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmHvcArm64FtraceEvent>;
+
+  static constexpr FieldMetadata_VcpuPc kVcpuPc{};
+  void set_vcpu_pc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VcpuPc::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 KvmHandleSysRegFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmHandleSysRegFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmHandleSysRegFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmHandleSysRegFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_hsr() const { return at<1>().valid(); }
+  uint64_t hsr() const { return at<1>().as_uint64(); }
+};
+
+class KvmHandleSysRegFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmHandleSysRegFtraceEvent_Decoder;
+  enum : int32_t {
+    kHsrFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmHandleSysRegFtraceEvent"; }
+
+
+  using FieldMetadata_Hsr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmHandleSysRegFtraceEvent>;
+
+  static constexpr FieldMetadata_Hsr kHsr{};
+  void set_hsr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Hsr::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 KvmGuestFaultFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmGuestFaultFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmGuestFaultFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmGuestFaultFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_hsr() const { return at<1>().valid(); }
+  uint64_t hsr() const { return at<1>().as_uint64(); }
+  bool has_hxfar() const { return at<2>().valid(); }
+  uint64_t hxfar() const { return at<2>().as_uint64(); }
+  bool has_ipa() const { return at<3>().valid(); }
+  uint64_t ipa() const { return at<3>().as_uint64(); }
+  bool has_vcpu_pc() const { return at<4>().valid(); }
+  uint64_t vcpu_pc() const { return at<4>().as_uint64(); }
+};
+
+class KvmGuestFaultFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmGuestFaultFtraceEvent_Decoder;
+  enum : int32_t {
+    kHsrFieldNumber = 1,
+    kHxfarFieldNumber = 2,
+    kIpaFieldNumber = 3,
+    kVcpuPcFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmGuestFaultFtraceEvent"; }
+
+
+  using FieldMetadata_Hsr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmGuestFaultFtraceEvent>;
+
+  static constexpr FieldMetadata_Hsr kHsr{};
+  void set_hsr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Hsr::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_Hxfar =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmGuestFaultFtraceEvent>;
+
+  static constexpr FieldMetadata_Hxfar kHxfar{};
+  void set_hxfar(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Hxfar::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_Ipa =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmGuestFaultFtraceEvent>;
+
+  static constexpr FieldMetadata_Ipa kIpa{};
+  void set_ipa(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ipa::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_VcpuPc =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmGuestFaultFtraceEvent>;
+
+  static constexpr FieldMetadata_VcpuPc kVcpuPc{};
+  void set_vcpu_pc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VcpuPc::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 KvmGetTimerMapFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmGetTimerMapFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmGetTimerMapFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmGetTimerMapFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_direct_ptimer() const { return at<1>().valid(); }
+  int32_t direct_ptimer() const { return at<1>().as_int32(); }
+  bool has_direct_vtimer() const { return at<2>().valid(); }
+  int32_t direct_vtimer() const { return at<2>().as_int32(); }
+  bool has_emul_ptimer() const { return at<3>().valid(); }
+  int32_t emul_ptimer() const { return at<3>().as_int32(); }
+  bool has_vcpu_id() const { return at<4>().valid(); }
+  uint64_t vcpu_id() const { return at<4>().as_uint64(); }
+};
+
+class KvmGetTimerMapFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmGetTimerMapFtraceEvent_Decoder;
+  enum : int32_t {
+    kDirectPtimerFieldNumber = 1,
+    kDirectVtimerFieldNumber = 2,
+    kEmulPtimerFieldNumber = 3,
+    kVcpuIdFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmGetTimerMapFtraceEvent"; }
+
+
+  using FieldMetadata_DirectPtimer =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      KvmGetTimerMapFtraceEvent>;
+
+  static constexpr FieldMetadata_DirectPtimer kDirectPtimer{};
+  void set_direct_ptimer(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DirectPtimer::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_DirectVtimer =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      KvmGetTimerMapFtraceEvent>;
+
+  static constexpr FieldMetadata_DirectVtimer kDirectVtimer{};
+  void set_direct_vtimer(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DirectVtimer::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_EmulPtimer =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      KvmGetTimerMapFtraceEvent>;
+
+  static constexpr FieldMetadata_EmulPtimer kEmulPtimer{};
+  void set_emul_ptimer(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EmulPtimer::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_VcpuId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmGetTimerMapFtraceEvent>;
+
+  static constexpr FieldMetadata_VcpuId kVcpuId{};
+  void set_vcpu_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VcpuId::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 KvmFpuFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmFpuFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmFpuFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmFpuFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_load() const { return at<1>().valid(); }
+  uint32_t load() const { return at<1>().as_uint32(); }
+};
+
+class KvmFpuFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmFpuFtraceEvent_Decoder;
+  enum : int32_t {
+    kLoadFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmFpuFtraceEvent"; }
+
+
+  using FieldMetadata_Load =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmFpuFtraceEvent>;
+
+  static constexpr FieldMetadata_Load kLoad{};
+  void set_load(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Load::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 KvmExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_esr_ec() const { return at<1>().valid(); }
+  uint32_t esr_ec() const { return at<1>().as_uint32(); }
+  bool has_ret() const { return at<2>().valid(); }
+  int32_t ret() const { return at<2>().as_int32(); }
+  bool has_vcpu_pc() const { return at<3>().valid(); }
+  uint64_t vcpu_pc() const { return at<3>().as_uint64(); }
+};
+
+class KvmExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kEsrEcFieldNumber = 1,
+    kRetFieldNumber = 2,
+    kVcpuPcFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmExitFtraceEvent"; }
+
+
+  using FieldMetadata_EsrEc =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmExitFtraceEvent>;
+
+  static constexpr FieldMetadata_EsrEc kEsrEc{};
+  void set_esr_ec(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EsrEc::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_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      KvmExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::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_VcpuPc =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmExitFtraceEvent>;
+
+  static constexpr FieldMetadata_VcpuPc kVcpuPc{};
+  void set_vcpu_pc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VcpuPc::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 KvmEntryFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmEntryFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmEntryFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmEntryFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_vcpu_pc() const { return at<1>().valid(); }
+  uint64_t vcpu_pc() const { return at<1>().as_uint64(); }
+};
+
+class KvmEntryFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmEntryFtraceEvent_Decoder;
+  enum : int32_t {
+    kVcpuPcFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmEntryFtraceEvent"; }
+
+
+  using FieldMetadata_VcpuPc =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_VcpuPc kVcpuPc{};
+  void set_vcpu_pc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VcpuPc::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 KvmArmSetupDebugFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmArmSetupDebugFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmArmSetupDebugFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmArmSetupDebugFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_guest_debug() const { return at<1>().valid(); }
+  uint32_t guest_debug() const { return at<1>().as_uint32(); }
+  bool has_vcpu() const { return at<2>().valid(); }
+  uint64_t vcpu() const { return at<2>().as_uint64(); }
+};
+
+class KvmArmSetupDebugFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmArmSetupDebugFtraceEvent_Decoder;
+  enum : int32_t {
+    kGuestDebugFieldNumber = 1,
+    kVcpuFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmArmSetupDebugFtraceEvent"; }
+
+
+  using FieldMetadata_GuestDebug =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmArmSetupDebugFtraceEvent>;
+
+  static constexpr FieldMetadata_GuestDebug kGuestDebug{};
+  void set_guest_debug(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GuestDebug::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_Vcpu =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmArmSetupDebugFtraceEvent>;
+
+  static constexpr FieldMetadata_Vcpu kVcpu{};
+  void set_vcpu(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Vcpu::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 KvmArmSetRegsetFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmArmSetRegsetFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmArmSetRegsetFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmArmSetRegsetFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_len() const { return at<1>().valid(); }
+  int32_t len() const { return at<1>().as_int32(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+};
+
+class KvmArmSetRegsetFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmArmSetRegsetFtraceEvent_Decoder;
+  enum : int32_t {
+    kLenFieldNumber = 1,
+    kNameFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmArmSetRegsetFtraceEvent"; }
+
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      KvmArmSetRegsetFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      KvmArmSetRegsetFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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);
+  }
+};
+
+class KvmArmSetDreg32FtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmArmSetDreg32FtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmArmSetDreg32FtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmArmSetDreg32FtraceEvent_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_value() const { return at<2>().valid(); }
+  uint32_t value() const { return at<2>().as_uint32(); }
+};
+
+class KvmArmSetDreg32FtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmArmSetDreg32FtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kValueFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmArmSetDreg32FtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      KvmArmSetDreg32FtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmArmSetDreg32FtraceEvent>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::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 KvmArmClearDebugFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmArmClearDebugFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmArmClearDebugFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmArmClearDebugFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_guest_debug() const { return at<1>().valid(); }
+  uint32_t guest_debug() const { return at<1>().as_uint32(); }
+};
+
+class KvmArmClearDebugFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmArmClearDebugFtraceEvent_Decoder;
+  enum : int32_t {
+    kGuestDebugFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmArmClearDebugFtraceEvent"; }
+
+
+  using FieldMetadata_GuestDebug =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmArmClearDebugFtraceEvent>;
+
+  static constexpr FieldMetadata_GuestDebug kGuestDebug{};
+  void set_guest_debug(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GuestDebug::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 KvmAgePageFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmAgePageFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmAgePageFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmAgePageFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_gfn() const { return at<1>().valid(); }
+  uint64_t gfn() const { return at<1>().as_uint64(); }
+  bool has_hva() const { return at<2>().valid(); }
+  uint64_t hva() const { return at<2>().as_uint64(); }
+  bool has_level() const { return at<3>().valid(); }
+  uint32_t level() const { return at<3>().as_uint32(); }
+  bool has_referenced() const { return at<4>().valid(); }
+  uint32_t referenced() const { return at<4>().as_uint32(); }
+};
+
+class KvmAgePageFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmAgePageFtraceEvent_Decoder;
+  enum : int32_t {
+    kGfnFieldNumber = 1,
+    kHvaFieldNumber = 2,
+    kLevelFieldNumber = 3,
+    kReferencedFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmAgePageFtraceEvent"; }
+
+
+  using FieldMetadata_Gfn =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmAgePageFtraceEvent>;
+
+  static constexpr FieldMetadata_Gfn kGfn{};
+  void set_gfn(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Gfn::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_Hva =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmAgePageFtraceEvent>;
+
+  static constexpr FieldMetadata_Hva kHva{};
+  void set_hva(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Hva::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_Level =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmAgePageFtraceEvent>;
+
+  static constexpr FieldMetadata_Level kLevel{};
+  void set_level(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Level::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_Referenced =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmAgePageFtraceEvent>;
+
+  static constexpr FieldMetadata_Referenced kReferenced{};
+  void set_referenced(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Referenced::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 KvmAgeHvaFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmAgeHvaFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmAgeHvaFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmAgeHvaFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_end() const { return at<1>().valid(); }
+  uint64_t end() const { return at<1>().as_uint64(); }
+  bool has_start() const { return at<2>().valid(); }
+  uint64_t start() const { return at<2>().as_uint64(); }
+};
+
+class KvmAgeHvaFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmAgeHvaFtraceEvent_Decoder;
+  enum : int32_t {
+    kEndFieldNumber = 1,
+    kStartFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmAgeHvaFtraceEvent"; }
+
+
+  using FieldMetadata_End =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmAgeHvaFtraceEvent>;
+
+  static constexpr FieldMetadata_End kEnd{};
+  void set_end(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_End::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_Start =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmAgeHvaFtraceEvent>;
+
+  static constexpr FieldMetadata_Start kStart{};
+  void set_start(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Start::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 KvmAckIrqFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmAckIrqFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmAckIrqFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmAckIrqFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_irqchip() const { return at<1>().valid(); }
+  uint32_t irqchip() const { return at<1>().as_uint32(); }
+  bool has_pin() const { return at<2>().valid(); }
+  uint32_t pin() const { return at<2>().as_uint32(); }
+};
+
+class KvmAckIrqFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmAckIrqFtraceEvent_Decoder;
+  enum : int32_t {
+    kIrqchipFieldNumber = 1,
+    kPinFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmAckIrqFtraceEvent"; }
+
+
+  using FieldMetadata_Irqchip =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmAckIrqFtraceEvent>;
+
+  static constexpr FieldMetadata_Irqchip kIrqchip{};
+  void set_irqchip(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Irqchip::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_Pin =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmAckIrqFtraceEvent>;
+
+  static constexpr FieldMetadata_Pin kPin{};
+  void set_pin(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pin::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 KvmAccessFaultFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmAccessFaultFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmAccessFaultFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmAccessFaultFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ipa() const { return at<1>().valid(); }
+  uint64_t ipa() const { return at<1>().as_uint64(); }
+};
+
+class KvmAccessFaultFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmAccessFaultFtraceEvent_Decoder;
+  enum : int32_t {
+    kIpaFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmAccessFaultFtraceEvent"; }
+
+
+  using FieldMetadata_Ipa =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmAccessFaultFtraceEvent>;
+
+  static constexpr FieldMetadata_Ipa kIpa{};
+  void set_ipa(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ipa::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/lowmemorykiller.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_LOWMEMORYKILLER_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_LOWMEMORYKILLER_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class LowmemoryKillFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  LowmemoryKillFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit LowmemoryKillFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit LowmemoryKillFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_comm() const { return at<1>().valid(); }
+  ::protozero::ConstChars comm() const { return at<1>().as_string(); }
+  bool has_pid() const { return at<2>().valid(); }
+  int32_t pid() const { return at<2>().as_int32(); }
+  bool has_pagecache_size() const { return at<3>().valid(); }
+  int64_t pagecache_size() const { return at<3>().as_int64(); }
+  bool has_pagecache_limit() const { return at<4>().valid(); }
+  int64_t pagecache_limit() const { return at<4>().as_int64(); }
+  bool has_free() const { return at<5>().valid(); }
+  int64_t free() const { return at<5>().as_int64(); }
+};
+
+class LowmemoryKillFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = LowmemoryKillFtraceEvent_Decoder;
+  enum : int32_t {
+    kCommFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kPagecacheSizeFieldNumber = 3,
+    kPagecacheLimitFieldNumber = 4,
+    kFreeFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.LowmemoryKillFtraceEvent"; }
+
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      LowmemoryKillFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LowmemoryKillFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_PagecacheSize =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      LowmemoryKillFtraceEvent>;
+
+  static constexpr FieldMetadata_PagecacheSize kPagecacheSize{};
+  void set_pagecache_size(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PagecacheSize::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_PagecacheLimit =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      LowmemoryKillFtraceEvent>;
+
+  static constexpr FieldMetadata_PagecacheLimit kPagecacheLimit{};
+  void set_pagecache_limit(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PagecacheLimit::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_Free =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      LowmemoryKillFtraceEvent>;
+
+  static constexpr FieldMetadata_Free kFree{};
+  void set_free(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Free::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/lwis.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_LWIS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_LWIS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class LwisTracingMarkWriteFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  LwisTracingMarkWriteFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit LwisTracingMarkWriteFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit LwisTracingMarkWriteFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_lwis_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars lwis_name() const { return at<1>().as_string(); }
+  bool has_type() const { return at<2>().valid(); }
+  uint32_t type() const { return at<2>().as_uint32(); }
+  bool has_pid() const { return at<3>().valid(); }
+  int32_t pid() const { return at<3>().as_int32(); }
+  bool has_func_name() const { return at<4>().valid(); }
+  ::protozero::ConstChars func_name() const { return at<4>().as_string(); }
+  bool has_value() const { return at<5>().valid(); }
+  int64_t value() const { return at<5>().as_int64(); }
+};
+
+class LwisTracingMarkWriteFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = LwisTracingMarkWriteFtraceEvent_Decoder;
+  enum : int32_t {
+    kLwisNameFieldNumber = 1,
+    kTypeFieldNumber = 2,
+    kPidFieldNumber = 3,
+    kFuncNameFieldNumber = 4,
+    kValueFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.LwisTracingMarkWriteFtraceEvent"; }
+
+
+  using FieldMetadata_LwisName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      LwisTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_LwisName kLwisName{};
+  void set_lwis_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_LwisName::kFieldId, data, size);
+  }
+  void set_lwis_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_LwisName::kFieldId, chars.data, chars.size);
+  }
+  void set_lwis_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_LwisName::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_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LwisTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LwisTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_FuncName =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      LwisTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_FuncName kFuncName{};
+  void set_func_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_FuncName::kFieldId, data, size);
+  }
+  void set_func_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_FuncName::kFieldId, chars.data, chars.size);
+  }
+  void set_func_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_FuncName::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_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      LwisTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/mali.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_MALI_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_MALI_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class MaliMaliCSFINTERRUPTENDFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MaliMaliCSFINTERRUPTENDFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MaliMaliCSFINTERRUPTENDFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MaliMaliCSFINTERRUPTENDFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_kctx_tgid() const { return at<1>().valid(); }
+  int32_t kctx_tgid() const { return at<1>().as_int32(); }
+  bool has_kctx_id() const { return at<2>().valid(); }
+  uint32_t kctx_id() const { return at<2>().as_uint32(); }
+  bool has_info_val() const { return at<3>().valid(); }
+  uint64_t info_val() const { return at<3>().as_uint64(); }
+};
+
+class MaliMaliCSFINTERRUPTENDFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MaliMaliCSFINTERRUPTENDFtraceEvent_Decoder;
+  enum : int32_t {
+    kKctxTgidFieldNumber = 1,
+    kKctxIdFieldNumber = 2,
+    kInfoValFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MaliMaliCSFINTERRUPTENDFtraceEvent"; }
+
+
+  using FieldMetadata_KctxTgid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MaliMaliCSFINTERRUPTENDFtraceEvent>;
+
+  static constexpr FieldMetadata_KctxTgid kKctxTgid{};
+  void set_kctx_tgid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KctxTgid::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_KctxId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MaliMaliCSFINTERRUPTENDFtraceEvent>;
+
+  static constexpr FieldMetadata_KctxId kKctxId{};
+  void set_kctx_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KctxId::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_InfoVal =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MaliMaliCSFINTERRUPTENDFtraceEvent>;
+
+  static constexpr FieldMetadata_InfoVal kInfoVal{};
+  void set_info_val(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InfoVal::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 MaliMaliCSFINTERRUPTSTARTFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MaliMaliCSFINTERRUPTSTARTFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MaliMaliCSFINTERRUPTSTARTFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MaliMaliCSFINTERRUPTSTARTFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_kctx_tgid() const { return at<1>().valid(); }
+  int32_t kctx_tgid() const { return at<1>().as_int32(); }
+  bool has_kctx_id() const { return at<2>().valid(); }
+  uint32_t kctx_id() const { return at<2>().as_uint32(); }
+  bool has_info_val() const { return at<3>().valid(); }
+  uint64_t info_val() const { return at<3>().as_uint64(); }
+};
+
+class MaliMaliCSFINTERRUPTSTARTFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MaliMaliCSFINTERRUPTSTARTFtraceEvent_Decoder;
+  enum : int32_t {
+    kKctxTgidFieldNumber = 1,
+    kKctxIdFieldNumber = 2,
+    kInfoValFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MaliMaliCSFINTERRUPTSTARTFtraceEvent"; }
+
+
+  using FieldMetadata_KctxTgid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MaliMaliCSFINTERRUPTSTARTFtraceEvent>;
+
+  static constexpr FieldMetadata_KctxTgid kKctxTgid{};
+  void set_kctx_tgid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KctxTgid::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_KctxId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MaliMaliCSFINTERRUPTSTARTFtraceEvent>;
+
+  static constexpr FieldMetadata_KctxId kKctxId{};
+  void set_kctx_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KctxId::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_InfoVal =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MaliMaliCSFINTERRUPTSTARTFtraceEvent>;
+
+  static constexpr FieldMetadata_InfoVal kInfoVal{};
+  void set_info_val(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InfoVal::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 MaliMaliKCPUFENCEWAITENDFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MaliMaliKCPUFENCEWAITENDFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MaliMaliKCPUFENCEWAITENDFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MaliMaliKCPUFENCEWAITENDFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_info_val1() const { return at<1>().valid(); }
+  uint64_t info_val1() const { return at<1>().as_uint64(); }
+  bool has_info_val2() const { return at<2>().valid(); }
+  uint64_t info_val2() const { return at<2>().as_uint64(); }
+  bool has_kctx_tgid() const { return at<3>().valid(); }
+  int32_t kctx_tgid() const { return at<3>().as_int32(); }
+  bool has_kctx_id() const { return at<4>().valid(); }
+  uint32_t kctx_id() const { return at<4>().as_uint32(); }
+  bool has_id() const { return at<5>().valid(); }
+  uint32_t id() const { return at<5>().as_uint32(); }
+};
+
+class MaliMaliKCPUFENCEWAITENDFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MaliMaliKCPUFENCEWAITENDFtraceEvent_Decoder;
+  enum : int32_t {
+    kInfoVal1FieldNumber = 1,
+    kInfoVal2FieldNumber = 2,
+    kKctxTgidFieldNumber = 3,
+    kKctxIdFieldNumber = 4,
+    kIdFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MaliMaliKCPUFENCEWAITENDFtraceEvent"; }
+
+
+  using FieldMetadata_InfoVal1 =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MaliMaliKCPUFENCEWAITENDFtraceEvent>;
+
+  static constexpr FieldMetadata_InfoVal1 kInfoVal1{};
+  void set_info_val1(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InfoVal1::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_InfoVal2 =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MaliMaliKCPUFENCEWAITENDFtraceEvent>;
+
+  static constexpr FieldMetadata_InfoVal2 kInfoVal2{};
+  void set_info_val2(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InfoVal2::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_KctxTgid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MaliMaliKCPUFENCEWAITENDFtraceEvent>;
+
+  static constexpr FieldMetadata_KctxTgid kKctxTgid{};
+  void set_kctx_tgid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KctxTgid::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_KctxId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MaliMaliKCPUFENCEWAITENDFtraceEvent>;
+
+  static constexpr FieldMetadata_KctxId kKctxId{};
+  void set_kctx_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KctxId::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_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MaliMaliKCPUFENCEWAITENDFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::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 MaliMaliKCPUFENCEWAITSTARTFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MaliMaliKCPUFENCEWAITSTARTFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MaliMaliKCPUFENCEWAITSTARTFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MaliMaliKCPUFENCEWAITSTARTFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_info_val1() const { return at<1>().valid(); }
+  uint64_t info_val1() const { return at<1>().as_uint64(); }
+  bool has_info_val2() const { return at<2>().valid(); }
+  uint64_t info_val2() const { return at<2>().as_uint64(); }
+  bool has_kctx_tgid() const { return at<3>().valid(); }
+  int32_t kctx_tgid() const { return at<3>().as_int32(); }
+  bool has_kctx_id() const { return at<4>().valid(); }
+  uint32_t kctx_id() const { return at<4>().as_uint32(); }
+  bool has_id() const { return at<5>().valid(); }
+  uint32_t id() const { return at<5>().as_uint32(); }
+};
+
+class MaliMaliKCPUFENCEWAITSTARTFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MaliMaliKCPUFENCEWAITSTARTFtraceEvent_Decoder;
+  enum : int32_t {
+    kInfoVal1FieldNumber = 1,
+    kInfoVal2FieldNumber = 2,
+    kKctxTgidFieldNumber = 3,
+    kKctxIdFieldNumber = 4,
+    kIdFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MaliMaliKCPUFENCEWAITSTARTFtraceEvent"; }
+
+
+  using FieldMetadata_InfoVal1 =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MaliMaliKCPUFENCEWAITSTARTFtraceEvent>;
+
+  static constexpr FieldMetadata_InfoVal1 kInfoVal1{};
+  void set_info_val1(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InfoVal1::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_InfoVal2 =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MaliMaliKCPUFENCEWAITSTARTFtraceEvent>;
+
+  static constexpr FieldMetadata_InfoVal2 kInfoVal2{};
+  void set_info_val2(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InfoVal2::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_KctxTgid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MaliMaliKCPUFENCEWAITSTARTFtraceEvent>;
+
+  static constexpr FieldMetadata_KctxTgid kKctxTgid{};
+  void set_kctx_tgid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KctxTgid::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_KctxId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MaliMaliKCPUFENCEWAITSTARTFtraceEvent>;
+
+  static constexpr FieldMetadata_KctxId kKctxId{};
+  void set_kctx_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KctxId::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_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MaliMaliKCPUFENCEWAITSTARTFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::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 MaliMaliKCPUFENCESIGNALFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MaliMaliKCPUFENCESIGNALFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MaliMaliKCPUFENCESIGNALFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MaliMaliKCPUFENCESIGNALFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_info_val1() const { return at<1>().valid(); }
+  uint64_t info_val1() const { return at<1>().as_uint64(); }
+  bool has_info_val2() const { return at<2>().valid(); }
+  uint64_t info_val2() const { return at<2>().as_uint64(); }
+  bool has_kctx_tgid() const { return at<3>().valid(); }
+  int32_t kctx_tgid() const { return at<3>().as_int32(); }
+  bool has_kctx_id() const { return at<4>().valid(); }
+  uint32_t kctx_id() const { return at<4>().as_uint32(); }
+  bool has_id() const { return at<5>().valid(); }
+  uint32_t id() const { return at<5>().as_uint32(); }
+};
+
+class MaliMaliKCPUFENCESIGNALFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MaliMaliKCPUFENCESIGNALFtraceEvent_Decoder;
+  enum : int32_t {
+    kInfoVal1FieldNumber = 1,
+    kInfoVal2FieldNumber = 2,
+    kKctxTgidFieldNumber = 3,
+    kKctxIdFieldNumber = 4,
+    kIdFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MaliMaliKCPUFENCESIGNALFtraceEvent"; }
+
+
+  using FieldMetadata_InfoVal1 =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MaliMaliKCPUFENCESIGNALFtraceEvent>;
+
+  static constexpr FieldMetadata_InfoVal1 kInfoVal1{};
+  void set_info_val1(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InfoVal1::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_InfoVal2 =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MaliMaliKCPUFENCESIGNALFtraceEvent>;
+
+  static constexpr FieldMetadata_InfoVal2 kInfoVal2{};
+  void set_info_val2(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InfoVal2::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_KctxTgid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MaliMaliKCPUFENCESIGNALFtraceEvent>;
+
+  static constexpr FieldMetadata_KctxTgid kKctxTgid{};
+  void set_kctx_tgid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KctxTgid::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_KctxId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MaliMaliKCPUFENCESIGNALFtraceEvent>;
+
+  static constexpr FieldMetadata_KctxId kKctxId{};
+  void set_kctx_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KctxId::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_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MaliMaliKCPUFENCESIGNALFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::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 MaliMaliKCPUCQSWAITENDFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MaliMaliKCPUCQSWAITENDFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MaliMaliKCPUCQSWAITENDFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MaliMaliKCPUCQSWAITENDFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  uint32_t id() const { return at<1>().as_uint32(); }
+  bool has_info_val1() const { return at<2>().valid(); }
+  uint64_t info_val1() const { return at<2>().as_uint64(); }
+  bool has_info_val2() const { return at<3>().valid(); }
+  uint64_t info_val2() const { return at<3>().as_uint64(); }
+  bool has_kctx_id() const { return at<4>().valid(); }
+  uint32_t kctx_id() const { return at<4>().as_uint32(); }
+  bool has_kctx_tgid() const { return at<5>().valid(); }
+  int32_t kctx_tgid() const { return at<5>().as_int32(); }
+};
+
+class MaliMaliKCPUCQSWAITENDFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MaliMaliKCPUCQSWAITENDFtraceEvent_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kInfoVal1FieldNumber = 2,
+    kInfoVal2FieldNumber = 3,
+    kKctxIdFieldNumber = 4,
+    kKctxTgidFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MaliMaliKCPUCQSWAITENDFtraceEvent"; }
+
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MaliMaliKCPUCQSWAITENDFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::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_InfoVal1 =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MaliMaliKCPUCQSWAITENDFtraceEvent>;
+
+  static constexpr FieldMetadata_InfoVal1 kInfoVal1{};
+  void set_info_val1(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InfoVal1::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_InfoVal2 =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MaliMaliKCPUCQSWAITENDFtraceEvent>;
+
+  static constexpr FieldMetadata_InfoVal2 kInfoVal2{};
+  void set_info_val2(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InfoVal2::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_KctxId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MaliMaliKCPUCQSWAITENDFtraceEvent>;
+
+  static constexpr FieldMetadata_KctxId kKctxId{};
+  void set_kctx_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KctxId::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_KctxTgid =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MaliMaliKCPUCQSWAITENDFtraceEvent>;
+
+  static constexpr FieldMetadata_KctxTgid kKctxTgid{};
+  void set_kctx_tgid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KctxTgid::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);
+  }
+};
+
+class MaliMaliKCPUCQSWAITSTARTFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MaliMaliKCPUCQSWAITSTARTFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MaliMaliKCPUCQSWAITSTARTFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MaliMaliKCPUCQSWAITSTARTFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  uint32_t id() const { return at<1>().as_uint32(); }
+  bool has_info_val1() const { return at<2>().valid(); }
+  uint64_t info_val1() const { return at<2>().as_uint64(); }
+  bool has_info_val2() const { return at<3>().valid(); }
+  uint64_t info_val2() const { return at<3>().as_uint64(); }
+  bool has_kctx_id() const { return at<4>().valid(); }
+  uint32_t kctx_id() const { return at<4>().as_uint32(); }
+  bool has_kctx_tgid() const { return at<5>().valid(); }
+  int32_t kctx_tgid() const { return at<5>().as_int32(); }
+};
+
+class MaliMaliKCPUCQSWAITSTARTFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MaliMaliKCPUCQSWAITSTARTFtraceEvent_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kInfoVal1FieldNumber = 2,
+    kInfoVal2FieldNumber = 3,
+    kKctxIdFieldNumber = 4,
+    kKctxTgidFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MaliMaliKCPUCQSWAITSTARTFtraceEvent"; }
+
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MaliMaliKCPUCQSWAITSTARTFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::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_InfoVal1 =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MaliMaliKCPUCQSWAITSTARTFtraceEvent>;
+
+  static constexpr FieldMetadata_InfoVal1 kInfoVal1{};
+  void set_info_val1(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InfoVal1::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_InfoVal2 =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MaliMaliKCPUCQSWAITSTARTFtraceEvent>;
+
+  static constexpr FieldMetadata_InfoVal2 kInfoVal2{};
+  void set_info_val2(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InfoVal2::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_KctxId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MaliMaliKCPUCQSWAITSTARTFtraceEvent>;
+
+  static constexpr FieldMetadata_KctxId kKctxId{};
+  void set_kctx_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KctxId::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_KctxTgid =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MaliMaliKCPUCQSWAITSTARTFtraceEvent>;
+
+  static constexpr FieldMetadata_KctxTgid kKctxTgid{};
+  void set_kctx_tgid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KctxTgid::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);
+  }
+};
+
+class MaliMaliKCPUCQSSETFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MaliMaliKCPUCQSSETFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MaliMaliKCPUCQSSETFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MaliMaliKCPUCQSSETFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  uint32_t id() const { return at<1>().as_uint32(); }
+  bool has_info_val1() const { return at<2>().valid(); }
+  uint64_t info_val1() const { return at<2>().as_uint64(); }
+  bool has_info_val2() const { return at<3>().valid(); }
+  uint64_t info_val2() const { return at<3>().as_uint64(); }
+  bool has_kctx_id() const { return at<4>().valid(); }
+  uint32_t kctx_id() const { return at<4>().as_uint32(); }
+  bool has_kctx_tgid() const { return at<5>().valid(); }
+  int32_t kctx_tgid() const { return at<5>().as_int32(); }
+};
+
+class MaliMaliKCPUCQSSETFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MaliMaliKCPUCQSSETFtraceEvent_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kInfoVal1FieldNumber = 2,
+    kInfoVal2FieldNumber = 3,
+    kKctxIdFieldNumber = 4,
+    kKctxTgidFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MaliMaliKCPUCQSSETFtraceEvent"; }
+
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MaliMaliKCPUCQSSETFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::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_InfoVal1 =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MaliMaliKCPUCQSSETFtraceEvent>;
+
+  static constexpr FieldMetadata_InfoVal1 kInfoVal1{};
+  void set_info_val1(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InfoVal1::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_InfoVal2 =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MaliMaliKCPUCQSSETFtraceEvent>;
+
+  static constexpr FieldMetadata_InfoVal2 kInfoVal2{};
+  void set_info_val2(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InfoVal2::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_KctxId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MaliMaliKCPUCQSSETFtraceEvent>;
+
+  static constexpr FieldMetadata_KctxId kKctxId{};
+  void set_kctx_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KctxId::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_KctxTgid =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MaliMaliKCPUCQSSETFtraceEvent>;
+
+  static constexpr FieldMetadata_KctxTgid kKctxTgid{};
+  void set_kctx_tgid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KctxTgid::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);
+  }
+};
+
+class MaliTracingMarkWriteFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MaliTracingMarkWriteFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MaliTracingMarkWriteFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MaliTracingMarkWriteFtraceEvent_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_pid() const { return at<2>().valid(); }
+  int32_t pid() const { return at<2>().as_int32(); }
+  bool has_type() const { return at<3>().valid(); }
+  uint32_t type() const { return at<3>().as_uint32(); }
+  bool has_value() const { return at<4>().valid(); }
+  int32_t value() const { return at<4>().as_int32(); }
+};
+
+class MaliTracingMarkWriteFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MaliTracingMarkWriteFtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kTypeFieldNumber = 3,
+    kValueFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MaliTracingMarkWriteFtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      MaliTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MaliTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MaliTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::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_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MaliTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/mdss.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_MDSS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_MDSS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class RotatorBwAoAsContextFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  RotatorBwAoAsContextFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit RotatorBwAoAsContextFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit RotatorBwAoAsContextFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_state() const { return at<1>().valid(); }
+  uint32_t state() const { return at<1>().as_uint32(); }
+};
+
+class RotatorBwAoAsContextFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = RotatorBwAoAsContextFtraceEvent_Decoder;
+  enum : int32_t {
+    kStateFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.RotatorBwAoAsContextFtraceEvent"; }
+
+
+  using FieldMetadata_State =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      RotatorBwAoAsContextFtraceEvent>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::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 MdpPerfUpdateBusFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpPerfUpdateBusFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpPerfUpdateBusFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpPerfUpdateBusFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_client() const { return at<1>().valid(); }
+  int32_t client() const { return at<1>().as_int32(); }
+  bool has_ab_quota() const { return at<2>().valid(); }
+  uint64_t ab_quota() const { return at<2>().as_uint64(); }
+  bool has_ib_quota() const { return at<3>().valid(); }
+  uint64_t ib_quota() const { return at<3>().as_uint64(); }
+};
+
+class MdpPerfUpdateBusFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpPerfUpdateBusFtraceEvent_Decoder;
+  enum : int32_t {
+    kClientFieldNumber = 1,
+    kAbQuotaFieldNumber = 2,
+    kIbQuotaFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpPerfUpdateBusFtraceEvent"; }
+
+
+  using FieldMetadata_Client =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MdpPerfUpdateBusFtraceEvent>;
+
+  static constexpr FieldMetadata_Client kClient{};
+  void set_client(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Client::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_AbQuota =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MdpPerfUpdateBusFtraceEvent>;
+
+  static constexpr FieldMetadata_AbQuota kAbQuota{};
+  void set_ab_quota(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AbQuota::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_IbQuota =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MdpPerfUpdateBusFtraceEvent>;
+
+  static constexpr FieldMetadata_IbQuota kIbQuota{};
+  void set_ib_quota(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IbQuota::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 MdpPerfPrefillCalcFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/10, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpPerfPrefillCalcFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpPerfPrefillCalcFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpPerfPrefillCalcFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pnum() const { return at<1>().valid(); }
+  uint32_t pnum() const { return at<1>().as_uint32(); }
+  bool has_latency_buf() const { return at<2>().valid(); }
+  uint32_t latency_buf() const { return at<2>().as_uint32(); }
+  bool has_ot() const { return at<3>().valid(); }
+  uint32_t ot() const { return at<3>().as_uint32(); }
+  bool has_y_buf() const { return at<4>().valid(); }
+  uint32_t y_buf() const { return at<4>().as_uint32(); }
+  bool has_y_scaler() const { return at<5>().valid(); }
+  uint32_t y_scaler() const { return at<5>().as_uint32(); }
+  bool has_pp_lines() const { return at<6>().valid(); }
+  uint32_t pp_lines() const { return at<6>().as_uint32(); }
+  bool has_pp_bytes() const { return at<7>().valid(); }
+  uint32_t pp_bytes() const { return at<7>().as_uint32(); }
+  bool has_post_sc() const { return at<8>().valid(); }
+  uint32_t post_sc() const { return at<8>().as_uint32(); }
+  bool has_fbc_bytes() const { return at<9>().valid(); }
+  uint32_t fbc_bytes() const { return at<9>().as_uint32(); }
+  bool has_prefill_bytes() const { return at<10>().valid(); }
+  uint32_t prefill_bytes() const { return at<10>().as_uint32(); }
+};
+
+class MdpPerfPrefillCalcFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpPerfPrefillCalcFtraceEvent_Decoder;
+  enum : int32_t {
+    kPnumFieldNumber = 1,
+    kLatencyBufFieldNumber = 2,
+    kOtFieldNumber = 3,
+    kYBufFieldNumber = 4,
+    kYScalerFieldNumber = 5,
+    kPpLinesFieldNumber = 6,
+    kPpBytesFieldNumber = 7,
+    kPostScFieldNumber = 8,
+    kFbcBytesFieldNumber = 9,
+    kPrefillBytesFieldNumber = 10,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpPerfPrefillCalcFtraceEvent"; }
+
+
+  using FieldMetadata_Pnum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfPrefillCalcFtraceEvent>;
+
+  static constexpr FieldMetadata_Pnum kPnum{};
+  void set_pnum(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pnum::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_LatencyBuf =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfPrefillCalcFtraceEvent>;
+
+  static constexpr FieldMetadata_LatencyBuf kLatencyBuf{};
+  void set_latency_buf(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LatencyBuf::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_Ot =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfPrefillCalcFtraceEvent>;
+
+  static constexpr FieldMetadata_Ot kOt{};
+  void set_ot(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ot::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_YBuf =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfPrefillCalcFtraceEvent>;
+
+  static constexpr FieldMetadata_YBuf kYBuf{};
+  void set_y_buf(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_YBuf::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_YScaler =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfPrefillCalcFtraceEvent>;
+
+  static constexpr FieldMetadata_YScaler kYScaler{};
+  void set_y_scaler(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_YScaler::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_PpLines =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfPrefillCalcFtraceEvent>;
+
+  static constexpr FieldMetadata_PpLines kPpLines{};
+  void set_pp_lines(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PpLines::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_PpBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfPrefillCalcFtraceEvent>;
+
+  static constexpr FieldMetadata_PpBytes kPpBytes{};
+  void set_pp_bytes(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PpBytes::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_PostSc =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfPrefillCalcFtraceEvent>;
+
+  static constexpr FieldMetadata_PostSc kPostSc{};
+  void set_post_sc(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PostSc::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_FbcBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfPrefillCalcFtraceEvent>;
+
+  static constexpr FieldMetadata_FbcBytes kFbcBytes{};
+  void set_fbc_bytes(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FbcBytes::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_PrefillBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfPrefillCalcFtraceEvent>;
+
+  static constexpr FieldMetadata_PrefillBytes kPrefillBytes{};
+  void set_prefill_bytes(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PrefillBytes::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 MdpCmdWaitPingpongFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpCmdWaitPingpongFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpCmdWaitPingpongFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpCmdWaitPingpongFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ctl_num() const { return at<1>().valid(); }
+  uint32_t ctl_num() const { return at<1>().as_uint32(); }
+  bool has_kickoff_cnt() const { return at<2>().valid(); }
+  int32_t kickoff_cnt() const { return at<2>().as_int32(); }
+};
+
+class MdpCmdWaitPingpongFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpCmdWaitPingpongFtraceEvent_Decoder;
+  enum : int32_t {
+    kCtlNumFieldNumber = 1,
+    kKickoffCntFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpCmdWaitPingpongFtraceEvent"; }
+
+
+  using FieldMetadata_CtlNum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpCmdWaitPingpongFtraceEvent>;
+
+  static constexpr FieldMetadata_CtlNum kCtlNum{};
+  void set_ctl_num(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CtlNum::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_KickoffCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MdpCmdWaitPingpongFtraceEvent>;
+
+  static constexpr FieldMetadata_KickoffCnt kKickoffCnt{};
+  void set_kickoff_cnt(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KickoffCnt::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);
+  }
+};
+
+class MdpVideoUnderrunDoneFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpVideoUnderrunDoneFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpVideoUnderrunDoneFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpVideoUnderrunDoneFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ctl_num() const { return at<1>().valid(); }
+  uint32_t ctl_num() const { return at<1>().as_uint32(); }
+  bool has_underrun_cnt() const { return at<2>().valid(); }
+  uint32_t underrun_cnt() const { return at<2>().as_uint32(); }
+};
+
+class MdpVideoUnderrunDoneFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpVideoUnderrunDoneFtraceEvent_Decoder;
+  enum : int32_t {
+    kCtlNumFieldNumber = 1,
+    kUnderrunCntFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpVideoUnderrunDoneFtraceEvent"; }
+
+
+  using FieldMetadata_CtlNum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpVideoUnderrunDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_CtlNum kCtlNum{};
+  void set_ctl_num(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CtlNum::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_UnderrunCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpVideoUnderrunDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_UnderrunCnt kUnderrunCnt{};
+  void set_underrun_cnt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UnderrunCnt::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 MdpPerfSetWmLevelsFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpPerfSetWmLevelsFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpPerfSetWmLevelsFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpPerfSetWmLevelsFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pnum() const { return at<1>().valid(); }
+  uint32_t pnum() const { return at<1>().as_uint32(); }
+  bool has_use_space() const { return at<2>().valid(); }
+  uint32_t use_space() const { return at<2>().as_uint32(); }
+  bool has_priority_bytes() const { return at<3>().valid(); }
+  uint32_t priority_bytes() const { return at<3>().as_uint32(); }
+  bool has_wm0() const { return at<4>().valid(); }
+  uint32_t wm0() const { return at<4>().as_uint32(); }
+  bool has_wm1() const { return at<5>().valid(); }
+  uint32_t wm1() const { return at<5>().as_uint32(); }
+  bool has_wm2() const { return at<6>().valid(); }
+  uint32_t wm2() const { return at<6>().as_uint32(); }
+  bool has_mb_cnt() const { return at<7>().valid(); }
+  uint32_t mb_cnt() const { return at<7>().as_uint32(); }
+  bool has_mb_size() const { return at<8>().valid(); }
+  uint32_t mb_size() const { return at<8>().as_uint32(); }
+};
+
+class MdpPerfSetWmLevelsFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpPerfSetWmLevelsFtraceEvent_Decoder;
+  enum : int32_t {
+    kPnumFieldNumber = 1,
+    kUseSpaceFieldNumber = 2,
+    kPriorityBytesFieldNumber = 3,
+    kWm0FieldNumber = 4,
+    kWm1FieldNumber = 5,
+    kWm2FieldNumber = 6,
+    kMbCntFieldNumber = 7,
+    kMbSizeFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpPerfSetWmLevelsFtraceEvent"; }
+
+
+  using FieldMetadata_Pnum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetWmLevelsFtraceEvent>;
+
+  static constexpr FieldMetadata_Pnum kPnum{};
+  void set_pnum(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pnum::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_UseSpace =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetWmLevelsFtraceEvent>;
+
+  static constexpr FieldMetadata_UseSpace kUseSpace{};
+  void set_use_space(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UseSpace::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_PriorityBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetWmLevelsFtraceEvent>;
+
+  static constexpr FieldMetadata_PriorityBytes kPriorityBytes{};
+  void set_priority_bytes(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PriorityBytes::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_Wm0 =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetWmLevelsFtraceEvent>;
+
+  static constexpr FieldMetadata_Wm0 kWm0{};
+  void set_wm0(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Wm0::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_Wm1 =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetWmLevelsFtraceEvent>;
+
+  static constexpr FieldMetadata_Wm1 kWm1{};
+  void set_wm1(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Wm1::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_Wm2 =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetWmLevelsFtraceEvent>;
+
+  static constexpr FieldMetadata_Wm2 kWm2{};
+  void set_wm2(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Wm2::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_MbCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetWmLevelsFtraceEvent>;
+
+  static constexpr FieldMetadata_MbCnt kMbCnt{};
+  void set_mb_cnt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MbCnt::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_MbSize =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetWmLevelsFtraceEvent>;
+
+  static constexpr FieldMetadata_MbSize kMbSize{};
+  void set_mb_size(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MbSize::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 MdpMixerUpdateFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpMixerUpdateFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpMixerUpdateFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpMixerUpdateFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_mixer_num() const { return at<1>().valid(); }
+  uint32_t mixer_num() const { return at<1>().as_uint32(); }
+};
+
+class MdpMixerUpdateFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpMixerUpdateFtraceEvent_Decoder;
+  enum : int32_t {
+    kMixerNumFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpMixerUpdateFtraceEvent"; }
+
+
+  using FieldMetadata_MixerNum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpMixerUpdateFtraceEvent>;
+
+  static constexpr FieldMetadata_MixerNum kMixerNum{};
+  void set_mixer_num(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MixerNum::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 MdpCmdReleaseBwFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpCmdReleaseBwFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpCmdReleaseBwFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpCmdReleaseBwFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ctl_num() const { return at<1>().valid(); }
+  uint32_t ctl_num() const { return at<1>().as_uint32(); }
+};
+
+class MdpCmdReleaseBwFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpCmdReleaseBwFtraceEvent_Decoder;
+  enum : int32_t {
+    kCtlNumFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpCmdReleaseBwFtraceEvent"; }
+
+
+  using FieldMetadata_CtlNum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpCmdReleaseBwFtraceEvent>;
+
+  static constexpr FieldMetadata_CtlNum kCtlNum{};
+  void set_ctl_num(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CtlNum::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 MdpTraceCounterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpTraceCounterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpTraceCounterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpTraceCounterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  int32_t pid() const { return at<1>().as_int32(); }
+  bool has_counter_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars counter_name() const { return at<2>().as_string(); }
+  bool has_value() const { return at<3>().valid(); }
+  int32_t value() const { return at<3>().as_int32(); }
+};
+
+class MdpTraceCounterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpTraceCounterFtraceEvent_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kCounterNameFieldNumber = 2,
+    kValueFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpTraceCounterFtraceEvent"; }
+
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MdpTraceCounterFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_CounterName =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      MdpTraceCounterFtraceEvent>;
+
+  static constexpr FieldMetadata_CounterName kCounterName{};
+  void set_counter_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_CounterName::kFieldId, data, size);
+  }
+  void set_counter_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_CounterName::kFieldId, chars.data, chars.size);
+  }
+  void set_counter_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_CounterName::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_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MdpTraceCounterFtraceEvent>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::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);
+  }
+};
+
+class MdpPerfSetQosLutsFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpPerfSetQosLutsFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpPerfSetQosLutsFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpPerfSetQosLutsFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pnum() const { return at<1>().valid(); }
+  uint32_t pnum() const { return at<1>().as_uint32(); }
+  bool has_fmt() const { return at<2>().valid(); }
+  uint32_t fmt() const { return at<2>().as_uint32(); }
+  bool has_intf() const { return at<3>().valid(); }
+  uint32_t intf() const { return at<3>().as_uint32(); }
+  bool has_rot() const { return at<4>().valid(); }
+  uint32_t rot() const { return at<4>().as_uint32(); }
+  bool has_fl() const { return at<5>().valid(); }
+  uint32_t fl() const { return at<5>().as_uint32(); }
+  bool has_lut() const { return at<6>().valid(); }
+  uint32_t lut() const { return at<6>().as_uint32(); }
+  bool has_linear() const { return at<7>().valid(); }
+  uint32_t linear() const { return at<7>().as_uint32(); }
+};
+
+class MdpPerfSetQosLutsFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpPerfSetQosLutsFtraceEvent_Decoder;
+  enum : int32_t {
+    kPnumFieldNumber = 1,
+    kFmtFieldNumber = 2,
+    kIntfFieldNumber = 3,
+    kRotFieldNumber = 4,
+    kFlFieldNumber = 5,
+    kLutFieldNumber = 6,
+    kLinearFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpPerfSetQosLutsFtraceEvent"; }
+
+
+  using FieldMetadata_Pnum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetQosLutsFtraceEvent>;
+
+  static constexpr FieldMetadata_Pnum kPnum{};
+  void set_pnum(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pnum::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_Fmt =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetQosLutsFtraceEvent>;
+
+  static constexpr FieldMetadata_Fmt kFmt{};
+  void set_fmt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Fmt::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_Intf =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetQosLutsFtraceEvent>;
+
+  static constexpr FieldMetadata_Intf kIntf{};
+  void set_intf(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Intf::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_Rot =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetQosLutsFtraceEvent>;
+
+  static constexpr FieldMetadata_Rot kRot{};
+  void set_rot(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rot::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_Fl =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetQosLutsFtraceEvent>;
+
+  static constexpr FieldMetadata_Fl kFl{};
+  void set_fl(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Fl::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_Lut =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetQosLutsFtraceEvent>;
+
+  static constexpr FieldMetadata_Lut kLut{};
+  void set_lut(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lut::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_Linear =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetQosLutsFtraceEvent>;
+
+  static constexpr FieldMetadata_Linear kLinear{};
+  void set_linear(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Linear::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 MdpMisrCrcFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpMisrCrcFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpMisrCrcFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpMisrCrcFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_block_id() const { return at<1>().valid(); }
+  uint32_t block_id() const { return at<1>().as_uint32(); }
+  bool has_vsync_cnt() const { return at<2>().valid(); }
+  uint32_t vsync_cnt() const { return at<2>().as_uint32(); }
+  bool has_crc() const { return at<3>().valid(); }
+  uint32_t crc() const { return at<3>().as_uint32(); }
+};
+
+class MdpMisrCrcFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpMisrCrcFtraceEvent_Decoder;
+  enum : int32_t {
+    kBlockIdFieldNumber = 1,
+    kVsyncCntFieldNumber = 2,
+    kCrcFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpMisrCrcFtraceEvent"; }
+
+
+  using FieldMetadata_BlockId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpMisrCrcFtraceEvent>;
+
+  static constexpr FieldMetadata_BlockId kBlockId{};
+  void set_block_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BlockId::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_VsyncCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpMisrCrcFtraceEvent>;
+
+  static constexpr FieldMetadata_VsyncCnt kVsyncCnt{};
+  void set_vsync_cnt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VsyncCnt::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_Crc =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpMisrCrcFtraceEvent>;
+
+  static constexpr FieldMetadata_Crc kCrc{};
+  void set_crc(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Crc::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 MdpCmdReadptrDoneFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpCmdReadptrDoneFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpCmdReadptrDoneFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpCmdReadptrDoneFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ctl_num() const { return at<1>().valid(); }
+  uint32_t ctl_num() const { return at<1>().as_uint32(); }
+  bool has_koff_cnt() const { return at<2>().valid(); }
+  int32_t koff_cnt() const { return at<2>().as_int32(); }
+};
+
+class MdpCmdReadptrDoneFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpCmdReadptrDoneFtraceEvent_Decoder;
+  enum : int32_t {
+    kCtlNumFieldNumber = 1,
+    kKoffCntFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpCmdReadptrDoneFtraceEvent"; }
+
+
+  using FieldMetadata_CtlNum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpCmdReadptrDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_CtlNum kCtlNum{};
+  void set_ctl_num(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CtlNum::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_KoffCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MdpCmdReadptrDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_KoffCnt kKoffCnt{};
+  void set_koff_cnt(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KoffCnt::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);
+  }
+};
+
+class MdpSsppSetFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/16, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpSsppSetFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpSsppSetFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpSsppSetFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_num() const { return at<1>().valid(); }
+  uint32_t num() const { return at<1>().as_uint32(); }
+  bool has_play_cnt() const { return at<2>().valid(); }
+  uint32_t play_cnt() const { return at<2>().as_uint32(); }
+  bool has_mixer() const { return at<3>().valid(); }
+  uint32_t mixer() const { return at<3>().as_uint32(); }
+  bool has_stage() const { return at<4>().valid(); }
+  uint32_t stage() const { return at<4>().as_uint32(); }
+  bool has_flags() const { return at<5>().valid(); }
+  uint32_t flags() const { return at<5>().as_uint32(); }
+  bool has_format() const { return at<6>().valid(); }
+  uint32_t format() const { return at<6>().as_uint32(); }
+  bool has_img_w() const { return at<7>().valid(); }
+  uint32_t img_w() const { return at<7>().as_uint32(); }
+  bool has_img_h() const { return at<8>().valid(); }
+  uint32_t img_h() const { return at<8>().as_uint32(); }
+  bool has_src_x() const { return at<9>().valid(); }
+  uint32_t src_x() const { return at<9>().as_uint32(); }
+  bool has_src_y() const { return at<10>().valid(); }
+  uint32_t src_y() const { return at<10>().as_uint32(); }
+  bool has_src_w() const { return at<11>().valid(); }
+  uint32_t src_w() const { return at<11>().as_uint32(); }
+  bool has_src_h() const { return at<12>().valid(); }
+  uint32_t src_h() const { return at<12>().as_uint32(); }
+  bool has_dst_x() const { return at<13>().valid(); }
+  uint32_t dst_x() const { return at<13>().as_uint32(); }
+  bool has_dst_y() const { return at<14>().valid(); }
+  uint32_t dst_y() const { return at<14>().as_uint32(); }
+  bool has_dst_w() const { return at<15>().valid(); }
+  uint32_t dst_w() const { return at<15>().as_uint32(); }
+  bool has_dst_h() const { return at<16>().valid(); }
+  uint32_t dst_h() const { return at<16>().as_uint32(); }
+};
+
+class MdpSsppSetFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpSsppSetFtraceEvent_Decoder;
+  enum : int32_t {
+    kNumFieldNumber = 1,
+    kPlayCntFieldNumber = 2,
+    kMixerFieldNumber = 3,
+    kStageFieldNumber = 4,
+    kFlagsFieldNumber = 5,
+    kFormatFieldNumber = 6,
+    kImgWFieldNumber = 7,
+    kImgHFieldNumber = 8,
+    kSrcXFieldNumber = 9,
+    kSrcYFieldNumber = 10,
+    kSrcWFieldNumber = 11,
+    kSrcHFieldNumber = 12,
+    kDstXFieldNumber = 13,
+    kDstYFieldNumber = 14,
+    kDstWFieldNumber = 15,
+    kDstHFieldNumber = 16,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpSsppSetFtraceEvent"; }
+
+
+  using FieldMetadata_Num =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppSetFtraceEvent>;
+
+  static constexpr FieldMetadata_Num kNum{};
+  void set_num(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Num::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_PlayCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppSetFtraceEvent>;
+
+  static constexpr FieldMetadata_PlayCnt kPlayCnt{};
+  void set_play_cnt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PlayCnt::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_Mixer =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppSetFtraceEvent>;
+
+  static constexpr FieldMetadata_Mixer kMixer{};
+  void set_mixer(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mixer::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_Stage =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppSetFtraceEvent>;
+
+  static constexpr FieldMetadata_Stage kStage{};
+  void set_stage(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Stage::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppSetFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_Format =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppSetFtraceEvent>;
+
+  static constexpr FieldMetadata_Format kFormat{};
+  void set_format(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Format::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_ImgW =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppSetFtraceEvent>;
+
+  static constexpr FieldMetadata_ImgW kImgW{};
+  void set_img_w(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ImgW::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_ImgH =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppSetFtraceEvent>;
+
+  static constexpr FieldMetadata_ImgH kImgH{};
+  void set_img_h(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ImgH::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_SrcX =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppSetFtraceEvent>;
+
+  static constexpr FieldMetadata_SrcX kSrcX{};
+  void set_src_x(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SrcX::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_SrcY =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppSetFtraceEvent>;
+
+  static constexpr FieldMetadata_SrcY kSrcY{};
+  void set_src_y(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SrcY::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_SrcW =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppSetFtraceEvent>;
+
+  static constexpr FieldMetadata_SrcW kSrcW{};
+  void set_src_w(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SrcW::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_SrcH =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppSetFtraceEvent>;
+
+  static constexpr FieldMetadata_SrcH kSrcH{};
+  void set_src_h(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SrcH::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_DstX =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppSetFtraceEvent>;
+
+  static constexpr FieldMetadata_DstX kDstX{};
+  void set_dst_x(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DstX::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_DstY =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppSetFtraceEvent>;
+
+  static constexpr FieldMetadata_DstY kDstY{};
+  void set_dst_y(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DstY::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_DstW =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppSetFtraceEvent>;
+
+  static constexpr FieldMetadata_DstW kDstW{};
+  void set_dst_w(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DstW::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_DstH =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppSetFtraceEvent>;
+
+  static constexpr FieldMetadata_DstH kDstH{};
+  void set_dst_h(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DstH::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 MdpPerfSetPanicLutsFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpPerfSetPanicLutsFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpPerfSetPanicLutsFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpPerfSetPanicLutsFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pnum() const { return at<1>().valid(); }
+  uint32_t pnum() const { return at<1>().as_uint32(); }
+  bool has_fmt() const { return at<2>().valid(); }
+  uint32_t fmt() const { return at<2>().as_uint32(); }
+  bool has_mode() const { return at<3>().valid(); }
+  uint32_t mode() const { return at<3>().as_uint32(); }
+  bool has_panic_lut() const { return at<4>().valid(); }
+  uint32_t panic_lut() const { return at<4>().as_uint32(); }
+  bool has_robust_lut() const { return at<5>().valid(); }
+  uint32_t robust_lut() const { return at<5>().as_uint32(); }
+};
+
+class MdpPerfSetPanicLutsFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpPerfSetPanicLutsFtraceEvent_Decoder;
+  enum : int32_t {
+    kPnumFieldNumber = 1,
+    kFmtFieldNumber = 2,
+    kModeFieldNumber = 3,
+    kPanicLutFieldNumber = 4,
+    kRobustLutFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpPerfSetPanicLutsFtraceEvent"; }
+
+
+  using FieldMetadata_Pnum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetPanicLutsFtraceEvent>;
+
+  static constexpr FieldMetadata_Pnum kPnum{};
+  void set_pnum(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pnum::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_Fmt =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetPanicLutsFtraceEvent>;
+
+  static constexpr FieldMetadata_Fmt kFmt{};
+  void set_fmt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Fmt::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_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetPanicLutsFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::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_PanicLut =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetPanicLutsFtraceEvent>;
+
+  static constexpr FieldMetadata_PanicLut kPanicLut{};
+  void set_panic_lut(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PanicLut::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_RobustLut =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetPanicLutsFtraceEvent>;
+
+  static constexpr FieldMetadata_RobustLut kRobustLut{};
+  void set_robust_lut(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RobustLut::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 MdpCompareBwFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpCompareBwFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpCompareBwFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpCompareBwFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_new_ab() const { return at<1>().valid(); }
+  uint64_t new_ab() const { return at<1>().as_uint64(); }
+  bool has_new_ib() const { return at<2>().valid(); }
+  uint64_t new_ib() const { return at<2>().as_uint64(); }
+  bool has_new_wb() const { return at<3>().valid(); }
+  uint64_t new_wb() const { return at<3>().as_uint64(); }
+  bool has_old_ab() const { return at<4>().valid(); }
+  uint64_t old_ab() const { return at<4>().as_uint64(); }
+  bool has_old_ib() const { return at<5>().valid(); }
+  uint64_t old_ib() const { return at<5>().as_uint64(); }
+  bool has_old_wb() const { return at<6>().valid(); }
+  uint64_t old_wb() const { return at<6>().as_uint64(); }
+  bool has_params_changed() const { return at<7>().valid(); }
+  uint32_t params_changed() const { return at<7>().as_uint32(); }
+  bool has_update_bw() const { return at<8>().valid(); }
+  uint32_t update_bw() const { return at<8>().as_uint32(); }
+};
+
+class MdpCompareBwFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpCompareBwFtraceEvent_Decoder;
+  enum : int32_t {
+    kNewAbFieldNumber = 1,
+    kNewIbFieldNumber = 2,
+    kNewWbFieldNumber = 3,
+    kOldAbFieldNumber = 4,
+    kOldIbFieldNumber = 5,
+    kOldWbFieldNumber = 6,
+    kParamsChangedFieldNumber = 7,
+    kUpdateBwFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpCompareBwFtraceEvent"; }
+
+
+  using FieldMetadata_NewAb =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MdpCompareBwFtraceEvent>;
+
+  static constexpr FieldMetadata_NewAb kNewAb{};
+  void set_new_ab(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NewAb::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_NewIb =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MdpCompareBwFtraceEvent>;
+
+  static constexpr FieldMetadata_NewIb kNewIb{};
+  void set_new_ib(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NewIb::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_NewWb =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MdpCompareBwFtraceEvent>;
+
+  static constexpr FieldMetadata_NewWb kNewWb{};
+  void set_new_wb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NewWb::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_OldAb =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MdpCompareBwFtraceEvent>;
+
+  static constexpr FieldMetadata_OldAb kOldAb{};
+  void set_old_ab(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OldAb::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_OldIb =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MdpCompareBwFtraceEvent>;
+
+  static constexpr FieldMetadata_OldIb kOldIb{};
+  void set_old_ib(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OldIb::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_OldWb =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MdpCompareBwFtraceEvent>;
+
+  static constexpr FieldMetadata_OldWb kOldWb{};
+  void set_old_wb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OldWb::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_ParamsChanged =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpCompareBwFtraceEvent>;
+
+  static constexpr FieldMetadata_ParamsChanged kParamsChanged{};
+  void set_params_changed(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ParamsChanged::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_UpdateBw =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpCompareBwFtraceEvent>;
+
+  static constexpr FieldMetadata_UpdateBw kUpdateBw{};
+  void set_update_bw(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UpdateBw::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 MdpCmdPingpongDoneFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpCmdPingpongDoneFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpCmdPingpongDoneFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpCmdPingpongDoneFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ctl_num() const { return at<1>().valid(); }
+  uint32_t ctl_num() const { return at<1>().as_uint32(); }
+  bool has_intf_num() const { return at<2>().valid(); }
+  uint32_t intf_num() const { return at<2>().as_uint32(); }
+  bool has_pp_num() const { return at<3>().valid(); }
+  uint32_t pp_num() const { return at<3>().as_uint32(); }
+  bool has_koff_cnt() const { return at<4>().valid(); }
+  int32_t koff_cnt() const { return at<4>().as_int32(); }
+};
+
+class MdpCmdPingpongDoneFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpCmdPingpongDoneFtraceEvent_Decoder;
+  enum : int32_t {
+    kCtlNumFieldNumber = 1,
+    kIntfNumFieldNumber = 2,
+    kPpNumFieldNumber = 3,
+    kKoffCntFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpCmdPingpongDoneFtraceEvent"; }
+
+
+  using FieldMetadata_CtlNum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpCmdPingpongDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_CtlNum kCtlNum{};
+  void set_ctl_num(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CtlNum::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_IntfNum =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpCmdPingpongDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_IntfNum kIntfNum{};
+  void set_intf_num(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IntfNum::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_PpNum =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpCmdPingpongDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_PpNum kPpNum{};
+  void set_pp_num(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PpNum::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_KoffCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MdpCmdPingpongDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_KoffCnt kKoffCnt{};
+  void set_koff_cnt(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KoffCnt::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);
+  }
+};
+
+class TracingMarkWriteFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TracingMarkWriteFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TracingMarkWriteFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TracingMarkWriteFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  int32_t pid() const { return at<1>().as_int32(); }
+  bool has_trace_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars trace_name() const { return at<2>().as_string(); }
+  bool has_trace_begin() const { return at<3>().valid(); }
+  uint32_t trace_begin() const { return at<3>().as_uint32(); }
+};
+
+class TracingMarkWriteFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TracingMarkWriteFtraceEvent_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kTraceNameFieldNumber = 2,
+    kTraceBeginFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TracingMarkWriteFtraceEvent"; }
+
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_TraceName =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_TraceName kTraceName{};
+  void set_trace_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TraceName::kFieldId, data, size);
+  }
+  void set_trace_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_TraceName::kFieldId, chars.data, chars.size);
+  }
+  void set_trace_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_TraceName::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_TraceBegin =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_TraceBegin kTraceBegin{};
+  void set_trace_begin(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TraceBegin::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 MdpSsppChangeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/16, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpSsppChangeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpSsppChangeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpSsppChangeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_num() const { return at<1>().valid(); }
+  uint32_t num() const { return at<1>().as_uint32(); }
+  bool has_play_cnt() const { return at<2>().valid(); }
+  uint32_t play_cnt() const { return at<2>().as_uint32(); }
+  bool has_mixer() const { return at<3>().valid(); }
+  uint32_t mixer() const { return at<3>().as_uint32(); }
+  bool has_stage() const { return at<4>().valid(); }
+  uint32_t stage() const { return at<4>().as_uint32(); }
+  bool has_flags() const { return at<5>().valid(); }
+  uint32_t flags() const { return at<5>().as_uint32(); }
+  bool has_format() const { return at<6>().valid(); }
+  uint32_t format() const { return at<6>().as_uint32(); }
+  bool has_img_w() const { return at<7>().valid(); }
+  uint32_t img_w() const { return at<7>().as_uint32(); }
+  bool has_img_h() const { return at<8>().valid(); }
+  uint32_t img_h() const { return at<8>().as_uint32(); }
+  bool has_src_x() const { return at<9>().valid(); }
+  uint32_t src_x() const { return at<9>().as_uint32(); }
+  bool has_src_y() const { return at<10>().valid(); }
+  uint32_t src_y() const { return at<10>().as_uint32(); }
+  bool has_src_w() const { return at<11>().valid(); }
+  uint32_t src_w() const { return at<11>().as_uint32(); }
+  bool has_src_h() const { return at<12>().valid(); }
+  uint32_t src_h() const { return at<12>().as_uint32(); }
+  bool has_dst_x() const { return at<13>().valid(); }
+  uint32_t dst_x() const { return at<13>().as_uint32(); }
+  bool has_dst_y() const { return at<14>().valid(); }
+  uint32_t dst_y() const { return at<14>().as_uint32(); }
+  bool has_dst_w() const { return at<15>().valid(); }
+  uint32_t dst_w() const { return at<15>().as_uint32(); }
+  bool has_dst_h() const { return at<16>().valid(); }
+  uint32_t dst_h() const { return at<16>().as_uint32(); }
+};
+
+class MdpSsppChangeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpSsppChangeFtraceEvent_Decoder;
+  enum : int32_t {
+    kNumFieldNumber = 1,
+    kPlayCntFieldNumber = 2,
+    kMixerFieldNumber = 3,
+    kStageFieldNumber = 4,
+    kFlagsFieldNumber = 5,
+    kFormatFieldNumber = 6,
+    kImgWFieldNumber = 7,
+    kImgHFieldNumber = 8,
+    kSrcXFieldNumber = 9,
+    kSrcYFieldNumber = 10,
+    kSrcWFieldNumber = 11,
+    kSrcHFieldNumber = 12,
+    kDstXFieldNumber = 13,
+    kDstYFieldNumber = 14,
+    kDstWFieldNumber = 15,
+    kDstHFieldNumber = 16,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpSsppChangeFtraceEvent"; }
+
+
+  using FieldMetadata_Num =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppChangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Num kNum{};
+  void set_num(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Num::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_PlayCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppChangeFtraceEvent>;
+
+  static constexpr FieldMetadata_PlayCnt kPlayCnt{};
+  void set_play_cnt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PlayCnt::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_Mixer =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppChangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Mixer kMixer{};
+  void set_mixer(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mixer::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_Stage =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppChangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Stage kStage{};
+  void set_stage(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Stage::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppChangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_Format =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppChangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Format kFormat{};
+  void set_format(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Format::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_ImgW =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppChangeFtraceEvent>;
+
+  static constexpr FieldMetadata_ImgW kImgW{};
+  void set_img_w(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ImgW::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_ImgH =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppChangeFtraceEvent>;
+
+  static constexpr FieldMetadata_ImgH kImgH{};
+  void set_img_h(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ImgH::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_SrcX =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppChangeFtraceEvent>;
+
+  static constexpr FieldMetadata_SrcX kSrcX{};
+  void set_src_x(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SrcX::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_SrcY =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppChangeFtraceEvent>;
+
+  static constexpr FieldMetadata_SrcY kSrcY{};
+  void set_src_y(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SrcY::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_SrcW =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppChangeFtraceEvent>;
+
+  static constexpr FieldMetadata_SrcW kSrcW{};
+  void set_src_w(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SrcW::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_SrcH =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppChangeFtraceEvent>;
+
+  static constexpr FieldMetadata_SrcH kSrcH{};
+  void set_src_h(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SrcH::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_DstX =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppChangeFtraceEvent>;
+
+  static constexpr FieldMetadata_DstX kDstX{};
+  void set_dst_x(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DstX::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_DstY =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppChangeFtraceEvent>;
+
+  static constexpr FieldMetadata_DstY kDstY{};
+  void set_dst_y(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DstY::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_DstW =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppChangeFtraceEvent>;
+
+  static constexpr FieldMetadata_DstW kDstW{};
+  void set_dst_w(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DstW::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_DstH =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppChangeFtraceEvent>;
+
+  static constexpr FieldMetadata_DstH kDstH{};
+  void set_dst_h(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DstH::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 MdpPerfSetOtFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpPerfSetOtFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpPerfSetOtFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpPerfSetOtFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pnum() const { return at<1>().valid(); }
+  uint32_t pnum() const { return at<1>().as_uint32(); }
+  bool has_xin_id() const { return at<2>().valid(); }
+  uint32_t xin_id() const { return at<2>().as_uint32(); }
+  bool has_rd_lim() const { return at<3>().valid(); }
+  uint32_t rd_lim() const { return at<3>().as_uint32(); }
+  bool has_is_vbif_rt() const { return at<4>().valid(); }
+  uint32_t is_vbif_rt() const { return at<4>().as_uint32(); }
+};
+
+class MdpPerfSetOtFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpPerfSetOtFtraceEvent_Decoder;
+  enum : int32_t {
+    kPnumFieldNumber = 1,
+    kXinIdFieldNumber = 2,
+    kRdLimFieldNumber = 3,
+    kIsVbifRtFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpPerfSetOtFtraceEvent"; }
+
+
+  using FieldMetadata_Pnum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetOtFtraceEvent>;
+
+  static constexpr FieldMetadata_Pnum kPnum{};
+  void set_pnum(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pnum::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_XinId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetOtFtraceEvent>;
+
+  static constexpr FieldMetadata_XinId kXinId{};
+  void set_xin_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_XinId::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_RdLim =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetOtFtraceEvent>;
+
+  static constexpr FieldMetadata_RdLim kRdLim{};
+  void set_rd_lim(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RdLim::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_IsVbifRt =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetOtFtraceEvent>;
+
+  static constexpr FieldMetadata_IsVbifRt kIsVbifRt{};
+  void set_is_vbif_rt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsVbifRt::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 MdpCommitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpCommitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpCommitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpCommitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_num() const { return at<1>().valid(); }
+  uint32_t num() const { return at<1>().as_uint32(); }
+  bool has_play_cnt() const { return at<2>().valid(); }
+  uint32_t play_cnt() const { return at<2>().as_uint32(); }
+  bool has_clk_rate() const { return at<3>().valid(); }
+  uint32_t clk_rate() const { return at<3>().as_uint32(); }
+  bool has_bandwidth() const { return at<4>().valid(); }
+  uint64_t bandwidth() const { return at<4>().as_uint64(); }
+};
+
+class MdpCommitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpCommitFtraceEvent_Decoder;
+  enum : int32_t {
+    kNumFieldNumber = 1,
+    kPlayCntFieldNumber = 2,
+    kClkRateFieldNumber = 3,
+    kBandwidthFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpCommitFtraceEvent"; }
+
+
+  using FieldMetadata_Num =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpCommitFtraceEvent>;
+
+  static constexpr FieldMetadata_Num kNum{};
+  void set_num(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Num::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_PlayCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpCommitFtraceEvent>;
+
+  static constexpr FieldMetadata_PlayCnt kPlayCnt{};
+  void set_play_cnt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PlayCnt::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_ClkRate =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpCommitFtraceEvent>;
+
+  static constexpr FieldMetadata_ClkRate kClkRate{};
+  void set_clk_rate(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ClkRate::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_Bandwidth =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MdpCommitFtraceEvent>;
+
+  static constexpr FieldMetadata_Bandwidth kBandwidth{};
+  void set_bandwidth(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Bandwidth::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 MdpCmdKickoffFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpCmdKickoffFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpCmdKickoffFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpCmdKickoffFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ctl_num() const { return at<1>().valid(); }
+  uint32_t ctl_num() const { return at<1>().as_uint32(); }
+  bool has_kickoff_cnt() const { return at<2>().valid(); }
+  int32_t kickoff_cnt() const { return at<2>().as_int32(); }
+};
+
+class MdpCmdKickoffFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpCmdKickoffFtraceEvent_Decoder;
+  enum : int32_t {
+    kCtlNumFieldNumber = 1,
+    kKickoffCntFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpCmdKickoffFtraceEvent"; }
+
+
+  using FieldMetadata_CtlNum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpCmdKickoffFtraceEvent>;
+
+  static constexpr FieldMetadata_CtlNum kCtlNum{};
+  void set_ctl_num(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CtlNum::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_KickoffCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MdpCmdKickoffFtraceEvent>;
+
+  static constexpr FieldMetadata_KickoffCnt kKickoffCnt{};
+  void set_kickoff_cnt(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KickoffCnt::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/mm_event.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_MM_EVENT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_MM_EVENT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class MmEventRecordFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmEventRecordFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmEventRecordFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmEventRecordFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_avg_lat() const { return at<1>().valid(); }
+  uint32_t avg_lat() const { return at<1>().as_uint32(); }
+  bool has_count() const { return at<2>().valid(); }
+  uint32_t count() const { return at<2>().as_uint32(); }
+  bool has_max_lat() const { return at<3>().valid(); }
+  uint32_t max_lat() const { return at<3>().as_uint32(); }
+  bool has_type() const { return at<4>().valid(); }
+  uint32_t type() const { return at<4>().as_uint32(); }
+};
+
+class MmEventRecordFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmEventRecordFtraceEvent_Decoder;
+  enum : int32_t {
+    kAvgLatFieldNumber = 1,
+    kCountFieldNumber = 2,
+    kMaxLatFieldNumber = 3,
+    kTypeFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmEventRecordFtraceEvent"; }
+
+
+  using FieldMetadata_AvgLat =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmEventRecordFtraceEvent>;
+
+  static constexpr FieldMetadata_AvgLat kAvgLat{};
+  void set_avg_lat(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AvgLat::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_Count =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmEventRecordFtraceEvent>;
+
+  static constexpr FieldMetadata_Count kCount{};
+  void set_count(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Count::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_MaxLat =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmEventRecordFtraceEvent>;
+
+  static constexpr FieldMetadata_MaxLat kMaxLat{};
+  void set_max_lat(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MaxLat::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_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmEventRecordFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/net.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_NET_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_NET_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class NapiGroReceiveExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  NapiGroReceiveExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit NapiGroReceiveExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit NapiGroReceiveExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ret() const { return at<1>().valid(); }
+  int32_t ret() const { return at<1>().as_int32(); }
+};
+
+class NapiGroReceiveExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = NapiGroReceiveExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kRetFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.NapiGroReceiveExitFtraceEvent"; }
+
+
+  using FieldMetadata_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      NapiGroReceiveExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::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);
+  }
+};
+
+class NapiGroReceiveEntryFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/19, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  NapiGroReceiveEntryFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit NapiGroReceiveEntryFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit NapiGroReceiveEntryFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_data_len() const { return at<1>().valid(); }
+  uint32_t data_len() const { return at<1>().as_uint32(); }
+  bool has_gso_size() const { return at<2>().valid(); }
+  uint32_t gso_size() const { return at<2>().as_uint32(); }
+  bool has_gso_type() const { return at<3>().valid(); }
+  uint32_t gso_type() const { return at<3>().as_uint32(); }
+  bool has_hash() const { return at<4>().valid(); }
+  uint32_t hash() const { return at<4>().as_uint32(); }
+  bool has_ip_summed() const { return at<5>().valid(); }
+  uint32_t ip_summed() const { return at<5>().as_uint32(); }
+  bool has_l4_hash() const { return at<6>().valid(); }
+  uint32_t l4_hash() const { return at<6>().as_uint32(); }
+  bool has_len() const { return at<7>().valid(); }
+  uint32_t len() const { return at<7>().as_uint32(); }
+  bool has_mac_header() const { return at<8>().valid(); }
+  int32_t mac_header() const { return at<8>().as_int32(); }
+  bool has_mac_header_valid() const { return at<9>().valid(); }
+  uint32_t mac_header_valid() const { return at<9>().as_uint32(); }
+  bool has_name() const { return at<10>().valid(); }
+  ::protozero::ConstChars name() const { return at<10>().as_string(); }
+  bool has_napi_id() const { return at<11>().valid(); }
+  uint32_t napi_id() const { return at<11>().as_uint32(); }
+  bool has_nr_frags() const { return at<12>().valid(); }
+  uint32_t nr_frags() const { return at<12>().as_uint32(); }
+  bool has_protocol() const { return at<13>().valid(); }
+  uint32_t protocol() const { return at<13>().as_uint32(); }
+  bool has_queue_mapping() const { return at<14>().valid(); }
+  uint32_t queue_mapping() const { return at<14>().as_uint32(); }
+  bool has_skbaddr() const { return at<15>().valid(); }
+  uint64_t skbaddr() const { return at<15>().as_uint64(); }
+  bool has_truesize() const { return at<16>().valid(); }
+  uint32_t truesize() const { return at<16>().as_uint32(); }
+  bool has_vlan_proto() const { return at<17>().valid(); }
+  uint32_t vlan_proto() const { return at<17>().as_uint32(); }
+  bool has_vlan_tagged() const { return at<18>().valid(); }
+  uint32_t vlan_tagged() const { return at<18>().as_uint32(); }
+  bool has_vlan_tci() const { return at<19>().valid(); }
+  uint32_t vlan_tci() const { return at<19>().as_uint32(); }
+};
+
+class NapiGroReceiveEntryFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = NapiGroReceiveEntryFtraceEvent_Decoder;
+  enum : int32_t {
+    kDataLenFieldNumber = 1,
+    kGsoSizeFieldNumber = 2,
+    kGsoTypeFieldNumber = 3,
+    kHashFieldNumber = 4,
+    kIpSummedFieldNumber = 5,
+    kL4HashFieldNumber = 6,
+    kLenFieldNumber = 7,
+    kMacHeaderFieldNumber = 8,
+    kMacHeaderValidFieldNumber = 9,
+    kNameFieldNumber = 10,
+    kNapiIdFieldNumber = 11,
+    kNrFragsFieldNumber = 12,
+    kProtocolFieldNumber = 13,
+    kQueueMappingFieldNumber = 14,
+    kSkbaddrFieldNumber = 15,
+    kTruesizeFieldNumber = 16,
+    kVlanProtoFieldNumber = 17,
+    kVlanTaggedFieldNumber = 18,
+    kVlanTciFieldNumber = 19,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.NapiGroReceiveEntryFtraceEvent"; }
+
+
+  using FieldMetadata_DataLen =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_DataLen kDataLen{};
+  void set_data_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DataLen::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_GsoSize =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_GsoSize kGsoSize{};
+  void set_gso_size(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GsoSize::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_GsoType =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_GsoType kGsoType{};
+  void set_gso_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GsoType::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_Hash =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_Hash kHash{};
+  void set_hash(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Hash::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_IpSummed =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_IpSummed kIpSummed{};
+  void set_ip_summed(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IpSummed::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_L4Hash =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_L4Hash kL4Hash{};
+  void set_l4_hash(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_L4Hash::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_MacHeader =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_MacHeader kMacHeader{};
+  void set_mac_header(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MacHeader::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_MacHeaderValid =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_MacHeaderValid kMacHeaderValid{};
+  void set_mac_header_valid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MacHeaderValid::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_NapiId =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_NapiId kNapiId{};
+  void set_napi_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NapiId::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_NrFrags =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_NrFrags kNrFrags{};
+  void set_nr_frags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrFrags::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_Protocol =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_Protocol kProtocol{};
+  void set_protocol(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Protocol::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_QueueMapping =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_QueueMapping kQueueMapping{};
+  void set_queue_mapping(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_QueueMapping::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_Skbaddr =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_Skbaddr kSkbaddr{};
+  void set_skbaddr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Skbaddr::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_Truesize =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_Truesize kTruesize{};
+  void set_truesize(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Truesize::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_VlanProto =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_VlanProto kVlanProto{};
+  void set_vlan_proto(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VlanProto::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_VlanTagged =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_VlanTagged kVlanTagged{};
+  void set_vlan_tagged(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VlanTagged::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_VlanTci =
+    ::protozero::proto_utils::FieldMetadata<
+      19,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_VlanTci kVlanTci{};
+  void set_vlan_tci(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VlanTci::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 NetDevXmitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  NetDevXmitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit NetDevXmitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit NetDevXmitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_len() const { return at<1>().valid(); }
+  uint32_t len() const { return at<1>().as_uint32(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+  bool has_rc() const { return at<3>().valid(); }
+  int32_t rc() const { return at<3>().as_int32(); }
+  bool has_skbaddr() const { return at<4>().valid(); }
+  uint64_t skbaddr() const { return at<4>().as_uint64(); }
+};
+
+class NetDevXmitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = NetDevXmitFtraceEvent_Decoder;
+  enum : int32_t {
+    kLenFieldNumber = 1,
+    kNameFieldNumber = 2,
+    kRcFieldNumber = 3,
+    kSkbaddrFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.NetDevXmitFtraceEvent"; }
+
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NetDevXmitFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      NetDevXmitFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Rc =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      NetDevXmitFtraceEvent>;
+
+  static constexpr FieldMetadata_Rc kRc{};
+  void set_rc(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rc::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_Skbaddr =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      NetDevXmitFtraceEvent>;
+
+  static constexpr FieldMetadata_Skbaddr kSkbaddr{};
+  void set_skbaddr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Skbaddr::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 NetifReceiveSkbFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  NetifReceiveSkbFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit NetifReceiveSkbFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit NetifReceiveSkbFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_len() const { return at<1>().valid(); }
+  uint32_t len() const { return at<1>().as_uint32(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+  bool has_skbaddr() const { return at<3>().valid(); }
+  uint64_t skbaddr() const { return at<3>().as_uint64(); }
+};
+
+class NetifReceiveSkbFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = NetifReceiveSkbFtraceEvent_Decoder;
+  enum : int32_t {
+    kLenFieldNumber = 1,
+    kNameFieldNumber = 2,
+    kSkbaddrFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.NetifReceiveSkbFtraceEvent"; }
+
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NetifReceiveSkbFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      NetifReceiveSkbFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Skbaddr =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      NetifReceiveSkbFtraceEvent>;
+
+  static constexpr FieldMetadata_Skbaddr kSkbaddr{};
+  void set_skbaddr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Skbaddr::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/oom.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_OOM_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_OOM_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class MarkVictimFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MarkVictimFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MarkVictimFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MarkVictimFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  int32_t pid() const { return at<1>().as_int32(); }
+};
+
+class MarkVictimFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MarkVictimFtraceEvent_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MarkVictimFtraceEvent"; }
+
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MarkVictimFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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);
+  }
+};
+
+class OomScoreAdjUpdateFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  OomScoreAdjUpdateFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit OomScoreAdjUpdateFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit OomScoreAdjUpdateFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_comm() const { return at<1>().valid(); }
+  ::protozero::ConstChars comm() const { return at<1>().as_string(); }
+  bool has_oom_score_adj() const { return at<2>().valid(); }
+  int32_t oom_score_adj() const { return at<2>().as_int32(); }
+  bool has_pid() const { return at<3>().valid(); }
+  int32_t pid() const { return at<3>().as_int32(); }
+};
+
+class OomScoreAdjUpdateFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = OomScoreAdjUpdateFtraceEvent_Decoder;
+  enum : int32_t {
+    kCommFieldNumber = 1,
+    kOomScoreAdjFieldNumber = 2,
+    kPidFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.OomScoreAdjUpdateFtraceEvent"; }
+
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      OomScoreAdjUpdateFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::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_OomScoreAdj =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      OomScoreAdjUpdateFtraceEvent>;
+
+  static constexpr FieldMetadata_OomScoreAdj kOomScoreAdj{};
+  void set_oom_score_adj(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OomScoreAdj::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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      OomScoreAdjUpdateFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/panel.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_PANEL_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_PANEL_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class PanelWriteGenericFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  PanelWriteGenericFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PanelWriteGenericFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PanelWriteGenericFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  int32_t pid() const { return at<1>().as_int32(); }
+  bool has_trace_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars trace_name() const { return at<2>().as_string(); }
+  bool has_trace_begin() const { return at<3>().valid(); }
+  uint32_t trace_begin() const { return at<3>().as_uint32(); }
+  bool has_name() const { return at<4>().valid(); }
+  ::protozero::ConstChars name() const { return at<4>().as_string(); }
+  bool has_type() const { return at<5>().valid(); }
+  uint32_t type() const { return at<5>().as_uint32(); }
+  bool has_value() const { return at<6>().valid(); }
+  int32_t value() const { return at<6>().as_int32(); }
+};
+
+class PanelWriteGenericFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = PanelWriteGenericFtraceEvent_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kTraceNameFieldNumber = 2,
+    kTraceBeginFieldNumber = 3,
+    kNameFieldNumber = 4,
+    kTypeFieldNumber = 5,
+    kValueFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PanelWriteGenericFtraceEvent"; }
+
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      PanelWriteGenericFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_TraceName =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PanelWriteGenericFtraceEvent>;
+
+  static constexpr FieldMetadata_TraceName kTraceName{};
+  void set_trace_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TraceName::kFieldId, data, size);
+  }
+  void set_trace_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_TraceName::kFieldId, chars.data, chars.size);
+  }
+  void set_trace_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_TraceName::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_TraceBegin =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PanelWriteGenericFtraceEvent>;
+
+  static constexpr FieldMetadata_TraceBegin kTraceBegin{};
+  void set_trace_begin(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TraceBegin::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PanelWriteGenericFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PanelWriteGenericFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::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_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      PanelWriteGenericFtraceEvent>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::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);
+  }
+};
+
+class DsiTxFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DsiTxFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DsiTxFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DsiTxFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_last() const { return at<1>().valid(); }
+  uint32_t last() const { return at<1>().as_uint32(); }
+  bool has_tx_buf() const { return at<2>().valid(); }
+  uint32_t tx_buf() const { return at<2>().as_uint32(); }
+  bool has_type() const { return at<3>().valid(); }
+  uint32_t type() const { return at<3>().as_uint32(); }
+};
+
+class DsiTxFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = DsiTxFtraceEvent_Decoder;
+  enum : int32_t {
+    kLastFieldNumber = 1,
+    kTxBufFieldNumber = 2,
+    kTypeFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DsiTxFtraceEvent"; }
+
+
+  using FieldMetadata_Last =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DsiTxFtraceEvent>;
+
+  static constexpr FieldMetadata_Last kLast{};
+  void set_last(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Last::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_TxBuf =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DsiTxFtraceEvent>;
+
+  static constexpr FieldMetadata_TxBuf kTxBuf{};
+  void set_tx_buf(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TxBuf::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_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DsiTxFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::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 DsiRxFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DsiRxFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DsiRxFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DsiRxFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cmd() const { return at<1>().valid(); }
+  uint32_t cmd() const { return at<1>().as_uint32(); }
+  bool has_rx_buf() const { return at<2>().valid(); }
+  uint32_t rx_buf() const { return at<2>().as_uint32(); }
+};
+
+class DsiRxFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = DsiRxFtraceEvent_Decoder;
+  enum : int32_t {
+    kCmdFieldNumber = 1,
+    kRxBufFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DsiRxFtraceEvent"; }
+
+
+  using FieldMetadata_Cmd =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DsiRxFtraceEvent>;
+
+  static constexpr FieldMetadata_Cmd kCmd{};
+  void set_cmd(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cmd::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_RxBuf =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DsiRxFtraceEvent>;
+
+  static constexpr FieldMetadata_RxBuf kRxBuf{};
+  void set_rx_buf(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RxBuf::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 DsiCmdFifoStatusFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DsiCmdFifoStatusFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DsiCmdFifoStatusFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DsiCmdFifoStatusFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_header() const { return at<1>().valid(); }
+  uint32_t header() const { return at<1>().as_uint32(); }
+  bool has_payload() const { return at<2>().valid(); }
+  uint32_t payload() const { return at<2>().as_uint32(); }
+};
+
+class DsiCmdFifoStatusFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = DsiCmdFifoStatusFtraceEvent_Decoder;
+  enum : int32_t {
+    kHeaderFieldNumber = 1,
+    kPayloadFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DsiCmdFifoStatusFtraceEvent"; }
+
+
+  using FieldMetadata_Header =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DsiCmdFifoStatusFtraceEvent>;
+
+  static constexpr FieldMetadata_Header kHeader{};
+  void set_header(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Header::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_Payload =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DsiCmdFifoStatusFtraceEvent>;
+
+  static constexpr FieldMetadata_Payload kPayload{};
+  void set_payload(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Payload::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/perf_trace_counters.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_PERF_TRACE_COUNTERS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_PERF_TRACE_COUNTERS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class SchedSwitchWithCtrsFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/17, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SchedSwitchWithCtrsFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SchedSwitchWithCtrsFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SchedSwitchWithCtrsFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_old_pid() const { return at<1>().valid(); }
+  int32_t old_pid() const { return at<1>().as_int32(); }
+  bool has_new_pid() const { return at<2>().valid(); }
+  int32_t new_pid() const { return at<2>().as_int32(); }
+  bool has_cctr() const { return at<3>().valid(); }
+  uint32_t cctr() const { return at<3>().as_uint32(); }
+  bool has_ctr0() const { return at<4>().valid(); }
+  uint32_t ctr0() const { return at<4>().as_uint32(); }
+  bool has_ctr1() const { return at<5>().valid(); }
+  uint32_t ctr1() const { return at<5>().as_uint32(); }
+  bool has_ctr2() const { return at<6>().valid(); }
+  uint32_t ctr2() const { return at<6>().as_uint32(); }
+  bool has_ctr3() const { return at<7>().valid(); }
+  uint32_t ctr3() const { return at<7>().as_uint32(); }
+  bool has_lctr0() const { return at<8>().valid(); }
+  uint32_t lctr0() const { return at<8>().as_uint32(); }
+  bool has_lctr1() const { return at<9>().valid(); }
+  uint32_t lctr1() const { return at<9>().as_uint32(); }
+  bool has_ctr4() const { return at<10>().valid(); }
+  uint32_t ctr4() const { return at<10>().as_uint32(); }
+  bool has_ctr5() const { return at<11>().valid(); }
+  uint32_t ctr5() const { return at<11>().as_uint32(); }
+  bool has_prev_comm() const { return at<12>().valid(); }
+  ::protozero::ConstChars prev_comm() const { return at<12>().as_string(); }
+  bool has_prev_pid() const { return at<13>().valid(); }
+  int32_t prev_pid() const { return at<13>().as_int32(); }
+  bool has_cyc() const { return at<14>().valid(); }
+  uint32_t cyc() const { return at<14>().as_uint32(); }
+  bool has_inst() const { return at<15>().valid(); }
+  uint32_t inst() const { return at<15>().as_uint32(); }
+  bool has_stallbm() const { return at<16>().valid(); }
+  uint32_t stallbm() const { return at<16>().as_uint32(); }
+  bool has_l3dm() const { return at<17>().valid(); }
+  uint32_t l3dm() const { return at<17>().as_uint32(); }
+};
+
+class SchedSwitchWithCtrsFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SchedSwitchWithCtrsFtraceEvent_Decoder;
+  enum : int32_t {
+    kOldPidFieldNumber = 1,
+    kNewPidFieldNumber = 2,
+    kCctrFieldNumber = 3,
+    kCtr0FieldNumber = 4,
+    kCtr1FieldNumber = 5,
+    kCtr2FieldNumber = 6,
+    kCtr3FieldNumber = 7,
+    kLctr0FieldNumber = 8,
+    kLctr1FieldNumber = 9,
+    kCtr4FieldNumber = 10,
+    kCtr5FieldNumber = 11,
+    kPrevCommFieldNumber = 12,
+    kPrevPidFieldNumber = 13,
+    kCycFieldNumber = 14,
+    kInstFieldNumber = 15,
+    kStallbmFieldNumber = 16,
+    kL3dmFieldNumber = 17,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SchedSwitchWithCtrsFtraceEvent"; }
+
+
+  using FieldMetadata_OldPid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedSwitchWithCtrsFtraceEvent>;
+
+  static constexpr FieldMetadata_OldPid kOldPid{};
+  void set_old_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OldPid::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_NewPid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedSwitchWithCtrsFtraceEvent>;
+
+  static constexpr FieldMetadata_NewPid kNewPid{};
+  void set_new_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NewPid::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_Cctr =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedSwitchWithCtrsFtraceEvent>;
+
+  static constexpr FieldMetadata_Cctr kCctr{};
+  void set_cctr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cctr::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_Ctr0 =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedSwitchWithCtrsFtraceEvent>;
+
+  static constexpr FieldMetadata_Ctr0 kCtr0{};
+  void set_ctr0(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ctr0::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_Ctr1 =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedSwitchWithCtrsFtraceEvent>;
+
+  static constexpr FieldMetadata_Ctr1 kCtr1{};
+  void set_ctr1(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ctr1::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_Ctr2 =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedSwitchWithCtrsFtraceEvent>;
+
+  static constexpr FieldMetadata_Ctr2 kCtr2{};
+  void set_ctr2(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ctr2::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_Ctr3 =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedSwitchWithCtrsFtraceEvent>;
+
+  static constexpr FieldMetadata_Ctr3 kCtr3{};
+  void set_ctr3(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ctr3::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_Lctr0 =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedSwitchWithCtrsFtraceEvent>;
+
+  static constexpr FieldMetadata_Lctr0 kLctr0{};
+  void set_lctr0(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lctr0::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_Lctr1 =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedSwitchWithCtrsFtraceEvent>;
+
+  static constexpr FieldMetadata_Lctr1 kLctr1{};
+  void set_lctr1(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lctr1::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_Ctr4 =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedSwitchWithCtrsFtraceEvent>;
+
+  static constexpr FieldMetadata_Ctr4 kCtr4{};
+  void set_ctr4(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ctr4::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_Ctr5 =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedSwitchWithCtrsFtraceEvent>;
+
+  static constexpr FieldMetadata_Ctr5 kCtr5{};
+  void set_ctr5(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ctr5::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_PrevComm =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedSwitchWithCtrsFtraceEvent>;
+
+  static constexpr FieldMetadata_PrevComm kPrevComm{};
+  void set_prev_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_PrevComm::kFieldId, data, size);
+  }
+  void set_prev_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_PrevComm::kFieldId, chars.data, chars.size);
+  }
+  void set_prev_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_PrevComm::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_PrevPid =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedSwitchWithCtrsFtraceEvent>;
+
+  static constexpr FieldMetadata_PrevPid kPrevPid{};
+  void set_prev_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PrevPid::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_Cyc =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedSwitchWithCtrsFtraceEvent>;
+
+  static constexpr FieldMetadata_Cyc kCyc{};
+  void set_cyc(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cyc::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_Inst =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedSwitchWithCtrsFtraceEvent>;
+
+  static constexpr FieldMetadata_Inst kInst{};
+  void set_inst(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Inst::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_Stallbm =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedSwitchWithCtrsFtraceEvent>;
+
+  static constexpr FieldMetadata_Stallbm kStallbm{};
+  void set_stallbm(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Stallbm::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_L3dm =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedSwitchWithCtrsFtraceEvent>;
+
+  static constexpr FieldMetadata_L3dm kL3dm{};
+  void set_l3dm(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_L3dm::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/power.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_POWER_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_POWER_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class DevicePmCallbackEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DevicePmCallbackEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DevicePmCallbackEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DevicePmCallbackEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_device() const { return at<1>().valid(); }
+  ::protozero::ConstChars device() const { return at<1>().as_string(); }
+  bool has_driver() const { return at<2>().valid(); }
+  ::protozero::ConstChars driver() const { return at<2>().as_string(); }
+  bool has_error() const { return at<3>().valid(); }
+  int32_t error() const { return at<3>().as_int32(); }
+};
+
+class DevicePmCallbackEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = DevicePmCallbackEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kDeviceFieldNumber = 1,
+    kDriverFieldNumber = 2,
+    kErrorFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DevicePmCallbackEndFtraceEvent"; }
+
+
+  using FieldMetadata_Device =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DevicePmCallbackEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Device kDevice{};
+  void set_device(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Device::kFieldId, data, size);
+  }
+  void set_device(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Device::kFieldId, chars.data, chars.size);
+  }
+  void set_device(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Device::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_Driver =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DevicePmCallbackEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Driver kDriver{};
+  void set_driver(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, data, size);
+  }
+  void set_driver(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, chars.data, chars.size);
+  }
+  void set_driver(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Driver::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_Error =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      DevicePmCallbackEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Error kError{};
+  void set_error(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Error::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);
+  }
+};
+
+class DevicePmCallbackStartFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DevicePmCallbackStartFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DevicePmCallbackStartFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DevicePmCallbackStartFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_device() const { return at<1>().valid(); }
+  ::protozero::ConstChars device() const { return at<1>().as_string(); }
+  bool has_driver() const { return at<2>().valid(); }
+  ::protozero::ConstChars driver() const { return at<2>().as_string(); }
+  bool has_parent() const { return at<3>().valid(); }
+  ::protozero::ConstChars parent() const { return at<3>().as_string(); }
+  bool has_pm_ops() const { return at<4>().valid(); }
+  ::protozero::ConstChars pm_ops() const { return at<4>().as_string(); }
+  bool has_event() const { return at<5>().valid(); }
+  int32_t event() const { return at<5>().as_int32(); }
+};
+
+class DevicePmCallbackStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = DevicePmCallbackStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kDeviceFieldNumber = 1,
+    kDriverFieldNumber = 2,
+    kParentFieldNumber = 3,
+    kPmOpsFieldNumber = 4,
+    kEventFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DevicePmCallbackStartFtraceEvent"; }
+
+
+  using FieldMetadata_Device =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DevicePmCallbackStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Device kDevice{};
+  void set_device(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Device::kFieldId, data, size);
+  }
+  void set_device(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Device::kFieldId, chars.data, chars.size);
+  }
+  void set_device(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Device::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_Driver =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DevicePmCallbackStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Driver kDriver{};
+  void set_driver(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, data, size);
+  }
+  void set_driver(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, chars.data, chars.size);
+  }
+  void set_driver(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Driver::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_Parent =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DevicePmCallbackStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Parent kParent{};
+  void set_parent(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Parent::kFieldId, data, size);
+  }
+  void set_parent(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Parent::kFieldId, chars.data, chars.size);
+  }
+  void set_parent(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Parent::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_PmOps =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DevicePmCallbackStartFtraceEvent>;
+
+  static constexpr FieldMetadata_PmOps kPmOps{};
+  void set_pm_ops(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_PmOps::kFieldId, data, size);
+  }
+  void set_pm_ops(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_PmOps::kFieldId, chars.data, chars.size);
+  }
+  void set_pm_ops(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_PmOps::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_Event =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      DevicePmCallbackStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Event kEvent{};
+  void set_event(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Event::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);
+  }
+};
+
+class GpuWorkPeriodFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  GpuWorkPeriodFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GpuWorkPeriodFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GpuWorkPeriodFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_gpu_id() const { return at<1>().valid(); }
+  uint32_t gpu_id() const { return at<1>().as_uint32(); }
+  bool has_uid() const { return at<2>().valid(); }
+  uint32_t uid() const { return at<2>().as_uint32(); }
+  bool has_start_time_ns() const { return at<3>().valid(); }
+  uint64_t start_time_ns() const { return at<3>().as_uint64(); }
+  bool has_end_time_ns() const { return at<4>().valid(); }
+  uint64_t end_time_ns() const { return at<4>().as_uint64(); }
+  bool has_total_active_duration_ns() const { return at<5>().valid(); }
+  uint64_t total_active_duration_ns() const { return at<5>().as_uint64(); }
+};
+
+class GpuWorkPeriodFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = GpuWorkPeriodFtraceEvent_Decoder;
+  enum : int32_t {
+    kGpuIdFieldNumber = 1,
+    kUidFieldNumber = 2,
+    kStartTimeNsFieldNumber = 3,
+    kEndTimeNsFieldNumber = 4,
+    kTotalActiveDurationNsFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GpuWorkPeriodFtraceEvent"; }
+
+
+  using FieldMetadata_GpuId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GpuWorkPeriodFtraceEvent>;
+
+  static constexpr FieldMetadata_GpuId kGpuId{};
+  void set_gpu_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GpuId::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_Uid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GpuWorkPeriodFtraceEvent>;
+
+  static constexpr FieldMetadata_Uid kUid{};
+  void set_uid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Uid::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_StartTimeNs =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuWorkPeriodFtraceEvent>;
+
+  static constexpr FieldMetadata_StartTimeNs kStartTimeNs{};
+  void set_start_time_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StartTimeNs::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_EndTimeNs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuWorkPeriodFtraceEvent>;
+
+  static constexpr FieldMetadata_EndTimeNs kEndTimeNs{};
+  void set_end_time_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EndTimeNs::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_TotalActiveDurationNs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuWorkPeriodFtraceEvent>;
+
+  static constexpr FieldMetadata_TotalActiveDurationNs kTotalActiveDurationNs{};
+  void set_total_active_duration_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TotalActiveDurationNs::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 WakeupSourceDeactivateFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  WakeupSourceDeactivateFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit WakeupSourceDeactivateFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit WakeupSourceDeactivateFtraceEvent_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_state() const { return at<2>().valid(); }
+  uint64_t state() const { return at<2>().as_uint64(); }
+};
+
+class WakeupSourceDeactivateFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = WakeupSourceDeactivateFtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kStateFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.WakeupSourceDeactivateFtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      WakeupSourceDeactivateFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_State =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      WakeupSourceDeactivateFtraceEvent>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::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 WakeupSourceActivateFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  WakeupSourceActivateFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit WakeupSourceActivateFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit WakeupSourceActivateFtraceEvent_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_state() const { return at<2>().valid(); }
+  uint64_t state() const { return at<2>().as_uint64(); }
+};
+
+class WakeupSourceActivateFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = WakeupSourceActivateFtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kStateFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.WakeupSourceActivateFtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      WakeupSourceActivateFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_State =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      WakeupSourceActivateFtraceEvent>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::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 GpuFrequencyFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  GpuFrequencyFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GpuFrequencyFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GpuFrequencyFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_gpu_id() const { return at<1>().valid(); }
+  uint32_t gpu_id() const { return at<1>().as_uint32(); }
+  bool has_state() const { return at<2>().valid(); }
+  uint32_t state() const { return at<2>().as_uint32(); }
+};
+
+class GpuFrequencyFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = GpuFrequencyFtraceEvent_Decoder;
+  enum : int32_t {
+    kGpuIdFieldNumber = 1,
+    kStateFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GpuFrequencyFtraceEvent"; }
+
+
+  using FieldMetadata_GpuId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GpuFrequencyFtraceEvent>;
+
+  static constexpr FieldMetadata_GpuId kGpuId{};
+  void set_gpu_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GpuId::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_State =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GpuFrequencyFtraceEvent>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::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 SuspendResumeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SuspendResumeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SuspendResumeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SuspendResumeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_action() const { return at<1>().valid(); }
+  ::protozero::ConstChars action() const { return at<1>().as_string(); }
+  bool has_val() const { return at<2>().valid(); }
+  int32_t val() const { return at<2>().as_int32(); }
+  bool has_start() const { return at<3>().valid(); }
+  uint32_t start() const { return at<3>().as_uint32(); }
+};
+
+class SuspendResumeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SuspendResumeFtraceEvent_Decoder;
+  enum : int32_t {
+    kActionFieldNumber = 1,
+    kValFieldNumber = 2,
+    kStartFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SuspendResumeFtraceEvent"; }
+
+
+  using FieldMetadata_Action =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SuspendResumeFtraceEvent>;
+
+  static constexpr FieldMetadata_Action kAction{};
+  void set_action(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Action::kFieldId, data, size);
+  }
+  void set_action(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Action::kFieldId, chars.data, chars.size);
+  }
+  void set_action(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Action::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_Val =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SuspendResumeFtraceEvent>;
+
+  static constexpr FieldMetadata_Val kVal{};
+  void set_val(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Val::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_Start =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SuspendResumeFtraceEvent>;
+
+  static constexpr FieldMetadata_Start kStart{};
+  void set_start(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Start::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 ClockSetRateFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ClockSetRateFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ClockSetRateFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ClockSetRateFtraceEvent_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_state() const { return at<2>().valid(); }
+  uint64_t state() const { return at<2>().as_uint64(); }
+  bool has_cpu_id() const { return at<3>().valid(); }
+  uint64_t cpu_id() const { return at<3>().as_uint64(); }
+};
+
+class ClockSetRateFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = ClockSetRateFtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kStateFieldNumber = 2,
+    kCpuIdFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ClockSetRateFtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ClockSetRateFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_State =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ClockSetRateFtraceEvent>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::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_CpuId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ClockSetRateFtraceEvent>;
+
+  static constexpr FieldMetadata_CpuId kCpuId{};
+  void set_cpu_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CpuId::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 ClockDisableFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ClockDisableFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ClockDisableFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ClockDisableFtraceEvent_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_state() const { return at<2>().valid(); }
+  uint64_t state() const { return at<2>().as_uint64(); }
+  bool has_cpu_id() const { return at<3>().valid(); }
+  uint64_t cpu_id() const { return at<3>().as_uint64(); }
+};
+
+class ClockDisableFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = ClockDisableFtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kStateFieldNumber = 2,
+    kCpuIdFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ClockDisableFtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ClockDisableFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_State =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ClockDisableFtraceEvent>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::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_CpuId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ClockDisableFtraceEvent>;
+
+  static constexpr FieldMetadata_CpuId kCpuId{};
+  void set_cpu_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CpuId::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 ClockEnableFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ClockEnableFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ClockEnableFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ClockEnableFtraceEvent_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_state() const { return at<2>().valid(); }
+  uint64_t state() const { return at<2>().as_uint64(); }
+  bool has_cpu_id() const { return at<3>().valid(); }
+  uint64_t cpu_id() const { return at<3>().as_uint64(); }
+};
+
+class ClockEnableFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = ClockEnableFtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kStateFieldNumber = 2,
+    kCpuIdFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ClockEnableFtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ClockEnableFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_State =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ClockEnableFtraceEvent>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::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_CpuId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ClockEnableFtraceEvent>;
+
+  static constexpr FieldMetadata_CpuId kCpuId{};
+  void set_cpu_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CpuId::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 CpuIdleFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CpuIdleFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CpuIdleFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CpuIdleFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_state() const { return at<1>().valid(); }
+  uint32_t state() const { return at<1>().as_uint32(); }
+  bool has_cpu_id() const { return at<2>().valid(); }
+  uint32_t cpu_id() const { return at<2>().as_uint32(); }
+};
+
+class CpuIdleFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CpuIdleFtraceEvent_Decoder;
+  enum : int32_t {
+    kStateFieldNumber = 1,
+    kCpuIdFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CpuIdleFtraceEvent"; }
+
+
+  using FieldMetadata_State =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuIdleFtraceEvent>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::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_CpuId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuIdleFtraceEvent>;
+
+  static constexpr FieldMetadata_CpuId kCpuId{};
+  void set_cpu_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CpuId::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 CpuFrequencyLimitsFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CpuFrequencyLimitsFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CpuFrequencyLimitsFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CpuFrequencyLimitsFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_min_freq() const { return at<1>().valid(); }
+  uint32_t min_freq() const { return at<1>().as_uint32(); }
+  bool has_max_freq() const { return at<2>().valid(); }
+  uint32_t max_freq() const { return at<2>().as_uint32(); }
+  bool has_cpu_id() const { return at<3>().valid(); }
+  uint32_t cpu_id() const { return at<3>().as_uint32(); }
+};
+
+class CpuFrequencyLimitsFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CpuFrequencyLimitsFtraceEvent_Decoder;
+  enum : int32_t {
+    kMinFreqFieldNumber = 1,
+    kMaxFreqFieldNumber = 2,
+    kCpuIdFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CpuFrequencyLimitsFtraceEvent"; }
+
+
+  using FieldMetadata_MinFreq =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuFrequencyLimitsFtraceEvent>;
+
+  static constexpr FieldMetadata_MinFreq kMinFreq{};
+  void set_min_freq(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MinFreq::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_MaxFreq =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuFrequencyLimitsFtraceEvent>;
+
+  static constexpr FieldMetadata_MaxFreq kMaxFreq{};
+  void set_max_freq(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MaxFreq::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_CpuId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuFrequencyLimitsFtraceEvent>;
+
+  static constexpr FieldMetadata_CpuId kCpuId{};
+  void set_cpu_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CpuId::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 CpuFrequencyFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CpuFrequencyFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CpuFrequencyFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CpuFrequencyFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_state() const { return at<1>().valid(); }
+  uint32_t state() const { return at<1>().as_uint32(); }
+  bool has_cpu_id() const { return at<2>().valid(); }
+  uint32_t cpu_id() const { return at<2>().as_uint32(); }
+};
+
+class CpuFrequencyFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CpuFrequencyFtraceEvent_Decoder;
+  enum : int32_t {
+    kStateFieldNumber = 1,
+    kCpuIdFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CpuFrequencyFtraceEvent"; }
+
+
+  using FieldMetadata_State =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuFrequencyFtraceEvent>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::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_CpuId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuFrequencyFtraceEvent>;
+
+  static constexpr FieldMetadata_CpuId kCpuId{};
+  void set_cpu_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CpuId::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/printk.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_PRINTK_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_PRINTK_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class ConsoleFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ConsoleFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ConsoleFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ConsoleFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_msg() const { return at<1>().valid(); }
+  ::protozero::ConstChars msg() const { return at<1>().as_string(); }
+};
+
+class ConsoleFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = ConsoleFtraceEvent_Decoder;
+  enum : int32_t {
+    kMsgFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ConsoleFtraceEvent"; }
+
+
+  using FieldMetadata_Msg =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ConsoleFtraceEvent>;
+
+  static constexpr FieldMetadata_Msg kMsg{};
+  void set_msg(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Msg::kFieldId, data, size);
+  }
+  void set_msg(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Msg::kFieldId, chars.data, chars.size);
+  }
+  void set_msg(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Msg::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/raw_syscalls.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_RAW_SYSCALLS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_RAW_SYSCALLS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class SysExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SysExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SysExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SysExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  int64_t id() const { return at<1>().as_int64(); }
+  bool has_ret() const { return at<2>().valid(); }
+  int64_t ret() const { return at<2>().as_int64(); }
+};
+
+class SysExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SysExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kRetFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SysExitFtraceEvent"; }
+
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      SysExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::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_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      SysExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::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 SysEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  SysEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SysEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SysEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  int64_t id() const { return at<1>().as_int64(); }
+  bool has_args() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> args() const { return GetRepeated<uint64_t>(2); }
+};
+
+class SysEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SysEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kArgsFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SysEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      SysEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::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_Args =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Args kArgs{};
+  void add_args(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Args::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/regulator.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_REGULATOR_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_REGULATOR_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class RegulatorSetVoltageCompleteFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  RegulatorSetVoltageCompleteFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit RegulatorSetVoltageCompleteFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit RegulatorSetVoltageCompleteFtraceEvent_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_val() const { return at<2>().valid(); }
+  uint32_t val() const { return at<2>().as_uint32(); }
+};
+
+class RegulatorSetVoltageCompleteFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = RegulatorSetVoltageCompleteFtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kValFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.RegulatorSetVoltageCompleteFtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      RegulatorSetVoltageCompleteFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Val =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      RegulatorSetVoltageCompleteFtraceEvent>;
+
+  static constexpr FieldMetadata_Val kVal{};
+  void set_val(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Val::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 RegulatorSetVoltageFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  RegulatorSetVoltageFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit RegulatorSetVoltageFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit RegulatorSetVoltageFtraceEvent_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_min() const { return at<2>().valid(); }
+  int32_t min() const { return at<2>().as_int32(); }
+  bool has_max() const { return at<3>().valid(); }
+  int32_t max() const { return at<3>().as_int32(); }
+};
+
+class RegulatorSetVoltageFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = RegulatorSetVoltageFtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kMinFieldNumber = 2,
+    kMaxFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.RegulatorSetVoltageFtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      RegulatorSetVoltageFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Min =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      RegulatorSetVoltageFtraceEvent>;
+
+  static constexpr FieldMetadata_Min kMin{};
+  void set_min(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Min::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_Max =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      RegulatorSetVoltageFtraceEvent>;
+
+  static constexpr FieldMetadata_Max kMax{};
+  void set_max(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Max::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);
+  }
+};
+
+class RegulatorEnableDelayFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  RegulatorEnableDelayFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit RegulatorEnableDelayFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit RegulatorEnableDelayFtraceEvent_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(); }
+};
+
+class RegulatorEnableDelayFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = RegulatorEnableDelayFtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.RegulatorEnableDelayFtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      RegulatorEnableDelayFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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);
+  }
+};
+
+class RegulatorEnableCompleteFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  RegulatorEnableCompleteFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit RegulatorEnableCompleteFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit RegulatorEnableCompleteFtraceEvent_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(); }
+};
+
+class RegulatorEnableCompleteFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = RegulatorEnableCompleteFtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.RegulatorEnableCompleteFtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      RegulatorEnableCompleteFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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);
+  }
+};
+
+class RegulatorEnableFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  RegulatorEnableFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit RegulatorEnableFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit RegulatorEnableFtraceEvent_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(); }
+};
+
+class RegulatorEnableFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = RegulatorEnableFtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.RegulatorEnableFtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      RegulatorEnableFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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);
+  }
+};
+
+class RegulatorDisableCompleteFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  RegulatorDisableCompleteFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit RegulatorDisableCompleteFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit RegulatorDisableCompleteFtraceEvent_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(); }
+};
+
+class RegulatorDisableCompleteFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = RegulatorDisableCompleteFtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.RegulatorDisableCompleteFtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      RegulatorDisableCompleteFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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);
+  }
+};
+
+class RegulatorDisableFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  RegulatorDisableFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit RegulatorDisableFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit RegulatorDisableFtraceEvent_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(); }
+};
+
+class RegulatorDisableFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = RegulatorDisableFtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.RegulatorDisableFtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      RegulatorDisableFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/rpm.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_RPM_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_RPM_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class RpmStatusFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  RpmStatusFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit RpmStatusFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit RpmStatusFtraceEvent_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_status() const { return at<2>().valid(); }
+  int32_t status() const { return at<2>().as_int32(); }
+};
+
+class RpmStatusFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = RpmStatusFtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kStatusFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.RpmStatusFtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      RpmStatusFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Status =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      RpmStatusFtraceEvent>;
+
+  static constexpr FieldMetadata_Status kStatus{};
+  void set_status(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Status::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/samsung.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SAMSUNG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SAMSUNG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class SamsungTracingMarkWriteFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SamsungTracingMarkWriteFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SamsungTracingMarkWriteFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SamsungTracingMarkWriteFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  int32_t pid() const { return at<1>().as_int32(); }
+  bool has_trace_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars trace_name() const { return at<2>().as_string(); }
+  bool has_trace_begin() const { return at<3>().valid(); }
+  uint32_t trace_begin() const { return at<3>().as_uint32(); }
+  bool has_trace_type() const { return at<4>().valid(); }
+  uint32_t trace_type() const { return at<4>().as_uint32(); }
+  bool has_value() const { return at<5>().valid(); }
+  int32_t value() const { return at<5>().as_int32(); }
+};
+
+class SamsungTracingMarkWriteFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SamsungTracingMarkWriteFtraceEvent_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kTraceNameFieldNumber = 2,
+    kTraceBeginFieldNumber = 3,
+    kTraceTypeFieldNumber = 4,
+    kValueFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SamsungTracingMarkWriteFtraceEvent"; }
+
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SamsungTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_TraceName =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SamsungTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_TraceName kTraceName{};
+  void set_trace_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TraceName::kFieldId, data, size);
+  }
+  void set_trace_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_TraceName::kFieldId, chars.data, chars.size);
+  }
+  void set_trace_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_TraceName::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_TraceBegin =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SamsungTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_TraceBegin kTraceBegin{};
+  void set_trace_begin(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TraceBegin::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_TraceType =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SamsungTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_TraceType kTraceType{};
+  void set_trace_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TraceType::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_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SamsungTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/sched.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SCHED_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SCHED_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class SchedMigrateTaskFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SchedMigrateTaskFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SchedMigrateTaskFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SchedMigrateTaskFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_comm() const { return at<1>().valid(); }
+  ::protozero::ConstChars comm() const { return at<1>().as_string(); }
+  bool has_pid() const { return at<2>().valid(); }
+  int32_t pid() const { return at<2>().as_int32(); }
+  bool has_prio() const { return at<3>().valid(); }
+  int32_t prio() const { return at<3>().as_int32(); }
+  bool has_orig_cpu() const { return at<4>().valid(); }
+  int32_t orig_cpu() const { return at<4>().as_int32(); }
+  bool has_dest_cpu() const { return at<5>().valid(); }
+  int32_t dest_cpu() const { return at<5>().as_int32(); }
+  bool has_running() const { return at<6>().valid(); }
+  int32_t running() const { return at<6>().as_int32(); }
+  bool has_load() const { return at<7>().valid(); }
+  uint32_t load() const { return at<7>().as_uint32(); }
+};
+
+class SchedMigrateTaskFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SchedMigrateTaskFtraceEvent_Decoder;
+  enum : int32_t {
+    kCommFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kPrioFieldNumber = 3,
+    kOrigCpuFieldNumber = 4,
+    kDestCpuFieldNumber = 5,
+    kRunningFieldNumber = 6,
+    kLoadFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SchedMigrateTaskFtraceEvent"; }
+
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedMigrateTaskFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedMigrateTaskFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_Prio =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedMigrateTaskFtraceEvent>;
+
+  static constexpr FieldMetadata_Prio kPrio{};
+  void set_prio(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Prio::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_OrigCpu =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedMigrateTaskFtraceEvent>;
+
+  static constexpr FieldMetadata_OrigCpu kOrigCpu{};
+  void set_orig_cpu(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OrigCpu::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_DestCpu =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedMigrateTaskFtraceEvent>;
+
+  static constexpr FieldMetadata_DestCpu kDestCpu{};
+  void set_dest_cpu(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DestCpu::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_Running =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedMigrateTaskFtraceEvent>;
+
+  static constexpr FieldMetadata_Running kRunning{};
+  void set_running(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Running::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_Load =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedMigrateTaskFtraceEvent>;
+
+  static constexpr FieldMetadata_Load kLoad{};
+  void set_load(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Load::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 SchedCpuUtilCfsFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/15, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SchedCpuUtilCfsFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SchedCpuUtilCfsFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SchedCpuUtilCfsFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_active() const { return at<1>().valid(); }
+  int32_t active() const { return at<1>().as_int32(); }
+  bool has_capacity() const { return at<2>().valid(); }
+  uint64_t capacity() const { return at<2>().as_uint64(); }
+  bool has_capacity_orig() const { return at<3>().valid(); }
+  uint64_t capacity_orig() const { return at<3>().as_uint64(); }
+  bool has_cpu() const { return at<4>().valid(); }
+  uint32_t cpu() const { return at<4>().as_uint32(); }
+  bool has_cpu_importance() const { return at<5>().valid(); }
+  uint64_t cpu_importance() const { return at<5>().as_uint64(); }
+  bool has_cpu_util() const { return at<6>().valid(); }
+  uint64_t cpu_util() const { return at<6>().as_uint64(); }
+  bool has_exit_lat() const { return at<7>().valid(); }
+  uint32_t exit_lat() const { return at<7>().as_uint32(); }
+  bool has_group_capacity() const { return at<8>().valid(); }
+  uint64_t group_capacity() const { return at<8>().as_uint64(); }
+  bool has_grp_overutilized() const { return at<9>().valid(); }
+  uint32_t grp_overutilized() const { return at<9>().as_uint32(); }
+  bool has_idle_cpu() const { return at<10>().valid(); }
+  uint32_t idle_cpu() const { return at<10>().as_uint32(); }
+  bool has_nr_running() const { return at<11>().valid(); }
+  uint32_t nr_running() const { return at<11>().as_uint32(); }
+  bool has_spare_cap() const { return at<12>().valid(); }
+  int64_t spare_cap() const { return at<12>().as_int64(); }
+  bool has_task_fits() const { return at<13>().valid(); }
+  uint32_t task_fits() const { return at<13>().as_uint32(); }
+  bool has_wake_group_util() const { return at<14>().valid(); }
+  uint64_t wake_group_util() const { return at<14>().as_uint64(); }
+  bool has_wake_util() const { return at<15>().valid(); }
+  uint64_t wake_util() const { return at<15>().as_uint64(); }
+};
+
+class SchedCpuUtilCfsFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SchedCpuUtilCfsFtraceEvent_Decoder;
+  enum : int32_t {
+    kActiveFieldNumber = 1,
+    kCapacityFieldNumber = 2,
+    kCapacityOrigFieldNumber = 3,
+    kCpuFieldNumber = 4,
+    kCpuImportanceFieldNumber = 5,
+    kCpuUtilFieldNumber = 6,
+    kExitLatFieldNumber = 7,
+    kGroupCapacityFieldNumber = 8,
+    kGrpOverutilizedFieldNumber = 9,
+    kIdleCpuFieldNumber = 10,
+    kNrRunningFieldNumber = 11,
+    kSpareCapFieldNumber = 12,
+    kTaskFitsFieldNumber = 13,
+    kWakeGroupUtilFieldNumber = 14,
+    kWakeUtilFieldNumber = 15,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SchedCpuUtilCfsFtraceEvent"; }
+
+
+  using FieldMetadata_Active =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedCpuUtilCfsFtraceEvent>;
+
+  static constexpr FieldMetadata_Active kActive{};
+  void set_active(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Active::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_Capacity =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SchedCpuUtilCfsFtraceEvent>;
+
+  static constexpr FieldMetadata_Capacity kCapacity{};
+  void set_capacity(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Capacity::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_CapacityOrig =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SchedCpuUtilCfsFtraceEvent>;
+
+  static constexpr FieldMetadata_CapacityOrig kCapacityOrig{};
+  void set_capacity_orig(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CapacityOrig::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_Cpu =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedCpuUtilCfsFtraceEvent>;
+
+  static constexpr FieldMetadata_Cpu kCpu{};
+  void set_cpu(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cpu::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_CpuImportance =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SchedCpuUtilCfsFtraceEvent>;
+
+  static constexpr FieldMetadata_CpuImportance kCpuImportance{};
+  void set_cpu_importance(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CpuImportance::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_CpuUtil =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SchedCpuUtilCfsFtraceEvent>;
+
+  static constexpr FieldMetadata_CpuUtil kCpuUtil{};
+  void set_cpu_util(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CpuUtil::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_ExitLat =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedCpuUtilCfsFtraceEvent>;
+
+  static constexpr FieldMetadata_ExitLat kExitLat{};
+  void set_exit_lat(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ExitLat::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_GroupCapacity =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SchedCpuUtilCfsFtraceEvent>;
+
+  static constexpr FieldMetadata_GroupCapacity kGroupCapacity{};
+  void set_group_capacity(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GroupCapacity::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_GrpOverutilized =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedCpuUtilCfsFtraceEvent>;
+
+  static constexpr FieldMetadata_GrpOverutilized kGrpOverutilized{};
+  void set_grp_overutilized(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GrpOverutilized::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_IdleCpu =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedCpuUtilCfsFtraceEvent>;
+
+  static constexpr FieldMetadata_IdleCpu kIdleCpu{};
+  void set_idle_cpu(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IdleCpu::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_NrRunning =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedCpuUtilCfsFtraceEvent>;
+
+  static constexpr FieldMetadata_NrRunning kNrRunning{};
+  void set_nr_running(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrRunning::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_SpareCap =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      SchedCpuUtilCfsFtraceEvent>;
+
+  static constexpr FieldMetadata_SpareCap kSpareCap{};
+  void set_spare_cap(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SpareCap::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_TaskFits =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedCpuUtilCfsFtraceEvent>;
+
+  static constexpr FieldMetadata_TaskFits kTaskFits{};
+  void set_task_fits(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TaskFits::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_WakeGroupUtil =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SchedCpuUtilCfsFtraceEvent>;
+
+  static constexpr FieldMetadata_WakeGroupUtil kWakeGroupUtil{};
+  void set_wake_group_util(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_WakeGroupUtil::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_WakeUtil =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SchedCpuUtilCfsFtraceEvent>;
+
+  static constexpr FieldMetadata_WakeUtil kWakeUtil{};
+  void set_wake_util(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_WakeUtil::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 SchedPiSetprioFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SchedPiSetprioFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SchedPiSetprioFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SchedPiSetprioFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_comm() const { return at<1>().valid(); }
+  ::protozero::ConstChars comm() const { return at<1>().as_string(); }
+  bool has_newprio() const { return at<2>().valid(); }
+  int32_t newprio() const { return at<2>().as_int32(); }
+  bool has_oldprio() const { return at<3>().valid(); }
+  int32_t oldprio() const { return at<3>().as_int32(); }
+  bool has_pid() const { return at<4>().valid(); }
+  int32_t pid() const { return at<4>().as_int32(); }
+};
+
+class SchedPiSetprioFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SchedPiSetprioFtraceEvent_Decoder;
+  enum : int32_t {
+    kCommFieldNumber = 1,
+    kNewprioFieldNumber = 2,
+    kOldprioFieldNumber = 3,
+    kPidFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SchedPiSetprioFtraceEvent"; }
+
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedPiSetprioFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::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_Newprio =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedPiSetprioFtraceEvent>;
+
+  static constexpr FieldMetadata_Newprio kNewprio{};
+  void set_newprio(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Newprio::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_Oldprio =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedPiSetprioFtraceEvent>;
+
+  static constexpr FieldMetadata_Oldprio kOldprio{};
+  void set_oldprio(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Oldprio::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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedPiSetprioFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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);
+  }
+};
+
+class SchedProcessWaitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SchedProcessWaitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SchedProcessWaitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SchedProcessWaitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_comm() const { return at<1>().valid(); }
+  ::protozero::ConstChars comm() const { return at<1>().as_string(); }
+  bool has_pid() const { return at<2>().valid(); }
+  int32_t pid() const { return at<2>().as_int32(); }
+  bool has_prio() const { return at<3>().valid(); }
+  int32_t prio() const { return at<3>().as_int32(); }
+};
+
+class SchedProcessWaitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SchedProcessWaitFtraceEvent_Decoder;
+  enum : int32_t {
+    kCommFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kPrioFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SchedProcessWaitFtraceEvent"; }
+
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedProcessWaitFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedProcessWaitFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_Prio =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedProcessWaitFtraceEvent>;
+
+  static constexpr FieldMetadata_Prio kPrio{};
+  void set_prio(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Prio::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);
+  }
+};
+
+class SchedProcessHangFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SchedProcessHangFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SchedProcessHangFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SchedProcessHangFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_comm() const { return at<1>().valid(); }
+  ::protozero::ConstChars comm() const { return at<1>().as_string(); }
+  bool has_pid() const { return at<2>().valid(); }
+  int32_t pid() const { return at<2>().as_int32(); }
+};
+
+class SchedProcessHangFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SchedProcessHangFtraceEvent_Decoder;
+  enum : int32_t {
+    kCommFieldNumber = 1,
+    kPidFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SchedProcessHangFtraceEvent"; }
+
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedProcessHangFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedProcessHangFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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);
+  }
+};
+
+class SchedProcessFreeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SchedProcessFreeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SchedProcessFreeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SchedProcessFreeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_comm() const { return at<1>().valid(); }
+  ::protozero::ConstChars comm() const { return at<1>().as_string(); }
+  bool has_pid() const { return at<2>().valid(); }
+  int32_t pid() const { return at<2>().as_int32(); }
+  bool has_prio() const { return at<3>().valid(); }
+  int32_t prio() const { return at<3>().as_int32(); }
+};
+
+class SchedProcessFreeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SchedProcessFreeFtraceEvent_Decoder;
+  enum : int32_t {
+    kCommFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kPrioFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SchedProcessFreeFtraceEvent"; }
+
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedProcessFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedProcessFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_Prio =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedProcessFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_Prio kPrio{};
+  void set_prio(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Prio::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);
+  }
+};
+
+class SchedProcessForkFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SchedProcessForkFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SchedProcessForkFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SchedProcessForkFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_parent_comm() const { return at<1>().valid(); }
+  ::protozero::ConstChars parent_comm() const { return at<1>().as_string(); }
+  bool has_parent_pid() const { return at<2>().valid(); }
+  int32_t parent_pid() const { return at<2>().as_int32(); }
+  bool has_child_comm() const { return at<3>().valid(); }
+  ::protozero::ConstChars child_comm() const { return at<3>().as_string(); }
+  bool has_child_pid() const { return at<4>().valid(); }
+  int32_t child_pid() const { return at<4>().as_int32(); }
+};
+
+class SchedProcessForkFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SchedProcessForkFtraceEvent_Decoder;
+  enum : int32_t {
+    kParentCommFieldNumber = 1,
+    kParentPidFieldNumber = 2,
+    kChildCommFieldNumber = 3,
+    kChildPidFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SchedProcessForkFtraceEvent"; }
+
+
+  using FieldMetadata_ParentComm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedProcessForkFtraceEvent>;
+
+  static constexpr FieldMetadata_ParentComm kParentComm{};
+  void set_parent_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ParentComm::kFieldId, data, size);
+  }
+  void set_parent_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ParentComm::kFieldId, chars.data, chars.size);
+  }
+  void set_parent_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ParentComm::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_ParentPid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedProcessForkFtraceEvent>;
+
+  static constexpr FieldMetadata_ParentPid kParentPid{};
+  void set_parent_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ParentPid::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_ChildComm =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedProcessForkFtraceEvent>;
+
+  static constexpr FieldMetadata_ChildComm kChildComm{};
+  void set_child_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ChildComm::kFieldId, data, size);
+  }
+  void set_child_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ChildComm::kFieldId, chars.data, chars.size);
+  }
+  void set_child_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChildComm::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_ChildPid =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedProcessForkFtraceEvent>;
+
+  static constexpr FieldMetadata_ChildPid kChildPid{};
+  void set_child_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChildPid::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);
+  }
+};
+
+class SchedProcessExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SchedProcessExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SchedProcessExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SchedProcessExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_comm() const { return at<1>().valid(); }
+  ::protozero::ConstChars comm() const { return at<1>().as_string(); }
+  bool has_pid() const { return at<2>().valid(); }
+  int32_t pid() const { return at<2>().as_int32(); }
+  bool has_tgid() const { return at<3>().valid(); }
+  int32_t tgid() const { return at<3>().as_int32(); }
+  bool has_prio() const { return at<4>().valid(); }
+  int32_t prio() const { return at<4>().as_int32(); }
+};
+
+class SchedProcessExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SchedProcessExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kCommFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kTgidFieldNumber = 3,
+    kPrioFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SchedProcessExitFtraceEvent"; }
+
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedProcessExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedProcessExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_Tgid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedProcessExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Tgid kTgid{};
+  void set_tgid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tgid::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_Prio =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedProcessExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Prio kPrio{};
+  void set_prio(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Prio::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);
+  }
+};
+
+class SchedProcessExecFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SchedProcessExecFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SchedProcessExecFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SchedProcessExecFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_filename() const { return at<1>().valid(); }
+  ::protozero::ConstChars filename() const { return at<1>().as_string(); }
+  bool has_pid() const { return at<2>().valid(); }
+  int32_t pid() const { return at<2>().as_int32(); }
+  bool has_old_pid() const { return at<3>().valid(); }
+  int32_t old_pid() const { return at<3>().as_int32(); }
+};
+
+class SchedProcessExecFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SchedProcessExecFtraceEvent_Decoder;
+  enum : int32_t {
+    kFilenameFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kOldPidFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SchedProcessExecFtraceEvent"; }
+
+
+  using FieldMetadata_Filename =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedProcessExecFtraceEvent>;
+
+  static constexpr FieldMetadata_Filename kFilename{};
+  void set_filename(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Filename::kFieldId, data, size);
+  }
+  void set_filename(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Filename::kFieldId, chars.data, chars.size);
+  }
+  void set_filename(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Filename::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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedProcessExecFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_OldPid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedProcessExecFtraceEvent>;
+
+  static constexpr FieldMetadata_OldPid kOldPid{};
+  void set_old_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OldPid::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);
+  }
+};
+
+class SchedWakeupNewFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SchedWakeupNewFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SchedWakeupNewFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SchedWakeupNewFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_comm() const { return at<1>().valid(); }
+  ::protozero::ConstChars comm() const { return at<1>().as_string(); }
+  bool has_pid() const { return at<2>().valid(); }
+  int32_t pid() const { return at<2>().as_int32(); }
+  bool has_prio() const { return at<3>().valid(); }
+  int32_t prio() const { return at<3>().as_int32(); }
+  bool has_success() const { return at<4>().valid(); }
+  int32_t success() const { return at<4>().as_int32(); }
+  bool has_target_cpu() const { return at<5>().valid(); }
+  int32_t target_cpu() const { return at<5>().as_int32(); }
+};
+
+class SchedWakeupNewFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SchedWakeupNewFtraceEvent_Decoder;
+  enum : int32_t {
+    kCommFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kPrioFieldNumber = 3,
+    kSuccessFieldNumber = 4,
+    kTargetCpuFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SchedWakeupNewFtraceEvent"; }
+
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedWakeupNewFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedWakeupNewFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_Prio =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedWakeupNewFtraceEvent>;
+
+  static constexpr FieldMetadata_Prio kPrio{};
+  void set_prio(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Prio::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_Success =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedWakeupNewFtraceEvent>;
+
+  static constexpr FieldMetadata_Success kSuccess{};
+  void set_success(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Success::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_TargetCpu =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedWakeupNewFtraceEvent>;
+
+  static constexpr FieldMetadata_TargetCpu kTargetCpu{};
+  void set_target_cpu(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TargetCpu::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);
+  }
+};
+
+class SchedWakingFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SchedWakingFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SchedWakingFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SchedWakingFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_comm() const { return at<1>().valid(); }
+  ::protozero::ConstChars comm() const { return at<1>().as_string(); }
+  bool has_pid() const { return at<2>().valid(); }
+  int32_t pid() const { return at<2>().as_int32(); }
+  bool has_prio() const { return at<3>().valid(); }
+  int32_t prio() const { return at<3>().as_int32(); }
+  bool has_success() const { return at<4>().valid(); }
+  int32_t success() const { return at<4>().as_int32(); }
+  bool has_target_cpu() const { return at<5>().valid(); }
+  int32_t target_cpu() const { return at<5>().as_int32(); }
+};
+
+class SchedWakingFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SchedWakingFtraceEvent_Decoder;
+  enum : int32_t {
+    kCommFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kPrioFieldNumber = 3,
+    kSuccessFieldNumber = 4,
+    kTargetCpuFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SchedWakingFtraceEvent"; }
+
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedWakingFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedWakingFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_Prio =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedWakingFtraceEvent>;
+
+  static constexpr FieldMetadata_Prio kPrio{};
+  void set_prio(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Prio::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_Success =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedWakingFtraceEvent>;
+
+  static constexpr FieldMetadata_Success kSuccess{};
+  void set_success(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Success::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_TargetCpu =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedWakingFtraceEvent>;
+
+  static constexpr FieldMetadata_TargetCpu kTargetCpu{};
+  void set_target_cpu(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TargetCpu::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);
+  }
+};
+
+class SchedCpuHotplugFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SchedCpuHotplugFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SchedCpuHotplugFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SchedCpuHotplugFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_affected_cpu() const { return at<1>().valid(); }
+  int32_t affected_cpu() const { return at<1>().as_int32(); }
+  bool has_error() const { return at<2>().valid(); }
+  int32_t error() const { return at<2>().as_int32(); }
+  bool has_status() const { return at<3>().valid(); }
+  int32_t status() const { return at<3>().as_int32(); }
+};
+
+class SchedCpuHotplugFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SchedCpuHotplugFtraceEvent_Decoder;
+  enum : int32_t {
+    kAffectedCpuFieldNumber = 1,
+    kErrorFieldNumber = 2,
+    kStatusFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SchedCpuHotplugFtraceEvent"; }
+
+
+  using FieldMetadata_AffectedCpu =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedCpuHotplugFtraceEvent>;
+
+  static constexpr FieldMetadata_AffectedCpu kAffectedCpu{};
+  void set_affected_cpu(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AffectedCpu::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_Error =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedCpuHotplugFtraceEvent>;
+
+  static constexpr FieldMetadata_Error kError{};
+  void set_error(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Error::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_Status =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedCpuHotplugFtraceEvent>;
+
+  static constexpr FieldMetadata_Status kStatus{};
+  void set_status(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Status::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);
+  }
+};
+
+class SchedBlockedReasonFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SchedBlockedReasonFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SchedBlockedReasonFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SchedBlockedReasonFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  int32_t pid() const { return at<1>().as_int32(); }
+  bool has_caller() const { return at<2>().valid(); }
+  uint64_t caller() const { return at<2>().as_uint64(); }
+  bool has_io_wait() const { return at<3>().valid(); }
+  uint32_t io_wait() const { return at<3>().as_uint32(); }
+};
+
+class SchedBlockedReasonFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SchedBlockedReasonFtraceEvent_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kCallerFieldNumber = 2,
+    kIoWaitFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SchedBlockedReasonFtraceEvent"; }
+
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedBlockedReasonFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_Caller =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SchedBlockedReasonFtraceEvent>;
+
+  static constexpr FieldMetadata_Caller kCaller{};
+  void set_caller(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Caller::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_IoWait =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedBlockedReasonFtraceEvent>;
+
+  static constexpr FieldMetadata_IoWait kIoWait{};
+  void set_io_wait(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IoWait::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 SchedWakeupFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SchedWakeupFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SchedWakeupFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SchedWakeupFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_comm() const { return at<1>().valid(); }
+  ::protozero::ConstChars comm() const { return at<1>().as_string(); }
+  bool has_pid() const { return at<2>().valid(); }
+  int32_t pid() const { return at<2>().as_int32(); }
+  bool has_prio() const { return at<3>().valid(); }
+  int32_t prio() const { return at<3>().as_int32(); }
+  bool has_success() const { return at<4>().valid(); }
+  int32_t success() const { return at<4>().as_int32(); }
+  bool has_target_cpu() const { return at<5>().valid(); }
+  int32_t target_cpu() const { return at<5>().as_int32(); }
+};
+
+class SchedWakeupFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SchedWakeupFtraceEvent_Decoder;
+  enum : int32_t {
+    kCommFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kPrioFieldNumber = 3,
+    kSuccessFieldNumber = 4,
+    kTargetCpuFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SchedWakeupFtraceEvent"; }
+
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedWakeupFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedWakeupFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_Prio =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedWakeupFtraceEvent>;
+
+  static constexpr FieldMetadata_Prio kPrio{};
+  void set_prio(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Prio::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_Success =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedWakeupFtraceEvent>;
+
+  static constexpr FieldMetadata_Success kSuccess{};
+  void set_success(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Success::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_TargetCpu =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedWakeupFtraceEvent>;
+
+  static constexpr FieldMetadata_TargetCpu kTargetCpu{};
+  void set_target_cpu(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TargetCpu::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);
+  }
+};
+
+class SchedSwitchFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SchedSwitchFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SchedSwitchFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SchedSwitchFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_prev_comm() const { return at<1>().valid(); }
+  ::protozero::ConstChars prev_comm() const { return at<1>().as_string(); }
+  bool has_prev_pid() const { return at<2>().valid(); }
+  int32_t prev_pid() const { return at<2>().as_int32(); }
+  bool has_prev_prio() const { return at<3>().valid(); }
+  int32_t prev_prio() const { return at<3>().as_int32(); }
+  bool has_prev_state() const { return at<4>().valid(); }
+  int64_t prev_state() const { return at<4>().as_int64(); }
+  bool has_next_comm() const { return at<5>().valid(); }
+  ::protozero::ConstChars next_comm() const { return at<5>().as_string(); }
+  bool has_next_pid() const { return at<6>().valid(); }
+  int32_t next_pid() const { return at<6>().as_int32(); }
+  bool has_next_prio() const { return at<7>().valid(); }
+  int32_t next_prio() const { return at<7>().as_int32(); }
+};
+
+class SchedSwitchFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SchedSwitchFtraceEvent_Decoder;
+  enum : int32_t {
+    kPrevCommFieldNumber = 1,
+    kPrevPidFieldNumber = 2,
+    kPrevPrioFieldNumber = 3,
+    kPrevStateFieldNumber = 4,
+    kNextCommFieldNumber = 5,
+    kNextPidFieldNumber = 6,
+    kNextPrioFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SchedSwitchFtraceEvent"; }
+
+
+  using FieldMetadata_PrevComm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedSwitchFtraceEvent>;
+
+  static constexpr FieldMetadata_PrevComm kPrevComm{};
+  void set_prev_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_PrevComm::kFieldId, data, size);
+  }
+  void set_prev_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_PrevComm::kFieldId, chars.data, chars.size);
+  }
+  void set_prev_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_PrevComm::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_PrevPid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedSwitchFtraceEvent>;
+
+  static constexpr FieldMetadata_PrevPid kPrevPid{};
+  void set_prev_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PrevPid::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_PrevPrio =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedSwitchFtraceEvent>;
+
+  static constexpr FieldMetadata_PrevPrio kPrevPrio{};
+  void set_prev_prio(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PrevPrio::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_PrevState =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      SchedSwitchFtraceEvent>;
+
+  static constexpr FieldMetadata_PrevState kPrevState{};
+  void set_prev_state(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PrevState::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_NextComm =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedSwitchFtraceEvent>;
+
+  static constexpr FieldMetadata_NextComm kNextComm{};
+  void set_next_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_NextComm::kFieldId, data, size);
+  }
+  void set_next_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_NextComm::kFieldId, chars.data, chars.size);
+  }
+  void set_next_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_NextComm::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_NextPid =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedSwitchFtraceEvent>;
+
+  static constexpr FieldMetadata_NextPid kNextPid{};
+  void set_next_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NextPid::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_NextPrio =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedSwitchFtraceEvent>;
+
+  static constexpr FieldMetadata_NextPrio kNextPrio{};
+  void set_next_prio(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NextPrio::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/scm.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SCM_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SCM_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class ScmCallEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/0, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ScmCallEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ScmCallEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ScmCallEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+};
+
+class ScmCallEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = ScmCallEndFtraceEvent_Decoder;
+  static constexpr const char* GetName() { return ".perfetto.protos.ScmCallEndFtraceEvent"; }
+
+};
+
+class ScmCallStartFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ScmCallStartFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ScmCallStartFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ScmCallStartFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_arginfo() const { return at<1>().valid(); }
+  uint32_t arginfo() const { return at<1>().as_uint32(); }
+  bool has_x0() const { return at<2>().valid(); }
+  uint64_t x0() const { return at<2>().as_uint64(); }
+  bool has_x5() const { return at<3>().valid(); }
+  uint64_t x5() const { return at<3>().as_uint64(); }
+};
+
+class ScmCallStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = ScmCallStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kArginfoFieldNumber = 1,
+    kX0FieldNumber = 2,
+    kX5FieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ScmCallStartFtraceEvent"; }
+
+
+  using FieldMetadata_Arginfo =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ScmCallStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Arginfo kArginfo{};
+  void set_arginfo(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Arginfo::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_X0 =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ScmCallStartFtraceEvent>;
+
+  static constexpr FieldMetadata_X0 kX0{};
+  void set_x0(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_X0::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_X5 =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ScmCallStartFtraceEvent>;
+
+  static constexpr FieldMetadata_X5 kX5{};
+  void set_x5(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_X5::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/sde.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SDE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SDE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class SdeSdePerfUpdateBusFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SdeSdePerfUpdateBusFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SdeSdePerfUpdateBusFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SdeSdePerfUpdateBusFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ab_quota() const { return at<1>().valid(); }
+  uint64_t ab_quota() const { return at<1>().as_uint64(); }
+  bool has_bus_id() const { return at<2>().valid(); }
+  uint32_t bus_id() const { return at<2>().as_uint32(); }
+  bool has_client() const { return at<3>().valid(); }
+  int32_t client() const { return at<3>().as_int32(); }
+  bool has_ib_quota() const { return at<4>().valid(); }
+  uint64_t ib_quota() const { return at<4>().as_uint64(); }
+};
+
+class SdeSdePerfUpdateBusFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SdeSdePerfUpdateBusFtraceEvent_Decoder;
+  enum : int32_t {
+    kAbQuotaFieldNumber = 1,
+    kBusIdFieldNumber = 2,
+    kClientFieldNumber = 3,
+    kIbQuotaFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SdeSdePerfUpdateBusFtraceEvent"; }
+
+
+  using FieldMetadata_AbQuota =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SdeSdePerfUpdateBusFtraceEvent>;
+
+  static constexpr FieldMetadata_AbQuota kAbQuota{};
+  void set_ab_quota(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AbQuota::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_BusId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SdeSdePerfUpdateBusFtraceEvent>;
+
+  static constexpr FieldMetadata_BusId kBusId{};
+  void set_bus_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BusId::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_Client =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SdeSdePerfUpdateBusFtraceEvent>;
+
+  static constexpr FieldMetadata_Client kClient{};
+  void set_client(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Client::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_IbQuota =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SdeSdePerfUpdateBusFtraceEvent>;
+
+  static constexpr FieldMetadata_IbQuota kIbQuota{};
+  void set_ib_quota(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IbQuota::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 SdeSdePerfSetQosLutsFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SdeSdePerfSetQosLutsFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SdeSdePerfSetQosLutsFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SdeSdePerfSetQosLutsFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_fl() const { return at<1>().valid(); }
+  uint32_t fl() const { return at<1>().as_uint32(); }
+  bool has_fmt() const { return at<2>().valid(); }
+  uint32_t fmt() const { return at<2>().as_uint32(); }
+  bool has_lut() const { return at<3>().valid(); }
+  uint64_t lut() const { return at<3>().as_uint64(); }
+  bool has_lut_usage() const { return at<4>().valid(); }
+  uint32_t lut_usage() const { return at<4>().as_uint32(); }
+  bool has_pnum() const { return at<5>().valid(); }
+  uint32_t pnum() const { return at<5>().as_uint32(); }
+  bool has_rt() const { return at<6>().valid(); }
+  uint32_t rt() const { return at<6>().as_uint32(); }
+};
+
+class SdeSdePerfSetQosLutsFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SdeSdePerfSetQosLutsFtraceEvent_Decoder;
+  enum : int32_t {
+    kFlFieldNumber = 1,
+    kFmtFieldNumber = 2,
+    kLutFieldNumber = 3,
+    kLutUsageFieldNumber = 4,
+    kPnumFieldNumber = 5,
+    kRtFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SdeSdePerfSetQosLutsFtraceEvent"; }
+
+
+  using FieldMetadata_Fl =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SdeSdePerfSetQosLutsFtraceEvent>;
+
+  static constexpr FieldMetadata_Fl kFl{};
+  void set_fl(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Fl::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_Fmt =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SdeSdePerfSetQosLutsFtraceEvent>;
+
+  static constexpr FieldMetadata_Fmt kFmt{};
+  void set_fmt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Fmt::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_Lut =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SdeSdePerfSetQosLutsFtraceEvent>;
+
+  static constexpr FieldMetadata_Lut kLut{};
+  void set_lut(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lut::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_LutUsage =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SdeSdePerfSetQosLutsFtraceEvent>;
+
+  static constexpr FieldMetadata_LutUsage kLutUsage{};
+  void set_lut_usage(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LutUsage::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_Pnum =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SdeSdePerfSetQosLutsFtraceEvent>;
+
+  static constexpr FieldMetadata_Pnum kPnum{};
+  void set_pnum(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pnum::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_Rt =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SdeSdePerfSetQosLutsFtraceEvent>;
+
+  static constexpr FieldMetadata_Rt kRt{};
+  void set_rt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rt::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 SdeSdePerfCrtcUpdateFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/12, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SdeSdePerfCrtcUpdateFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SdeSdePerfCrtcUpdateFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SdeSdePerfCrtcUpdateFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_bw_ctl_ebi() const { return at<1>().valid(); }
+  uint64_t bw_ctl_ebi() const { return at<1>().as_uint64(); }
+  bool has_bw_ctl_llcc() const { return at<2>().valid(); }
+  uint64_t bw_ctl_llcc() const { return at<2>().as_uint64(); }
+  bool has_bw_ctl_mnoc() const { return at<3>().valid(); }
+  uint64_t bw_ctl_mnoc() const { return at<3>().as_uint64(); }
+  bool has_core_clk_rate() const { return at<4>().valid(); }
+  uint32_t core_clk_rate() const { return at<4>().as_uint32(); }
+  bool has_crtc() const { return at<5>().valid(); }
+  uint32_t crtc() const { return at<5>().as_uint32(); }
+  bool has_params() const { return at<6>().valid(); }
+  int32_t params() const { return at<6>().as_int32(); }
+  bool has_per_pipe_ib_ebi() const { return at<7>().valid(); }
+  uint64_t per_pipe_ib_ebi() const { return at<7>().as_uint64(); }
+  bool has_per_pipe_ib_llcc() const { return at<8>().valid(); }
+  uint64_t per_pipe_ib_llcc() const { return at<8>().as_uint64(); }
+  bool has_per_pipe_ib_mnoc() const { return at<9>().valid(); }
+  uint64_t per_pipe_ib_mnoc() const { return at<9>().as_uint64(); }
+  bool has_stop_req() const { return at<10>().valid(); }
+  uint32_t stop_req() const { return at<10>().as_uint32(); }
+  bool has_update_bus() const { return at<11>().valid(); }
+  uint32_t update_bus() const { return at<11>().as_uint32(); }
+  bool has_update_clk() const { return at<12>().valid(); }
+  uint32_t update_clk() const { return at<12>().as_uint32(); }
+};
+
+class SdeSdePerfCrtcUpdateFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SdeSdePerfCrtcUpdateFtraceEvent_Decoder;
+  enum : int32_t {
+    kBwCtlEbiFieldNumber = 1,
+    kBwCtlLlccFieldNumber = 2,
+    kBwCtlMnocFieldNumber = 3,
+    kCoreClkRateFieldNumber = 4,
+    kCrtcFieldNumber = 5,
+    kParamsFieldNumber = 6,
+    kPerPipeIbEbiFieldNumber = 7,
+    kPerPipeIbLlccFieldNumber = 8,
+    kPerPipeIbMnocFieldNumber = 9,
+    kStopReqFieldNumber = 10,
+    kUpdateBusFieldNumber = 11,
+    kUpdateClkFieldNumber = 12,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SdeSdePerfCrtcUpdateFtraceEvent"; }
+
+
+  using FieldMetadata_BwCtlEbi =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SdeSdePerfCrtcUpdateFtraceEvent>;
+
+  static constexpr FieldMetadata_BwCtlEbi kBwCtlEbi{};
+  void set_bw_ctl_ebi(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BwCtlEbi::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_BwCtlLlcc =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SdeSdePerfCrtcUpdateFtraceEvent>;
+
+  static constexpr FieldMetadata_BwCtlLlcc kBwCtlLlcc{};
+  void set_bw_ctl_llcc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BwCtlLlcc::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_BwCtlMnoc =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SdeSdePerfCrtcUpdateFtraceEvent>;
+
+  static constexpr FieldMetadata_BwCtlMnoc kBwCtlMnoc{};
+  void set_bw_ctl_mnoc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BwCtlMnoc::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_CoreClkRate =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SdeSdePerfCrtcUpdateFtraceEvent>;
+
+  static constexpr FieldMetadata_CoreClkRate kCoreClkRate{};
+  void set_core_clk_rate(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CoreClkRate::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_Crtc =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SdeSdePerfCrtcUpdateFtraceEvent>;
+
+  static constexpr FieldMetadata_Crtc kCrtc{};
+  void set_crtc(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Crtc::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_Params =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SdeSdePerfCrtcUpdateFtraceEvent>;
+
+  static constexpr FieldMetadata_Params kParams{};
+  void set_params(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Params::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_PerPipeIbEbi =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SdeSdePerfCrtcUpdateFtraceEvent>;
+
+  static constexpr FieldMetadata_PerPipeIbEbi kPerPipeIbEbi{};
+  void set_per_pipe_ib_ebi(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PerPipeIbEbi::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_PerPipeIbLlcc =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SdeSdePerfCrtcUpdateFtraceEvent>;
+
+  static constexpr FieldMetadata_PerPipeIbLlcc kPerPipeIbLlcc{};
+  void set_per_pipe_ib_llcc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PerPipeIbLlcc::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_PerPipeIbMnoc =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SdeSdePerfCrtcUpdateFtraceEvent>;
+
+  static constexpr FieldMetadata_PerPipeIbMnoc kPerPipeIbMnoc{};
+  void set_per_pipe_ib_mnoc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PerPipeIbMnoc::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_StopReq =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SdeSdePerfCrtcUpdateFtraceEvent>;
+
+  static constexpr FieldMetadata_StopReq kStopReq{};
+  void set_stop_req(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StopReq::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_UpdateBus =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SdeSdePerfCrtcUpdateFtraceEvent>;
+
+  static constexpr FieldMetadata_UpdateBus kUpdateBus{};
+  void set_update_bus(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UpdateBus::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_UpdateClk =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SdeSdePerfCrtcUpdateFtraceEvent>;
+
+  static constexpr FieldMetadata_UpdateClk kUpdateClk{};
+  void set_update_clk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UpdateClk::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 SdeSdePerfCalcCrtcFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SdeSdePerfCalcCrtcFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SdeSdePerfCalcCrtcFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SdeSdePerfCalcCrtcFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_bw_ctl_ebi() const { return at<1>().valid(); }
+  uint64_t bw_ctl_ebi() const { return at<1>().as_uint64(); }
+  bool has_bw_ctl_llcc() const { return at<2>().valid(); }
+  uint64_t bw_ctl_llcc() const { return at<2>().as_uint64(); }
+  bool has_bw_ctl_mnoc() const { return at<3>().valid(); }
+  uint64_t bw_ctl_mnoc() const { return at<3>().as_uint64(); }
+  bool has_core_clk_rate() const { return at<4>().valid(); }
+  uint32_t core_clk_rate() const { return at<4>().as_uint32(); }
+  bool has_crtc() const { return at<5>().valid(); }
+  uint32_t crtc() const { return at<5>().as_uint32(); }
+  bool has_ib_ebi() const { return at<6>().valid(); }
+  uint64_t ib_ebi() const { return at<6>().as_uint64(); }
+  bool has_ib_llcc() const { return at<7>().valid(); }
+  uint64_t ib_llcc() const { return at<7>().as_uint64(); }
+  bool has_ib_mnoc() const { return at<8>().valid(); }
+  uint64_t ib_mnoc() const { return at<8>().as_uint64(); }
+};
+
+class SdeSdePerfCalcCrtcFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SdeSdePerfCalcCrtcFtraceEvent_Decoder;
+  enum : int32_t {
+    kBwCtlEbiFieldNumber = 1,
+    kBwCtlLlccFieldNumber = 2,
+    kBwCtlMnocFieldNumber = 3,
+    kCoreClkRateFieldNumber = 4,
+    kCrtcFieldNumber = 5,
+    kIbEbiFieldNumber = 6,
+    kIbLlccFieldNumber = 7,
+    kIbMnocFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SdeSdePerfCalcCrtcFtraceEvent"; }
+
+
+  using FieldMetadata_BwCtlEbi =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SdeSdePerfCalcCrtcFtraceEvent>;
+
+  static constexpr FieldMetadata_BwCtlEbi kBwCtlEbi{};
+  void set_bw_ctl_ebi(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BwCtlEbi::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_BwCtlLlcc =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SdeSdePerfCalcCrtcFtraceEvent>;
+
+  static constexpr FieldMetadata_BwCtlLlcc kBwCtlLlcc{};
+  void set_bw_ctl_llcc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BwCtlLlcc::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_BwCtlMnoc =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SdeSdePerfCalcCrtcFtraceEvent>;
+
+  static constexpr FieldMetadata_BwCtlMnoc kBwCtlMnoc{};
+  void set_bw_ctl_mnoc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BwCtlMnoc::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_CoreClkRate =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SdeSdePerfCalcCrtcFtraceEvent>;
+
+  static constexpr FieldMetadata_CoreClkRate kCoreClkRate{};
+  void set_core_clk_rate(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CoreClkRate::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_Crtc =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SdeSdePerfCalcCrtcFtraceEvent>;
+
+  static constexpr FieldMetadata_Crtc kCrtc{};
+  void set_crtc(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Crtc::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_IbEbi =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SdeSdePerfCalcCrtcFtraceEvent>;
+
+  static constexpr FieldMetadata_IbEbi kIbEbi{};
+  void set_ib_ebi(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IbEbi::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_IbLlcc =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SdeSdePerfCalcCrtcFtraceEvent>;
+
+  static constexpr FieldMetadata_IbLlcc kIbLlcc{};
+  void set_ib_llcc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IbLlcc::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_IbMnoc =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SdeSdePerfCalcCrtcFtraceEvent>;
+
+  static constexpr FieldMetadata_IbMnoc kIbMnoc{};
+  void set_ib_mnoc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IbMnoc::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 SdeSdeEvtlogFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SdeSdeEvtlogFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SdeSdeEvtlogFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SdeSdeEvtlogFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_evtlog_tag() const { return at<1>().valid(); }
+  ::protozero::ConstChars evtlog_tag() const { return at<1>().as_string(); }
+  bool has_pid() const { return at<2>().valid(); }
+  int32_t pid() const { return at<2>().as_int32(); }
+  bool has_tag_id() const { return at<3>().valid(); }
+  uint32_t tag_id() const { return at<3>().as_uint32(); }
+};
+
+class SdeSdeEvtlogFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SdeSdeEvtlogFtraceEvent_Decoder;
+  enum : int32_t {
+    kEvtlogTagFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kTagIdFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SdeSdeEvtlogFtraceEvent"; }
+
+
+  using FieldMetadata_EvtlogTag =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SdeSdeEvtlogFtraceEvent>;
+
+  static constexpr FieldMetadata_EvtlogTag kEvtlogTag{};
+  void set_evtlog_tag(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_EvtlogTag::kFieldId, data, size);
+  }
+  void set_evtlog_tag(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_EvtlogTag::kFieldId, chars.data, chars.size);
+  }
+  void set_evtlog_tag(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_EvtlogTag::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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SdeSdeEvtlogFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_TagId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SdeSdeEvtlogFtraceEvent>;
+
+  static constexpr FieldMetadata_TagId kTagId{};
+  void set_tag_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TagId::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 SdeTracingMarkWriteFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SdeTracingMarkWriteFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SdeTracingMarkWriteFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SdeTracingMarkWriteFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  int32_t pid() const { return at<1>().as_int32(); }
+  bool has_trace_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars trace_name() const { return at<2>().as_string(); }
+  bool has_trace_type() const { return at<3>().valid(); }
+  uint32_t trace_type() const { return at<3>().as_uint32(); }
+  bool has_value() const { return at<4>().valid(); }
+  int32_t value() const { return at<4>().as_int32(); }
+  bool has_trace_begin() const { return at<5>().valid(); }
+  uint32_t trace_begin() const { return at<5>().as_uint32(); }
+};
+
+class SdeTracingMarkWriteFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SdeTracingMarkWriteFtraceEvent_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kTraceNameFieldNumber = 2,
+    kTraceTypeFieldNumber = 3,
+    kValueFieldNumber = 4,
+    kTraceBeginFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SdeTracingMarkWriteFtraceEvent"; }
+
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SdeTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_TraceName =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SdeTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_TraceName kTraceName{};
+  void set_trace_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TraceName::kFieldId, data, size);
+  }
+  void set_trace_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_TraceName::kFieldId, chars.data, chars.size);
+  }
+  void set_trace_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_TraceName::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_TraceType =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SdeTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_TraceType kTraceType{};
+  void set_trace_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TraceType::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_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SdeTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::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_TraceBegin =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SdeTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_TraceBegin kTraceBegin{};
+  void set_trace_begin(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TraceBegin::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/signal.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SIGNAL_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SIGNAL_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class SignalGenerateFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SignalGenerateFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SignalGenerateFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SignalGenerateFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_code() const { return at<1>().valid(); }
+  int32_t code() const { return at<1>().as_int32(); }
+  bool has_comm() const { return at<2>().valid(); }
+  ::protozero::ConstChars comm() const { return at<2>().as_string(); }
+  bool has_group() const { return at<3>().valid(); }
+  int32_t group() const { return at<3>().as_int32(); }
+  bool has_pid() const { return at<4>().valid(); }
+  int32_t pid() const { return at<4>().as_int32(); }
+  bool has_result() const { return at<5>().valid(); }
+  int32_t result() const { return at<5>().as_int32(); }
+  bool has_sig() const { return at<6>().valid(); }
+  int32_t sig() const { return at<6>().as_int32(); }
+};
+
+class SignalGenerateFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SignalGenerateFtraceEvent_Decoder;
+  enum : int32_t {
+    kCodeFieldNumber = 1,
+    kCommFieldNumber = 2,
+    kGroupFieldNumber = 3,
+    kPidFieldNumber = 4,
+    kResultFieldNumber = 5,
+    kSigFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SignalGenerateFtraceEvent"; }
+
+
+  using FieldMetadata_Code =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SignalGenerateFtraceEvent>;
+
+  static constexpr FieldMetadata_Code kCode{};
+  void set_code(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Code::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_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SignalGenerateFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::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_Group =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SignalGenerateFtraceEvent>;
+
+  static constexpr FieldMetadata_Group kGroup{};
+  void set_group(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Group::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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SignalGenerateFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_Result =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SignalGenerateFtraceEvent>;
+
+  static constexpr FieldMetadata_Result kResult{};
+  void set_result(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Result::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_Sig =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SignalGenerateFtraceEvent>;
+
+  static constexpr FieldMetadata_Sig kSig{};
+  void set_sig(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sig::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);
+  }
+};
+
+class SignalDeliverFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SignalDeliverFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SignalDeliverFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SignalDeliverFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_code() const { return at<1>().valid(); }
+  int32_t code() const { return at<1>().as_int32(); }
+  bool has_sa_flags() const { return at<2>().valid(); }
+  uint64_t sa_flags() const { return at<2>().as_uint64(); }
+  bool has_sig() const { return at<3>().valid(); }
+  int32_t sig() const { return at<3>().as_int32(); }
+};
+
+class SignalDeliverFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SignalDeliverFtraceEvent_Decoder;
+  enum : int32_t {
+    kCodeFieldNumber = 1,
+    kSaFlagsFieldNumber = 2,
+    kSigFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SignalDeliverFtraceEvent"; }
+
+
+  using FieldMetadata_Code =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SignalDeliverFtraceEvent>;
+
+  static constexpr FieldMetadata_Code kCode{};
+  void set_code(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Code::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_SaFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SignalDeliverFtraceEvent>;
+
+  static constexpr FieldMetadata_SaFlags kSaFlags{};
+  void set_sa_flags(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SaFlags::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_Sig =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SignalDeliverFtraceEvent>;
+
+  static constexpr FieldMetadata_Sig kSig{};
+  void set_sig(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sig::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/skb.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SKB_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SKB_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class KfreeSkbFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KfreeSkbFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KfreeSkbFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KfreeSkbFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_location() const { return at<1>().valid(); }
+  uint64_t location() const { return at<1>().as_uint64(); }
+  bool has_protocol() const { return at<2>().valid(); }
+  uint32_t protocol() const { return at<2>().as_uint32(); }
+  bool has_skbaddr() const { return at<3>().valid(); }
+  uint64_t skbaddr() const { return at<3>().as_uint64(); }
+};
+
+class KfreeSkbFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KfreeSkbFtraceEvent_Decoder;
+  enum : int32_t {
+    kLocationFieldNumber = 1,
+    kProtocolFieldNumber = 2,
+    kSkbaddrFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KfreeSkbFtraceEvent"; }
+
+
+  using FieldMetadata_Location =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KfreeSkbFtraceEvent>;
+
+  static constexpr FieldMetadata_Location kLocation{};
+  void set_location(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Location::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_Protocol =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KfreeSkbFtraceEvent>;
+
+  static constexpr FieldMetadata_Protocol kProtocol{};
+  void set_protocol(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Protocol::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_Skbaddr =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KfreeSkbFtraceEvent>;
+
+  static constexpr FieldMetadata_Skbaddr kSkbaddr{};
+  void set_skbaddr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Skbaddr::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/sock.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SOCK_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SOCK_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class InetSockSetStateFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  InetSockSetStateFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit InetSockSetStateFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit InetSockSetStateFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_daddr() const { return at<1>().valid(); }
+  uint32_t daddr() const { return at<1>().as_uint32(); }
+  bool has_dport() const { return at<2>().valid(); }
+  uint32_t dport() const { return at<2>().as_uint32(); }
+  bool has_family() const { return at<3>().valid(); }
+  uint32_t family() const { return at<3>().as_uint32(); }
+  bool has_newstate() const { return at<4>().valid(); }
+  int32_t newstate() const { return at<4>().as_int32(); }
+  bool has_oldstate() const { return at<5>().valid(); }
+  int32_t oldstate() const { return at<5>().as_int32(); }
+  bool has_protocol() const { return at<6>().valid(); }
+  uint32_t protocol() const { return at<6>().as_uint32(); }
+  bool has_saddr() const { return at<7>().valid(); }
+  uint32_t saddr() const { return at<7>().as_uint32(); }
+  bool has_skaddr() const { return at<8>().valid(); }
+  uint64_t skaddr() const { return at<8>().as_uint64(); }
+  bool has_sport() const { return at<9>().valid(); }
+  uint32_t sport() const { return at<9>().as_uint32(); }
+};
+
+class InetSockSetStateFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = InetSockSetStateFtraceEvent_Decoder;
+  enum : int32_t {
+    kDaddrFieldNumber = 1,
+    kDportFieldNumber = 2,
+    kFamilyFieldNumber = 3,
+    kNewstateFieldNumber = 4,
+    kOldstateFieldNumber = 5,
+    kProtocolFieldNumber = 6,
+    kSaddrFieldNumber = 7,
+    kSkaddrFieldNumber = 8,
+    kSportFieldNumber = 9,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.InetSockSetStateFtraceEvent"; }
+
+
+  using FieldMetadata_Daddr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      InetSockSetStateFtraceEvent>;
+
+  static constexpr FieldMetadata_Daddr kDaddr{};
+  void set_daddr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Daddr::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_Dport =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      InetSockSetStateFtraceEvent>;
+
+  static constexpr FieldMetadata_Dport kDport{};
+  void set_dport(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dport::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_Family =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      InetSockSetStateFtraceEvent>;
+
+  static constexpr FieldMetadata_Family kFamily{};
+  void set_family(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Family::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_Newstate =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      InetSockSetStateFtraceEvent>;
+
+  static constexpr FieldMetadata_Newstate kNewstate{};
+  void set_newstate(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Newstate::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_Oldstate =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      InetSockSetStateFtraceEvent>;
+
+  static constexpr FieldMetadata_Oldstate kOldstate{};
+  void set_oldstate(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Oldstate::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_Protocol =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      InetSockSetStateFtraceEvent>;
+
+  static constexpr FieldMetadata_Protocol kProtocol{};
+  void set_protocol(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Protocol::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_Saddr =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      InetSockSetStateFtraceEvent>;
+
+  static constexpr FieldMetadata_Saddr kSaddr{};
+  void set_saddr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Saddr::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_Skaddr =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      InetSockSetStateFtraceEvent>;
+
+  static constexpr FieldMetadata_Skaddr kSkaddr{};
+  void set_skaddr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Skaddr::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_Sport =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      InetSockSetStateFtraceEvent>;
+
+  static constexpr FieldMetadata_Sport kSport{};
+  void set_sport(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sport::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/sync.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SYNC_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SYNC_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class SyncWaitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SyncWaitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SyncWaitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SyncWaitFtraceEvent_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_status() const { return at<2>().valid(); }
+  int32_t status() const { return at<2>().as_int32(); }
+  bool has_begin() const { return at<3>().valid(); }
+  uint32_t begin() const { return at<3>().as_uint32(); }
+};
+
+class SyncWaitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SyncWaitFtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kStatusFieldNumber = 2,
+    kBeginFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SyncWaitFtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SyncWaitFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Status =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SyncWaitFtraceEvent>;
+
+  static constexpr FieldMetadata_Status kStatus{};
+  void set_status(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Status::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_Begin =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SyncWaitFtraceEvent>;
+
+  static constexpr FieldMetadata_Begin kBegin{};
+  void set_begin(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Begin::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 SyncTimelineFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SyncTimelineFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SyncTimelineFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SyncTimelineFtraceEvent_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_value() const { return at<2>().valid(); }
+  ::protozero::ConstChars value() const { return at<2>().as_string(); }
+};
+
+class SyncTimelineFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SyncTimelineFtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kValueFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SyncTimelineFtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SyncTimelineFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SyncTimelineFtraceEvent>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Value::kFieldId, data, size);
+  }
+  void set_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Value::kFieldId, chars.data, chars.size);
+  }
+  void set_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::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 SyncPtFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SyncPtFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SyncPtFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SyncPtFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_timeline() const { return at<1>().valid(); }
+  ::protozero::ConstChars timeline() const { return at<1>().as_string(); }
+  bool has_value() const { return at<2>().valid(); }
+  ::protozero::ConstChars value() const { return at<2>().as_string(); }
+};
+
+class SyncPtFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SyncPtFtraceEvent_Decoder;
+  enum : int32_t {
+    kTimelineFieldNumber = 1,
+    kValueFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SyncPtFtraceEvent"; }
+
+
+  using FieldMetadata_Timeline =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SyncPtFtraceEvent>;
+
+  static constexpr FieldMetadata_Timeline kTimeline{};
+  void set_timeline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, data, size);
+  }
+  void set_timeline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, chars.data, chars.size);
+  }
+  void set_timeline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timeline::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_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SyncPtFtraceEvent>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Value::kFieldId, data, size);
+  }
+  void set_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Value::kFieldId, chars.data, chars.size);
+  }
+  void set_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/synthetic.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SYNTHETIC_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SYNTHETIC_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class SuspendResumeMinimalFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SuspendResumeMinimalFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SuspendResumeMinimalFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SuspendResumeMinimalFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_start() const { return at<1>().valid(); }
+  uint32_t start() const { return at<1>().as_uint32(); }
+};
+
+class SuspendResumeMinimalFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SuspendResumeMinimalFtraceEvent_Decoder;
+  enum : int32_t {
+    kStartFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SuspendResumeMinimalFtraceEvent"; }
+
+
+  using FieldMetadata_Start =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SuspendResumeMinimalFtraceEvent>;
+
+  static constexpr FieldMetadata_Start kStart{};
+  void set_start(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Start::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 RssStatThrottledFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  RssStatThrottledFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit RssStatThrottledFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit RssStatThrottledFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_curr() const { return at<1>().valid(); }
+  uint32_t curr() const { return at<1>().as_uint32(); }
+  bool has_member() const { return at<2>().valid(); }
+  int32_t member() const { return at<2>().as_int32(); }
+  bool has_mm_id() const { return at<3>().valid(); }
+  uint32_t mm_id() const { return at<3>().as_uint32(); }
+  bool has_size() const { return at<4>().valid(); }
+  int64_t size() const { return at<4>().as_int64(); }
+};
+
+class RssStatThrottledFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = RssStatThrottledFtraceEvent_Decoder;
+  enum : int32_t {
+    kCurrFieldNumber = 1,
+    kMemberFieldNumber = 2,
+    kMmIdFieldNumber = 3,
+    kSizeFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.RssStatThrottledFtraceEvent"; }
+
+
+  using FieldMetadata_Curr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      RssStatThrottledFtraceEvent>;
+
+  static constexpr FieldMetadata_Curr kCurr{};
+  void set_curr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Curr::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_Member =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      RssStatThrottledFtraceEvent>;
+
+  static constexpr FieldMetadata_Member kMember{};
+  void set_member(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Member::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_MmId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      RssStatThrottledFtraceEvent>;
+
+  static constexpr FieldMetadata_MmId kMmId{};
+  void set_mm_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MmId::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_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      RssStatThrottledFtraceEvent>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void set_size(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/systrace.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SYSTRACE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SYSTRACE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class ZeroFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ZeroFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ZeroFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ZeroFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_flag() const { return at<1>().valid(); }
+  int32_t flag() const { return at<1>().as_int32(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+  bool has_pid() const { return at<3>().valid(); }
+  int32_t pid() const { return at<3>().as_int32(); }
+  bool has_value() const { return at<4>().valid(); }
+  int64_t value() const { return at<4>().as_int64(); }
+};
+
+class ZeroFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = ZeroFtraceEvent_Decoder;
+  enum : int32_t {
+    kFlagFieldNumber = 1,
+    kNameFieldNumber = 2,
+    kPidFieldNumber = 3,
+    kValueFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ZeroFtraceEvent"; }
+
+
+  using FieldMetadata_Flag =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ZeroFtraceEvent>;
+
+  static constexpr FieldMetadata_Flag kFlag{};
+  void set_flag(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flag::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ZeroFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ZeroFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ZeroFtraceEvent>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/task.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_TASK_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_TASK_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class TaskRenameFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TaskRenameFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TaskRenameFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TaskRenameFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  int32_t pid() const { return at<1>().as_int32(); }
+  bool has_oldcomm() const { return at<2>().valid(); }
+  ::protozero::ConstChars oldcomm() const { return at<2>().as_string(); }
+  bool has_newcomm() const { return at<3>().valid(); }
+  ::protozero::ConstChars newcomm() const { return at<3>().as_string(); }
+  bool has_oom_score_adj() const { return at<4>().valid(); }
+  int32_t oom_score_adj() const { return at<4>().as_int32(); }
+};
+
+class TaskRenameFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TaskRenameFtraceEvent_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kOldcommFieldNumber = 2,
+    kNewcommFieldNumber = 3,
+    kOomScoreAdjFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TaskRenameFtraceEvent"; }
+
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TaskRenameFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_Oldcomm =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TaskRenameFtraceEvent>;
+
+  static constexpr FieldMetadata_Oldcomm kOldcomm{};
+  void set_oldcomm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Oldcomm::kFieldId, data, size);
+  }
+  void set_oldcomm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Oldcomm::kFieldId, chars.data, chars.size);
+  }
+  void set_oldcomm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Oldcomm::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_Newcomm =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TaskRenameFtraceEvent>;
+
+  static constexpr FieldMetadata_Newcomm kNewcomm{};
+  void set_newcomm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Newcomm::kFieldId, data, size);
+  }
+  void set_newcomm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Newcomm::kFieldId, chars.data, chars.size);
+  }
+  void set_newcomm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Newcomm::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_OomScoreAdj =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TaskRenameFtraceEvent>;
+
+  static constexpr FieldMetadata_OomScoreAdj kOomScoreAdj{};
+  void set_oom_score_adj(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OomScoreAdj::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);
+  }
+};
+
+class TaskNewtaskFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TaskNewtaskFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TaskNewtaskFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TaskNewtaskFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  int32_t pid() const { return at<1>().as_int32(); }
+  bool has_comm() const { return at<2>().valid(); }
+  ::protozero::ConstChars comm() const { return at<2>().as_string(); }
+  bool has_clone_flags() const { return at<3>().valid(); }
+  uint64_t clone_flags() const { return at<3>().as_uint64(); }
+  bool has_oom_score_adj() const { return at<4>().valid(); }
+  int32_t oom_score_adj() const { return at<4>().as_int32(); }
+};
+
+class TaskNewtaskFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TaskNewtaskFtraceEvent_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kCommFieldNumber = 2,
+    kCloneFlagsFieldNumber = 3,
+    kOomScoreAdjFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TaskNewtaskFtraceEvent"; }
+
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TaskNewtaskFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TaskNewtaskFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::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_CloneFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TaskNewtaskFtraceEvent>;
+
+  static constexpr FieldMetadata_CloneFlags kCloneFlags{};
+  void set_clone_flags(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CloneFlags::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_OomScoreAdj =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TaskNewtaskFtraceEvent>;
+
+  static constexpr FieldMetadata_OomScoreAdj kOomScoreAdj{};
+  void set_oom_score_adj(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OomScoreAdj::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/tcp.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_TCP_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_TCP_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class TcpRetransmitSkbFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TcpRetransmitSkbFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TcpRetransmitSkbFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TcpRetransmitSkbFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_daddr() const { return at<1>().valid(); }
+  uint32_t daddr() const { return at<1>().as_uint32(); }
+  bool has_dport() const { return at<2>().valid(); }
+  uint32_t dport() const { return at<2>().as_uint32(); }
+  bool has_saddr() const { return at<3>().valid(); }
+  uint32_t saddr() const { return at<3>().as_uint32(); }
+  bool has_skaddr() const { return at<4>().valid(); }
+  uint64_t skaddr() const { return at<4>().as_uint64(); }
+  bool has_skbaddr() const { return at<5>().valid(); }
+  uint64_t skbaddr() const { return at<5>().as_uint64(); }
+  bool has_sport() const { return at<6>().valid(); }
+  uint32_t sport() const { return at<6>().as_uint32(); }
+  bool has_state() const { return at<7>().valid(); }
+  int32_t state() const { return at<7>().as_int32(); }
+};
+
+class TcpRetransmitSkbFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TcpRetransmitSkbFtraceEvent_Decoder;
+  enum : int32_t {
+    kDaddrFieldNumber = 1,
+    kDportFieldNumber = 2,
+    kSaddrFieldNumber = 3,
+    kSkaddrFieldNumber = 4,
+    kSkbaddrFieldNumber = 5,
+    kSportFieldNumber = 6,
+    kStateFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TcpRetransmitSkbFtraceEvent"; }
+
+
+  using FieldMetadata_Daddr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TcpRetransmitSkbFtraceEvent>;
+
+  static constexpr FieldMetadata_Daddr kDaddr{};
+  void set_daddr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Daddr::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_Dport =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TcpRetransmitSkbFtraceEvent>;
+
+  static constexpr FieldMetadata_Dport kDport{};
+  void set_dport(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dport::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_Saddr =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TcpRetransmitSkbFtraceEvent>;
+
+  static constexpr FieldMetadata_Saddr kSaddr{};
+  void set_saddr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Saddr::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_Skaddr =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TcpRetransmitSkbFtraceEvent>;
+
+  static constexpr FieldMetadata_Skaddr kSkaddr{};
+  void set_skaddr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Skaddr::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_Skbaddr =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TcpRetransmitSkbFtraceEvent>;
+
+  static constexpr FieldMetadata_Skbaddr kSkbaddr{};
+  void set_skbaddr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Skbaddr::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_Sport =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TcpRetransmitSkbFtraceEvent>;
+
+  static constexpr FieldMetadata_Sport kSport{};
+  void set_sport(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sport::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_State =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TcpRetransmitSkbFtraceEvent>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/thermal.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_THERMAL_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_THERMAL_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class CdevUpdateFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CdevUpdateFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CdevUpdateFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CdevUpdateFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_target() const { return at<1>().valid(); }
+  uint64_t target() const { return at<1>().as_uint64(); }
+  bool has_type() const { return at<2>().valid(); }
+  ::protozero::ConstChars type() const { return at<2>().as_string(); }
+};
+
+class CdevUpdateFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CdevUpdateFtraceEvent_Decoder;
+  enum : int32_t {
+    kTargetFieldNumber = 1,
+    kTypeFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CdevUpdateFtraceEvent"; }
+
+
+  using FieldMetadata_Target =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      CdevUpdateFtraceEvent>;
+
+  static constexpr FieldMetadata_Target kTarget{};
+  void set_target(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Target::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_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CdevUpdateFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Type::kFieldId, data, size);
+  }
+  void set_type(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Type::kFieldId, chars.data, chars.size);
+  }
+  void set_type(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::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 ThermalTemperatureFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ThermalTemperatureFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ThermalTemperatureFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ThermalTemperatureFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  int32_t id() const { return at<1>().as_int32(); }
+  bool has_temp() const { return at<2>().valid(); }
+  int32_t temp() const { return at<2>().as_int32(); }
+  bool has_temp_prev() const { return at<3>().valid(); }
+  int32_t temp_prev() const { return at<3>().as_int32(); }
+  bool has_thermal_zone() const { return at<4>().valid(); }
+  ::protozero::ConstChars thermal_zone() const { return at<4>().as_string(); }
+};
+
+class ThermalTemperatureFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = ThermalTemperatureFtraceEvent_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kTempFieldNumber = 2,
+    kTempPrevFieldNumber = 3,
+    kThermalZoneFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ThermalTemperatureFtraceEvent"; }
+
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ThermalTemperatureFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::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_Temp =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ThermalTemperatureFtraceEvent>;
+
+  static constexpr FieldMetadata_Temp kTemp{};
+  void set_temp(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Temp::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_TempPrev =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ThermalTemperatureFtraceEvent>;
+
+  static constexpr FieldMetadata_TempPrev kTempPrev{};
+  void set_temp_prev(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TempPrev::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_ThermalZone =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ThermalTemperatureFtraceEvent>;
+
+  static constexpr FieldMetadata_ThermalZone kThermalZone{};
+  void set_thermal_zone(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ThermalZone::kFieldId, data, size);
+  }
+  void set_thermal_zone(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ThermalZone::kFieldId, chars.data, chars.size);
+  }
+  void set_thermal_zone(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ThermalZone::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/trusty.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_TRUSTY_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_TRUSTY_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class TrustyEnqueueNopFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrustyEnqueueNopFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrustyEnqueueNopFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrustyEnqueueNopFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_arg1() const { return at<1>().valid(); }
+  uint32_t arg1() const { return at<1>().as_uint32(); }
+  bool has_arg2() const { return at<2>().valid(); }
+  uint32_t arg2() const { return at<2>().as_uint32(); }
+  bool has_arg3() const { return at<3>().valid(); }
+  uint32_t arg3() const { return at<3>().as_uint32(); }
+};
+
+class TrustyEnqueueNopFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrustyEnqueueNopFtraceEvent_Decoder;
+  enum : int32_t {
+    kArg1FieldNumber = 1,
+    kArg2FieldNumber = 2,
+    kArg3FieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrustyEnqueueNopFtraceEvent"; }
+
+
+  using FieldMetadata_Arg1 =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TrustyEnqueueNopFtraceEvent>;
+
+  static constexpr FieldMetadata_Arg1 kArg1{};
+  void set_arg1(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Arg1::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_Arg2 =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TrustyEnqueueNopFtraceEvent>;
+
+  static constexpr FieldMetadata_Arg2 kArg2{};
+  void set_arg2(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Arg2::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_Arg3 =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TrustyEnqueueNopFtraceEvent>;
+
+  static constexpr FieldMetadata_Arg3 kArg3{};
+  void set_arg3(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Arg3::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 TrustyIpcRxFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrustyIpcRxFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrustyIpcRxFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrustyIpcRxFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_buf_id() const { return at<1>().valid(); }
+  uint64_t buf_id() const { return at<1>().as_uint64(); }
+  bool has_chan() const { return at<2>().valid(); }
+  uint32_t chan() const { return at<2>().as_uint32(); }
+  bool has_srv_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars srv_name() const { return at<3>().as_string(); }
+};
+
+class TrustyIpcRxFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrustyIpcRxFtraceEvent_Decoder;
+  enum : int32_t {
+    kBufIdFieldNumber = 1,
+    kChanFieldNumber = 2,
+    kSrvNameFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrustyIpcRxFtraceEvent"; }
+
+
+  using FieldMetadata_BufId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustyIpcRxFtraceEvent>;
+
+  static constexpr FieldMetadata_BufId kBufId{};
+  void set_buf_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BufId::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_Chan =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TrustyIpcRxFtraceEvent>;
+
+  static constexpr FieldMetadata_Chan kChan{};
+  void set_chan(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Chan::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_SrvName =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrustyIpcRxFtraceEvent>;
+
+  static constexpr FieldMetadata_SrvName kSrvName{};
+  void set_srv_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_SrvName::kFieldId, data, size);
+  }
+  void set_srv_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_SrvName::kFieldId, chars.data, chars.size);
+  }
+  void set_srv_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_SrvName::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 TrustyIpcReadEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrustyIpcReadEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrustyIpcReadEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrustyIpcReadEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_buf_id() const { return at<1>().valid(); }
+  uint64_t buf_id() const { return at<1>().as_uint64(); }
+  bool has_chan() const { return at<2>().valid(); }
+  uint32_t chan() const { return at<2>().as_uint32(); }
+  bool has_len_or_err() const { return at<3>().valid(); }
+  int32_t len_or_err() const { return at<3>().as_int32(); }
+  bool has_shm_cnt() const { return at<4>().valid(); }
+  uint64_t shm_cnt() const { return at<4>().as_uint64(); }
+  bool has_srv_name() const { return at<5>().valid(); }
+  ::protozero::ConstChars srv_name() const { return at<5>().as_string(); }
+};
+
+class TrustyIpcReadEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrustyIpcReadEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kBufIdFieldNumber = 1,
+    kChanFieldNumber = 2,
+    kLenOrErrFieldNumber = 3,
+    kShmCntFieldNumber = 4,
+    kSrvNameFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrustyIpcReadEndFtraceEvent"; }
+
+
+  using FieldMetadata_BufId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustyIpcReadEndFtraceEvent>;
+
+  static constexpr FieldMetadata_BufId kBufId{};
+  void set_buf_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BufId::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_Chan =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TrustyIpcReadEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Chan kChan{};
+  void set_chan(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Chan::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_LenOrErr =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TrustyIpcReadEndFtraceEvent>;
+
+  static constexpr FieldMetadata_LenOrErr kLenOrErr{};
+  void set_len_or_err(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LenOrErr::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_ShmCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustyIpcReadEndFtraceEvent>;
+
+  static constexpr FieldMetadata_ShmCnt kShmCnt{};
+  void set_shm_cnt(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ShmCnt::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_SrvName =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrustyIpcReadEndFtraceEvent>;
+
+  static constexpr FieldMetadata_SrvName kSrvName{};
+  void set_srv_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_SrvName::kFieldId, data, size);
+  }
+  void set_srv_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_SrvName::kFieldId, chars.data, chars.size);
+  }
+  void set_srv_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_SrvName::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 TrustyIpcReadFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrustyIpcReadFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrustyIpcReadFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrustyIpcReadFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_chan() const { return at<1>().valid(); }
+  uint32_t chan() const { return at<1>().as_uint32(); }
+  bool has_srv_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars srv_name() const { return at<2>().as_string(); }
+};
+
+class TrustyIpcReadFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrustyIpcReadFtraceEvent_Decoder;
+  enum : int32_t {
+    kChanFieldNumber = 1,
+    kSrvNameFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrustyIpcReadFtraceEvent"; }
+
+
+  using FieldMetadata_Chan =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TrustyIpcReadFtraceEvent>;
+
+  static constexpr FieldMetadata_Chan kChan{};
+  void set_chan(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Chan::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_SrvName =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrustyIpcReadFtraceEvent>;
+
+  static constexpr FieldMetadata_SrvName kSrvName{};
+  void set_srv_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_SrvName::kFieldId, data, size);
+  }
+  void set_srv_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_SrvName::kFieldId, chars.data, chars.size);
+  }
+  void set_srv_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_SrvName::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 TrustyIpcPollFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrustyIpcPollFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrustyIpcPollFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrustyIpcPollFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_chan() const { return at<1>().valid(); }
+  uint32_t chan() const { return at<1>().as_uint32(); }
+  bool has_poll_mask() const { return at<2>().valid(); }
+  uint32_t poll_mask() const { return at<2>().as_uint32(); }
+  bool has_srv_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars srv_name() const { return at<3>().as_string(); }
+};
+
+class TrustyIpcPollFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrustyIpcPollFtraceEvent_Decoder;
+  enum : int32_t {
+    kChanFieldNumber = 1,
+    kPollMaskFieldNumber = 2,
+    kSrvNameFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrustyIpcPollFtraceEvent"; }
+
+
+  using FieldMetadata_Chan =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TrustyIpcPollFtraceEvent>;
+
+  static constexpr FieldMetadata_Chan kChan{};
+  void set_chan(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Chan::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_PollMask =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TrustyIpcPollFtraceEvent>;
+
+  static constexpr FieldMetadata_PollMask kPollMask{};
+  void set_poll_mask(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PollMask::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_SrvName =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrustyIpcPollFtraceEvent>;
+
+  static constexpr FieldMetadata_SrvName kSrvName{};
+  void set_srv_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_SrvName::kFieldId, data, size);
+  }
+  void set_srv_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_SrvName::kFieldId, chars.data, chars.size);
+  }
+  void set_srv_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_SrvName::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 TrustyIpcWriteFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrustyIpcWriteFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrustyIpcWriteFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrustyIpcWriteFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_buf_id() const { return at<1>().valid(); }
+  uint64_t buf_id() const { return at<1>().as_uint64(); }
+  bool has_chan() const { return at<2>().valid(); }
+  uint32_t chan() const { return at<2>().as_uint32(); }
+  bool has_kind_shm() const { return at<3>().valid(); }
+  int32_t kind_shm() const { return at<3>().as_int32(); }
+  bool has_len_or_err() const { return at<4>().valid(); }
+  int32_t len_or_err() const { return at<4>().as_int32(); }
+  bool has_shm_cnt() const { return at<5>().valid(); }
+  uint64_t shm_cnt() const { return at<5>().as_uint64(); }
+  bool has_srv_name() const { return at<6>().valid(); }
+  ::protozero::ConstChars srv_name() const { return at<6>().as_string(); }
+};
+
+class TrustyIpcWriteFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrustyIpcWriteFtraceEvent_Decoder;
+  enum : int32_t {
+    kBufIdFieldNumber = 1,
+    kChanFieldNumber = 2,
+    kKindShmFieldNumber = 3,
+    kLenOrErrFieldNumber = 4,
+    kShmCntFieldNumber = 5,
+    kSrvNameFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrustyIpcWriteFtraceEvent"; }
+
+
+  using FieldMetadata_BufId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustyIpcWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_BufId kBufId{};
+  void set_buf_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BufId::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_Chan =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TrustyIpcWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Chan kChan{};
+  void set_chan(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Chan::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_KindShm =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TrustyIpcWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_KindShm kKindShm{};
+  void set_kind_shm(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KindShm::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_LenOrErr =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TrustyIpcWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_LenOrErr kLenOrErr{};
+  void set_len_or_err(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LenOrErr::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_ShmCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustyIpcWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_ShmCnt kShmCnt{};
+  void set_shm_cnt(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ShmCnt::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_SrvName =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrustyIpcWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_SrvName kSrvName{};
+  void set_srv_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_SrvName::kFieldId, data, size);
+  }
+  void set_srv_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_SrvName::kFieldId, chars.data, chars.size);
+  }
+  void set_srv_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_SrvName::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 TrustyIpcConnectEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrustyIpcConnectEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrustyIpcConnectEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrustyIpcConnectEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_chan() const { return at<1>().valid(); }
+  uint32_t chan() const { return at<1>().as_uint32(); }
+  bool has_err() const { return at<2>().valid(); }
+  int32_t err() const { return at<2>().as_int32(); }
+  bool has_state() const { return at<3>().valid(); }
+  int32_t state() const { return at<3>().as_int32(); }
+};
+
+class TrustyIpcConnectEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrustyIpcConnectEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kChanFieldNumber = 1,
+    kErrFieldNumber = 2,
+    kStateFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrustyIpcConnectEndFtraceEvent"; }
+
+
+  using FieldMetadata_Chan =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TrustyIpcConnectEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Chan kChan{};
+  void set_chan(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Chan::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_Err =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TrustyIpcConnectEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Err kErr{};
+  void set_err(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Err::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_State =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TrustyIpcConnectEndFtraceEvent>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::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);
+  }
+};
+
+class TrustyIpcConnectFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrustyIpcConnectFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrustyIpcConnectFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrustyIpcConnectFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_chan() const { return at<1>().valid(); }
+  uint32_t chan() const { return at<1>().as_uint32(); }
+  bool has_port() const { return at<2>().valid(); }
+  ::protozero::ConstChars port() const { return at<2>().as_string(); }
+  bool has_state() const { return at<3>().valid(); }
+  int32_t state() const { return at<3>().as_int32(); }
+};
+
+class TrustyIpcConnectFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrustyIpcConnectFtraceEvent_Decoder;
+  enum : int32_t {
+    kChanFieldNumber = 1,
+    kPortFieldNumber = 2,
+    kStateFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrustyIpcConnectFtraceEvent"; }
+
+
+  using FieldMetadata_Chan =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TrustyIpcConnectFtraceEvent>;
+
+  static constexpr FieldMetadata_Chan kChan{};
+  void set_chan(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Chan::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_Port =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrustyIpcConnectFtraceEvent>;
+
+  static constexpr FieldMetadata_Port kPort{};
+  void set_port(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Port::kFieldId, data, size);
+  }
+  void set_port(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Port::kFieldId, chars.data, chars.size);
+  }
+  void set_port(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Port::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_State =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TrustyIpcConnectFtraceEvent>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::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);
+  }
+};
+
+class TrustyIpcHandleEventFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrustyIpcHandleEventFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrustyIpcHandleEventFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrustyIpcHandleEventFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_chan() const { return at<1>().valid(); }
+  uint32_t chan() const { return at<1>().as_uint32(); }
+  bool has_event_id() const { return at<2>().valid(); }
+  uint32_t event_id() const { return at<2>().as_uint32(); }
+  bool has_srv_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars srv_name() const { return at<3>().as_string(); }
+};
+
+class TrustyIpcHandleEventFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrustyIpcHandleEventFtraceEvent_Decoder;
+  enum : int32_t {
+    kChanFieldNumber = 1,
+    kEventIdFieldNumber = 2,
+    kSrvNameFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrustyIpcHandleEventFtraceEvent"; }
+
+
+  using FieldMetadata_Chan =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TrustyIpcHandleEventFtraceEvent>;
+
+  static constexpr FieldMetadata_Chan kChan{};
+  void set_chan(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Chan::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_EventId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TrustyIpcHandleEventFtraceEvent>;
+
+  static constexpr FieldMetadata_EventId kEventId{};
+  void set_event_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EventId::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_SrvName =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrustyIpcHandleEventFtraceEvent>;
+
+  static constexpr FieldMetadata_SrvName kSrvName{};
+  void set_srv_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_SrvName::kFieldId, data, size);
+  }
+  void set_srv_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_SrvName::kFieldId, chars.data, chars.size);
+  }
+  void set_srv_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_SrvName::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 TrustyIrqFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrustyIrqFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrustyIrqFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrustyIrqFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_irq() const { return at<1>().valid(); }
+  int32_t irq() const { return at<1>().as_int32(); }
+};
+
+class TrustyIrqFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrustyIrqFtraceEvent_Decoder;
+  enum : int32_t {
+    kIrqFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrustyIrqFtraceEvent"; }
+
+
+  using FieldMetadata_Irq =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TrustyIrqFtraceEvent>;
+
+  static constexpr FieldMetadata_Irq kIrq{};
+  void set_irq(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Irq::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);
+  }
+};
+
+class TrustyReclaimMemoryDoneFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrustyReclaimMemoryDoneFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrustyReclaimMemoryDoneFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrustyReclaimMemoryDoneFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  uint64_t id() const { return at<1>().as_uint64(); }
+  bool has_ret() const { return at<2>().valid(); }
+  int32_t ret() const { return at<2>().as_int32(); }
+};
+
+class TrustyReclaimMemoryDoneFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrustyReclaimMemoryDoneFtraceEvent_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kRetFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrustyReclaimMemoryDoneFtraceEvent"; }
+
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustyReclaimMemoryDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::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_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TrustyReclaimMemoryDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::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);
+  }
+};
+
+class TrustyReclaimMemoryFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrustyReclaimMemoryFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrustyReclaimMemoryFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrustyReclaimMemoryFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  uint64_t id() const { return at<1>().as_uint64(); }
+};
+
+class TrustyReclaimMemoryFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrustyReclaimMemoryFtraceEvent_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrustyReclaimMemoryFtraceEvent"; }
+
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustyReclaimMemoryFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::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 TrustyShareMemoryDoneFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrustyShareMemoryDoneFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrustyShareMemoryDoneFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrustyShareMemoryDoneFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_handle() const { return at<1>().valid(); }
+  uint64_t handle() const { return at<1>().as_uint64(); }
+  bool has_len() const { return at<2>().valid(); }
+  uint64_t len() const { return at<2>().as_uint64(); }
+  bool has_lend() const { return at<3>().valid(); }
+  uint32_t lend() const { return at<3>().as_uint32(); }
+  bool has_nents() const { return at<4>().valid(); }
+  uint32_t nents() const { return at<4>().as_uint32(); }
+  bool has_ret() const { return at<5>().valid(); }
+  int32_t ret() const { return at<5>().as_int32(); }
+};
+
+class TrustyShareMemoryDoneFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrustyShareMemoryDoneFtraceEvent_Decoder;
+  enum : int32_t {
+    kHandleFieldNumber = 1,
+    kLenFieldNumber = 2,
+    kLendFieldNumber = 3,
+    kNentsFieldNumber = 4,
+    kRetFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrustyShareMemoryDoneFtraceEvent"; }
+
+
+  using FieldMetadata_Handle =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustyShareMemoryDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Handle kHandle{};
+  void set_handle(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Handle::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_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustyShareMemoryDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Lend =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TrustyShareMemoryDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Lend kLend{};
+  void set_lend(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lend::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_Nents =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TrustyShareMemoryDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Nents kNents{};
+  void set_nents(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nents::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_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TrustyShareMemoryDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::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);
+  }
+};
+
+class TrustyShareMemoryFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrustyShareMemoryFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrustyShareMemoryFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrustyShareMemoryFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_len() const { return at<1>().valid(); }
+  uint64_t len() const { return at<1>().as_uint64(); }
+  bool has_lend() const { return at<2>().valid(); }
+  uint32_t lend() const { return at<2>().as_uint32(); }
+  bool has_nents() const { return at<3>().valid(); }
+  uint32_t nents() const { return at<3>().as_uint32(); }
+};
+
+class TrustyShareMemoryFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrustyShareMemoryFtraceEvent_Decoder;
+  enum : int32_t {
+    kLenFieldNumber = 1,
+    kLendFieldNumber = 2,
+    kNentsFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrustyShareMemoryFtraceEvent"; }
+
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustyShareMemoryFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::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_Lend =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TrustyShareMemoryFtraceEvent>;
+
+  static constexpr FieldMetadata_Lend kLend{};
+  void set_lend(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lend::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_Nents =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TrustyShareMemoryFtraceEvent>;
+
+  static constexpr FieldMetadata_Nents kNents{};
+  void set_nents(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nents::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 TrustyStdCall32DoneFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrustyStdCall32DoneFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrustyStdCall32DoneFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrustyStdCall32DoneFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ret() const { return at<1>().valid(); }
+  int64_t ret() const { return at<1>().as_int64(); }
+};
+
+class TrustyStdCall32DoneFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrustyStdCall32DoneFtraceEvent_Decoder;
+  enum : int32_t {
+    kRetFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrustyStdCall32DoneFtraceEvent"; }
+
+
+  using FieldMetadata_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TrustyStdCall32DoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::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 TrustyStdCall32FtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrustyStdCall32FtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrustyStdCall32FtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrustyStdCall32FtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_r0() const { return at<1>().valid(); }
+  uint64_t r0() const { return at<1>().as_uint64(); }
+  bool has_r1() const { return at<2>().valid(); }
+  uint64_t r1() const { return at<2>().as_uint64(); }
+  bool has_r2() const { return at<3>().valid(); }
+  uint64_t r2() const { return at<3>().as_uint64(); }
+  bool has_r3() const { return at<4>().valid(); }
+  uint64_t r3() const { return at<4>().as_uint64(); }
+};
+
+class TrustyStdCall32FtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrustyStdCall32FtraceEvent_Decoder;
+  enum : int32_t {
+    kR0FieldNumber = 1,
+    kR1FieldNumber = 2,
+    kR2FieldNumber = 3,
+    kR3FieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrustyStdCall32FtraceEvent"; }
+
+
+  using FieldMetadata_R0 =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustyStdCall32FtraceEvent>;
+
+  static constexpr FieldMetadata_R0 kR0{};
+  void set_r0(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_R0::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_R1 =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustyStdCall32FtraceEvent>;
+
+  static constexpr FieldMetadata_R1 kR1{};
+  void set_r1(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_R1::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_R2 =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustyStdCall32FtraceEvent>;
+
+  static constexpr FieldMetadata_R2 kR2{};
+  void set_r2(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_R2::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_R3 =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustyStdCall32FtraceEvent>;
+
+  static constexpr FieldMetadata_R3 kR3{};
+  void set_r3(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_R3::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 TrustySmcDoneFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrustySmcDoneFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrustySmcDoneFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrustySmcDoneFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ret() const { return at<1>().valid(); }
+  uint64_t ret() const { return at<1>().as_uint64(); }
+};
+
+class TrustySmcDoneFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrustySmcDoneFtraceEvent_Decoder;
+  enum : int32_t {
+    kRetFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrustySmcDoneFtraceEvent"; }
+
+
+  using FieldMetadata_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustySmcDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::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 TrustySmcFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrustySmcFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrustySmcFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrustySmcFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_r0() const { return at<1>().valid(); }
+  uint64_t r0() const { return at<1>().as_uint64(); }
+  bool has_r1() const { return at<2>().valid(); }
+  uint64_t r1() const { return at<2>().as_uint64(); }
+  bool has_r2() const { return at<3>().valid(); }
+  uint64_t r2() const { return at<3>().as_uint64(); }
+  bool has_r3() const { return at<4>().valid(); }
+  uint64_t r3() const { return at<4>().as_uint64(); }
+};
+
+class TrustySmcFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrustySmcFtraceEvent_Decoder;
+  enum : int32_t {
+    kR0FieldNumber = 1,
+    kR1FieldNumber = 2,
+    kR2FieldNumber = 3,
+    kR3FieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrustySmcFtraceEvent"; }
+
+
+  using FieldMetadata_R0 =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustySmcFtraceEvent>;
+
+  static constexpr FieldMetadata_R0 kR0{};
+  void set_r0(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_R0::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_R1 =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustySmcFtraceEvent>;
+
+  static constexpr FieldMetadata_R1 kR1{};
+  void set_r1(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_R1::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_R2 =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustySmcFtraceEvent>;
+
+  static constexpr FieldMetadata_R2 kR2{};
+  void set_r2(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_R2::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_R3 =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustySmcFtraceEvent>;
+
+  static constexpr FieldMetadata_R3 kR3{};
+  void set_r3(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_R3::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/ufs.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_UFS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_UFS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class UfshcdClkGatingFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  UfshcdClkGatingFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit UfshcdClkGatingFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit UfshcdClkGatingFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars dev_name() const { return at<1>().as_string(); }
+  bool has_state() const { return at<2>().valid(); }
+  int32_t state() const { return at<2>().as_int32(); }
+};
+
+class UfshcdClkGatingFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = UfshcdClkGatingFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevNameFieldNumber = 1,
+    kStateFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.UfshcdClkGatingFtraceEvent"; }
+
+
+  using FieldMetadata_DevName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      UfshcdClkGatingFtraceEvent>;
+
+  static constexpr FieldMetadata_DevName kDevName{};
+  void set_dev_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DevName::kFieldId, data, size);
+  }
+  void set_dev_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_DevName::kFieldId, chars.data, chars.size);
+  }
+  void set_dev_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_DevName::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_State =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      UfshcdClkGatingFtraceEvent>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::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);
+  }
+};
+
+class UfshcdCommandFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/10, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  UfshcdCommandFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit UfshcdCommandFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit UfshcdCommandFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars dev_name() const { return at<1>().as_string(); }
+  bool has_doorbell() const { return at<2>().valid(); }
+  uint32_t doorbell() const { return at<2>().as_uint32(); }
+  bool has_intr() const { return at<3>().valid(); }
+  uint32_t intr() const { return at<3>().as_uint32(); }
+  bool has_lba() const { return at<4>().valid(); }
+  uint64_t lba() const { return at<4>().as_uint64(); }
+  bool has_opcode() const { return at<5>().valid(); }
+  uint32_t opcode() const { return at<5>().as_uint32(); }
+  bool has_str() const { return at<6>().valid(); }
+  ::protozero::ConstChars str() const { return at<6>().as_string(); }
+  bool has_tag() const { return at<7>().valid(); }
+  uint32_t tag() const { return at<7>().as_uint32(); }
+  bool has_transfer_len() const { return at<8>().valid(); }
+  int32_t transfer_len() const { return at<8>().as_int32(); }
+  bool has_group_id() const { return at<9>().valid(); }
+  uint32_t group_id() const { return at<9>().as_uint32(); }
+  bool has_str_t() const { return at<10>().valid(); }
+  uint32_t str_t() const { return at<10>().as_uint32(); }
+};
+
+class UfshcdCommandFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = UfshcdCommandFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevNameFieldNumber = 1,
+    kDoorbellFieldNumber = 2,
+    kIntrFieldNumber = 3,
+    kLbaFieldNumber = 4,
+    kOpcodeFieldNumber = 5,
+    kStrFieldNumber = 6,
+    kTagFieldNumber = 7,
+    kTransferLenFieldNumber = 8,
+    kGroupIdFieldNumber = 9,
+    kStrTFieldNumber = 10,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.UfshcdCommandFtraceEvent"; }
+
+
+  using FieldMetadata_DevName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      UfshcdCommandFtraceEvent>;
+
+  static constexpr FieldMetadata_DevName kDevName{};
+  void set_dev_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DevName::kFieldId, data, size);
+  }
+  void set_dev_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_DevName::kFieldId, chars.data, chars.size);
+  }
+  void set_dev_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_DevName::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_Doorbell =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      UfshcdCommandFtraceEvent>;
+
+  static constexpr FieldMetadata_Doorbell kDoorbell{};
+  void set_doorbell(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Doorbell::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_Intr =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      UfshcdCommandFtraceEvent>;
+
+  static constexpr FieldMetadata_Intr kIntr{};
+  void set_intr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Intr::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_Lba =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      UfshcdCommandFtraceEvent>;
+
+  static constexpr FieldMetadata_Lba kLba{};
+  void set_lba(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lba::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_Opcode =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      UfshcdCommandFtraceEvent>;
+
+  static constexpr FieldMetadata_Opcode kOpcode{};
+  void set_opcode(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Opcode::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_Str =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      UfshcdCommandFtraceEvent>;
+
+  static constexpr FieldMetadata_Str kStr{};
+  void set_str(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Str::kFieldId, data, size);
+  }
+  void set_str(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Str::kFieldId, chars.data, chars.size);
+  }
+  void set_str(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Str::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_Tag =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      UfshcdCommandFtraceEvent>;
+
+  static constexpr FieldMetadata_Tag kTag{};
+  void set_tag(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tag::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_TransferLen =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      UfshcdCommandFtraceEvent>;
+
+  static constexpr FieldMetadata_TransferLen kTransferLen{};
+  void set_transfer_len(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TransferLen::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_GroupId =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      UfshcdCommandFtraceEvent>;
+
+  static constexpr FieldMetadata_GroupId kGroupId{};
+  void set_group_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GroupId::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_StrT =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      UfshcdCommandFtraceEvent>;
+
+  static constexpr FieldMetadata_StrT kStrT{};
+  void set_str_t(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StrT::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/v4l2.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_V4L2_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_V4L2_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class Vb2V4l2DqbufFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/15, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Vb2V4l2DqbufFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Vb2V4l2DqbufFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Vb2V4l2DqbufFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_field() const { return at<1>().valid(); }
+  uint32_t field() const { return at<1>().as_uint32(); }
+  bool has_flags() const { return at<2>().valid(); }
+  uint32_t flags() const { return at<2>().as_uint32(); }
+  bool has_minor() const { return at<3>().valid(); }
+  int32_t minor() const { return at<3>().as_int32(); }
+  bool has_sequence() const { return at<4>().valid(); }
+  uint32_t sequence() const { return at<4>().as_uint32(); }
+  bool has_timecode_flags() const { return at<5>().valid(); }
+  uint32_t timecode_flags() const { return at<5>().as_uint32(); }
+  bool has_timecode_frames() const { return at<6>().valid(); }
+  uint32_t timecode_frames() const { return at<6>().as_uint32(); }
+  bool has_timecode_hours() const { return at<7>().valid(); }
+  uint32_t timecode_hours() const { return at<7>().as_uint32(); }
+  bool has_timecode_minutes() const { return at<8>().valid(); }
+  uint32_t timecode_minutes() const { return at<8>().as_uint32(); }
+  bool has_timecode_seconds() const { return at<9>().valid(); }
+  uint32_t timecode_seconds() const { return at<9>().as_uint32(); }
+  bool has_timecode_type() const { return at<10>().valid(); }
+  uint32_t timecode_type() const { return at<10>().as_uint32(); }
+  bool has_timecode_userbits0() const { return at<11>().valid(); }
+  uint32_t timecode_userbits0() const { return at<11>().as_uint32(); }
+  bool has_timecode_userbits1() const { return at<12>().valid(); }
+  uint32_t timecode_userbits1() const { return at<12>().as_uint32(); }
+  bool has_timecode_userbits2() const { return at<13>().valid(); }
+  uint32_t timecode_userbits2() const { return at<13>().as_uint32(); }
+  bool has_timecode_userbits3() const { return at<14>().valid(); }
+  uint32_t timecode_userbits3() const { return at<14>().as_uint32(); }
+  bool has_timestamp() const { return at<15>().valid(); }
+  int64_t timestamp() const { return at<15>().as_int64(); }
+};
+
+class Vb2V4l2DqbufFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Vb2V4l2DqbufFtraceEvent_Decoder;
+  enum : int32_t {
+    kFieldFieldNumber = 1,
+    kFlagsFieldNumber = 2,
+    kMinorFieldNumber = 3,
+    kSequenceFieldNumber = 4,
+    kTimecodeFlagsFieldNumber = 5,
+    kTimecodeFramesFieldNumber = 6,
+    kTimecodeHoursFieldNumber = 7,
+    kTimecodeMinutesFieldNumber = 8,
+    kTimecodeSecondsFieldNumber = 9,
+    kTimecodeTypeFieldNumber = 10,
+    kTimecodeUserbits0FieldNumber = 11,
+    kTimecodeUserbits1FieldNumber = 12,
+    kTimecodeUserbits2FieldNumber = 13,
+    kTimecodeUserbits3FieldNumber = 14,
+    kTimestampFieldNumber = 15,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Vb2V4l2DqbufFtraceEvent"; }
+
+
+  using FieldMetadata_Field =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Field kField{};
+  void set_field(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Field::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_Minor =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Vb2V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Minor kMinor{};
+  void set_minor(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Minor::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_Sequence =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Sequence kSequence{};
+  void set_sequence(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sequence::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_TimecodeFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeFlags kTimecodeFlags{};
+  void set_timecode_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeFlags::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_TimecodeFrames =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeFrames kTimecodeFrames{};
+  void set_timecode_frames(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeFrames::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_TimecodeHours =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeHours kTimecodeHours{};
+  void set_timecode_hours(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeHours::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_TimecodeMinutes =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeMinutes kTimecodeMinutes{};
+  void set_timecode_minutes(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeMinutes::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_TimecodeSeconds =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeSeconds kTimecodeSeconds{};
+  void set_timecode_seconds(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeSeconds::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_TimecodeType =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeType kTimecodeType{};
+  void set_timecode_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeType::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_TimecodeUserbits0 =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits0 kTimecodeUserbits0{};
+  void set_timecode_userbits0(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits0::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_TimecodeUserbits1 =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits1 kTimecodeUserbits1{};
+  void set_timecode_userbits1(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits1::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_TimecodeUserbits2 =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits2 kTimecodeUserbits2{};
+  void set_timecode_userbits2(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits2::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_TimecodeUserbits3 =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits3 kTimecodeUserbits3{};
+  void set_timecode_userbits3(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits3::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_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Vb2V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Timestamp kTimestamp{};
+  void set_timestamp(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timestamp::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 Vb2V4l2QbufFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/15, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Vb2V4l2QbufFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Vb2V4l2QbufFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Vb2V4l2QbufFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_field() const { return at<1>().valid(); }
+  uint32_t field() const { return at<1>().as_uint32(); }
+  bool has_flags() const { return at<2>().valid(); }
+  uint32_t flags() const { return at<2>().as_uint32(); }
+  bool has_minor() const { return at<3>().valid(); }
+  int32_t minor() const { return at<3>().as_int32(); }
+  bool has_sequence() const { return at<4>().valid(); }
+  uint32_t sequence() const { return at<4>().as_uint32(); }
+  bool has_timecode_flags() const { return at<5>().valid(); }
+  uint32_t timecode_flags() const { return at<5>().as_uint32(); }
+  bool has_timecode_frames() const { return at<6>().valid(); }
+  uint32_t timecode_frames() const { return at<6>().as_uint32(); }
+  bool has_timecode_hours() const { return at<7>().valid(); }
+  uint32_t timecode_hours() const { return at<7>().as_uint32(); }
+  bool has_timecode_minutes() const { return at<8>().valid(); }
+  uint32_t timecode_minutes() const { return at<8>().as_uint32(); }
+  bool has_timecode_seconds() const { return at<9>().valid(); }
+  uint32_t timecode_seconds() const { return at<9>().as_uint32(); }
+  bool has_timecode_type() const { return at<10>().valid(); }
+  uint32_t timecode_type() const { return at<10>().as_uint32(); }
+  bool has_timecode_userbits0() const { return at<11>().valid(); }
+  uint32_t timecode_userbits0() const { return at<11>().as_uint32(); }
+  bool has_timecode_userbits1() const { return at<12>().valid(); }
+  uint32_t timecode_userbits1() const { return at<12>().as_uint32(); }
+  bool has_timecode_userbits2() const { return at<13>().valid(); }
+  uint32_t timecode_userbits2() const { return at<13>().as_uint32(); }
+  bool has_timecode_userbits3() const { return at<14>().valid(); }
+  uint32_t timecode_userbits3() const { return at<14>().as_uint32(); }
+  bool has_timestamp() const { return at<15>().valid(); }
+  int64_t timestamp() const { return at<15>().as_int64(); }
+};
+
+class Vb2V4l2QbufFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Vb2V4l2QbufFtraceEvent_Decoder;
+  enum : int32_t {
+    kFieldFieldNumber = 1,
+    kFlagsFieldNumber = 2,
+    kMinorFieldNumber = 3,
+    kSequenceFieldNumber = 4,
+    kTimecodeFlagsFieldNumber = 5,
+    kTimecodeFramesFieldNumber = 6,
+    kTimecodeHoursFieldNumber = 7,
+    kTimecodeMinutesFieldNumber = 8,
+    kTimecodeSecondsFieldNumber = 9,
+    kTimecodeTypeFieldNumber = 10,
+    kTimecodeUserbits0FieldNumber = 11,
+    kTimecodeUserbits1FieldNumber = 12,
+    kTimecodeUserbits2FieldNumber = 13,
+    kTimecodeUserbits3FieldNumber = 14,
+    kTimestampFieldNumber = 15,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Vb2V4l2QbufFtraceEvent"; }
+
+
+  using FieldMetadata_Field =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Field kField{};
+  void set_field(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Field::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_Minor =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Vb2V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Minor kMinor{};
+  void set_minor(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Minor::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_Sequence =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Sequence kSequence{};
+  void set_sequence(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sequence::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_TimecodeFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeFlags kTimecodeFlags{};
+  void set_timecode_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeFlags::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_TimecodeFrames =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeFrames kTimecodeFrames{};
+  void set_timecode_frames(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeFrames::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_TimecodeHours =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeHours kTimecodeHours{};
+  void set_timecode_hours(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeHours::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_TimecodeMinutes =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeMinutes kTimecodeMinutes{};
+  void set_timecode_minutes(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeMinutes::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_TimecodeSeconds =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeSeconds kTimecodeSeconds{};
+  void set_timecode_seconds(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeSeconds::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_TimecodeType =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeType kTimecodeType{};
+  void set_timecode_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeType::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_TimecodeUserbits0 =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits0 kTimecodeUserbits0{};
+  void set_timecode_userbits0(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits0::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_TimecodeUserbits1 =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits1 kTimecodeUserbits1{};
+  void set_timecode_userbits1(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits1::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_TimecodeUserbits2 =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits2 kTimecodeUserbits2{};
+  void set_timecode_userbits2(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits2::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_TimecodeUserbits3 =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits3 kTimecodeUserbits3{};
+  void set_timecode_userbits3(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits3::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_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Vb2V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Timestamp kTimestamp{};
+  void set_timestamp(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timestamp::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 Vb2V4l2BufDoneFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/15, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Vb2V4l2BufDoneFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Vb2V4l2BufDoneFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Vb2V4l2BufDoneFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_field() const { return at<1>().valid(); }
+  uint32_t field() const { return at<1>().as_uint32(); }
+  bool has_flags() const { return at<2>().valid(); }
+  uint32_t flags() const { return at<2>().as_uint32(); }
+  bool has_minor() const { return at<3>().valid(); }
+  int32_t minor() const { return at<3>().as_int32(); }
+  bool has_sequence() const { return at<4>().valid(); }
+  uint32_t sequence() const { return at<4>().as_uint32(); }
+  bool has_timecode_flags() const { return at<5>().valid(); }
+  uint32_t timecode_flags() const { return at<5>().as_uint32(); }
+  bool has_timecode_frames() const { return at<6>().valid(); }
+  uint32_t timecode_frames() const { return at<6>().as_uint32(); }
+  bool has_timecode_hours() const { return at<7>().valid(); }
+  uint32_t timecode_hours() const { return at<7>().as_uint32(); }
+  bool has_timecode_minutes() const { return at<8>().valid(); }
+  uint32_t timecode_minutes() const { return at<8>().as_uint32(); }
+  bool has_timecode_seconds() const { return at<9>().valid(); }
+  uint32_t timecode_seconds() const { return at<9>().as_uint32(); }
+  bool has_timecode_type() const { return at<10>().valid(); }
+  uint32_t timecode_type() const { return at<10>().as_uint32(); }
+  bool has_timecode_userbits0() const { return at<11>().valid(); }
+  uint32_t timecode_userbits0() const { return at<11>().as_uint32(); }
+  bool has_timecode_userbits1() const { return at<12>().valid(); }
+  uint32_t timecode_userbits1() const { return at<12>().as_uint32(); }
+  bool has_timecode_userbits2() const { return at<13>().valid(); }
+  uint32_t timecode_userbits2() const { return at<13>().as_uint32(); }
+  bool has_timecode_userbits3() const { return at<14>().valid(); }
+  uint32_t timecode_userbits3() const { return at<14>().as_uint32(); }
+  bool has_timestamp() const { return at<15>().valid(); }
+  int64_t timestamp() const { return at<15>().as_int64(); }
+};
+
+class Vb2V4l2BufDoneFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Vb2V4l2BufDoneFtraceEvent_Decoder;
+  enum : int32_t {
+    kFieldFieldNumber = 1,
+    kFlagsFieldNumber = 2,
+    kMinorFieldNumber = 3,
+    kSequenceFieldNumber = 4,
+    kTimecodeFlagsFieldNumber = 5,
+    kTimecodeFramesFieldNumber = 6,
+    kTimecodeHoursFieldNumber = 7,
+    kTimecodeMinutesFieldNumber = 8,
+    kTimecodeSecondsFieldNumber = 9,
+    kTimecodeTypeFieldNumber = 10,
+    kTimecodeUserbits0FieldNumber = 11,
+    kTimecodeUserbits1FieldNumber = 12,
+    kTimecodeUserbits2FieldNumber = 13,
+    kTimecodeUserbits3FieldNumber = 14,
+    kTimestampFieldNumber = 15,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Vb2V4l2BufDoneFtraceEvent"; }
+
+
+  using FieldMetadata_Field =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Field kField{};
+  void set_field(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Field::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_Minor =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Vb2V4l2BufDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Minor kMinor{};
+  void set_minor(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Minor::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_Sequence =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Sequence kSequence{};
+  void set_sequence(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sequence::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_TimecodeFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeFlags kTimecodeFlags{};
+  void set_timecode_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeFlags::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_TimecodeFrames =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeFrames kTimecodeFrames{};
+  void set_timecode_frames(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeFrames::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_TimecodeHours =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeHours kTimecodeHours{};
+  void set_timecode_hours(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeHours::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_TimecodeMinutes =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeMinutes kTimecodeMinutes{};
+  void set_timecode_minutes(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeMinutes::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_TimecodeSeconds =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeSeconds kTimecodeSeconds{};
+  void set_timecode_seconds(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeSeconds::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_TimecodeType =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeType kTimecodeType{};
+  void set_timecode_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeType::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_TimecodeUserbits0 =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits0 kTimecodeUserbits0{};
+  void set_timecode_userbits0(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits0::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_TimecodeUserbits1 =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits1 kTimecodeUserbits1{};
+  void set_timecode_userbits1(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits1::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_TimecodeUserbits2 =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits2 kTimecodeUserbits2{};
+  void set_timecode_userbits2(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits2::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_TimecodeUserbits3 =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits3 kTimecodeUserbits3{};
+  void set_timecode_userbits3(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits3::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_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Vb2V4l2BufDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Timestamp kTimestamp{};
+  void set_timestamp(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timestamp::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 Vb2V4l2BufQueueFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/15, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Vb2V4l2BufQueueFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Vb2V4l2BufQueueFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Vb2V4l2BufQueueFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_field() const { return at<1>().valid(); }
+  uint32_t field() const { return at<1>().as_uint32(); }
+  bool has_flags() const { return at<2>().valid(); }
+  uint32_t flags() const { return at<2>().as_uint32(); }
+  bool has_minor() const { return at<3>().valid(); }
+  int32_t minor() const { return at<3>().as_int32(); }
+  bool has_sequence() const { return at<4>().valid(); }
+  uint32_t sequence() const { return at<4>().as_uint32(); }
+  bool has_timecode_flags() const { return at<5>().valid(); }
+  uint32_t timecode_flags() const { return at<5>().as_uint32(); }
+  bool has_timecode_frames() const { return at<6>().valid(); }
+  uint32_t timecode_frames() const { return at<6>().as_uint32(); }
+  bool has_timecode_hours() const { return at<7>().valid(); }
+  uint32_t timecode_hours() const { return at<7>().as_uint32(); }
+  bool has_timecode_minutes() const { return at<8>().valid(); }
+  uint32_t timecode_minutes() const { return at<8>().as_uint32(); }
+  bool has_timecode_seconds() const { return at<9>().valid(); }
+  uint32_t timecode_seconds() const { return at<9>().as_uint32(); }
+  bool has_timecode_type() const { return at<10>().valid(); }
+  uint32_t timecode_type() const { return at<10>().as_uint32(); }
+  bool has_timecode_userbits0() const { return at<11>().valid(); }
+  uint32_t timecode_userbits0() const { return at<11>().as_uint32(); }
+  bool has_timecode_userbits1() const { return at<12>().valid(); }
+  uint32_t timecode_userbits1() const { return at<12>().as_uint32(); }
+  bool has_timecode_userbits2() const { return at<13>().valid(); }
+  uint32_t timecode_userbits2() const { return at<13>().as_uint32(); }
+  bool has_timecode_userbits3() const { return at<14>().valid(); }
+  uint32_t timecode_userbits3() const { return at<14>().as_uint32(); }
+  bool has_timestamp() const { return at<15>().valid(); }
+  int64_t timestamp() const { return at<15>().as_int64(); }
+};
+
+class Vb2V4l2BufQueueFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Vb2V4l2BufQueueFtraceEvent_Decoder;
+  enum : int32_t {
+    kFieldFieldNumber = 1,
+    kFlagsFieldNumber = 2,
+    kMinorFieldNumber = 3,
+    kSequenceFieldNumber = 4,
+    kTimecodeFlagsFieldNumber = 5,
+    kTimecodeFramesFieldNumber = 6,
+    kTimecodeHoursFieldNumber = 7,
+    kTimecodeMinutesFieldNumber = 8,
+    kTimecodeSecondsFieldNumber = 9,
+    kTimecodeTypeFieldNumber = 10,
+    kTimecodeUserbits0FieldNumber = 11,
+    kTimecodeUserbits1FieldNumber = 12,
+    kTimecodeUserbits2FieldNumber = 13,
+    kTimecodeUserbits3FieldNumber = 14,
+    kTimestampFieldNumber = 15,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Vb2V4l2BufQueueFtraceEvent"; }
+
+
+  using FieldMetadata_Field =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_Field kField{};
+  void set_field(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Field::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_Minor =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Vb2V4l2BufQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_Minor kMinor{};
+  void set_minor(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Minor::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_Sequence =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_Sequence kSequence{};
+  void set_sequence(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sequence::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_TimecodeFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeFlags kTimecodeFlags{};
+  void set_timecode_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeFlags::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_TimecodeFrames =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeFrames kTimecodeFrames{};
+  void set_timecode_frames(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeFrames::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_TimecodeHours =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeHours kTimecodeHours{};
+  void set_timecode_hours(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeHours::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_TimecodeMinutes =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeMinutes kTimecodeMinutes{};
+  void set_timecode_minutes(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeMinutes::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_TimecodeSeconds =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeSeconds kTimecodeSeconds{};
+  void set_timecode_seconds(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeSeconds::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_TimecodeType =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeType kTimecodeType{};
+  void set_timecode_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeType::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_TimecodeUserbits0 =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits0 kTimecodeUserbits0{};
+  void set_timecode_userbits0(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits0::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_TimecodeUserbits1 =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits1 kTimecodeUserbits1{};
+  void set_timecode_userbits1(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits1::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_TimecodeUserbits2 =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits2 kTimecodeUserbits2{};
+  void set_timecode_userbits2(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits2::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_TimecodeUserbits3 =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits3 kTimecodeUserbits3{};
+  void set_timecode_userbits3(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits3::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_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Vb2V4l2BufQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_Timestamp kTimestamp{};
+  void set_timestamp(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timestamp::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 V4l2DqbufFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/18, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  V4l2DqbufFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit V4l2DqbufFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit V4l2DqbufFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_bytesused() const { return at<1>().valid(); }
+  uint32_t bytesused() const { return at<1>().as_uint32(); }
+  bool has_field() const { return at<2>().valid(); }
+  uint32_t field() const { return at<2>().as_uint32(); }
+  bool has_flags() const { return at<3>().valid(); }
+  uint32_t flags() const { return at<3>().as_uint32(); }
+  bool has_index() const { return at<4>().valid(); }
+  uint32_t index() const { return at<4>().as_uint32(); }
+  bool has_minor() const { return at<5>().valid(); }
+  int32_t minor() const { return at<5>().as_int32(); }
+  bool has_sequence() const { return at<6>().valid(); }
+  uint32_t sequence() const { return at<6>().as_uint32(); }
+  bool has_timecode_flags() const { return at<7>().valid(); }
+  uint32_t timecode_flags() const { return at<7>().as_uint32(); }
+  bool has_timecode_frames() const { return at<8>().valid(); }
+  uint32_t timecode_frames() const { return at<8>().as_uint32(); }
+  bool has_timecode_hours() const { return at<9>().valid(); }
+  uint32_t timecode_hours() const { return at<9>().as_uint32(); }
+  bool has_timecode_minutes() const { return at<10>().valid(); }
+  uint32_t timecode_minutes() const { return at<10>().as_uint32(); }
+  bool has_timecode_seconds() const { return at<11>().valid(); }
+  uint32_t timecode_seconds() const { return at<11>().as_uint32(); }
+  bool has_timecode_type() const { return at<12>().valid(); }
+  uint32_t timecode_type() const { return at<12>().as_uint32(); }
+  bool has_timecode_userbits0() const { return at<13>().valid(); }
+  uint32_t timecode_userbits0() const { return at<13>().as_uint32(); }
+  bool has_timecode_userbits1() const { return at<14>().valid(); }
+  uint32_t timecode_userbits1() const { return at<14>().as_uint32(); }
+  bool has_timecode_userbits2() const { return at<15>().valid(); }
+  uint32_t timecode_userbits2() const { return at<15>().as_uint32(); }
+  bool has_timecode_userbits3() const { return at<16>().valid(); }
+  uint32_t timecode_userbits3() const { return at<16>().as_uint32(); }
+  bool has_timestamp() const { return at<17>().valid(); }
+  int64_t timestamp() const { return at<17>().as_int64(); }
+  bool has_type() const { return at<18>().valid(); }
+  uint32_t type() const { return at<18>().as_uint32(); }
+};
+
+class V4l2DqbufFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = V4l2DqbufFtraceEvent_Decoder;
+  enum : int32_t {
+    kBytesusedFieldNumber = 1,
+    kFieldFieldNumber = 2,
+    kFlagsFieldNumber = 3,
+    kIndexFieldNumber = 4,
+    kMinorFieldNumber = 5,
+    kSequenceFieldNumber = 6,
+    kTimecodeFlagsFieldNumber = 7,
+    kTimecodeFramesFieldNumber = 8,
+    kTimecodeHoursFieldNumber = 9,
+    kTimecodeMinutesFieldNumber = 10,
+    kTimecodeSecondsFieldNumber = 11,
+    kTimecodeTypeFieldNumber = 12,
+    kTimecodeUserbits0FieldNumber = 13,
+    kTimecodeUserbits1FieldNumber = 14,
+    kTimecodeUserbits2FieldNumber = 15,
+    kTimecodeUserbits3FieldNumber = 16,
+    kTimestampFieldNumber = 17,
+    kTypeFieldNumber = 18,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.V4l2DqbufFtraceEvent"; }
+
+
+  using FieldMetadata_Bytesused =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Bytesused kBytesused{};
+  void set_bytesused(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Bytesused::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_Field =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Field kField{};
+  void set_field(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Field::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Index kIndex{};
+  void set_index(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Index::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_Minor =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Minor kMinor{};
+  void set_minor(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Minor::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_Sequence =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Sequence kSequence{};
+  void set_sequence(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sequence::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_TimecodeFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeFlags kTimecodeFlags{};
+  void set_timecode_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeFlags::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_TimecodeFrames =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeFrames kTimecodeFrames{};
+  void set_timecode_frames(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeFrames::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_TimecodeHours =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeHours kTimecodeHours{};
+  void set_timecode_hours(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeHours::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_TimecodeMinutes =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeMinutes kTimecodeMinutes{};
+  void set_timecode_minutes(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeMinutes::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_TimecodeSeconds =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeSeconds kTimecodeSeconds{};
+  void set_timecode_seconds(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeSeconds::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_TimecodeType =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeType kTimecodeType{};
+  void set_timecode_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeType::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_TimecodeUserbits0 =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits0 kTimecodeUserbits0{};
+  void set_timecode_userbits0(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits0::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_TimecodeUserbits1 =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits1 kTimecodeUserbits1{};
+  void set_timecode_userbits1(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits1::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_TimecodeUserbits2 =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits2 kTimecodeUserbits2{};
+  void set_timecode_userbits2(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits2::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_TimecodeUserbits3 =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits3 kTimecodeUserbits3{};
+  void set_timecode_userbits3(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits3::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_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Timestamp kTimestamp{};
+  void set_timestamp(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timestamp::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_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::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 V4l2QbufFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/18, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  V4l2QbufFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit V4l2QbufFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit V4l2QbufFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_bytesused() const { return at<1>().valid(); }
+  uint32_t bytesused() const { return at<1>().as_uint32(); }
+  bool has_field() const { return at<2>().valid(); }
+  uint32_t field() const { return at<2>().as_uint32(); }
+  bool has_flags() const { return at<3>().valid(); }
+  uint32_t flags() const { return at<3>().as_uint32(); }
+  bool has_index() const { return at<4>().valid(); }
+  uint32_t index() const { return at<4>().as_uint32(); }
+  bool has_minor() const { return at<5>().valid(); }
+  int32_t minor() const { return at<5>().as_int32(); }
+  bool has_sequence() const { return at<6>().valid(); }
+  uint32_t sequence() const { return at<6>().as_uint32(); }
+  bool has_timecode_flags() const { return at<7>().valid(); }
+  uint32_t timecode_flags() const { return at<7>().as_uint32(); }
+  bool has_timecode_frames() const { return at<8>().valid(); }
+  uint32_t timecode_frames() const { return at<8>().as_uint32(); }
+  bool has_timecode_hours() const { return at<9>().valid(); }
+  uint32_t timecode_hours() const { return at<9>().as_uint32(); }
+  bool has_timecode_minutes() const { return at<10>().valid(); }
+  uint32_t timecode_minutes() const { return at<10>().as_uint32(); }
+  bool has_timecode_seconds() const { return at<11>().valid(); }
+  uint32_t timecode_seconds() const { return at<11>().as_uint32(); }
+  bool has_timecode_type() const { return at<12>().valid(); }
+  uint32_t timecode_type() const { return at<12>().as_uint32(); }
+  bool has_timecode_userbits0() const { return at<13>().valid(); }
+  uint32_t timecode_userbits0() const { return at<13>().as_uint32(); }
+  bool has_timecode_userbits1() const { return at<14>().valid(); }
+  uint32_t timecode_userbits1() const { return at<14>().as_uint32(); }
+  bool has_timecode_userbits2() const { return at<15>().valid(); }
+  uint32_t timecode_userbits2() const { return at<15>().as_uint32(); }
+  bool has_timecode_userbits3() const { return at<16>().valid(); }
+  uint32_t timecode_userbits3() const { return at<16>().as_uint32(); }
+  bool has_timestamp() const { return at<17>().valid(); }
+  int64_t timestamp() const { return at<17>().as_int64(); }
+  bool has_type() const { return at<18>().valid(); }
+  uint32_t type() const { return at<18>().as_uint32(); }
+};
+
+class V4l2QbufFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = V4l2QbufFtraceEvent_Decoder;
+  enum : int32_t {
+    kBytesusedFieldNumber = 1,
+    kFieldFieldNumber = 2,
+    kFlagsFieldNumber = 3,
+    kIndexFieldNumber = 4,
+    kMinorFieldNumber = 5,
+    kSequenceFieldNumber = 6,
+    kTimecodeFlagsFieldNumber = 7,
+    kTimecodeFramesFieldNumber = 8,
+    kTimecodeHoursFieldNumber = 9,
+    kTimecodeMinutesFieldNumber = 10,
+    kTimecodeSecondsFieldNumber = 11,
+    kTimecodeTypeFieldNumber = 12,
+    kTimecodeUserbits0FieldNumber = 13,
+    kTimecodeUserbits1FieldNumber = 14,
+    kTimecodeUserbits2FieldNumber = 15,
+    kTimecodeUserbits3FieldNumber = 16,
+    kTimestampFieldNumber = 17,
+    kTypeFieldNumber = 18,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.V4l2QbufFtraceEvent"; }
+
+
+  using FieldMetadata_Bytesused =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Bytesused kBytesused{};
+  void set_bytesused(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Bytesused::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_Field =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Field kField{};
+  void set_field(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Field::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Index kIndex{};
+  void set_index(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Index::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_Minor =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Minor kMinor{};
+  void set_minor(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Minor::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_Sequence =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Sequence kSequence{};
+  void set_sequence(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sequence::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_TimecodeFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeFlags kTimecodeFlags{};
+  void set_timecode_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeFlags::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_TimecodeFrames =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeFrames kTimecodeFrames{};
+  void set_timecode_frames(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeFrames::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_TimecodeHours =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeHours kTimecodeHours{};
+  void set_timecode_hours(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeHours::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_TimecodeMinutes =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeMinutes kTimecodeMinutes{};
+  void set_timecode_minutes(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeMinutes::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_TimecodeSeconds =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeSeconds kTimecodeSeconds{};
+  void set_timecode_seconds(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeSeconds::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_TimecodeType =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeType kTimecodeType{};
+  void set_timecode_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeType::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_TimecodeUserbits0 =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits0 kTimecodeUserbits0{};
+  void set_timecode_userbits0(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits0::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_TimecodeUserbits1 =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits1 kTimecodeUserbits1{};
+  void set_timecode_userbits1(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits1::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_TimecodeUserbits2 =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits2 kTimecodeUserbits2{};
+  void set_timecode_userbits2(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits2::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_TimecodeUserbits3 =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits3 kTimecodeUserbits3{};
+  void set_timecode_userbits3(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits3::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_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Timestamp kTimestamp{};
+  void set_timestamp(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timestamp::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_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/virtio_gpu.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_VIRTIO_GPU_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_VIRTIO_GPU_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class VirtioGpuCmdResponseFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  VirtioGpuCmdResponseFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit VirtioGpuCmdResponseFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit VirtioGpuCmdResponseFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ctx_id() const { return at<1>().valid(); }
+  uint32_t ctx_id() const { return at<1>().as_uint32(); }
+  bool has_dev() const { return at<2>().valid(); }
+  int32_t dev() const { return at<2>().as_int32(); }
+  bool has_fence_id() const { return at<3>().valid(); }
+  uint64_t fence_id() const { return at<3>().as_uint64(); }
+  bool has_flags() const { return at<4>().valid(); }
+  uint32_t flags() const { return at<4>().as_uint32(); }
+  bool has_name() const { return at<5>().valid(); }
+  ::protozero::ConstChars name() const { return at<5>().as_string(); }
+  bool has_num_free() const { return at<6>().valid(); }
+  uint32_t num_free() const { return at<6>().as_uint32(); }
+  bool has_seqno() const { return at<7>().valid(); }
+  uint32_t seqno() const { return at<7>().as_uint32(); }
+  bool has_type() const { return at<8>().valid(); }
+  uint32_t type() const { return at<8>().as_uint32(); }
+  bool has_vq() const { return at<9>().valid(); }
+  uint32_t vq() const { return at<9>().as_uint32(); }
+};
+
+class VirtioGpuCmdResponseFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = VirtioGpuCmdResponseFtraceEvent_Decoder;
+  enum : int32_t {
+    kCtxIdFieldNumber = 1,
+    kDevFieldNumber = 2,
+    kFenceIdFieldNumber = 3,
+    kFlagsFieldNumber = 4,
+    kNameFieldNumber = 5,
+    kNumFreeFieldNumber = 6,
+    kSeqnoFieldNumber = 7,
+    kTypeFieldNumber = 8,
+    kVqFieldNumber = 9,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.VirtioGpuCmdResponseFtraceEvent"; }
+
+
+  using FieldMetadata_CtxId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioGpuCmdResponseFtraceEvent>;
+
+  static constexpr FieldMetadata_CtxId kCtxId{};
+  void set_ctx_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CtxId::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_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      VirtioGpuCmdResponseFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_FenceId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      VirtioGpuCmdResponseFtraceEvent>;
+
+  static constexpr FieldMetadata_FenceId kFenceId{};
+  void set_fence_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FenceId::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioGpuCmdResponseFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      VirtioGpuCmdResponseFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_NumFree =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioGpuCmdResponseFtraceEvent>;
+
+  static constexpr FieldMetadata_NumFree kNumFree{};
+  void set_num_free(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NumFree::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_Seqno =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioGpuCmdResponseFtraceEvent>;
+
+  static constexpr FieldMetadata_Seqno kSeqno{};
+  void set_seqno(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Seqno::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_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioGpuCmdResponseFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::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_Vq =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioGpuCmdResponseFtraceEvent>;
+
+  static constexpr FieldMetadata_Vq kVq{};
+  void set_vq(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Vq::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 VirtioGpuCmdQueueFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  VirtioGpuCmdQueueFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit VirtioGpuCmdQueueFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit VirtioGpuCmdQueueFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ctx_id() const { return at<1>().valid(); }
+  uint32_t ctx_id() const { return at<1>().as_uint32(); }
+  bool has_dev() const { return at<2>().valid(); }
+  int32_t dev() const { return at<2>().as_int32(); }
+  bool has_fence_id() const { return at<3>().valid(); }
+  uint64_t fence_id() const { return at<3>().as_uint64(); }
+  bool has_flags() const { return at<4>().valid(); }
+  uint32_t flags() const { return at<4>().as_uint32(); }
+  bool has_name() const { return at<5>().valid(); }
+  ::protozero::ConstChars name() const { return at<5>().as_string(); }
+  bool has_num_free() const { return at<6>().valid(); }
+  uint32_t num_free() const { return at<6>().as_uint32(); }
+  bool has_seqno() const { return at<7>().valid(); }
+  uint32_t seqno() const { return at<7>().as_uint32(); }
+  bool has_type() const { return at<8>().valid(); }
+  uint32_t type() const { return at<8>().as_uint32(); }
+  bool has_vq() const { return at<9>().valid(); }
+  uint32_t vq() const { return at<9>().as_uint32(); }
+};
+
+class VirtioGpuCmdQueueFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = VirtioGpuCmdQueueFtraceEvent_Decoder;
+  enum : int32_t {
+    kCtxIdFieldNumber = 1,
+    kDevFieldNumber = 2,
+    kFenceIdFieldNumber = 3,
+    kFlagsFieldNumber = 4,
+    kNameFieldNumber = 5,
+    kNumFreeFieldNumber = 6,
+    kSeqnoFieldNumber = 7,
+    kTypeFieldNumber = 8,
+    kVqFieldNumber = 9,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.VirtioGpuCmdQueueFtraceEvent"; }
+
+
+  using FieldMetadata_CtxId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioGpuCmdQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_CtxId kCtxId{};
+  void set_ctx_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CtxId::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_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      VirtioGpuCmdQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::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_FenceId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      VirtioGpuCmdQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_FenceId kFenceId{};
+  void set_fence_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FenceId::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_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioGpuCmdQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      VirtioGpuCmdQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_NumFree =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioGpuCmdQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_NumFree kNumFree{};
+  void set_num_free(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NumFree::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_Seqno =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioGpuCmdQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_Seqno kSeqno{};
+  void set_seqno(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Seqno::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_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioGpuCmdQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::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_Vq =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioGpuCmdQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_Vq kVq{};
+  void set_vq(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Vq::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/virtio_video.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_VIRTIO_VIDEO_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_VIRTIO_VIDEO_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class VirtioVideoResourceQueueDoneFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  VirtioVideoResourceQueueDoneFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit VirtioVideoResourceQueueDoneFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit VirtioVideoResourceQueueDoneFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_data_size0() const { return at<1>().valid(); }
+  uint32_t data_size0() const { return at<1>().as_uint32(); }
+  bool has_data_size1() const { return at<2>().valid(); }
+  uint32_t data_size1() const { return at<2>().as_uint32(); }
+  bool has_data_size2() const { return at<3>().valid(); }
+  uint32_t data_size2() const { return at<3>().as_uint32(); }
+  bool has_data_size3() const { return at<4>().valid(); }
+  uint32_t data_size3() const { return at<4>().as_uint32(); }
+  bool has_queue_type() const { return at<5>().valid(); }
+  uint32_t queue_type() const { return at<5>().as_uint32(); }
+  bool has_resource_id() const { return at<6>().valid(); }
+  int32_t resource_id() const { return at<6>().as_int32(); }
+  bool has_stream_id() const { return at<7>().valid(); }
+  int32_t stream_id() const { return at<7>().as_int32(); }
+  bool has_timestamp() const { return at<8>().valid(); }
+  uint64_t timestamp() const { return at<8>().as_uint64(); }
+};
+
+class VirtioVideoResourceQueueDoneFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = VirtioVideoResourceQueueDoneFtraceEvent_Decoder;
+  enum : int32_t {
+    kDataSize0FieldNumber = 1,
+    kDataSize1FieldNumber = 2,
+    kDataSize2FieldNumber = 3,
+    kDataSize3FieldNumber = 4,
+    kQueueTypeFieldNumber = 5,
+    kResourceIdFieldNumber = 6,
+    kStreamIdFieldNumber = 7,
+    kTimestampFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.VirtioVideoResourceQueueDoneFtraceEvent"; }
+
+
+  using FieldMetadata_DataSize0 =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioVideoResourceQueueDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_DataSize0 kDataSize0{};
+  void set_data_size0(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DataSize0::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_DataSize1 =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioVideoResourceQueueDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_DataSize1 kDataSize1{};
+  void set_data_size1(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DataSize1::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_DataSize2 =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioVideoResourceQueueDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_DataSize2 kDataSize2{};
+  void set_data_size2(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DataSize2::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_DataSize3 =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioVideoResourceQueueDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_DataSize3 kDataSize3{};
+  void set_data_size3(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DataSize3::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_QueueType =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioVideoResourceQueueDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_QueueType kQueueType{};
+  void set_queue_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_QueueType::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_ResourceId =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      VirtioVideoResourceQueueDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_ResourceId kResourceId{};
+  void set_resource_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResourceId::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_StreamId =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      VirtioVideoResourceQueueDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_StreamId kStreamId{};
+  void set_stream_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StreamId::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_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      VirtioVideoResourceQueueDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Timestamp kTimestamp{};
+  void set_timestamp(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timestamp::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 VirtioVideoResourceQueueFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  VirtioVideoResourceQueueFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit VirtioVideoResourceQueueFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit VirtioVideoResourceQueueFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_data_size0() const { return at<1>().valid(); }
+  uint32_t data_size0() const { return at<1>().as_uint32(); }
+  bool has_data_size1() const { return at<2>().valid(); }
+  uint32_t data_size1() const { return at<2>().as_uint32(); }
+  bool has_data_size2() const { return at<3>().valid(); }
+  uint32_t data_size2() const { return at<3>().as_uint32(); }
+  bool has_data_size3() const { return at<4>().valid(); }
+  uint32_t data_size3() const { return at<4>().as_uint32(); }
+  bool has_queue_type() const { return at<5>().valid(); }
+  uint32_t queue_type() const { return at<5>().as_uint32(); }
+  bool has_resource_id() const { return at<6>().valid(); }
+  int32_t resource_id() const { return at<6>().as_int32(); }
+  bool has_stream_id() const { return at<7>().valid(); }
+  int32_t stream_id() const { return at<7>().as_int32(); }
+  bool has_timestamp() const { return at<8>().valid(); }
+  uint64_t timestamp() const { return at<8>().as_uint64(); }
+};
+
+class VirtioVideoResourceQueueFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = VirtioVideoResourceQueueFtraceEvent_Decoder;
+  enum : int32_t {
+    kDataSize0FieldNumber = 1,
+    kDataSize1FieldNumber = 2,
+    kDataSize2FieldNumber = 3,
+    kDataSize3FieldNumber = 4,
+    kQueueTypeFieldNumber = 5,
+    kResourceIdFieldNumber = 6,
+    kStreamIdFieldNumber = 7,
+    kTimestampFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.VirtioVideoResourceQueueFtraceEvent"; }
+
+
+  using FieldMetadata_DataSize0 =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioVideoResourceQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_DataSize0 kDataSize0{};
+  void set_data_size0(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DataSize0::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_DataSize1 =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioVideoResourceQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_DataSize1 kDataSize1{};
+  void set_data_size1(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DataSize1::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_DataSize2 =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioVideoResourceQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_DataSize2 kDataSize2{};
+  void set_data_size2(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DataSize2::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_DataSize3 =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioVideoResourceQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_DataSize3 kDataSize3{};
+  void set_data_size3(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DataSize3::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_QueueType =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioVideoResourceQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_QueueType kQueueType{};
+  void set_queue_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_QueueType::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_ResourceId =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      VirtioVideoResourceQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_ResourceId kResourceId{};
+  void set_resource_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResourceId::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_StreamId =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      VirtioVideoResourceQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_StreamId kStreamId{};
+  void set_stream_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StreamId::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_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      VirtioVideoResourceQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_Timestamp kTimestamp{};
+  void set_timestamp(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timestamp::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 VirtioVideoCmdDoneFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  VirtioVideoCmdDoneFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit VirtioVideoCmdDoneFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit VirtioVideoCmdDoneFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_stream_id() const { return at<1>().valid(); }
+  uint32_t stream_id() const { return at<1>().as_uint32(); }
+  bool has_type() const { return at<2>().valid(); }
+  uint32_t type() const { return at<2>().as_uint32(); }
+};
+
+class VirtioVideoCmdDoneFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = VirtioVideoCmdDoneFtraceEvent_Decoder;
+  enum : int32_t {
+    kStreamIdFieldNumber = 1,
+    kTypeFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.VirtioVideoCmdDoneFtraceEvent"; }
+
+
+  using FieldMetadata_StreamId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioVideoCmdDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_StreamId kStreamId{};
+  void set_stream_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StreamId::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_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioVideoCmdDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::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 VirtioVideoCmdFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  VirtioVideoCmdFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit VirtioVideoCmdFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit VirtioVideoCmdFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_stream_id() const { return at<1>().valid(); }
+  uint32_t stream_id() const { return at<1>().as_uint32(); }
+  bool has_type() const { return at<2>().valid(); }
+  uint32_t type() const { return at<2>().as_uint32(); }
+};
+
+class VirtioVideoCmdFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = VirtioVideoCmdFtraceEvent_Decoder;
+  enum : int32_t {
+    kStreamIdFieldNumber = 1,
+    kTypeFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.VirtioVideoCmdFtraceEvent"; }
+
+
+  using FieldMetadata_StreamId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioVideoCmdFtraceEvent>;
+
+  static constexpr FieldMetadata_StreamId kStreamId{};
+  void set_stream_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StreamId::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_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioVideoCmdFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/vmscan.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_VMSCAN_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_VMSCAN_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class MmShrinkSlabEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmShrinkSlabEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmShrinkSlabEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmShrinkSlabEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_new_scan() const { return at<1>().valid(); }
+  int64_t new_scan() const { return at<1>().as_int64(); }
+  bool has_retval() const { return at<2>().valid(); }
+  int32_t retval() const { return at<2>().as_int32(); }
+  bool has_shr() const { return at<3>().valid(); }
+  uint64_t shr() const { return at<3>().as_uint64(); }
+  bool has_shrink() const { return at<4>().valid(); }
+  uint64_t shrink() const { return at<4>().as_uint64(); }
+  bool has_total_scan() const { return at<5>().valid(); }
+  int64_t total_scan() const { return at<5>().as_int64(); }
+  bool has_unused_scan() const { return at<6>().valid(); }
+  int64_t unused_scan() const { return at<6>().as_int64(); }
+  bool has_nid() const { return at<7>().valid(); }
+  int32_t nid() const { return at<7>().as_int32(); }
+};
+
+class MmShrinkSlabEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmShrinkSlabEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kNewScanFieldNumber = 1,
+    kRetvalFieldNumber = 2,
+    kShrFieldNumber = 3,
+    kShrinkFieldNumber = 4,
+    kTotalScanFieldNumber = 5,
+    kUnusedScanFieldNumber = 6,
+    kNidFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmShrinkSlabEndFtraceEvent"; }
+
+
+  using FieldMetadata_NewScan =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      MmShrinkSlabEndFtraceEvent>;
+
+  static constexpr FieldMetadata_NewScan kNewScan{};
+  void set_new_scan(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NewScan::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_Retval =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmShrinkSlabEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Retval kRetval{};
+  void set_retval(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Retval::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_Shr =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmShrinkSlabEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Shr kShr{};
+  void set_shr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Shr::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_Shrink =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmShrinkSlabEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Shrink kShrink{};
+  void set_shrink(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Shrink::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_TotalScan =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      MmShrinkSlabEndFtraceEvent>;
+
+  static constexpr FieldMetadata_TotalScan kTotalScan{};
+  void set_total_scan(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TotalScan::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_UnusedScan =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      MmShrinkSlabEndFtraceEvent>;
+
+  static constexpr FieldMetadata_UnusedScan kUnusedScan{};
+  void set_unused_scan(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UnusedScan::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_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmShrinkSlabEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Nid kNid{};
+  void set_nid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nid::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);
+  }
+};
+
+class MmShrinkSlabStartFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/11, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmShrinkSlabStartFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmShrinkSlabStartFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmShrinkSlabStartFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cache_items() const { return at<1>().valid(); }
+  uint64_t cache_items() const { return at<1>().as_uint64(); }
+  bool has_delta() const { return at<2>().valid(); }
+  uint64_t delta() const { return at<2>().as_uint64(); }
+  bool has_gfp_flags() const { return at<3>().valid(); }
+  uint32_t gfp_flags() const { return at<3>().as_uint32(); }
+  bool has_lru_pgs() const { return at<4>().valid(); }
+  uint64_t lru_pgs() const { return at<4>().as_uint64(); }
+  bool has_nr_objects_to_shrink() const { return at<5>().valid(); }
+  int64_t nr_objects_to_shrink() const { return at<5>().as_int64(); }
+  bool has_pgs_scanned() const { return at<6>().valid(); }
+  uint64_t pgs_scanned() const { return at<6>().as_uint64(); }
+  bool has_shr() const { return at<7>().valid(); }
+  uint64_t shr() const { return at<7>().as_uint64(); }
+  bool has_shrink() const { return at<8>().valid(); }
+  uint64_t shrink() const { return at<8>().as_uint64(); }
+  bool has_total_scan() const { return at<9>().valid(); }
+  uint64_t total_scan() const { return at<9>().as_uint64(); }
+  bool has_nid() const { return at<10>().valid(); }
+  int32_t nid() const { return at<10>().as_int32(); }
+  bool has_priority() const { return at<11>().valid(); }
+  int32_t priority() const { return at<11>().as_int32(); }
+};
+
+class MmShrinkSlabStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmShrinkSlabStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kCacheItemsFieldNumber = 1,
+    kDeltaFieldNumber = 2,
+    kGfpFlagsFieldNumber = 3,
+    kLruPgsFieldNumber = 4,
+    kNrObjectsToShrinkFieldNumber = 5,
+    kPgsScannedFieldNumber = 6,
+    kShrFieldNumber = 7,
+    kShrinkFieldNumber = 8,
+    kTotalScanFieldNumber = 9,
+    kNidFieldNumber = 10,
+    kPriorityFieldNumber = 11,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmShrinkSlabStartFtraceEvent"; }
+
+
+  using FieldMetadata_CacheItems =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmShrinkSlabStartFtraceEvent>;
+
+  static constexpr FieldMetadata_CacheItems kCacheItems{};
+  void set_cache_items(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CacheItems::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_Delta =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmShrinkSlabStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Delta kDelta{};
+  void set_delta(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Delta::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_GfpFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmShrinkSlabStartFtraceEvent>;
+
+  static constexpr FieldMetadata_GfpFlags kGfpFlags{};
+  void set_gfp_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GfpFlags::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_LruPgs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmShrinkSlabStartFtraceEvent>;
+
+  static constexpr FieldMetadata_LruPgs kLruPgs{};
+  void set_lru_pgs(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LruPgs::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_NrObjectsToShrink =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      MmShrinkSlabStartFtraceEvent>;
+
+  static constexpr FieldMetadata_NrObjectsToShrink kNrObjectsToShrink{};
+  void set_nr_objects_to_shrink(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrObjectsToShrink::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_PgsScanned =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmShrinkSlabStartFtraceEvent>;
+
+  static constexpr FieldMetadata_PgsScanned kPgsScanned{};
+  void set_pgs_scanned(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PgsScanned::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_Shr =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmShrinkSlabStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Shr kShr{};
+  void set_shr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Shr::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_Shrink =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmShrinkSlabStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Shrink kShrink{};
+  void set_shrink(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Shrink::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_TotalScan =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmShrinkSlabStartFtraceEvent>;
+
+  static constexpr FieldMetadata_TotalScan kTotalScan{};
+  void set_total_scan(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TotalScan::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_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmShrinkSlabStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Nid kNid{};
+  void set_nid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nid::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_Priority =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmShrinkSlabStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Priority kPriority{};
+  void set_priority(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Priority::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);
+  }
+};
+
+class MmVmscanKswapdSleepFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmVmscanKswapdSleepFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmVmscanKswapdSleepFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmVmscanKswapdSleepFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_nid() const { return at<1>().valid(); }
+  int32_t nid() const { return at<1>().as_int32(); }
+};
+
+class MmVmscanKswapdSleepFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmVmscanKswapdSleepFtraceEvent_Decoder;
+  enum : int32_t {
+    kNidFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmVmscanKswapdSleepFtraceEvent"; }
+
+
+  using FieldMetadata_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmVmscanKswapdSleepFtraceEvent>;
+
+  static constexpr FieldMetadata_Nid kNid{};
+  void set_nid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nid::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);
+  }
+};
+
+class MmVmscanKswapdWakeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmVmscanKswapdWakeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmVmscanKswapdWakeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmVmscanKswapdWakeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_nid() const { return at<1>().valid(); }
+  int32_t nid() const { return at<1>().as_int32(); }
+  bool has_order() const { return at<2>().valid(); }
+  int32_t order() const { return at<2>().as_int32(); }
+  bool has_zid() const { return at<3>().valid(); }
+  int32_t zid() const { return at<3>().as_int32(); }
+};
+
+class MmVmscanKswapdWakeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmVmscanKswapdWakeFtraceEvent_Decoder;
+  enum : int32_t {
+    kNidFieldNumber = 1,
+    kOrderFieldNumber = 2,
+    kZidFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmVmscanKswapdWakeFtraceEvent"; }
+
+
+  using FieldMetadata_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmVmscanKswapdWakeFtraceEvent>;
+
+  static constexpr FieldMetadata_Nid kNid{};
+  void set_nid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nid::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_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmVmscanKswapdWakeFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::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_Zid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmVmscanKswapdWakeFtraceEvent>;
+
+  static constexpr FieldMetadata_Zid kZid{};
+  void set_zid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Zid::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);
+  }
+};
+
+class MmVmscanDirectReclaimEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmVmscanDirectReclaimEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmVmscanDirectReclaimEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmVmscanDirectReclaimEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_nr_reclaimed() const { return at<1>().valid(); }
+  uint64_t nr_reclaimed() const { return at<1>().as_uint64(); }
+};
+
+class MmVmscanDirectReclaimEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmVmscanDirectReclaimEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kNrReclaimedFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmVmscanDirectReclaimEndFtraceEvent"; }
+
+
+  using FieldMetadata_NrReclaimed =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmVmscanDirectReclaimEndFtraceEvent>;
+
+  static constexpr FieldMetadata_NrReclaimed kNrReclaimed{};
+  void set_nr_reclaimed(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrReclaimed::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 MmVmscanDirectReclaimBeginFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmVmscanDirectReclaimBeginFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmVmscanDirectReclaimBeginFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmVmscanDirectReclaimBeginFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_order() const { return at<1>().valid(); }
+  int32_t order() const { return at<1>().as_int32(); }
+  bool has_may_writepage() const { return at<2>().valid(); }
+  int32_t may_writepage() const { return at<2>().as_int32(); }
+  bool has_gfp_flags() const { return at<3>().valid(); }
+  uint32_t gfp_flags() const { return at<3>().as_uint32(); }
+};
+
+class MmVmscanDirectReclaimBeginFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmVmscanDirectReclaimBeginFtraceEvent_Decoder;
+  enum : int32_t {
+    kOrderFieldNumber = 1,
+    kMayWritepageFieldNumber = 2,
+    kGfpFlagsFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmVmscanDirectReclaimBeginFtraceEvent"; }
+
+
+  using FieldMetadata_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmVmscanDirectReclaimBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::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_MayWritepage =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmVmscanDirectReclaimBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_MayWritepage kMayWritepage{};
+  void set_may_writepage(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MayWritepage::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_GfpFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmVmscanDirectReclaimBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_GfpFlags kGfpFlags{};
+  void set_gfp_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GfpFlags::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/workqueue.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_WORKQUEUE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_WORKQUEUE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class WorkqueueQueueWorkFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  WorkqueueQueueWorkFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit WorkqueueQueueWorkFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit WorkqueueQueueWorkFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_work() const { return at<1>().valid(); }
+  uint64_t work() const { return at<1>().as_uint64(); }
+  bool has_function() const { return at<2>().valid(); }
+  uint64_t function() const { return at<2>().as_uint64(); }
+  bool has_workqueue() const { return at<3>().valid(); }
+  uint64_t workqueue() const { return at<3>().as_uint64(); }
+  bool has_req_cpu() const { return at<4>().valid(); }
+  uint32_t req_cpu() const { return at<4>().as_uint32(); }
+  bool has_cpu() const { return at<5>().valid(); }
+  uint32_t cpu() const { return at<5>().as_uint32(); }
+};
+
+class WorkqueueQueueWorkFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = WorkqueueQueueWorkFtraceEvent_Decoder;
+  enum : int32_t {
+    kWorkFieldNumber = 1,
+    kFunctionFieldNumber = 2,
+    kWorkqueueFieldNumber = 3,
+    kReqCpuFieldNumber = 4,
+    kCpuFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.WorkqueueQueueWorkFtraceEvent"; }
+
+
+  using FieldMetadata_Work =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      WorkqueueQueueWorkFtraceEvent>;
+
+  static constexpr FieldMetadata_Work kWork{};
+  void set_work(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Work::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_Function =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      WorkqueueQueueWorkFtraceEvent>;
+
+  static constexpr FieldMetadata_Function kFunction{};
+  void set_function(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Function::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_Workqueue =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      WorkqueueQueueWorkFtraceEvent>;
+
+  static constexpr FieldMetadata_Workqueue kWorkqueue{};
+  void set_workqueue(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Workqueue::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_ReqCpu =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      WorkqueueQueueWorkFtraceEvent>;
+
+  static constexpr FieldMetadata_ReqCpu kReqCpu{};
+  void set_req_cpu(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReqCpu::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_Cpu =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      WorkqueueQueueWorkFtraceEvent>;
+
+  static constexpr FieldMetadata_Cpu kCpu{};
+  void set_cpu(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cpu::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 WorkqueueExecuteStartFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  WorkqueueExecuteStartFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit WorkqueueExecuteStartFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit WorkqueueExecuteStartFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_work() const { return at<1>().valid(); }
+  uint64_t work() const { return at<1>().as_uint64(); }
+  bool has_function() const { return at<2>().valid(); }
+  uint64_t function() const { return at<2>().as_uint64(); }
+};
+
+class WorkqueueExecuteStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = WorkqueueExecuteStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kWorkFieldNumber = 1,
+    kFunctionFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.WorkqueueExecuteStartFtraceEvent"; }
+
+
+  using FieldMetadata_Work =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      WorkqueueExecuteStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Work kWork{};
+  void set_work(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Work::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_Function =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      WorkqueueExecuteStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Function kFunction{};
+  void set_function(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Function::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 WorkqueueExecuteEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  WorkqueueExecuteEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit WorkqueueExecuteEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit WorkqueueExecuteEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_work() const { return at<1>().valid(); }
+  uint64_t work() const { return at<1>().as_uint64(); }
+  bool has_function() const { return at<2>().valid(); }
+  uint64_t function() const { return at<2>().as_uint64(); }
+};
+
+class WorkqueueExecuteEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = WorkqueueExecuteEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kWorkFieldNumber = 1,
+    kFunctionFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.WorkqueueExecuteEndFtraceEvent"; }
+
+
+  using FieldMetadata_Work =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      WorkqueueExecuteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Work kWork{};
+  void set_work(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Work::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_Function =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      WorkqueueExecuteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Function kFunction{};
+  void set_function(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Function::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 WorkqueueActivateWorkFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  WorkqueueActivateWorkFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit WorkqueueActivateWorkFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit WorkqueueActivateWorkFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_work() const { return at<1>().valid(); }
+  uint64_t work() const { return at<1>().as_uint64(); }
+};
+
+class WorkqueueActivateWorkFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = WorkqueueActivateWorkFtraceEvent_Decoder;
+  enum : int32_t {
+    kWorkFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.WorkqueueActivateWorkFtraceEvent"; }
+
+
+  using FieldMetadata_Work =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      WorkqueueActivateWorkFtraceEvent>;
+
+  static constexpr FieldMetadata_Work kWork{};
+  void set_work(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Work::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/gpu/gpu_counter_event.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_GPU_GPU_COUNTER_EVENT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_GPU_GPU_COUNTER_EVENT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class GpuCounterDescriptor;
+class GpuCounterEvent_GpuCounter;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class GpuCounterEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  GpuCounterEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GpuCounterEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GpuCounterEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_counter_descriptor() const { return at<1>().valid(); }
+  ::protozero::ConstBytes counter_descriptor() const { return at<1>().as_bytes(); }
+  bool has_counters() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> counters() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_gpu_id() const { return at<3>().valid(); }
+  int32_t gpu_id() const { return at<3>().as_int32(); }
+};
+
+class GpuCounterEvent : public ::protozero::Message {
+ public:
+  using Decoder = GpuCounterEvent_Decoder;
+  enum : int32_t {
+    kCounterDescriptorFieldNumber = 1,
+    kCountersFieldNumber = 2,
+    kGpuIdFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GpuCounterEvent"; }
+
+  using GpuCounter = ::perfetto::protos::pbzero::GpuCounterEvent_GpuCounter;
+
+  using FieldMetadata_CounterDescriptor =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuCounterDescriptor,
+      GpuCounterEvent>;
+
+  static constexpr FieldMetadata_CounterDescriptor kCounterDescriptor{};
+  template <typename T = GpuCounterDescriptor> T* set_counter_descriptor() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_Counters =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuCounterEvent_GpuCounter,
+      GpuCounterEvent>;
+
+  static constexpr FieldMetadata_Counters kCounters{};
+  template <typename T = GpuCounterEvent_GpuCounter> T* add_counters() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_GpuId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      GpuCounterEvent>;
+
+  static constexpr FieldMetadata_GpuId kGpuId{};
+  void set_gpu_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GpuId::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);
+  }
+};
+
+class GpuCounterEvent_GpuCounter_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  GpuCounterEvent_GpuCounter_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GpuCounterEvent_GpuCounter_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GpuCounterEvent_GpuCounter_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_counter_id() const { return at<1>().valid(); }
+  uint32_t counter_id() const { return at<1>().as_uint32(); }
+  bool has_int_value() const { return at<2>().valid(); }
+  int64_t int_value() const { return at<2>().as_int64(); }
+  bool has_double_value() const { return at<3>().valid(); }
+  double double_value() const { return at<3>().as_double(); }
+};
+
+class GpuCounterEvent_GpuCounter : public ::protozero::Message {
+ public:
+  using Decoder = GpuCounterEvent_GpuCounter_Decoder;
+  enum : int32_t {
+    kCounterIdFieldNumber = 1,
+    kIntValueFieldNumber = 2,
+    kDoubleValueFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GpuCounterEvent.GpuCounter"; }
+
+
+  using FieldMetadata_CounterId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GpuCounterEvent_GpuCounter>;
+
+  static constexpr FieldMetadata_CounterId kCounterId{};
+  void set_counter_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CounterId::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_IntValue =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      GpuCounterEvent_GpuCounter>;
+
+  static constexpr FieldMetadata_IntValue kIntValue{};
+  void set_int_value(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IntValue::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_DoubleValue =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      GpuCounterEvent_GpuCounter>;
+
+  static constexpr FieldMetadata_DoubleValue kDoubleValue{};
+  void set_double_value(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_DoubleValue::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/gpu/gpu_log.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_GPU_GPU_LOG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_GPU_GPU_LOG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+namespace perfetto_pbzero_enum_GpuLog {
+enum Severity : int32_t;
+}  // namespace perfetto_pbzero_enum_GpuLog
+using GpuLog_Severity = perfetto_pbzero_enum_GpuLog::Severity;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_GpuLog {
+enum Severity : int32_t {
+  LOG_SEVERITY_UNSPECIFIED = 0,
+  LOG_SEVERITY_VERBOSE = 1,
+  LOG_SEVERITY_DEBUG = 2,
+  LOG_SEVERITY_INFO = 3,
+  LOG_SEVERITY_WARNING = 4,
+  LOG_SEVERITY_ERROR = 5,
+};
+} // namespace perfetto_pbzero_enum_GpuLog
+using GpuLog_Severity = perfetto_pbzero_enum_GpuLog::Severity;
+
+
+constexpr GpuLog_Severity GpuLog_Severity_MIN = GpuLog_Severity::LOG_SEVERITY_UNSPECIFIED;
+constexpr GpuLog_Severity GpuLog_Severity_MAX = GpuLog_Severity::LOG_SEVERITY_ERROR;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* GpuLog_Severity_Name(::perfetto::protos::pbzero::GpuLog_Severity value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::GpuLog_Severity::LOG_SEVERITY_UNSPECIFIED:
+    return "LOG_SEVERITY_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::GpuLog_Severity::LOG_SEVERITY_VERBOSE:
+    return "LOG_SEVERITY_VERBOSE";
+
+  case ::perfetto::protos::pbzero::GpuLog_Severity::LOG_SEVERITY_DEBUG:
+    return "LOG_SEVERITY_DEBUG";
+
+  case ::perfetto::protos::pbzero::GpuLog_Severity::LOG_SEVERITY_INFO:
+    return "LOG_SEVERITY_INFO";
+
+  case ::perfetto::protos::pbzero::GpuLog_Severity::LOG_SEVERITY_WARNING:
+    return "LOG_SEVERITY_WARNING";
+
+  case ::perfetto::protos::pbzero::GpuLog_Severity::LOG_SEVERITY_ERROR:
+    return "LOG_SEVERITY_ERROR";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class GpuLog_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  GpuLog_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GpuLog_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GpuLog_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_severity() const { return at<1>().valid(); }
+  int32_t severity() const { return at<1>().as_int32(); }
+  bool has_tag() const { return at<2>().valid(); }
+  ::protozero::ConstChars tag() const { return at<2>().as_string(); }
+  bool has_log_message() const { return at<3>().valid(); }
+  ::protozero::ConstChars log_message() const { return at<3>().as_string(); }
+};
+
+class GpuLog : public ::protozero::Message {
+ public:
+  using Decoder = GpuLog_Decoder;
+  enum : int32_t {
+    kSeverityFieldNumber = 1,
+    kTagFieldNumber = 2,
+    kLogMessageFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GpuLog"; }
+
+
+  using Severity = ::perfetto::protos::pbzero::GpuLog_Severity;
+  static inline const char* Severity_Name(Severity value) {
+    return ::perfetto::protos::pbzero::GpuLog_Severity_Name(value);
+  }
+  static inline const Severity LOG_SEVERITY_UNSPECIFIED = Severity::LOG_SEVERITY_UNSPECIFIED;
+  static inline const Severity LOG_SEVERITY_VERBOSE = Severity::LOG_SEVERITY_VERBOSE;
+  static inline const Severity LOG_SEVERITY_DEBUG = Severity::LOG_SEVERITY_DEBUG;
+  static inline const Severity LOG_SEVERITY_INFO = Severity::LOG_SEVERITY_INFO;
+  static inline const Severity LOG_SEVERITY_WARNING = Severity::LOG_SEVERITY_WARNING;
+  static inline const Severity LOG_SEVERITY_ERROR = Severity::LOG_SEVERITY_ERROR;
+
+  using FieldMetadata_Severity =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      GpuLog_Severity,
+      GpuLog>;
+
+  static constexpr FieldMetadata_Severity kSeverity{};
+  void set_severity(GpuLog_Severity value) {
+    static constexpr uint32_t field_id = FieldMetadata_Severity::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_Tag =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      GpuLog>;
+
+  static constexpr FieldMetadata_Tag kTag{};
+  void set_tag(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Tag::kFieldId, data, size);
+  }
+  void set_tag(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Tag::kFieldId, chars.data, chars.size);
+  }
+  void set_tag(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tag::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_LogMessage =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      GpuLog>;
+
+  static constexpr FieldMetadata_LogMessage kLogMessage{};
+  void set_log_message(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_LogMessage::kFieldId, data, size);
+  }
+  void set_log_message(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_LogMessage::kFieldId, chars.data, chars.size);
+  }
+  void set_log_message(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_LogMessage::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/gpu/gpu_render_stage_event.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_GPU_GPU_RENDER_STAGE_EVENT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_GPU_GPU_RENDER_STAGE_EVENT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class GpuRenderStageEvent_ExtraData;
+class GpuRenderStageEvent_Specifications;
+class GpuRenderStageEvent_Specifications_ContextSpec;
+class GpuRenderStageEvent_Specifications_Description;
+namespace perfetto_pbzero_enum_InternedGpuRenderStageSpecification {
+enum RenderStageCategory : int32_t;
+}  // namespace perfetto_pbzero_enum_InternedGpuRenderStageSpecification
+using InternedGpuRenderStageSpecification_RenderStageCategory = perfetto_pbzero_enum_InternedGpuRenderStageSpecification::RenderStageCategory;
+namespace perfetto_pbzero_enum_InternedGraphicsContext {
+enum Api : int32_t;
+}  // namespace perfetto_pbzero_enum_InternedGraphicsContext
+using InternedGraphicsContext_Api = perfetto_pbzero_enum_InternedGraphicsContext::Api;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_InternedGpuRenderStageSpecification {
+enum RenderStageCategory : int32_t {
+  OTHER = 0,
+  GRAPHICS = 1,
+  COMPUTE = 2,
+};
+} // namespace perfetto_pbzero_enum_InternedGpuRenderStageSpecification
+using InternedGpuRenderStageSpecification_RenderStageCategory = perfetto_pbzero_enum_InternedGpuRenderStageSpecification::RenderStageCategory;
+
+
+constexpr InternedGpuRenderStageSpecification_RenderStageCategory InternedGpuRenderStageSpecification_RenderStageCategory_MIN = InternedGpuRenderStageSpecification_RenderStageCategory::OTHER;
+constexpr InternedGpuRenderStageSpecification_RenderStageCategory InternedGpuRenderStageSpecification_RenderStageCategory_MAX = InternedGpuRenderStageSpecification_RenderStageCategory::COMPUTE;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* InternedGpuRenderStageSpecification_RenderStageCategory_Name(::perfetto::protos::pbzero::InternedGpuRenderStageSpecification_RenderStageCategory value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::InternedGpuRenderStageSpecification_RenderStageCategory::OTHER:
+    return "OTHER";
+
+  case ::perfetto::protos::pbzero::InternedGpuRenderStageSpecification_RenderStageCategory::GRAPHICS:
+    return "GRAPHICS";
+
+  case ::perfetto::protos::pbzero::InternedGpuRenderStageSpecification_RenderStageCategory::COMPUTE:
+    return "COMPUTE";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_InternedGraphicsContext {
+enum Api : int32_t {
+  UNDEFINED = 0,
+  OPEN_GL = 1,
+  VULKAN = 2,
+  OPEN_CL = 3,
+};
+} // namespace perfetto_pbzero_enum_InternedGraphicsContext
+using InternedGraphicsContext_Api = perfetto_pbzero_enum_InternedGraphicsContext::Api;
+
+
+constexpr InternedGraphicsContext_Api InternedGraphicsContext_Api_MIN = InternedGraphicsContext_Api::UNDEFINED;
+constexpr InternedGraphicsContext_Api InternedGraphicsContext_Api_MAX = InternedGraphicsContext_Api::OPEN_CL;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* InternedGraphicsContext_Api_Name(::perfetto::protos::pbzero::InternedGraphicsContext_Api value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::InternedGraphicsContext_Api::UNDEFINED:
+    return "UNDEFINED";
+
+  case ::perfetto::protos::pbzero::InternedGraphicsContext_Api::OPEN_GL:
+    return "OPEN_GL";
+
+  case ::perfetto::protos::pbzero::InternedGraphicsContext_Api::VULKAN:
+    return "VULKAN";
+
+  case ::perfetto::protos::pbzero::InternedGraphicsContext_Api::OPEN_CL:
+    return "OPEN_CL";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class InternedGpuRenderStageSpecification_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  InternedGpuRenderStageSpecification_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit InternedGpuRenderStageSpecification_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit InternedGpuRenderStageSpecification_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+  bool has_description() const { return at<3>().valid(); }
+  ::protozero::ConstChars description() const { return at<3>().as_string(); }
+  bool has_category() const { return at<4>().valid(); }
+  int32_t category() const { return at<4>().as_int32(); }
+};
+
+class InternedGpuRenderStageSpecification : public ::protozero::Message {
+ public:
+  using Decoder = InternedGpuRenderStageSpecification_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kNameFieldNumber = 2,
+    kDescriptionFieldNumber = 3,
+    kCategoryFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.InternedGpuRenderStageSpecification"; }
+
+
+  using RenderStageCategory = ::perfetto::protos::pbzero::InternedGpuRenderStageSpecification_RenderStageCategory;
+  static inline const char* RenderStageCategory_Name(RenderStageCategory value) {
+    return ::perfetto::protos::pbzero::InternedGpuRenderStageSpecification_RenderStageCategory_Name(value);
+  }
+  static inline const RenderStageCategory OTHER = RenderStageCategory::OTHER;
+  static inline const RenderStageCategory GRAPHICS = RenderStageCategory::GRAPHICS;
+  static inline const RenderStageCategory COMPUTE = RenderStageCategory::COMPUTE;
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      InternedGpuRenderStageSpecification>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      InternedGpuRenderStageSpecification>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Description =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      InternedGpuRenderStageSpecification>;
+
+  static constexpr FieldMetadata_Description kDescription{};
+  void set_description(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Description::kFieldId, data, size);
+  }
+  void set_description(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Description::kFieldId, chars.data, chars.size);
+  }
+  void set_description(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Description::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_Category =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      InternedGpuRenderStageSpecification_RenderStageCategory,
+      InternedGpuRenderStageSpecification>;
+
+  static constexpr FieldMetadata_Category kCategory{};
+  void set_category(InternedGpuRenderStageSpecification_RenderStageCategory value) {
+    static constexpr uint32_t field_id = FieldMetadata_Category::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);
+  }
+};
+
+class InternedGraphicsContext_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  InternedGraphicsContext_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit InternedGraphicsContext_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit InternedGraphicsContext_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_pid() const { return at<2>().valid(); }
+  int32_t pid() const { return at<2>().as_int32(); }
+  bool has_api() const { return at<3>().valid(); }
+  int32_t api() const { return at<3>().as_int32(); }
+};
+
+class InternedGraphicsContext : public ::protozero::Message {
+ public:
+  using Decoder = InternedGraphicsContext_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kApiFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.InternedGraphicsContext"; }
+
+
+  using Api = ::perfetto::protos::pbzero::InternedGraphicsContext_Api;
+  static inline const char* Api_Name(Api value) {
+    return ::perfetto::protos::pbzero::InternedGraphicsContext_Api_Name(value);
+  }
+  static inline const Api UNDEFINED = Api::UNDEFINED;
+  static inline const Api OPEN_GL = Api::OPEN_GL;
+  static inline const Api VULKAN = Api::VULKAN;
+  static inline const Api OPEN_CL = Api::OPEN_CL;
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      InternedGraphicsContext>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      InternedGraphicsContext>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_Api =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      InternedGraphicsContext_Api,
+      InternedGraphicsContext>;
+
+  static constexpr FieldMetadata_Api kApi{};
+  void set_api(InternedGraphicsContext_Api value) {
+    static constexpr uint32_t field_id = FieldMetadata_Api::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);
+  }
+};
+
+class GpuRenderStageEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/100, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  GpuRenderStageEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GpuRenderStageEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GpuRenderStageEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_event_id() const { return at<1>().valid(); }
+  uint64_t event_id() const { return at<1>().as_uint64(); }
+  bool has_duration() const { return at<2>().valid(); }
+  uint64_t duration() const { return at<2>().as_uint64(); }
+  bool has_hw_queue_iid() const { return at<13>().valid(); }
+  uint64_t hw_queue_iid() const { return at<13>().as_uint64(); }
+  bool has_stage_iid() const { return at<14>().valid(); }
+  uint64_t stage_iid() const { return at<14>().as_uint64(); }
+  bool has_gpu_id() const { return at<11>().valid(); }
+  int32_t gpu_id() const { return at<11>().as_int32(); }
+  bool has_context() const { return at<5>().valid(); }
+  uint64_t context() const { return at<5>().as_uint64(); }
+  bool has_render_target_handle() const { return at<8>().valid(); }
+  uint64_t render_target_handle() const { return at<8>().as_uint64(); }
+  bool has_submission_id() const { return at<10>().valid(); }
+  uint32_t submission_id() const { return at<10>().as_uint32(); }
+  bool has_extra_data() const { return at<6>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> extra_data() const { return GetRepeated<::protozero::ConstBytes>(6); }
+  bool has_render_pass_handle() const { return at<9>().valid(); }
+  uint64_t render_pass_handle() const { return at<9>().as_uint64(); }
+  bool has_render_subpass_index_mask() const { return at<15>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> render_subpass_index_mask() const { return GetRepeated<uint64_t>(15); }
+  bool has_command_buffer_handle() const { return at<12>().valid(); }
+  uint64_t command_buffer_handle() const { return at<12>().as_uint64(); }
+  bool has_specifications() const { return at<7>().valid(); }
+  ::protozero::ConstBytes specifications() const { return at<7>().as_bytes(); }
+  bool has_hw_queue_id() const { return at<3>().valid(); }
+  int32_t hw_queue_id() const { return at<3>().as_int32(); }
+  bool has_stage_id() const { return at<4>().valid(); }
+  int32_t stage_id() const { return at<4>().as_int32(); }
+};
+
+class GpuRenderStageEvent : public ::protozero::Message {
+ public:
+  using Decoder = GpuRenderStageEvent_Decoder;
+  enum : int32_t {
+    kEventIdFieldNumber = 1,
+    kDurationFieldNumber = 2,
+    kHwQueueIidFieldNumber = 13,
+    kStageIidFieldNumber = 14,
+    kGpuIdFieldNumber = 11,
+    kContextFieldNumber = 5,
+    kRenderTargetHandleFieldNumber = 8,
+    kSubmissionIdFieldNumber = 10,
+    kExtraDataFieldNumber = 6,
+    kRenderPassHandleFieldNumber = 9,
+    kRenderSubpassIndexMaskFieldNumber = 15,
+    kCommandBufferHandleFieldNumber = 12,
+    kSpecificationsFieldNumber = 7,
+    kHwQueueIdFieldNumber = 3,
+    kStageIdFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GpuRenderStageEvent"; }
+
+  using ExtraData = ::perfetto::protos::pbzero::GpuRenderStageEvent_ExtraData;
+  using Specifications = ::perfetto::protos::pbzero::GpuRenderStageEvent_Specifications;
+
+  using FieldMetadata_EventId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuRenderStageEvent>;
+
+  static constexpr FieldMetadata_EventId kEventId{};
+  void set_event_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EventId::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_Duration =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuRenderStageEvent>;
+
+  static constexpr FieldMetadata_Duration kDuration{};
+  void set_duration(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Duration::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_HwQueueIid =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuRenderStageEvent>;
+
+  static constexpr FieldMetadata_HwQueueIid kHwQueueIid{};
+  void set_hw_queue_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_HwQueueIid::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_StageIid =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuRenderStageEvent>;
+
+  static constexpr FieldMetadata_StageIid kStageIid{};
+  void set_stage_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StageIid::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_GpuId =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      GpuRenderStageEvent>;
+
+  static constexpr FieldMetadata_GpuId kGpuId{};
+  void set_gpu_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GpuId::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_Context =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuRenderStageEvent>;
+
+  static constexpr FieldMetadata_Context kContext{};
+  void set_context(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Context::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_RenderTargetHandle =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuRenderStageEvent>;
+
+  static constexpr FieldMetadata_RenderTargetHandle kRenderTargetHandle{};
+  void set_render_target_handle(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RenderTargetHandle::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_SubmissionId =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GpuRenderStageEvent>;
+
+  static constexpr FieldMetadata_SubmissionId kSubmissionId{};
+  void set_submission_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SubmissionId::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_ExtraData =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuRenderStageEvent_ExtraData,
+      GpuRenderStageEvent>;
+
+  static constexpr FieldMetadata_ExtraData kExtraData{};
+  template <typename T = GpuRenderStageEvent_ExtraData> T* add_extra_data() {
+    return BeginNestedMessage<T>(6);
+  }
+
+
+  using FieldMetadata_RenderPassHandle =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuRenderStageEvent>;
+
+  static constexpr FieldMetadata_RenderPassHandle kRenderPassHandle{};
+  void set_render_pass_handle(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RenderPassHandle::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_RenderSubpassIndexMask =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuRenderStageEvent>;
+
+  static constexpr FieldMetadata_RenderSubpassIndexMask kRenderSubpassIndexMask{};
+  void add_render_subpass_index_mask(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RenderSubpassIndexMask::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_CommandBufferHandle =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuRenderStageEvent>;
+
+  static constexpr FieldMetadata_CommandBufferHandle kCommandBufferHandle{};
+  void set_command_buffer_handle(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CommandBufferHandle::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_Specifications =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuRenderStageEvent_Specifications,
+      GpuRenderStageEvent>;
+
+  static constexpr FieldMetadata_Specifications kSpecifications{};
+  template <typename T = GpuRenderStageEvent_Specifications> T* set_specifications() {
+    return BeginNestedMessage<T>(7);
+  }
+
+
+  using FieldMetadata_HwQueueId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      GpuRenderStageEvent>;
+
+  static constexpr FieldMetadata_HwQueueId kHwQueueId{};
+  void set_hw_queue_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_HwQueueId::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_StageId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      GpuRenderStageEvent>;
+
+  static constexpr FieldMetadata_StageId kStageId{};
+  void set_stage_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StageId::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);
+  }
+};
+
+class GpuRenderStageEvent_Specifications_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  GpuRenderStageEvent_Specifications_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GpuRenderStageEvent_Specifications_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GpuRenderStageEvent_Specifications_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_context_spec() const { return at<1>().valid(); }
+  ::protozero::ConstBytes context_spec() const { return at<1>().as_bytes(); }
+  bool has_hw_queue() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> hw_queue() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_stage() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> stage() const { return GetRepeated<::protozero::ConstBytes>(3); }
+};
+
+class GpuRenderStageEvent_Specifications : public ::protozero::Message {
+ public:
+  using Decoder = GpuRenderStageEvent_Specifications_Decoder;
+  enum : int32_t {
+    kContextSpecFieldNumber = 1,
+    kHwQueueFieldNumber = 2,
+    kStageFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GpuRenderStageEvent.Specifications"; }
+
+  using ContextSpec = ::perfetto::protos::pbzero::GpuRenderStageEvent_Specifications_ContextSpec;
+  using Description = ::perfetto::protos::pbzero::GpuRenderStageEvent_Specifications_Description;
+
+  using FieldMetadata_ContextSpec =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuRenderStageEvent_Specifications_ContextSpec,
+      GpuRenderStageEvent_Specifications>;
+
+  static constexpr FieldMetadata_ContextSpec kContextSpec{};
+  template <typename T = GpuRenderStageEvent_Specifications_ContextSpec> T* set_context_spec() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_HwQueue =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuRenderStageEvent_Specifications_Description,
+      GpuRenderStageEvent_Specifications>;
+
+  static constexpr FieldMetadata_HwQueue kHwQueue{};
+  template <typename T = GpuRenderStageEvent_Specifications_Description> T* add_hw_queue() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_Stage =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuRenderStageEvent_Specifications_Description,
+      GpuRenderStageEvent_Specifications>;
+
+  static constexpr FieldMetadata_Stage kStage{};
+  template <typename T = GpuRenderStageEvent_Specifications_Description> T* add_stage() {
+    return BeginNestedMessage<T>(3);
+  }
+
+};
+
+class GpuRenderStageEvent_Specifications_Description_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  GpuRenderStageEvent_Specifications_Description_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GpuRenderStageEvent_Specifications_Description_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GpuRenderStageEvent_Specifications_Description_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_description() const { return at<2>().valid(); }
+  ::protozero::ConstChars description() const { return at<2>().as_string(); }
+};
+
+class GpuRenderStageEvent_Specifications_Description : public ::protozero::Message {
+ public:
+  using Decoder = GpuRenderStageEvent_Specifications_Description_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kDescriptionFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GpuRenderStageEvent.Specifications.Description"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      GpuRenderStageEvent_Specifications_Description>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Description =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      GpuRenderStageEvent_Specifications_Description>;
+
+  static constexpr FieldMetadata_Description kDescription{};
+  void set_description(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Description::kFieldId, data, size);
+  }
+  void set_description(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Description::kFieldId, chars.data, chars.size);
+  }
+  void set_description(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Description::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 GpuRenderStageEvent_Specifications_ContextSpec_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  GpuRenderStageEvent_Specifications_ContextSpec_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GpuRenderStageEvent_Specifications_ContextSpec_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GpuRenderStageEvent_Specifications_ContextSpec_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_context() const { return at<1>().valid(); }
+  uint64_t context() const { return at<1>().as_uint64(); }
+  bool has_pid() const { return at<2>().valid(); }
+  int32_t pid() const { return at<2>().as_int32(); }
+};
+
+class GpuRenderStageEvent_Specifications_ContextSpec : public ::protozero::Message {
+ public:
+  using Decoder = GpuRenderStageEvent_Specifications_ContextSpec_Decoder;
+  enum : int32_t {
+    kContextFieldNumber = 1,
+    kPidFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GpuRenderStageEvent.Specifications.ContextSpec"; }
+
+
+  using FieldMetadata_Context =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuRenderStageEvent_Specifications_ContextSpec>;
+
+  static constexpr FieldMetadata_Context kContext{};
+  void set_context(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Context::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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      GpuRenderStageEvent_Specifications_ContextSpec>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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);
+  }
+};
+
+class GpuRenderStageEvent_ExtraData_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  GpuRenderStageEvent_ExtraData_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GpuRenderStageEvent_ExtraData_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GpuRenderStageEvent_ExtraData_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_value() const { return at<2>().valid(); }
+  ::protozero::ConstChars value() const { return at<2>().as_string(); }
+};
+
+class GpuRenderStageEvent_ExtraData : public ::protozero::Message {
+ public:
+  using Decoder = GpuRenderStageEvent_ExtraData_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kValueFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GpuRenderStageEvent.ExtraData"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      GpuRenderStageEvent_ExtraData>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      GpuRenderStageEvent_ExtraData>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Value::kFieldId, data, size);
+  }
+  void set_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Value::kFieldId, chars.data, chars.size);
+  }
+  void set_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/gpu/vulkan_api_event.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_GPU_VULKAN_API_EVENT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_GPU_VULKAN_API_EVENT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class VulkanApiEvent_VkDebugUtilsObjectName;
+class VulkanApiEvent_VkQueueSubmit;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class VulkanApiEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  VulkanApiEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit VulkanApiEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit VulkanApiEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_vk_debug_utils_object_name() const { return at<1>().valid(); }
+  ::protozero::ConstBytes vk_debug_utils_object_name() const { return at<1>().as_bytes(); }
+  bool has_vk_queue_submit() const { return at<2>().valid(); }
+  ::protozero::ConstBytes vk_queue_submit() const { return at<2>().as_bytes(); }
+};
+
+class VulkanApiEvent : public ::protozero::Message {
+ public:
+  using Decoder = VulkanApiEvent_Decoder;
+  enum : int32_t {
+    kVkDebugUtilsObjectNameFieldNumber = 1,
+    kVkQueueSubmitFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.VulkanApiEvent"; }
+
+  using VkDebugUtilsObjectName = ::perfetto::protos::pbzero::VulkanApiEvent_VkDebugUtilsObjectName;
+  using VkQueueSubmit = ::perfetto::protos::pbzero::VulkanApiEvent_VkQueueSubmit;
+
+  using FieldMetadata_VkDebugUtilsObjectName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      VulkanApiEvent_VkDebugUtilsObjectName,
+      VulkanApiEvent>;
+
+  static constexpr FieldMetadata_VkDebugUtilsObjectName kVkDebugUtilsObjectName{};
+  template <typename T = VulkanApiEvent_VkDebugUtilsObjectName> T* set_vk_debug_utils_object_name() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_VkQueueSubmit =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      VulkanApiEvent_VkQueueSubmit,
+      VulkanApiEvent>;
+
+  static constexpr FieldMetadata_VkQueueSubmit kVkQueueSubmit{};
+  template <typename T = VulkanApiEvent_VkQueueSubmit> T* set_vk_queue_submit() {
+    return BeginNestedMessage<T>(2);
+  }
+
+};
+
+class VulkanApiEvent_VkQueueSubmit_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  VulkanApiEvent_VkQueueSubmit_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit VulkanApiEvent_VkQueueSubmit_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit VulkanApiEvent_VkQueueSubmit_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_duration_ns() const { return at<1>().valid(); }
+  uint64_t duration_ns() const { return at<1>().as_uint64(); }
+  bool has_pid() const { return at<2>().valid(); }
+  uint32_t pid() const { return at<2>().as_uint32(); }
+  bool has_tid() const { return at<3>().valid(); }
+  uint32_t tid() const { return at<3>().as_uint32(); }
+  bool has_vk_queue() const { return at<4>().valid(); }
+  uint64_t vk_queue() const { return at<4>().as_uint64(); }
+  bool has_vk_command_buffers() const { return at<5>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> vk_command_buffers() const { return GetRepeated<uint64_t>(5); }
+  bool has_submission_id() const { return at<6>().valid(); }
+  uint32_t submission_id() const { return at<6>().as_uint32(); }
+};
+
+class VulkanApiEvent_VkQueueSubmit : public ::protozero::Message {
+ public:
+  using Decoder = VulkanApiEvent_VkQueueSubmit_Decoder;
+  enum : int32_t {
+    kDurationNsFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kTidFieldNumber = 3,
+    kVkQueueFieldNumber = 4,
+    kVkCommandBuffersFieldNumber = 5,
+    kSubmissionIdFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.VulkanApiEvent.VkQueueSubmit"; }
+
+
+  using FieldMetadata_DurationNs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      VulkanApiEvent_VkQueueSubmit>;
+
+  static constexpr FieldMetadata_DurationNs kDurationNs{};
+  void set_duration_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DurationNs::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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VulkanApiEvent_VkQueueSubmit>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_Tid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VulkanApiEvent_VkQueueSubmit>;
+
+  static constexpr FieldMetadata_Tid kTid{};
+  void set_tid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tid::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_VkQueue =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      VulkanApiEvent_VkQueueSubmit>;
+
+  static constexpr FieldMetadata_VkQueue kVkQueue{};
+  void set_vk_queue(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VkQueue::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_VkCommandBuffers =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      VulkanApiEvent_VkQueueSubmit>;
+
+  static constexpr FieldMetadata_VkCommandBuffers kVkCommandBuffers{};
+  void add_vk_command_buffers(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VkCommandBuffers::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_SubmissionId =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VulkanApiEvent_VkQueueSubmit>;
+
+  static constexpr FieldMetadata_SubmissionId kSubmissionId{};
+  void set_submission_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SubmissionId::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 VulkanApiEvent_VkDebugUtilsObjectName_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  VulkanApiEvent_VkDebugUtilsObjectName_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit VulkanApiEvent_VkDebugUtilsObjectName_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit VulkanApiEvent_VkDebugUtilsObjectName_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  uint32_t pid() const { return at<1>().as_uint32(); }
+  bool has_vk_device() const { return at<2>().valid(); }
+  uint64_t vk_device() const { return at<2>().as_uint64(); }
+  bool has_object_type() const { return at<3>().valid(); }
+  int32_t object_type() const { return at<3>().as_int32(); }
+  bool has_object() const { return at<4>().valid(); }
+  uint64_t object() const { return at<4>().as_uint64(); }
+  bool has_object_name() const { return at<5>().valid(); }
+  ::protozero::ConstChars object_name() const { return at<5>().as_string(); }
+};
+
+class VulkanApiEvent_VkDebugUtilsObjectName : public ::protozero::Message {
+ public:
+  using Decoder = VulkanApiEvent_VkDebugUtilsObjectName_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kVkDeviceFieldNumber = 2,
+    kObjectTypeFieldNumber = 3,
+    kObjectFieldNumber = 4,
+    kObjectNameFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.VulkanApiEvent.VkDebugUtilsObjectName"; }
+
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VulkanApiEvent_VkDebugUtilsObjectName>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_VkDevice =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      VulkanApiEvent_VkDebugUtilsObjectName>;
+
+  static constexpr FieldMetadata_VkDevice kVkDevice{};
+  void set_vk_device(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VkDevice::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_ObjectType =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      VulkanApiEvent_VkDebugUtilsObjectName>;
+
+  static constexpr FieldMetadata_ObjectType kObjectType{};
+  void set_object_type(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ObjectType::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_Object =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      VulkanApiEvent_VkDebugUtilsObjectName>;
+
+  static constexpr FieldMetadata_Object kObject{};
+  void set_object(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Object::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_ObjectName =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      VulkanApiEvent_VkDebugUtilsObjectName>;
+
+  static constexpr FieldMetadata_ObjectName kObjectName{};
+  void set_object_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ObjectName::kFieldId, data, size);
+  }
+  void set_object_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ObjectName::kFieldId, chars.data, chars.size);
+  }
+  void set_object_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ObjectName::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/gpu/vulkan_memory_event.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_GPU_VULKAN_MEMORY_EVENT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_GPU_VULKAN_MEMORY_EVENT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class VulkanMemoryEventAnnotation;
+namespace perfetto_pbzero_enum_VulkanMemoryEvent {
+enum AllocationScope : int32_t;
+}  // namespace perfetto_pbzero_enum_VulkanMemoryEvent
+using VulkanMemoryEvent_AllocationScope = perfetto_pbzero_enum_VulkanMemoryEvent::AllocationScope;
+namespace perfetto_pbzero_enum_VulkanMemoryEvent {
+enum Operation : int32_t;
+}  // namespace perfetto_pbzero_enum_VulkanMemoryEvent
+using VulkanMemoryEvent_Operation = perfetto_pbzero_enum_VulkanMemoryEvent::Operation;
+namespace perfetto_pbzero_enum_VulkanMemoryEvent {
+enum Source : int32_t;
+}  // namespace perfetto_pbzero_enum_VulkanMemoryEvent
+using VulkanMemoryEvent_Source = perfetto_pbzero_enum_VulkanMemoryEvent::Source;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_VulkanMemoryEvent {
+enum Source : int32_t {
+  SOURCE_UNSPECIFIED = 0,
+  SOURCE_DRIVER = 1,
+  SOURCE_DEVICE = 2,
+  SOURCE_DEVICE_MEMORY = 3,
+  SOURCE_BUFFER = 4,
+  SOURCE_IMAGE = 5,
+};
+} // namespace perfetto_pbzero_enum_VulkanMemoryEvent
+using VulkanMemoryEvent_Source = perfetto_pbzero_enum_VulkanMemoryEvent::Source;
+
+
+constexpr VulkanMemoryEvent_Source VulkanMemoryEvent_Source_MIN = VulkanMemoryEvent_Source::SOURCE_UNSPECIFIED;
+constexpr VulkanMemoryEvent_Source VulkanMemoryEvent_Source_MAX = VulkanMemoryEvent_Source::SOURCE_IMAGE;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* VulkanMemoryEvent_Source_Name(::perfetto::protos::pbzero::VulkanMemoryEvent_Source value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::VulkanMemoryEvent_Source::SOURCE_UNSPECIFIED:
+    return "SOURCE_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::VulkanMemoryEvent_Source::SOURCE_DRIVER:
+    return "SOURCE_DRIVER";
+
+  case ::perfetto::protos::pbzero::VulkanMemoryEvent_Source::SOURCE_DEVICE:
+    return "SOURCE_DEVICE";
+
+  case ::perfetto::protos::pbzero::VulkanMemoryEvent_Source::SOURCE_DEVICE_MEMORY:
+    return "SOURCE_DEVICE_MEMORY";
+
+  case ::perfetto::protos::pbzero::VulkanMemoryEvent_Source::SOURCE_BUFFER:
+    return "SOURCE_BUFFER";
+
+  case ::perfetto::protos::pbzero::VulkanMemoryEvent_Source::SOURCE_IMAGE:
+    return "SOURCE_IMAGE";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_VulkanMemoryEvent {
+enum Operation : int32_t {
+  OP_UNSPECIFIED = 0,
+  OP_CREATE = 1,
+  OP_DESTROY = 2,
+  OP_BIND = 3,
+  OP_DESTROY_BOUND = 4,
+  OP_ANNOTATIONS = 5,
+};
+} // namespace perfetto_pbzero_enum_VulkanMemoryEvent
+using VulkanMemoryEvent_Operation = perfetto_pbzero_enum_VulkanMemoryEvent::Operation;
+
+
+constexpr VulkanMemoryEvent_Operation VulkanMemoryEvent_Operation_MIN = VulkanMemoryEvent_Operation::OP_UNSPECIFIED;
+constexpr VulkanMemoryEvent_Operation VulkanMemoryEvent_Operation_MAX = VulkanMemoryEvent_Operation::OP_ANNOTATIONS;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* VulkanMemoryEvent_Operation_Name(::perfetto::protos::pbzero::VulkanMemoryEvent_Operation value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::VulkanMemoryEvent_Operation::OP_UNSPECIFIED:
+    return "OP_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::VulkanMemoryEvent_Operation::OP_CREATE:
+    return "OP_CREATE";
+
+  case ::perfetto::protos::pbzero::VulkanMemoryEvent_Operation::OP_DESTROY:
+    return "OP_DESTROY";
+
+  case ::perfetto::protos::pbzero::VulkanMemoryEvent_Operation::OP_BIND:
+    return "OP_BIND";
+
+  case ::perfetto::protos::pbzero::VulkanMemoryEvent_Operation::OP_DESTROY_BOUND:
+    return "OP_DESTROY_BOUND";
+
+  case ::perfetto::protos::pbzero::VulkanMemoryEvent_Operation::OP_ANNOTATIONS:
+    return "OP_ANNOTATIONS";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_VulkanMemoryEvent {
+enum AllocationScope : int32_t {
+  SCOPE_UNSPECIFIED = 0,
+  SCOPE_COMMAND = 1,
+  SCOPE_OBJECT = 2,
+  SCOPE_CACHE = 3,
+  SCOPE_DEVICE = 4,
+  SCOPE_INSTANCE = 5,
+};
+} // namespace perfetto_pbzero_enum_VulkanMemoryEvent
+using VulkanMemoryEvent_AllocationScope = perfetto_pbzero_enum_VulkanMemoryEvent::AllocationScope;
+
+
+constexpr VulkanMemoryEvent_AllocationScope VulkanMemoryEvent_AllocationScope_MIN = VulkanMemoryEvent_AllocationScope::SCOPE_UNSPECIFIED;
+constexpr VulkanMemoryEvent_AllocationScope VulkanMemoryEvent_AllocationScope_MAX = VulkanMemoryEvent_AllocationScope::SCOPE_INSTANCE;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* VulkanMemoryEvent_AllocationScope_Name(::perfetto::protos::pbzero::VulkanMemoryEvent_AllocationScope value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::VulkanMemoryEvent_AllocationScope::SCOPE_UNSPECIFIED:
+    return "SCOPE_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::VulkanMemoryEvent_AllocationScope::SCOPE_COMMAND:
+    return "SCOPE_COMMAND";
+
+  case ::perfetto::protos::pbzero::VulkanMemoryEvent_AllocationScope::SCOPE_OBJECT:
+    return "SCOPE_OBJECT";
+
+  case ::perfetto::protos::pbzero::VulkanMemoryEvent_AllocationScope::SCOPE_CACHE:
+    return "SCOPE_CACHE";
+
+  case ::perfetto::protos::pbzero::VulkanMemoryEvent_AllocationScope::SCOPE_DEVICE:
+    return "SCOPE_DEVICE";
+
+  case ::perfetto::protos::pbzero::VulkanMemoryEvent_AllocationScope::SCOPE_INSTANCE:
+    return "SCOPE_INSTANCE";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class VulkanMemoryEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/20, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  VulkanMemoryEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit VulkanMemoryEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit VulkanMemoryEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_source() const { return at<1>().valid(); }
+  int32_t source() const { return at<1>().as_int32(); }
+  bool has_operation() const { return at<2>().valid(); }
+  int32_t operation() const { return at<2>().as_int32(); }
+  bool has_timestamp() const { return at<3>().valid(); }
+  int64_t timestamp() const { return at<3>().as_int64(); }
+  bool has_pid() const { return at<4>().valid(); }
+  uint32_t pid() const { return at<4>().as_uint32(); }
+  bool has_memory_address() const { return at<5>().valid(); }
+  uint64_t memory_address() const { return at<5>().as_uint64(); }
+  bool has_memory_size() const { return at<6>().valid(); }
+  uint64_t memory_size() const { return at<6>().as_uint64(); }
+  bool has_caller_iid() const { return at<7>().valid(); }
+  uint64_t caller_iid() const { return at<7>().as_uint64(); }
+  bool has_allocation_scope() const { return at<8>().valid(); }
+  int32_t allocation_scope() const { return at<8>().as_int32(); }
+  bool has_annotations() const { return at<9>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> annotations() const { return GetRepeated<::protozero::ConstBytes>(9); }
+  bool has_device() const { return at<16>().valid(); }
+  uint64_t device() const { return at<16>().as_uint64(); }
+  bool has_device_memory() const { return at<17>().valid(); }
+  uint64_t device_memory() const { return at<17>().as_uint64(); }
+  bool has_memory_type() const { return at<18>().valid(); }
+  uint32_t memory_type() const { return at<18>().as_uint32(); }
+  bool has_heap() const { return at<19>().valid(); }
+  uint32_t heap() const { return at<19>().as_uint32(); }
+  bool has_object_handle() const { return at<20>().valid(); }
+  uint64_t object_handle() const { return at<20>().as_uint64(); }
+};
+
+class VulkanMemoryEvent : public ::protozero::Message {
+ public:
+  using Decoder = VulkanMemoryEvent_Decoder;
+  enum : int32_t {
+    kSourceFieldNumber = 1,
+    kOperationFieldNumber = 2,
+    kTimestampFieldNumber = 3,
+    kPidFieldNumber = 4,
+    kMemoryAddressFieldNumber = 5,
+    kMemorySizeFieldNumber = 6,
+    kCallerIidFieldNumber = 7,
+    kAllocationScopeFieldNumber = 8,
+    kAnnotationsFieldNumber = 9,
+    kDeviceFieldNumber = 16,
+    kDeviceMemoryFieldNumber = 17,
+    kMemoryTypeFieldNumber = 18,
+    kHeapFieldNumber = 19,
+    kObjectHandleFieldNumber = 20,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.VulkanMemoryEvent"; }
+
+
+  using Source = ::perfetto::protos::pbzero::VulkanMemoryEvent_Source;
+  static inline const char* Source_Name(Source value) {
+    return ::perfetto::protos::pbzero::VulkanMemoryEvent_Source_Name(value);
+  }
+
+  using Operation = ::perfetto::protos::pbzero::VulkanMemoryEvent_Operation;
+  static inline const char* Operation_Name(Operation value) {
+    return ::perfetto::protos::pbzero::VulkanMemoryEvent_Operation_Name(value);
+  }
+
+  using AllocationScope = ::perfetto::protos::pbzero::VulkanMemoryEvent_AllocationScope;
+  static inline const char* AllocationScope_Name(AllocationScope value) {
+    return ::perfetto::protos::pbzero::VulkanMemoryEvent_AllocationScope_Name(value);
+  }
+  static inline const Source SOURCE_UNSPECIFIED = Source::SOURCE_UNSPECIFIED;
+  static inline const Source SOURCE_DRIVER = Source::SOURCE_DRIVER;
+  static inline const Source SOURCE_DEVICE = Source::SOURCE_DEVICE;
+  static inline const Source SOURCE_DEVICE_MEMORY = Source::SOURCE_DEVICE_MEMORY;
+  static inline const Source SOURCE_BUFFER = Source::SOURCE_BUFFER;
+  static inline const Source SOURCE_IMAGE = Source::SOURCE_IMAGE;
+  static inline const Operation OP_UNSPECIFIED = Operation::OP_UNSPECIFIED;
+  static inline const Operation OP_CREATE = Operation::OP_CREATE;
+  static inline const Operation OP_DESTROY = Operation::OP_DESTROY;
+  static inline const Operation OP_BIND = Operation::OP_BIND;
+  static inline const Operation OP_DESTROY_BOUND = Operation::OP_DESTROY_BOUND;
+  static inline const Operation OP_ANNOTATIONS = Operation::OP_ANNOTATIONS;
+  static inline const AllocationScope SCOPE_UNSPECIFIED = AllocationScope::SCOPE_UNSPECIFIED;
+  static inline const AllocationScope SCOPE_COMMAND = AllocationScope::SCOPE_COMMAND;
+  static inline const AllocationScope SCOPE_OBJECT = AllocationScope::SCOPE_OBJECT;
+  static inline const AllocationScope SCOPE_CACHE = AllocationScope::SCOPE_CACHE;
+  static inline const AllocationScope SCOPE_DEVICE = AllocationScope::SCOPE_DEVICE;
+  static inline const AllocationScope SCOPE_INSTANCE = AllocationScope::SCOPE_INSTANCE;
+
+  using FieldMetadata_Source =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      VulkanMemoryEvent_Source,
+      VulkanMemoryEvent>;
+
+  static constexpr FieldMetadata_Source kSource{};
+  void set_source(VulkanMemoryEvent_Source value) {
+    static constexpr uint32_t field_id = FieldMetadata_Source::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_Operation =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      VulkanMemoryEvent_Operation,
+      VulkanMemoryEvent>;
+
+  static constexpr FieldMetadata_Operation kOperation{};
+  void set_operation(VulkanMemoryEvent_Operation value) {
+    static constexpr uint32_t field_id = FieldMetadata_Operation::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_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      VulkanMemoryEvent>;
+
+  static constexpr FieldMetadata_Timestamp kTimestamp{};
+  void set_timestamp(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timestamp::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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VulkanMemoryEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_MemoryAddress =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64,
+      uint64_t,
+      VulkanMemoryEvent>;
+
+  static constexpr FieldMetadata_MemoryAddress kMemoryAddress{};
+  void set_memory_address(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MemoryAddress::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MemorySize =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      VulkanMemoryEvent>;
+
+  static constexpr FieldMetadata_MemorySize kMemorySize{};
+  void set_memory_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MemorySize::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_CallerIid =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      VulkanMemoryEvent>;
+
+  static constexpr FieldMetadata_CallerIid kCallerIid{};
+  void set_caller_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CallerIid::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_AllocationScope =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      VulkanMemoryEvent_AllocationScope,
+      VulkanMemoryEvent>;
+
+  static constexpr FieldMetadata_AllocationScope kAllocationScope{};
+  void set_allocation_scope(VulkanMemoryEvent_AllocationScope value) {
+    static constexpr uint32_t field_id = FieldMetadata_AllocationScope::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_Annotations =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      VulkanMemoryEventAnnotation,
+      VulkanMemoryEvent>;
+
+  static constexpr FieldMetadata_Annotations kAnnotations{};
+  template <typename T = VulkanMemoryEventAnnotation> T* add_annotations() {
+    return BeginNestedMessage<T>(9);
+  }
+
+
+  using FieldMetadata_Device =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64,
+      uint64_t,
+      VulkanMemoryEvent>;
+
+  static constexpr FieldMetadata_Device kDevice{};
+  void set_device(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Device::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DeviceMemory =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64,
+      uint64_t,
+      VulkanMemoryEvent>;
+
+  static constexpr FieldMetadata_DeviceMemory kDeviceMemory{};
+  void set_device_memory(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DeviceMemory::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MemoryType =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VulkanMemoryEvent>;
+
+  static constexpr FieldMetadata_MemoryType kMemoryType{};
+  void set_memory_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MemoryType::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_Heap =
+    ::protozero::proto_utils::FieldMetadata<
+      19,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VulkanMemoryEvent>;
+
+  static constexpr FieldMetadata_Heap kHeap{};
+  void set_heap(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Heap::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_ObjectHandle =
+    ::protozero::proto_utils::FieldMetadata<
+      20,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64,
+      uint64_t,
+      VulkanMemoryEvent>;
+
+  static constexpr FieldMetadata_ObjectHandle kObjectHandle{};
+  void set_object_handle(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ObjectHandle::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class VulkanMemoryEventAnnotation_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  VulkanMemoryEventAnnotation_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit VulkanMemoryEventAnnotation_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit VulkanMemoryEventAnnotation_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_key_iid() const { return at<1>().valid(); }
+  uint64_t key_iid() const { return at<1>().as_uint64(); }
+  bool has_int_value() const { return at<2>().valid(); }
+  int64_t int_value() const { return at<2>().as_int64(); }
+  bool has_double_value() const { return at<3>().valid(); }
+  double double_value() const { return at<3>().as_double(); }
+  bool has_string_iid() const { return at<4>().valid(); }
+  uint64_t string_iid() const { return at<4>().as_uint64(); }
+};
+
+class VulkanMemoryEventAnnotation : public ::protozero::Message {
+ public:
+  using Decoder = VulkanMemoryEventAnnotation_Decoder;
+  enum : int32_t {
+    kKeyIidFieldNumber = 1,
+    kIntValueFieldNumber = 2,
+    kDoubleValueFieldNumber = 3,
+    kStringIidFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.VulkanMemoryEventAnnotation"; }
+
+
+  using FieldMetadata_KeyIid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      VulkanMemoryEventAnnotation>;
+
+  static constexpr FieldMetadata_KeyIid kKeyIid{};
+  void set_key_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KeyIid::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_IntValue =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      VulkanMemoryEventAnnotation>;
+
+  static constexpr FieldMetadata_IntValue kIntValue{};
+  void set_int_value(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IntValue::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_DoubleValue =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      VulkanMemoryEventAnnotation>;
+
+  static constexpr FieldMetadata_DoubleValue kDoubleValue{};
+  void set_double_value(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_DoubleValue::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);
+  }
+
+  using FieldMetadata_StringIid =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      VulkanMemoryEventAnnotation>;
+
+  static constexpr FieldMetadata_StringIid kStringIid{};
+  void set_string_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StringIid::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/profiling/deobfuscation.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PROFILING_DEOBFUSCATION_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PROFILING_DEOBFUSCATION_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class ObfuscatedClass;
+class ObfuscatedMember;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class DeobfuscationMapping_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  DeobfuscationMapping_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DeobfuscationMapping_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DeobfuscationMapping_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_package_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars package_name() const { return at<1>().as_string(); }
+  bool has_version_code() const { return at<2>().valid(); }
+  int64_t version_code() const { return at<2>().as_int64(); }
+  bool has_obfuscated_classes() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> obfuscated_classes() const { return GetRepeated<::protozero::ConstBytes>(3); }
+};
+
+class DeobfuscationMapping : public ::protozero::Message {
+ public:
+  using Decoder = DeobfuscationMapping_Decoder;
+  enum : int32_t {
+    kPackageNameFieldNumber = 1,
+    kVersionCodeFieldNumber = 2,
+    kObfuscatedClassesFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DeobfuscationMapping"; }
+
+
+  using FieldMetadata_PackageName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DeobfuscationMapping>;
+
+  static constexpr FieldMetadata_PackageName kPackageName{};
+  void set_package_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_PackageName::kFieldId, data, size);
+  }
+  void set_package_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_PackageName::kFieldId, chars.data, chars.size);
+  }
+  void set_package_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_PackageName::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_VersionCode =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      DeobfuscationMapping>;
+
+  static constexpr FieldMetadata_VersionCode kVersionCode{};
+  void set_version_code(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VersionCode::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_ObfuscatedClasses =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ObfuscatedClass,
+      DeobfuscationMapping>;
+
+  static constexpr FieldMetadata_ObfuscatedClasses kObfuscatedClasses{};
+  template <typename T = ObfuscatedClass> T* add_obfuscated_classes() {
+    return BeginNestedMessage<T>(3);
+  }
+
+};
+
+class ObfuscatedClass_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ObfuscatedClass_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ObfuscatedClass_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ObfuscatedClass_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_obfuscated_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars obfuscated_name() const { return at<1>().as_string(); }
+  bool has_deobfuscated_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars deobfuscated_name() const { return at<2>().as_string(); }
+  bool has_obfuscated_members() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> obfuscated_members() const { return GetRepeated<::protozero::ConstBytes>(3); }
+  bool has_obfuscated_methods() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> obfuscated_methods() const { return GetRepeated<::protozero::ConstBytes>(4); }
+};
+
+class ObfuscatedClass : public ::protozero::Message {
+ public:
+  using Decoder = ObfuscatedClass_Decoder;
+  enum : int32_t {
+    kObfuscatedNameFieldNumber = 1,
+    kDeobfuscatedNameFieldNumber = 2,
+    kObfuscatedMembersFieldNumber = 3,
+    kObfuscatedMethodsFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ObfuscatedClass"; }
+
+
+  using FieldMetadata_ObfuscatedName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ObfuscatedClass>;
+
+  static constexpr FieldMetadata_ObfuscatedName kObfuscatedName{};
+  void set_obfuscated_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ObfuscatedName::kFieldId, data, size);
+  }
+  void set_obfuscated_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ObfuscatedName::kFieldId, chars.data, chars.size);
+  }
+  void set_obfuscated_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ObfuscatedName::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_DeobfuscatedName =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ObfuscatedClass>;
+
+  static constexpr FieldMetadata_DeobfuscatedName kDeobfuscatedName{};
+  void set_deobfuscated_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DeobfuscatedName::kFieldId, data, size);
+  }
+  void set_deobfuscated_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_DeobfuscatedName::kFieldId, chars.data, chars.size);
+  }
+  void set_deobfuscated_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_DeobfuscatedName::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_ObfuscatedMembers =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ObfuscatedMember,
+      ObfuscatedClass>;
+
+  static constexpr FieldMetadata_ObfuscatedMembers kObfuscatedMembers{};
+  template <typename T = ObfuscatedMember> T* add_obfuscated_members() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_ObfuscatedMethods =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ObfuscatedMember,
+      ObfuscatedClass>;
+
+  static constexpr FieldMetadata_ObfuscatedMethods kObfuscatedMethods{};
+  template <typename T = ObfuscatedMember> T* add_obfuscated_methods() {
+    return BeginNestedMessage<T>(4);
+  }
+
+};
+
+class ObfuscatedMember_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ObfuscatedMember_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ObfuscatedMember_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ObfuscatedMember_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_obfuscated_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars obfuscated_name() const { return at<1>().as_string(); }
+  bool has_deobfuscated_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars deobfuscated_name() const { return at<2>().as_string(); }
+};
+
+class ObfuscatedMember : public ::protozero::Message {
+ public:
+  using Decoder = ObfuscatedMember_Decoder;
+  enum : int32_t {
+    kObfuscatedNameFieldNumber = 1,
+    kDeobfuscatedNameFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ObfuscatedMember"; }
+
+
+  using FieldMetadata_ObfuscatedName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ObfuscatedMember>;
+
+  static constexpr FieldMetadata_ObfuscatedName kObfuscatedName{};
+  void set_obfuscated_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ObfuscatedName::kFieldId, data, size);
+  }
+  void set_obfuscated_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ObfuscatedName::kFieldId, chars.data, chars.size);
+  }
+  void set_obfuscated_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ObfuscatedName::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_DeobfuscatedName =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ObfuscatedMember>;
+
+  static constexpr FieldMetadata_DeobfuscatedName kDeobfuscatedName{};
+  void set_deobfuscated_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DeobfuscatedName::kFieldId, data, size);
+  }
+  void set_deobfuscated_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_DeobfuscatedName::kFieldId, chars.data, chars.size);
+  }
+  void set_deobfuscated_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_DeobfuscatedName::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/profiling/heap_graph.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PROFILING_HEAP_GRAPH_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PROFILING_HEAP_GRAPH_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/profiling/deobfuscation.pbzero.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class HeapGraphObject;
+class HeapGraphRoot;
+class HeapGraphType;
+class InternedString;
+namespace perfetto_pbzero_enum_HeapGraphRoot {
+enum Type : int32_t;
+}  // namespace perfetto_pbzero_enum_HeapGraphRoot
+using HeapGraphRoot_Type = perfetto_pbzero_enum_HeapGraphRoot::Type;
+namespace perfetto_pbzero_enum_HeapGraphType {
+enum Kind : int32_t;
+}  // namespace perfetto_pbzero_enum_HeapGraphType
+using HeapGraphType_Kind = perfetto_pbzero_enum_HeapGraphType::Kind;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_HeapGraphType {
+enum Kind : int32_t {
+  KIND_UNKNOWN = 0,
+  KIND_NORMAL = 1,
+  KIND_NOREFERENCES = 2,
+  KIND_STRING = 3,
+  KIND_ARRAY = 4,
+  KIND_CLASS = 5,
+  KIND_CLASSLOADER = 6,
+  KIND_DEXCACHE = 7,
+  KIND_SOFT_REFERENCE = 8,
+  KIND_WEAK_REFERENCE = 9,
+  KIND_FINALIZER_REFERENCE = 10,
+  KIND_PHANTOM_REFERENCE = 11,
+};
+} // namespace perfetto_pbzero_enum_HeapGraphType
+using HeapGraphType_Kind = perfetto_pbzero_enum_HeapGraphType::Kind;
+
+
+constexpr HeapGraphType_Kind HeapGraphType_Kind_MIN = HeapGraphType_Kind::KIND_UNKNOWN;
+constexpr HeapGraphType_Kind HeapGraphType_Kind_MAX = HeapGraphType_Kind::KIND_PHANTOM_REFERENCE;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* HeapGraphType_Kind_Name(::perfetto::protos::pbzero::HeapGraphType_Kind value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::HeapGraphType_Kind::KIND_UNKNOWN:
+    return "KIND_UNKNOWN";
+
+  case ::perfetto::protos::pbzero::HeapGraphType_Kind::KIND_NORMAL:
+    return "KIND_NORMAL";
+
+  case ::perfetto::protos::pbzero::HeapGraphType_Kind::KIND_NOREFERENCES:
+    return "KIND_NOREFERENCES";
+
+  case ::perfetto::protos::pbzero::HeapGraphType_Kind::KIND_STRING:
+    return "KIND_STRING";
+
+  case ::perfetto::protos::pbzero::HeapGraphType_Kind::KIND_ARRAY:
+    return "KIND_ARRAY";
+
+  case ::perfetto::protos::pbzero::HeapGraphType_Kind::KIND_CLASS:
+    return "KIND_CLASS";
+
+  case ::perfetto::protos::pbzero::HeapGraphType_Kind::KIND_CLASSLOADER:
+    return "KIND_CLASSLOADER";
+
+  case ::perfetto::protos::pbzero::HeapGraphType_Kind::KIND_DEXCACHE:
+    return "KIND_DEXCACHE";
+
+  case ::perfetto::protos::pbzero::HeapGraphType_Kind::KIND_SOFT_REFERENCE:
+    return "KIND_SOFT_REFERENCE";
+
+  case ::perfetto::protos::pbzero::HeapGraphType_Kind::KIND_WEAK_REFERENCE:
+    return "KIND_WEAK_REFERENCE";
+
+  case ::perfetto::protos::pbzero::HeapGraphType_Kind::KIND_FINALIZER_REFERENCE:
+    return "KIND_FINALIZER_REFERENCE";
+
+  case ::perfetto::protos::pbzero::HeapGraphType_Kind::KIND_PHANTOM_REFERENCE:
+    return "KIND_PHANTOM_REFERENCE";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_HeapGraphRoot {
+enum Type : int32_t {
+  ROOT_UNKNOWN = 0,
+  ROOT_JNI_GLOBAL = 1,
+  ROOT_JNI_LOCAL = 2,
+  ROOT_JAVA_FRAME = 3,
+  ROOT_NATIVE_STACK = 4,
+  ROOT_STICKY_CLASS = 5,
+  ROOT_THREAD_BLOCK = 6,
+  ROOT_MONITOR_USED = 7,
+  ROOT_THREAD_OBJECT = 8,
+  ROOT_INTERNED_STRING = 9,
+  ROOT_FINALIZING = 10,
+  ROOT_DEBUGGER = 11,
+  ROOT_REFERENCE_CLEANUP = 12,
+  ROOT_VM_INTERNAL = 13,
+  ROOT_JNI_MONITOR = 14,
+};
+} // namespace perfetto_pbzero_enum_HeapGraphRoot
+using HeapGraphRoot_Type = perfetto_pbzero_enum_HeapGraphRoot::Type;
+
+
+constexpr HeapGraphRoot_Type HeapGraphRoot_Type_MIN = HeapGraphRoot_Type::ROOT_UNKNOWN;
+constexpr HeapGraphRoot_Type HeapGraphRoot_Type_MAX = HeapGraphRoot_Type::ROOT_JNI_MONITOR;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* HeapGraphRoot_Type_Name(::perfetto::protos::pbzero::HeapGraphRoot_Type value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::HeapGraphRoot_Type::ROOT_UNKNOWN:
+    return "ROOT_UNKNOWN";
+
+  case ::perfetto::protos::pbzero::HeapGraphRoot_Type::ROOT_JNI_GLOBAL:
+    return "ROOT_JNI_GLOBAL";
+
+  case ::perfetto::protos::pbzero::HeapGraphRoot_Type::ROOT_JNI_LOCAL:
+    return "ROOT_JNI_LOCAL";
+
+  case ::perfetto::protos::pbzero::HeapGraphRoot_Type::ROOT_JAVA_FRAME:
+    return "ROOT_JAVA_FRAME";
+
+  case ::perfetto::protos::pbzero::HeapGraphRoot_Type::ROOT_NATIVE_STACK:
+    return "ROOT_NATIVE_STACK";
+
+  case ::perfetto::protos::pbzero::HeapGraphRoot_Type::ROOT_STICKY_CLASS:
+    return "ROOT_STICKY_CLASS";
+
+  case ::perfetto::protos::pbzero::HeapGraphRoot_Type::ROOT_THREAD_BLOCK:
+    return "ROOT_THREAD_BLOCK";
+
+  case ::perfetto::protos::pbzero::HeapGraphRoot_Type::ROOT_MONITOR_USED:
+    return "ROOT_MONITOR_USED";
+
+  case ::perfetto::protos::pbzero::HeapGraphRoot_Type::ROOT_THREAD_OBJECT:
+    return "ROOT_THREAD_OBJECT";
+
+  case ::perfetto::protos::pbzero::HeapGraphRoot_Type::ROOT_INTERNED_STRING:
+    return "ROOT_INTERNED_STRING";
+
+  case ::perfetto::protos::pbzero::HeapGraphRoot_Type::ROOT_FINALIZING:
+    return "ROOT_FINALIZING";
+
+  case ::perfetto::protos::pbzero::HeapGraphRoot_Type::ROOT_DEBUGGER:
+    return "ROOT_DEBUGGER";
+
+  case ::perfetto::protos::pbzero::HeapGraphRoot_Type::ROOT_REFERENCE_CLEANUP:
+    return "ROOT_REFERENCE_CLEANUP";
+
+  case ::perfetto::protos::pbzero::HeapGraphRoot_Type::ROOT_VM_INTERNAL:
+    return "ROOT_VM_INTERNAL";
+
+  case ::perfetto::protos::pbzero::HeapGraphRoot_Type::ROOT_JNI_MONITOR:
+    return "ROOT_JNI_MONITOR";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class HeapGraph_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  HeapGraph_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit HeapGraph_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit HeapGraph_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  int32_t pid() const { return at<1>().as_int32(); }
+  bool has_objects() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> objects() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_roots() const { return at<7>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> roots() const { return GetRepeated<::protozero::ConstBytes>(7); }
+  bool has_types() const { return at<9>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> types() const { return GetRepeated<::protozero::ConstBytes>(9); }
+  bool has_field_names() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> field_names() const { return GetRepeated<::protozero::ConstBytes>(4); }
+  bool has_location_names() const { return at<8>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> location_names() const { return GetRepeated<::protozero::ConstBytes>(8); }
+  bool has_continued() const { return at<5>().valid(); }
+  bool continued() const { return at<5>().as_bool(); }
+  bool has_index() const { return at<6>().valid(); }
+  uint64_t index() const { return at<6>().as_uint64(); }
+};
+
+class HeapGraph : public ::protozero::Message {
+ public:
+  using Decoder = HeapGraph_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kObjectsFieldNumber = 2,
+    kRootsFieldNumber = 7,
+    kTypesFieldNumber = 9,
+    kFieldNamesFieldNumber = 4,
+    kLocationNamesFieldNumber = 8,
+    kContinuedFieldNumber = 5,
+    kIndexFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.HeapGraph"; }
+
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      HeapGraph>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_Objects =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      HeapGraphObject,
+      HeapGraph>;
+
+  static constexpr FieldMetadata_Objects kObjects{};
+  template <typename T = HeapGraphObject> T* add_objects() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_Roots =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      HeapGraphRoot,
+      HeapGraph>;
+
+  static constexpr FieldMetadata_Roots kRoots{};
+  template <typename T = HeapGraphRoot> T* add_roots() {
+    return BeginNestedMessage<T>(7);
+  }
+
+
+  using FieldMetadata_Types =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      HeapGraphType,
+      HeapGraph>;
+
+  static constexpr FieldMetadata_Types kTypes{};
+  template <typename T = HeapGraphType> T* add_types() {
+    return BeginNestedMessage<T>(9);
+  }
+
+
+  using FieldMetadata_FieldNames =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InternedString,
+      HeapGraph>;
+
+  static constexpr FieldMetadata_FieldNames kFieldNames{};
+  template <typename T = InternedString> T* add_field_names() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_LocationNames =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InternedString,
+      HeapGraph>;
+
+  static constexpr FieldMetadata_LocationNames kLocationNames{};
+  template <typename T = InternedString> T* add_location_names() {
+    return BeginNestedMessage<T>(8);
+  }
+
+
+  using FieldMetadata_Continued =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      HeapGraph>;
+
+  static constexpr FieldMetadata_Continued kContinued{};
+  void set_continued(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_Continued::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_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapGraph>;
+
+  static constexpr FieldMetadata_Index kIndex{};
+  void set_index(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Index::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 HeapGraphObject_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  HeapGraphObject_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit HeapGraphObject_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit HeapGraphObject_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  uint64_t id() const { return at<1>().as_uint64(); }
+  bool has_id_delta() const { return at<7>().valid(); }
+  uint64_t id_delta() const { return at<7>().as_uint64(); }
+  bool has_type_id() const { return at<2>().valid(); }
+  uint64_t type_id() const { return at<2>().as_uint64(); }
+  bool has_self_size() const { return at<3>().valid(); }
+  uint64_t self_size() const { return at<3>().as_uint64(); }
+  bool has_reference_field_id_base() const { return at<6>().valid(); }
+  uint64_t reference_field_id_base() const { return at<6>().as_uint64(); }
+  bool has_reference_field_id() const { return at<4>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, uint64_t> reference_field_id(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, uint64_t>(4, parse_error_ptr); }
+  bool has_reference_object_id() const { return at<5>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, uint64_t> reference_object_id(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, uint64_t>(5, parse_error_ptr); }
+  bool has_native_allocation_registry_size_field() const { return at<8>().valid(); }
+  int64_t native_allocation_registry_size_field() const { return at<8>().as_int64(); }
+};
+
+class HeapGraphObject : public ::protozero::Message {
+ public:
+  using Decoder = HeapGraphObject_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kIdDeltaFieldNumber = 7,
+    kTypeIdFieldNumber = 2,
+    kSelfSizeFieldNumber = 3,
+    kReferenceFieldIdBaseFieldNumber = 6,
+    kReferenceFieldIdFieldNumber = 4,
+    kReferenceObjectIdFieldNumber = 5,
+    kNativeAllocationRegistrySizeFieldFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.HeapGraphObject"; }
+
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapGraphObject>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::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_IdDelta =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapGraphObject>;
+
+  static constexpr FieldMetadata_IdDelta kIdDelta{};
+  void set_id_delta(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IdDelta::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_TypeId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapGraphObject>;
+
+  static constexpr FieldMetadata_TypeId kTypeId{};
+  void set_type_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TypeId::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_SelfSize =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapGraphObject>;
+
+  static constexpr FieldMetadata_SelfSize kSelfSize{};
+  void set_self_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SelfSize::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_ReferenceFieldIdBase =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapGraphObject>;
+
+  static constexpr FieldMetadata_ReferenceFieldIdBase kReferenceFieldIdBase{};
+  void set_reference_field_id_base(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReferenceFieldIdBase::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_ReferenceFieldId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapGraphObject>;
+
+  static constexpr FieldMetadata_ReferenceFieldId kReferenceFieldId{};
+  void set_reference_field_id(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_ReferenceFieldId::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_ReferenceObjectId =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapGraphObject>;
+
+  static constexpr FieldMetadata_ReferenceObjectId kReferenceObjectId{};
+  void set_reference_object_id(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_ReferenceObjectId::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_NativeAllocationRegistrySizeField =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      HeapGraphObject>;
+
+  static constexpr FieldMetadata_NativeAllocationRegistrySizeField kNativeAllocationRegistrySizeField{};
+  void set_native_allocation_registry_size_field(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NativeAllocationRegistrySizeField::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 HeapGraphType_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  HeapGraphType_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit HeapGraphType_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit HeapGraphType_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  uint64_t id() const { return at<1>().as_uint64(); }
+  bool has_location_id() const { return at<2>().valid(); }
+  uint64_t location_id() const { return at<2>().as_uint64(); }
+  bool has_class_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars class_name() const { return at<3>().as_string(); }
+  bool has_object_size() const { return at<4>().valid(); }
+  uint64_t object_size() const { return at<4>().as_uint64(); }
+  bool has_superclass_id() const { return at<5>().valid(); }
+  uint64_t superclass_id() const { return at<5>().as_uint64(); }
+  bool has_reference_field_id() const { return at<6>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, uint64_t> reference_field_id(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, uint64_t>(6, parse_error_ptr); }
+  bool has_kind() const { return at<7>().valid(); }
+  int32_t kind() const { return at<7>().as_int32(); }
+  bool has_classloader_id() const { return at<8>().valid(); }
+  uint64_t classloader_id() const { return at<8>().as_uint64(); }
+};
+
+class HeapGraphType : public ::protozero::Message {
+ public:
+  using Decoder = HeapGraphType_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kLocationIdFieldNumber = 2,
+    kClassNameFieldNumber = 3,
+    kObjectSizeFieldNumber = 4,
+    kSuperclassIdFieldNumber = 5,
+    kReferenceFieldIdFieldNumber = 6,
+    kKindFieldNumber = 7,
+    kClassloaderIdFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.HeapGraphType"; }
+
+
+  using Kind = ::perfetto::protos::pbzero::HeapGraphType_Kind;
+  static inline const char* Kind_Name(Kind value) {
+    return ::perfetto::protos::pbzero::HeapGraphType_Kind_Name(value);
+  }
+  static inline const Kind KIND_UNKNOWN = Kind::KIND_UNKNOWN;
+  static inline const Kind KIND_NORMAL = Kind::KIND_NORMAL;
+  static inline const Kind KIND_NOREFERENCES = Kind::KIND_NOREFERENCES;
+  static inline const Kind KIND_STRING = Kind::KIND_STRING;
+  static inline const Kind KIND_ARRAY = Kind::KIND_ARRAY;
+  static inline const Kind KIND_CLASS = Kind::KIND_CLASS;
+  static inline const Kind KIND_CLASSLOADER = Kind::KIND_CLASSLOADER;
+  static inline const Kind KIND_DEXCACHE = Kind::KIND_DEXCACHE;
+  static inline const Kind KIND_SOFT_REFERENCE = Kind::KIND_SOFT_REFERENCE;
+  static inline const Kind KIND_WEAK_REFERENCE = Kind::KIND_WEAK_REFERENCE;
+  static inline const Kind KIND_FINALIZER_REFERENCE = Kind::KIND_FINALIZER_REFERENCE;
+  static inline const Kind KIND_PHANTOM_REFERENCE = Kind::KIND_PHANTOM_REFERENCE;
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapGraphType>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::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_LocationId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapGraphType>;
+
+  static constexpr FieldMetadata_LocationId kLocationId{};
+  void set_location_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LocationId::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_ClassName =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      HeapGraphType>;
+
+  static constexpr FieldMetadata_ClassName kClassName{};
+  void set_class_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ClassName::kFieldId, data, size);
+  }
+  void set_class_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ClassName::kFieldId, chars.data, chars.size);
+  }
+  void set_class_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ClassName::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_ObjectSize =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapGraphType>;
+
+  static constexpr FieldMetadata_ObjectSize kObjectSize{};
+  void set_object_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ObjectSize::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_SuperclassId =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapGraphType>;
+
+  static constexpr FieldMetadata_SuperclassId kSuperclassId{};
+  void set_superclass_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SuperclassId::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_ReferenceFieldId =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapGraphType>;
+
+  static constexpr FieldMetadata_ReferenceFieldId kReferenceFieldId{};
+  void set_reference_field_id(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_ReferenceFieldId::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_Kind =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      HeapGraphType_Kind,
+      HeapGraphType>;
+
+  static constexpr FieldMetadata_Kind kKind{};
+  void set_kind(HeapGraphType_Kind value) {
+    static constexpr uint32_t field_id = FieldMetadata_Kind::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_ClassloaderId =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapGraphType>;
+
+  static constexpr FieldMetadata_ClassloaderId kClassloaderId{};
+  void set_classloader_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ClassloaderId::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 HeapGraphRoot_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  HeapGraphRoot_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit HeapGraphRoot_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit HeapGraphRoot_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_object_ids() const { return at<1>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, uint64_t> object_ids(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, uint64_t>(1, parse_error_ptr); }
+  bool has_root_type() const { return at<2>().valid(); }
+  int32_t root_type() const { return at<2>().as_int32(); }
+};
+
+class HeapGraphRoot : public ::protozero::Message {
+ public:
+  using Decoder = HeapGraphRoot_Decoder;
+  enum : int32_t {
+    kObjectIdsFieldNumber = 1,
+    kRootTypeFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.HeapGraphRoot"; }
+
+
+  using Type = ::perfetto::protos::pbzero::HeapGraphRoot_Type;
+  static inline const char* Type_Name(Type value) {
+    return ::perfetto::protos::pbzero::HeapGraphRoot_Type_Name(value);
+  }
+  static inline const Type ROOT_UNKNOWN = Type::ROOT_UNKNOWN;
+  static inline const Type ROOT_JNI_GLOBAL = Type::ROOT_JNI_GLOBAL;
+  static inline const Type ROOT_JNI_LOCAL = Type::ROOT_JNI_LOCAL;
+  static inline const Type ROOT_JAVA_FRAME = Type::ROOT_JAVA_FRAME;
+  static inline const Type ROOT_NATIVE_STACK = Type::ROOT_NATIVE_STACK;
+  static inline const Type ROOT_STICKY_CLASS = Type::ROOT_STICKY_CLASS;
+  static inline const Type ROOT_THREAD_BLOCK = Type::ROOT_THREAD_BLOCK;
+  static inline const Type ROOT_MONITOR_USED = Type::ROOT_MONITOR_USED;
+  static inline const Type ROOT_THREAD_OBJECT = Type::ROOT_THREAD_OBJECT;
+  static inline const Type ROOT_INTERNED_STRING = Type::ROOT_INTERNED_STRING;
+  static inline const Type ROOT_FINALIZING = Type::ROOT_FINALIZING;
+  static inline const Type ROOT_DEBUGGER = Type::ROOT_DEBUGGER;
+  static inline const Type ROOT_REFERENCE_CLEANUP = Type::ROOT_REFERENCE_CLEANUP;
+  static inline const Type ROOT_VM_INTERNAL = Type::ROOT_VM_INTERNAL;
+  static inline const Type ROOT_JNI_MONITOR = Type::ROOT_JNI_MONITOR;
+
+  using FieldMetadata_ObjectIds =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapGraphRoot>;
+
+  static constexpr FieldMetadata_ObjectIds kObjectIds{};
+  void set_object_ids(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_ObjectIds::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_RootType =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      HeapGraphRoot_Type,
+      HeapGraphRoot>;
+
+  static constexpr FieldMetadata_RootType kRootType{};
+  void set_root_type(HeapGraphRoot_Type value) {
+    static constexpr uint32_t field_id = FieldMetadata_RootType::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.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/profiling/profile_common.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PROFILING_PROFILE_COMMON_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PROFILING_PROFILE_COMMON_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class AddressSymbols;
+class Line;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class Callstack_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  Callstack_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Callstack_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Callstack_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_frame_ids() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> frame_ids() const { return GetRepeated<uint64_t>(2); }
+};
+
+class Callstack : public ::protozero::Message {
+ public:
+  using Decoder = Callstack_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kFrameIdsFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Callstack"; }
+
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Callstack>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::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_FrameIds =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Callstack>;
+
+  static constexpr FieldMetadata_FrameIds kFrameIds{};
+  void add_frame_ids(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FrameIds::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 Frame_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Frame_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Frame_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Frame_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_function_name_id() const { return at<2>().valid(); }
+  uint64_t function_name_id() const { return at<2>().as_uint64(); }
+  bool has_mapping_id() const { return at<3>().valid(); }
+  uint64_t mapping_id() const { return at<3>().as_uint64(); }
+  bool has_rel_pc() const { return at<4>().valid(); }
+  uint64_t rel_pc() const { return at<4>().as_uint64(); }
+};
+
+class Frame : public ::protozero::Message {
+ public:
+  using Decoder = Frame_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kFunctionNameIdFieldNumber = 2,
+    kMappingIdFieldNumber = 3,
+    kRelPcFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Frame"; }
+
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Frame>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::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_FunctionNameId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Frame>;
+
+  static constexpr FieldMetadata_FunctionNameId kFunctionNameId{};
+  void set_function_name_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FunctionNameId::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_MappingId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Frame>;
+
+  static constexpr FieldMetadata_MappingId kMappingId{};
+  void set_mapping_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MappingId::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_RelPc =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Frame>;
+
+  static constexpr FieldMetadata_RelPc kRelPc{};
+  void set_rel_pc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RelPc::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 Mapping_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  Mapping_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Mapping_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Mapping_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_build_id() const { return at<2>().valid(); }
+  uint64_t build_id() const { return at<2>().as_uint64(); }
+  bool has_exact_offset() const { return at<8>().valid(); }
+  uint64_t exact_offset() const { return at<8>().as_uint64(); }
+  bool has_start_offset() const { return at<3>().valid(); }
+  uint64_t start_offset() const { return at<3>().as_uint64(); }
+  bool has_start() const { return at<4>().valid(); }
+  uint64_t start() const { return at<4>().as_uint64(); }
+  bool has_end() const { return at<5>().valid(); }
+  uint64_t end() const { return at<5>().as_uint64(); }
+  bool has_load_bias() const { return at<6>().valid(); }
+  uint64_t load_bias() const { return at<6>().as_uint64(); }
+  bool has_path_string_ids() const { return at<7>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> path_string_ids() const { return GetRepeated<uint64_t>(7); }
+};
+
+class Mapping : public ::protozero::Message {
+ public:
+  using Decoder = Mapping_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kBuildIdFieldNumber = 2,
+    kExactOffsetFieldNumber = 8,
+    kStartOffsetFieldNumber = 3,
+    kStartFieldNumber = 4,
+    kEndFieldNumber = 5,
+    kLoadBiasFieldNumber = 6,
+    kPathStringIdsFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Mapping"; }
+
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Mapping>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::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_BuildId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Mapping>;
+
+  static constexpr FieldMetadata_BuildId kBuildId{};
+  void set_build_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BuildId::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_ExactOffset =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Mapping>;
+
+  static constexpr FieldMetadata_ExactOffset kExactOffset{};
+  void set_exact_offset(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ExactOffset::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_StartOffset =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Mapping>;
+
+  static constexpr FieldMetadata_StartOffset kStartOffset{};
+  void set_start_offset(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StartOffset::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_Start =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Mapping>;
+
+  static constexpr FieldMetadata_Start kStart{};
+  void set_start(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Start::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_End =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Mapping>;
+
+  static constexpr FieldMetadata_End kEnd{};
+  void set_end(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_End::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_LoadBias =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Mapping>;
+
+  static constexpr FieldMetadata_LoadBias kLoadBias{};
+  void set_load_bias(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LoadBias::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_PathStringIds =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Mapping>;
+
+  static constexpr FieldMetadata_PathStringIds kPathStringIds{};
+  void add_path_string_ids(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PathStringIds::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 ModuleSymbols_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ModuleSymbols_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ModuleSymbols_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ModuleSymbols_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_path() const { return at<1>().valid(); }
+  ::protozero::ConstChars path() const { return at<1>().as_string(); }
+  bool has_build_id() const { return at<2>().valid(); }
+  ::protozero::ConstChars build_id() const { return at<2>().as_string(); }
+  bool has_address_symbols() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> address_symbols() const { return GetRepeated<::protozero::ConstBytes>(3); }
+};
+
+class ModuleSymbols : public ::protozero::Message {
+ public:
+  using Decoder = ModuleSymbols_Decoder;
+  enum : int32_t {
+    kPathFieldNumber = 1,
+    kBuildIdFieldNumber = 2,
+    kAddressSymbolsFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ModuleSymbols"; }
+
+
+  using FieldMetadata_Path =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ModuleSymbols>;
+
+  static constexpr FieldMetadata_Path kPath{};
+  void set_path(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Path::kFieldId, data, size);
+  }
+  void set_path(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Path::kFieldId, chars.data, chars.size);
+  }
+  void set_path(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Path::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_BuildId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ModuleSymbols>;
+
+  static constexpr FieldMetadata_BuildId kBuildId{};
+  void set_build_id(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_BuildId::kFieldId, data, size);
+  }
+  void set_build_id(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_BuildId::kFieldId, chars.data, chars.size);
+  }
+  void set_build_id(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_BuildId::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_AddressSymbols =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AddressSymbols,
+      ModuleSymbols>;
+
+  static constexpr FieldMetadata_AddressSymbols kAddressSymbols{};
+  template <typename T = AddressSymbols> T* add_address_symbols() {
+    return BeginNestedMessage<T>(3);
+  }
+
+};
+
+class AddressSymbols_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AddressSymbols_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AddressSymbols_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AddressSymbols_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_address() const { return at<1>().valid(); }
+  uint64_t address() const { return at<1>().as_uint64(); }
+  bool has_lines() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> lines() const { return GetRepeated<::protozero::ConstBytes>(2); }
+};
+
+class AddressSymbols : public ::protozero::Message {
+ public:
+  using Decoder = AddressSymbols_Decoder;
+  enum : int32_t {
+    kAddressFieldNumber = 1,
+    kLinesFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AddressSymbols"; }
+
+
+  using FieldMetadata_Address =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      AddressSymbols>;
+
+  static constexpr FieldMetadata_Address kAddress{};
+  void set_address(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Address::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_Lines =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Line,
+      AddressSymbols>;
+
+  static constexpr FieldMetadata_Lines kLines{};
+  template <typename T = Line> T* add_lines() {
+    return BeginNestedMessage<T>(2);
+  }
+
+};
+
+class Line_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Line_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Line_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Line_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_function_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars function_name() const { return at<1>().as_string(); }
+  bool has_source_file_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars source_file_name() const { return at<2>().as_string(); }
+  bool has_line_number() const { return at<3>().valid(); }
+  uint32_t line_number() const { return at<3>().as_uint32(); }
+};
+
+class Line : public ::protozero::Message {
+ public:
+  using Decoder = Line_Decoder;
+  enum : int32_t {
+    kFunctionNameFieldNumber = 1,
+    kSourceFileNameFieldNumber = 2,
+    kLineNumberFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Line"; }
+
+
+  using FieldMetadata_FunctionName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      Line>;
+
+  static constexpr FieldMetadata_FunctionName kFunctionName{};
+  void set_function_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_FunctionName::kFieldId, data, size);
+  }
+  void set_function_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_FunctionName::kFieldId, chars.data, chars.size);
+  }
+  void set_function_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_FunctionName::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_SourceFileName =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      Line>;
+
+  static constexpr FieldMetadata_SourceFileName kSourceFileName{};
+  void set_source_file_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_SourceFileName::kFieldId, data, size);
+  }
+  void set_source_file_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_SourceFileName::kFieldId, chars.data, chars.size);
+  }
+  void set_source_file_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_SourceFileName::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_LineNumber =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Line>;
+
+  static constexpr FieldMetadata_LineNumber kLineNumber{};
+  void set_line_number(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LineNumber::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 ProfiledFrameSymbols_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ProfiledFrameSymbols_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProfiledFrameSymbols_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProfiledFrameSymbols_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_frame_iid() const { return at<1>().valid(); }
+  uint64_t frame_iid() const { return at<1>().as_uint64(); }
+  bool has_function_name_id() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> function_name_id() const { return GetRepeated<uint64_t>(2); }
+  bool has_file_name_id() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> file_name_id() const { return GetRepeated<uint64_t>(3); }
+  bool has_line_number() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint32_t> line_number() const { return GetRepeated<uint32_t>(4); }
+};
+
+class ProfiledFrameSymbols : public ::protozero::Message {
+ public:
+  using Decoder = ProfiledFrameSymbols_Decoder;
+  enum : int32_t {
+    kFrameIidFieldNumber = 1,
+    kFunctionNameIdFieldNumber = 2,
+    kFileNameIdFieldNumber = 3,
+    kLineNumberFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProfiledFrameSymbols"; }
+
+
+  using FieldMetadata_FrameIid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfiledFrameSymbols>;
+
+  static constexpr FieldMetadata_FrameIid kFrameIid{};
+  void set_frame_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FrameIid::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_FunctionNameId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfiledFrameSymbols>;
+
+  static constexpr FieldMetadata_FunctionNameId kFunctionNameId{};
+  void add_function_name_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FunctionNameId::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_FileNameId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfiledFrameSymbols>;
+
+  static constexpr FieldMetadata_FileNameId kFileNameId{};
+  void add_file_name_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FileNameId::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_LineNumber =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ProfiledFrameSymbols>;
+
+  static constexpr FieldMetadata_LineNumber kLineNumber{};
+  void add_line_number(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LineNumber::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 InternedString_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  InternedString_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit InternedString_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit InternedString_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_str() const { return at<2>().valid(); }
+  ::protozero::ConstBytes str() const { return at<2>().as_bytes(); }
+};
+
+class InternedString : public ::protozero::Message {
+ public:
+  using Decoder = InternedString_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kStrFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.InternedString"; }
+
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      InternedString>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::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_Str =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      InternedString>;
+
+  static constexpr FieldMetadata_Str kStr{};
+  void set_str(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_Str::kFieldId, data, size);
+  }
+  void set_str(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_Str::kFieldId, bytes.data, bytes.size);
+  }
+  void set_str(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Str::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/profiling/profile_packet.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PROFILING_PROFILE_PACKET_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PROFILING_PROFILE_PACKET_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class Callstack;
+class Frame;
+class InternedString;
+class Mapping;
+class PerfEvents_Timebase;
+class PerfSample_ProducerEvent;
+class ProfilePacket_HeapSample;
+class ProfilePacket_Histogram;
+class ProfilePacket_Histogram_Bucket;
+class ProfilePacket_ProcessHeapSamples;
+class ProfilePacket_ProcessStats;
+namespace perfetto_pbzero_enum_PerfSample_ProducerEvent {
+enum DataSourceStopReason : int32_t;
+}  // namespace perfetto_pbzero_enum_PerfSample_ProducerEvent
+using PerfSample_ProducerEvent_DataSourceStopReason = perfetto_pbzero_enum_PerfSample_ProducerEvent::DataSourceStopReason;
+namespace perfetto_pbzero_enum_PerfSample {
+enum SampleSkipReason : int32_t;
+}  // namespace perfetto_pbzero_enum_PerfSample
+using PerfSample_SampleSkipReason = perfetto_pbzero_enum_PerfSample::SampleSkipReason;
+namespace perfetto_pbzero_enum_ProfilePacket_ProcessHeapSamples {
+enum ClientError : int32_t;
+}  // namespace perfetto_pbzero_enum_ProfilePacket_ProcessHeapSamples
+using ProfilePacket_ProcessHeapSamples_ClientError = perfetto_pbzero_enum_ProfilePacket_ProcessHeapSamples::ClientError;
+namespace perfetto_pbzero_enum_Profiling {
+enum CpuMode : int32_t;
+}  // namespace perfetto_pbzero_enum_Profiling
+using Profiling_CpuMode = perfetto_pbzero_enum_Profiling::CpuMode;
+namespace perfetto_pbzero_enum_Profiling {
+enum StackUnwindError : int32_t;
+}  // namespace perfetto_pbzero_enum_Profiling
+using Profiling_StackUnwindError = perfetto_pbzero_enum_Profiling::StackUnwindError;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_PerfSample {
+enum SampleSkipReason : int32_t {
+  PROFILER_SKIP_UNKNOWN = 0,
+  PROFILER_SKIP_READ_STAGE = 1,
+  PROFILER_SKIP_UNWIND_STAGE = 2,
+  PROFILER_SKIP_UNWIND_ENQUEUE = 3,
+};
+} // namespace perfetto_pbzero_enum_PerfSample
+using PerfSample_SampleSkipReason = perfetto_pbzero_enum_PerfSample::SampleSkipReason;
+
+
+constexpr PerfSample_SampleSkipReason PerfSample_SampleSkipReason_MIN = PerfSample_SampleSkipReason::PROFILER_SKIP_UNKNOWN;
+constexpr PerfSample_SampleSkipReason PerfSample_SampleSkipReason_MAX = PerfSample_SampleSkipReason::PROFILER_SKIP_UNWIND_ENQUEUE;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* PerfSample_SampleSkipReason_Name(::perfetto::protos::pbzero::PerfSample_SampleSkipReason value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::PerfSample_SampleSkipReason::PROFILER_SKIP_UNKNOWN:
+    return "PROFILER_SKIP_UNKNOWN";
+
+  case ::perfetto::protos::pbzero::PerfSample_SampleSkipReason::PROFILER_SKIP_READ_STAGE:
+    return "PROFILER_SKIP_READ_STAGE";
+
+  case ::perfetto::protos::pbzero::PerfSample_SampleSkipReason::PROFILER_SKIP_UNWIND_STAGE:
+    return "PROFILER_SKIP_UNWIND_STAGE";
+
+  case ::perfetto::protos::pbzero::PerfSample_SampleSkipReason::PROFILER_SKIP_UNWIND_ENQUEUE:
+    return "PROFILER_SKIP_UNWIND_ENQUEUE";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_PerfSample_ProducerEvent {
+enum DataSourceStopReason : int32_t {
+  PROFILER_STOP_UNKNOWN = 0,
+  PROFILER_STOP_GUARDRAIL = 1,
+};
+} // namespace perfetto_pbzero_enum_PerfSample_ProducerEvent
+using PerfSample_ProducerEvent_DataSourceStopReason = perfetto_pbzero_enum_PerfSample_ProducerEvent::DataSourceStopReason;
+
+
+constexpr PerfSample_ProducerEvent_DataSourceStopReason PerfSample_ProducerEvent_DataSourceStopReason_MIN = PerfSample_ProducerEvent_DataSourceStopReason::PROFILER_STOP_UNKNOWN;
+constexpr PerfSample_ProducerEvent_DataSourceStopReason PerfSample_ProducerEvent_DataSourceStopReason_MAX = PerfSample_ProducerEvent_DataSourceStopReason::PROFILER_STOP_GUARDRAIL;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* PerfSample_ProducerEvent_DataSourceStopReason_Name(::perfetto::protos::pbzero::PerfSample_ProducerEvent_DataSourceStopReason value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::PerfSample_ProducerEvent_DataSourceStopReason::PROFILER_STOP_UNKNOWN:
+    return "PROFILER_STOP_UNKNOWN";
+
+  case ::perfetto::protos::pbzero::PerfSample_ProducerEvent_DataSourceStopReason::PROFILER_STOP_GUARDRAIL:
+    return "PROFILER_STOP_GUARDRAIL";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_Profiling {
+enum CpuMode : int32_t {
+  MODE_UNKNOWN = 0,
+  MODE_KERNEL = 1,
+  MODE_USER = 2,
+  MODE_HYPERVISOR = 3,
+  MODE_GUEST_KERNEL = 4,
+  MODE_GUEST_USER = 5,
+};
+} // namespace perfetto_pbzero_enum_Profiling
+using Profiling_CpuMode = perfetto_pbzero_enum_Profiling::CpuMode;
+
+
+constexpr Profiling_CpuMode Profiling_CpuMode_MIN = Profiling_CpuMode::MODE_UNKNOWN;
+constexpr Profiling_CpuMode Profiling_CpuMode_MAX = Profiling_CpuMode::MODE_GUEST_USER;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* Profiling_CpuMode_Name(::perfetto::protos::pbzero::Profiling_CpuMode value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::Profiling_CpuMode::MODE_UNKNOWN:
+    return "MODE_UNKNOWN";
+
+  case ::perfetto::protos::pbzero::Profiling_CpuMode::MODE_KERNEL:
+    return "MODE_KERNEL";
+
+  case ::perfetto::protos::pbzero::Profiling_CpuMode::MODE_USER:
+    return "MODE_USER";
+
+  case ::perfetto::protos::pbzero::Profiling_CpuMode::MODE_HYPERVISOR:
+    return "MODE_HYPERVISOR";
+
+  case ::perfetto::protos::pbzero::Profiling_CpuMode::MODE_GUEST_KERNEL:
+    return "MODE_GUEST_KERNEL";
+
+  case ::perfetto::protos::pbzero::Profiling_CpuMode::MODE_GUEST_USER:
+    return "MODE_GUEST_USER";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_Profiling {
+enum StackUnwindError : int32_t {
+  UNWIND_ERROR_UNKNOWN = 0,
+  UNWIND_ERROR_NONE = 1,
+  UNWIND_ERROR_MEMORY_INVALID = 2,
+  UNWIND_ERROR_UNWIND_INFO = 3,
+  UNWIND_ERROR_UNSUPPORTED = 4,
+  UNWIND_ERROR_INVALID_MAP = 5,
+  UNWIND_ERROR_MAX_FRAMES_EXCEEDED = 6,
+  UNWIND_ERROR_REPEATED_FRAME = 7,
+  UNWIND_ERROR_INVALID_ELF = 8,
+  UNWIND_ERROR_SYSTEM_CALL = 9,
+  UNWIND_ERROR_THREAD_TIMEOUT = 10,
+  UNWIND_ERROR_THREAD_DOES_NOT_EXIST = 11,
+  UNWIND_ERROR_BAD_ARCH = 12,
+  UNWIND_ERROR_MAPS_PARSE = 13,
+  UNWIND_ERROR_INVALID_PARAMETER = 14,
+  UNWIND_ERROR_PTRACE_CALL = 15,
+};
+} // namespace perfetto_pbzero_enum_Profiling
+using Profiling_StackUnwindError = perfetto_pbzero_enum_Profiling::StackUnwindError;
+
+
+constexpr Profiling_StackUnwindError Profiling_StackUnwindError_MIN = Profiling_StackUnwindError::UNWIND_ERROR_UNKNOWN;
+constexpr Profiling_StackUnwindError Profiling_StackUnwindError_MAX = Profiling_StackUnwindError::UNWIND_ERROR_PTRACE_CALL;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* Profiling_StackUnwindError_Name(::perfetto::protos::pbzero::Profiling_StackUnwindError value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::Profiling_StackUnwindError::UNWIND_ERROR_UNKNOWN:
+    return "UNWIND_ERROR_UNKNOWN";
+
+  case ::perfetto::protos::pbzero::Profiling_StackUnwindError::UNWIND_ERROR_NONE:
+    return "UNWIND_ERROR_NONE";
+
+  case ::perfetto::protos::pbzero::Profiling_StackUnwindError::UNWIND_ERROR_MEMORY_INVALID:
+    return "UNWIND_ERROR_MEMORY_INVALID";
+
+  case ::perfetto::protos::pbzero::Profiling_StackUnwindError::UNWIND_ERROR_UNWIND_INFO:
+    return "UNWIND_ERROR_UNWIND_INFO";
+
+  case ::perfetto::protos::pbzero::Profiling_StackUnwindError::UNWIND_ERROR_UNSUPPORTED:
+    return "UNWIND_ERROR_UNSUPPORTED";
+
+  case ::perfetto::protos::pbzero::Profiling_StackUnwindError::UNWIND_ERROR_INVALID_MAP:
+    return "UNWIND_ERROR_INVALID_MAP";
+
+  case ::perfetto::protos::pbzero::Profiling_StackUnwindError::UNWIND_ERROR_MAX_FRAMES_EXCEEDED:
+    return "UNWIND_ERROR_MAX_FRAMES_EXCEEDED";
+
+  case ::perfetto::protos::pbzero::Profiling_StackUnwindError::UNWIND_ERROR_REPEATED_FRAME:
+    return "UNWIND_ERROR_REPEATED_FRAME";
+
+  case ::perfetto::protos::pbzero::Profiling_StackUnwindError::UNWIND_ERROR_INVALID_ELF:
+    return "UNWIND_ERROR_INVALID_ELF";
+
+  case ::perfetto::protos::pbzero::Profiling_StackUnwindError::UNWIND_ERROR_SYSTEM_CALL:
+    return "UNWIND_ERROR_SYSTEM_CALL";
+
+  case ::perfetto::protos::pbzero::Profiling_StackUnwindError::UNWIND_ERROR_THREAD_TIMEOUT:
+    return "UNWIND_ERROR_THREAD_TIMEOUT";
+
+  case ::perfetto::protos::pbzero::Profiling_StackUnwindError::UNWIND_ERROR_THREAD_DOES_NOT_EXIST:
+    return "UNWIND_ERROR_THREAD_DOES_NOT_EXIST";
+
+  case ::perfetto::protos::pbzero::Profiling_StackUnwindError::UNWIND_ERROR_BAD_ARCH:
+    return "UNWIND_ERROR_BAD_ARCH";
+
+  case ::perfetto::protos::pbzero::Profiling_StackUnwindError::UNWIND_ERROR_MAPS_PARSE:
+    return "UNWIND_ERROR_MAPS_PARSE";
+
+  case ::perfetto::protos::pbzero::Profiling_StackUnwindError::UNWIND_ERROR_INVALID_PARAMETER:
+    return "UNWIND_ERROR_INVALID_PARAMETER";
+
+  case ::perfetto::protos::pbzero::Profiling_StackUnwindError::UNWIND_ERROR_PTRACE_CALL:
+    return "UNWIND_ERROR_PTRACE_CALL";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_ProfilePacket_ProcessHeapSamples {
+enum ClientError : int32_t {
+  CLIENT_ERROR_NONE = 0,
+  CLIENT_ERROR_HIT_TIMEOUT = 1,
+  CLIENT_ERROR_INVALID_STACK_BOUNDS = 2,
+};
+} // namespace perfetto_pbzero_enum_ProfilePacket_ProcessHeapSamples
+using ProfilePacket_ProcessHeapSamples_ClientError = perfetto_pbzero_enum_ProfilePacket_ProcessHeapSamples::ClientError;
+
+
+constexpr ProfilePacket_ProcessHeapSamples_ClientError ProfilePacket_ProcessHeapSamples_ClientError_MIN = ProfilePacket_ProcessHeapSamples_ClientError::CLIENT_ERROR_NONE;
+constexpr ProfilePacket_ProcessHeapSamples_ClientError ProfilePacket_ProcessHeapSamples_ClientError_MAX = ProfilePacket_ProcessHeapSamples_ClientError::CLIENT_ERROR_INVALID_STACK_BOUNDS;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ProfilePacket_ProcessHeapSamples_ClientError_Name(::perfetto::protos::pbzero::ProfilePacket_ProcessHeapSamples_ClientError value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ProfilePacket_ProcessHeapSamples_ClientError::CLIENT_ERROR_NONE:
+    return "CLIENT_ERROR_NONE";
+
+  case ::perfetto::protos::pbzero::ProfilePacket_ProcessHeapSamples_ClientError::CLIENT_ERROR_HIT_TIMEOUT:
+    return "CLIENT_ERROR_HIT_TIMEOUT";
+
+  case ::perfetto::protos::pbzero::ProfilePacket_ProcessHeapSamples_ClientError::CLIENT_ERROR_INVALID_STACK_BOUNDS:
+    return "CLIENT_ERROR_INVALID_STACK_BOUNDS";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class PerfSampleDefaults_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  PerfSampleDefaults_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PerfSampleDefaults_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PerfSampleDefaults_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_timebase() const { return at<1>().valid(); }
+  ::protozero::ConstBytes timebase() const { return at<1>().as_bytes(); }
+  bool has_process_shard_count() const { return at<2>().valid(); }
+  uint32_t process_shard_count() const { return at<2>().as_uint32(); }
+  bool has_chosen_process_shard() const { return at<3>().valid(); }
+  uint32_t chosen_process_shard() const { return at<3>().as_uint32(); }
+};
+
+class PerfSampleDefaults : public ::protozero::Message {
+ public:
+  using Decoder = PerfSampleDefaults_Decoder;
+  enum : int32_t {
+    kTimebaseFieldNumber = 1,
+    kProcessShardCountFieldNumber = 2,
+    kChosenProcessShardFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PerfSampleDefaults"; }
+
+
+  using FieldMetadata_Timebase =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PerfEvents_Timebase,
+      PerfSampleDefaults>;
+
+  static constexpr FieldMetadata_Timebase kTimebase{};
+  template <typename T = PerfEvents_Timebase> T* set_timebase() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_ProcessShardCount =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfSampleDefaults>;
+
+  static constexpr FieldMetadata_ProcessShardCount kProcessShardCount{};
+  void set_process_shard_count(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProcessShardCount::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_ChosenProcessShard =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfSampleDefaults>;
+
+  static constexpr FieldMetadata_ChosenProcessShard kChosenProcessShard{};
+  void set_chosen_process_shard(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChosenProcessShard::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 PerfSample_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/19, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  PerfSample_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PerfSample_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PerfSample_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cpu() const { return at<1>().valid(); }
+  uint32_t cpu() const { return at<1>().as_uint32(); }
+  bool has_pid() const { return at<2>().valid(); }
+  uint32_t pid() const { return at<2>().as_uint32(); }
+  bool has_tid() const { return at<3>().valid(); }
+  uint32_t tid() const { return at<3>().as_uint32(); }
+  bool has_cpu_mode() const { return at<5>().valid(); }
+  int32_t cpu_mode() const { return at<5>().as_int32(); }
+  bool has_timebase_count() const { return at<6>().valid(); }
+  uint64_t timebase_count() const { return at<6>().as_uint64(); }
+  bool has_callstack_iid() const { return at<4>().valid(); }
+  uint64_t callstack_iid() const { return at<4>().as_uint64(); }
+  bool has_unwind_error() const { return at<16>().valid(); }
+  int32_t unwind_error() const { return at<16>().as_int32(); }
+  bool has_kernel_records_lost() const { return at<17>().valid(); }
+  uint64_t kernel_records_lost() const { return at<17>().as_uint64(); }
+  bool has_sample_skipped_reason() const { return at<18>().valid(); }
+  int32_t sample_skipped_reason() const { return at<18>().as_int32(); }
+  bool has_producer_event() const { return at<19>().valid(); }
+  ::protozero::ConstBytes producer_event() const { return at<19>().as_bytes(); }
+};
+
+class PerfSample : public ::protozero::Message {
+ public:
+  using Decoder = PerfSample_Decoder;
+  enum : int32_t {
+    kCpuFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kTidFieldNumber = 3,
+    kCpuModeFieldNumber = 5,
+    kTimebaseCountFieldNumber = 6,
+    kCallstackIidFieldNumber = 4,
+    kUnwindErrorFieldNumber = 16,
+    kKernelRecordsLostFieldNumber = 17,
+    kSampleSkippedReasonFieldNumber = 18,
+    kProducerEventFieldNumber = 19,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PerfSample"; }
+
+  using ProducerEvent = ::perfetto::protos::pbzero::PerfSample_ProducerEvent;
+
+  using SampleSkipReason = ::perfetto::protos::pbzero::PerfSample_SampleSkipReason;
+  static inline const char* SampleSkipReason_Name(SampleSkipReason value) {
+    return ::perfetto::protos::pbzero::PerfSample_SampleSkipReason_Name(value);
+  }
+  static inline const SampleSkipReason PROFILER_SKIP_UNKNOWN = SampleSkipReason::PROFILER_SKIP_UNKNOWN;
+  static inline const SampleSkipReason PROFILER_SKIP_READ_STAGE = SampleSkipReason::PROFILER_SKIP_READ_STAGE;
+  static inline const SampleSkipReason PROFILER_SKIP_UNWIND_STAGE = SampleSkipReason::PROFILER_SKIP_UNWIND_STAGE;
+  static inline const SampleSkipReason PROFILER_SKIP_UNWIND_ENQUEUE = SampleSkipReason::PROFILER_SKIP_UNWIND_ENQUEUE;
+
+  using FieldMetadata_Cpu =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfSample>;
+
+  static constexpr FieldMetadata_Cpu kCpu{};
+  void set_cpu(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cpu::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_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfSample>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_Tid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfSample>;
+
+  static constexpr FieldMetadata_Tid kTid{};
+  void set_tid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tid::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_CpuMode =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      Profiling_CpuMode,
+      PerfSample>;
+
+  static constexpr FieldMetadata_CpuMode kCpuMode{};
+  void set_cpu_mode(Profiling_CpuMode value) {
+    static constexpr uint32_t field_id = FieldMetadata_CpuMode::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_TimebaseCount =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PerfSample>;
+
+  static constexpr FieldMetadata_TimebaseCount kTimebaseCount{};
+  void set_timebase_count(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimebaseCount::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_CallstackIid =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PerfSample>;
+
+  static constexpr FieldMetadata_CallstackIid kCallstackIid{};
+  void set_callstack_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CallstackIid::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_UnwindError =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      Profiling_StackUnwindError,
+      PerfSample>;
+
+  static constexpr FieldMetadata_UnwindError kUnwindError{};
+  void set_unwind_error(Profiling_StackUnwindError value) {
+    static constexpr uint32_t field_id = FieldMetadata_UnwindError::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_KernelRecordsLost =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PerfSample>;
+
+  static constexpr FieldMetadata_KernelRecordsLost kKernelRecordsLost{};
+  void set_kernel_records_lost(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KernelRecordsLost::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_SampleSkippedReason =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      PerfSample_SampleSkipReason,
+      PerfSample>;
+
+  static constexpr FieldMetadata_SampleSkippedReason kSampleSkippedReason{};
+  void set_sample_skipped_reason(PerfSample_SampleSkipReason value) {
+    static constexpr uint32_t field_id = FieldMetadata_SampleSkippedReason::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_ProducerEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      19,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PerfSample_ProducerEvent,
+      PerfSample>;
+
+  static constexpr FieldMetadata_ProducerEvent kProducerEvent{};
+  template <typename T = PerfSample_ProducerEvent> T* set_producer_event() {
+    return BeginNestedMessage<T>(19);
+  }
+
+};
+
+class PerfSample_ProducerEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  PerfSample_ProducerEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PerfSample_ProducerEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PerfSample_ProducerEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_source_stop_reason() const { return at<1>().valid(); }
+  int32_t source_stop_reason() const { return at<1>().as_int32(); }
+};
+
+class PerfSample_ProducerEvent : public ::protozero::Message {
+ public:
+  using Decoder = PerfSample_ProducerEvent_Decoder;
+  enum : int32_t {
+    kSourceStopReasonFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PerfSample.ProducerEvent"; }
+
+
+  using DataSourceStopReason = ::perfetto::protos::pbzero::PerfSample_ProducerEvent_DataSourceStopReason;
+  static inline const char* DataSourceStopReason_Name(DataSourceStopReason value) {
+    return ::perfetto::protos::pbzero::PerfSample_ProducerEvent_DataSourceStopReason_Name(value);
+  }
+  static inline const DataSourceStopReason PROFILER_STOP_UNKNOWN = DataSourceStopReason::PROFILER_STOP_UNKNOWN;
+  static inline const DataSourceStopReason PROFILER_STOP_GUARDRAIL = DataSourceStopReason::PROFILER_STOP_GUARDRAIL;
+
+  using FieldMetadata_SourceStopReason =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      PerfSample_ProducerEvent_DataSourceStopReason,
+      PerfSample_ProducerEvent>;
+
+  static constexpr FieldMetadata_SourceStopReason kSourceStopReason{};
+  void set_source_stop_reason(PerfSample_ProducerEvent_DataSourceStopReason value) {
+    static constexpr uint32_t field_id = FieldMetadata_SourceStopReason::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);
+  }
+};
+
+class Profiling_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/0, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Profiling_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Profiling_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Profiling_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+};
+
+class Profiling : public ::protozero::Message {
+ public:
+  using Decoder = Profiling_Decoder;
+  static constexpr const char* GetName() { return ".perfetto.protos.Profiling"; }
+
+
+  using CpuMode = ::perfetto::protos::pbzero::Profiling_CpuMode;
+  static inline const char* CpuMode_Name(CpuMode value) {
+    return ::perfetto::protos::pbzero::Profiling_CpuMode_Name(value);
+  }
+
+  using StackUnwindError = ::perfetto::protos::pbzero::Profiling_StackUnwindError;
+  static inline const char* StackUnwindError_Name(StackUnwindError value) {
+    return ::perfetto::protos::pbzero::Profiling_StackUnwindError_Name(value);
+  }
+  static inline const CpuMode MODE_UNKNOWN = CpuMode::MODE_UNKNOWN;
+  static inline const CpuMode MODE_KERNEL = CpuMode::MODE_KERNEL;
+  static inline const CpuMode MODE_USER = CpuMode::MODE_USER;
+  static inline const CpuMode MODE_HYPERVISOR = CpuMode::MODE_HYPERVISOR;
+  static inline const CpuMode MODE_GUEST_KERNEL = CpuMode::MODE_GUEST_KERNEL;
+  static inline const CpuMode MODE_GUEST_USER = CpuMode::MODE_GUEST_USER;
+  static inline const StackUnwindError UNWIND_ERROR_UNKNOWN = StackUnwindError::UNWIND_ERROR_UNKNOWN;
+  static inline const StackUnwindError UNWIND_ERROR_NONE = StackUnwindError::UNWIND_ERROR_NONE;
+  static inline const StackUnwindError UNWIND_ERROR_MEMORY_INVALID = StackUnwindError::UNWIND_ERROR_MEMORY_INVALID;
+  static inline const StackUnwindError UNWIND_ERROR_UNWIND_INFO = StackUnwindError::UNWIND_ERROR_UNWIND_INFO;
+  static inline const StackUnwindError UNWIND_ERROR_UNSUPPORTED = StackUnwindError::UNWIND_ERROR_UNSUPPORTED;
+  static inline const StackUnwindError UNWIND_ERROR_INVALID_MAP = StackUnwindError::UNWIND_ERROR_INVALID_MAP;
+  static inline const StackUnwindError UNWIND_ERROR_MAX_FRAMES_EXCEEDED = StackUnwindError::UNWIND_ERROR_MAX_FRAMES_EXCEEDED;
+  static inline const StackUnwindError UNWIND_ERROR_REPEATED_FRAME = StackUnwindError::UNWIND_ERROR_REPEATED_FRAME;
+  static inline const StackUnwindError UNWIND_ERROR_INVALID_ELF = StackUnwindError::UNWIND_ERROR_INVALID_ELF;
+  static inline const StackUnwindError UNWIND_ERROR_SYSTEM_CALL = StackUnwindError::UNWIND_ERROR_SYSTEM_CALL;
+  static inline const StackUnwindError UNWIND_ERROR_THREAD_TIMEOUT = StackUnwindError::UNWIND_ERROR_THREAD_TIMEOUT;
+  static inline const StackUnwindError UNWIND_ERROR_THREAD_DOES_NOT_EXIST = StackUnwindError::UNWIND_ERROR_THREAD_DOES_NOT_EXIST;
+  static inline const StackUnwindError UNWIND_ERROR_BAD_ARCH = StackUnwindError::UNWIND_ERROR_BAD_ARCH;
+  static inline const StackUnwindError UNWIND_ERROR_MAPS_PARSE = StackUnwindError::UNWIND_ERROR_MAPS_PARSE;
+  static inline const StackUnwindError UNWIND_ERROR_INVALID_PARAMETER = StackUnwindError::UNWIND_ERROR_INVALID_PARAMETER;
+  static inline const StackUnwindError UNWIND_ERROR_PTRACE_CALL = StackUnwindError::UNWIND_ERROR_PTRACE_CALL;
+};
+
+class StreamingProfilePacket_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  StreamingProfilePacket_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit StreamingProfilePacket_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit StreamingProfilePacket_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_callstack_iid() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> callstack_iid() const { return GetRepeated<uint64_t>(1); }
+  bool has_timestamp_delta_us() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<int64_t> timestamp_delta_us() const { return GetRepeated<int64_t>(2); }
+  bool has_process_priority() const { return at<3>().valid(); }
+  int32_t process_priority() const { return at<3>().as_int32(); }
+};
+
+class StreamingProfilePacket : public ::protozero::Message {
+ public:
+  using Decoder = StreamingProfilePacket_Decoder;
+  enum : int32_t {
+    kCallstackIidFieldNumber = 1,
+    kTimestampDeltaUsFieldNumber = 2,
+    kProcessPriorityFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.StreamingProfilePacket"; }
+
+
+  using FieldMetadata_CallstackIid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      StreamingProfilePacket>;
+
+  static constexpr FieldMetadata_CallstackIid kCallstackIid{};
+  void add_callstack_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CallstackIid::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_TimestampDeltaUs =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      StreamingProfilePacket>;
+
+  static constexpr FieldMetadata_TimestampDeltaUs kTimestampDeltaUs{};
+  void add_timestamp_delta_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimestampDeltaUs::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_ProcessPriority =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      StreamingProfilePacket>;
+
+  static constexpr FieldMetadata_ProcessPriority kProcessPriority{};
+  void set_process_priority(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProcessPriority::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);
+  }
+};
+
+class StreamingFree_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  StreamingFree_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit StreamingFree_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit StreamingFree_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_address() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> address() const { return GetRepeated<uint64_t>(1); }
+  bool has_heap_id() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint32_t> heap_id() const { return GetRepeated<uint32_t>(2); }
+  bool has_sequence_number() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> sequence_number() const { return GetRepeated<uint64_t>(3); }
+};
+
+class StreamingFree : public ::protozero::Message {
+ public:
+  using Decoder = StreamingFree_Decoder;
+  enum : int32_t {
+    kAddressFieldNumber = 1,
+    kHeapIdFieldNumber = 2,
+    kSequenceNumberFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.StreamingFree"; }
+
+
+  using FieldMetadata_Address =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      StreamingFree>;
+
+  static constexpr FieldMetadata_Address kAddress{};
+  void add_address(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Address::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_HeapId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      StreamingFree>;
+
+  static constexpr FieldMetadata_HeapId kHeapId{};
+  void add_heap_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_HeapId::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_SequenceNumber =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      StreamingFree>;
+
+  static constexpr FieldMetadata_SequenceNumber kSequenceNumber{};
+  void add_sequence_number(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SequenceNumber::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 StreamingAllocation_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  StreamingAllocation_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit StreamingAllocation_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit StreamingAllocation_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_address() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> address() const { return GetRepeated<uint64_t>(1); }
+  bool has_size() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> size() const { return GetRepeated<uint64_t>(2); }
+  bool has_sample_size() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> sample_size() const { return GetRepeated<uint64_t>(3); }
+  bool has_clock_monotonic_coarse_timestamp() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> clock_monotonic_coarse_timestamp() const { return GetRepeated<uint64_t>(4); }
+  bool has_heap_id() const { return at<5>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint32_t> heap_id() const { return GetRepeated<uint32_t>(5); }
+  bool has_sequence_number() const { return at<6>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> sequence_number() const { return GetRepeated<uint64_t>(6); }
+};
+
+class StreamingAllocation : public ::protozero::Message {
+ public:
+  using Decoder = StreamingAllocation_Decoder;
+  enum : int32_t {
+    kAddressFieldNumber = 1,
+    kSizeFieldNumber = 2,
+    kSampleSizeFieldNumber = 3,
+    kClockMonotonicCoarseTimestampFieldNumber = 4,
+    kHeapIdFieldNumber = 5,
+    kSequenceNumberFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.StreamingAllocation"; }
+
+
+  using FieldMetadata_Address =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      StreamingAllocation>;
+
+  static constexpr FieldMetadata_Address kAddress{};
+  void add_address(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Address::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_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      StreamingAllocation>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void add_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::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_SampleSize =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      StreamingAllocation>;
+
+  static constexpr FieldMetadata_SampleSize kSampleSize{};
+  void add_sample_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SampleSize::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_ClockMonotonicCoarseTimestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      StreamingAllocation>;
+
+  static constexpr FieldMetadata_ClockMonotonicCoarseTimestamp kClockMonotonicCoarseTimestamp{};
+  void add_clock_monotonic_coarse_timestamp(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ClockMonotonicCoarseTimestamp::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_HeapId =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      StreamingAllocation>;
+
+  static constexpr FieldMetadata_HeapId kHeapId{};
+  void add_heap_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_HeapId::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_SequenceNumber =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      StreamingAllocation>;
+
+  static constexpr FieldMetadata_SequenceNumber kSequenceNumber{};
+  void add_sequence_number(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SequenceNumber::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 ProfilePacket_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ProfilePacket_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProfilePacket_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProfilePacket_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_strings() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> strings() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_mappings() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> mappings() const { return GetRepeated<::protozero::ConstBytes>(4); }
+  bool has_frames() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> frames() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_callstacks() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> callstacks() const { return GetRepeated<::protozero::ConstBytes>(3); }
+  bool has_process_dumps() const { return at<5>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> process_dumps() const { return GetRepeated<::protozero::ConstBytes>(5); }
+  bool has_continued() const { return at<6>().valid(); }
+  bool continued() const { return at<6>().as_bool(); }
+  bool has_index() const { return at<7>().valid(); }
+  uint64_t index() const { return at<7>().as_uint64(); }
+};
+
+class ProfilePacket : public ::protozero::Message {
+ public:
+  using Decoder = ProfilePacket_Decoder;
+  enum : int32_t {
+    kStringsFieldNumber = 1,
+    kMappingsFieldNumber = 4,
+    kFramesFieldNumber = 2,
+    kCallstacksFieldNumber = 3,
+    kProcessDumpsFieldNumber = 5,
+    kContinuedFieldNumber = 6,
+    kIndexFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProfilePacket"; }
+
+  using HeapSample = ::perfetto::protos::pbzero::ProfilePacket_HeapSample;
+  using Histogram = ::perfetto::protos::pbzero::ProfilePacket_Histogram;
+  using ProcessStats = ::perfetto::protos::pbzero::ProfilePacket_ProcessStats;
+  using ProcessHeapSamples = ::perfetto::protos::pbzero::ProfilePacket_ProcessHeapSamples;
+
+  using FieldMetadata_Strings =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InternedString,
+      ProfilePacket>;
+
+  static constexpr FieldMetadata_Strings kStrings{};
+  template <typename T = InternedString> T* add_strings() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_Mappings =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Mapping,
+      ProfilePacket>;
+
+  static constexpr FieldMetadata_Mappings kMappings{};
+  template <typename T = Mapping> T* add_mappings() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_Frames =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Frame,
+      ProfilePacket>;
+
+  static constexpr FieldMetadata_Frames kFrames{};
+  template <typename T = Frame> T* add_frames() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_Callstacks =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Callstack,
+      ProfilePacket>;
+
+  static constexpr FieldMetadata_Callstacks kCallstacks{};
+  template <typename T = Callstack> T* add_callstacks() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_ProcessDumps =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProfilePacket_ProcessHeapSamples,
+      ProfilePacket>;
+
+  static constexpr FieldMetadata_ProcessDumps kProcessDumps{};
+  template <typename T = ProfilePacket_ProcessHeapSamples> T* add_process_dumps() {
+    return BeginNestedMessage<T>(5);
+  }
+
+
+  using FieldMetadata_Continued =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ProfilePacket>;
+
+  static constexpr FieldMetadata_Continued kContinued{};
+  void set_continued(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_Continued::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_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket>;
+
+  static constexpr FieldMetadata_Index kIndex{};
+  void set_index(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Index::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 ProfilePacket_ProcessHeapSamples_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/14, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ProfilePacket_ProcessHeapSamples_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProfilePacket_ProcessHeapSamples_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProfilePacket_ProcessHeapSamples_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  uint64_t pid() const { return at<1>().as_uint64(); }
+  bool has_from_startup() const { return at<3>().valid(); }
+  bool from_startup() const { return at<3>().as_bool(); }
+  bool has_rejected_concurrent() const { return at<4>().valid(); }
+  bool rejected_concurrent() const { return at<4>().as_bool(); }
+  bool has_disconnected() const { return at<6>().valid(); }
+  bool disconnected() const { return at<6>().as_bool(); }
+  bool has_buffer_overran() const { return at<7>().valid(); }
+  bool buffer_overran() const { return at<7>().as_bool(); }
+  bool has_client_error() const { return at<14>().valid(); }
+  int32_t client_error() const { return at<14>().as_int32(); }
+  bool has_buffer_corrupted() const { return at<8>().valid(); }
+  bool buffer_corrupted() const { return at<8>().as_bool(); }
+  bool has_hit_guardrail() const { return at<10>().valid(); }
+  bool hit_guardrail() const { return at<10>().as_bool(); }
+  bool has_heap_name() const { return at<11>().valid(); }
+  ::protozero::ConstChars heap_name() const { return at<11>().as_string(); }
+  bool has_sampling_interval_bytes() const { return at<12>().valid(); }
+  uint64_t sampling_interval_bytes() const { return at<12>().as_uint64(); }
+  bool has_orig_sampling_interval_bytes() const { return at<13>().valid(); }
+  uint64_t orig_sampling_interval_bytes() const { return at<13>().as_uint64(); }
+  bool has_timestamp() const { return at<9>().valid(); }
+  uint64_t timestamp() const { return at<9>().as_uint64(); }
+  bool has_stats() const { return at<5>().valid(); }
+  ::protozero::ConstBytes stats() const { return at<5>().as_bytes(); }
+  bool has_samples() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> samples() const { return GetRepeated<::protozero::ConstBytes>(2); }
+};
+
+class ProfilePacket_ProcessHeapSamples : public ::protozero::Message {
+ public:
+  using Decoder = ProfilePacket_ProcessHeapSamples_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kFromStartupFieldNumber = 3,
+    kRejectedConcurrentFieldNumber = 4,
+    kDisconnectedFieldNumber = 6,
+    kBufferOverranFieldNumber = 7,
+    kClientErrorFieldNumber = 14,
+    kBufferCorruptedFieldNumber = 8,
+    kHitGuardrailFieldNumber = 10,
+    kHeapNameFieldNumber = 11,
+    kSamplingIntervalBytesFieldNumber = 12,
+    kOrigSamplingIntervalBytesFieldNumber = 13,
+    kTimestampFieldNumber = 9,
+    kStatsFieldNumber = 5,
+    kSamplesFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProfilePacket.ProcessHeapSamples"; }
+
+
+  using ClientError = ::perfetto::protos::pbzero::ProfilePacket_ProcessHeapSamples_ClientError;
+  static inline const char* ClientError_Name(ClientError value) {
+    return ::perfetto::protos::pbzero::ProfilePacket_ProcessHeapSamples_ClientError_Name(value);
+  }
+  static inline const ClientError CLIENT_ERROR_NONE = ClientError::CLIENT_ERROR_NONE;
+  static inline const ClientError CLIENT_ERROR_HIT_TIMEOUT = ClientError::CLIENT_ERROR_HIT_TIMEOUT;
+  static inline const ClientError CLIENT_ERROR_INVALID_STACK_BOUNDS = ClientError::CLIENT_ERROR_INVALID_STACK_BOUNDS;
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_ProcessHeapSamples>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_FromStartup =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ProfilePacket_ProcessHeapSamples>;
+
+  static constexpr FieldMetadata_FromStartup kFromStartup{};
+  void set_from_startup(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_FromStartup::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_RejectedConcurrent =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ProfilePacket_ProcessHeapSamples>;
+
+  static constexpr FieldMetadata_RejectedConcurrent kRejectedConcurrent{};
+  void set_rejected_concurrent(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_RejectedConcurrent::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_Disconnected =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ProfilePacket_ProcessHeapSamples>;
+
+  static constexpr FieldMetadata_Disconnected kDisconnected{};
+  void set_disconnected(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_Disconnected::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_BufferOverran =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ProfilePacket_ProcessHeapSamples>;
+
+  static constexpr FieldMetadata_BufferOverran kBufferOverran{};
+  void set_buffer_overran(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_BufferOverran::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_ClientError =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ProfilePacket_ProcessHeapSamples_ClientError,
+      ProfilePacket_ProcessHeapSamples>;
+
+  static constexpr FieldMetadata_ClientError kClientError{};
+  void set_client_error(ProfilePacket_ProcessHeapSamples_ClientError value) {
+    static constexpr uint32_t field_id = FieldMetadata_ClientError::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_BufferCorrupted =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ProfilePacket_ProcessHeapSamples>;
+
+  static constexpr FieldMetadata_BufferCorrupted kBufferCorrupted{};
+  void set_buffer_corrupted(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_BufferCorrupted::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_HitGuardrail =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ProfilePacket_ProcessHeapSamples>;
+
+  static constexpr FieldMetadata_HitGuardrail kHitGuardrail{};
+  void set_hit_guardrail(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_HitGuardrail::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_HeapName =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ProfilePacket_ProcessHeapSamples>;
+
+  static constexpr FieldMetadata_HeapName kHeapName{};
+  void set_heap_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, data, size);
+  }
+  void set_heap_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, chars.data, chars.size);
+  }
+  void set_heap_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_HeapName::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_SamplingIntervalBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_ProcessHeapSamples>;
+
+  static constexpr FieldMetadata_SamplingIntervalBytes kSamplingIntervalBytes{};
+  void set_sampling_interval_bytes(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SamplingIntervalBytes::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_OrigSamplingIntervalBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_ProcessHeapSamples>;
+
+  static constexpr FieldMetadata_OrigSamplingIntervalBytes kOrigSamplingIntervalBytes{};
+  void set_orig_sampling_interval_bytes(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OrigSamplingIntervalBytes::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_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_ProcessHeapSamples>;
+
+  static constexpr FieldMetadata_Timestamp kTimestamp{};
+  void set_timestamp(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timestamp::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_Stats =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProfilePacket_ProcessStats,
+      ProfilePacket_ProcessHeapSamples>;
+
+  static constexpr FieldMetadata_Stats kStats{};
+  template <typename T = ProfilePacket_ProcessStats> T* set_stats() {
+    return BeginNestedMessage<T>(5);
+  }
+
+
+  using FieldMetadata_Samples =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProfilePacket_HeapSample,
+      ProfilePacket_ProcessHeapSamples>;
+
+  static constexpr FieldMetadata_Samples kSamples{};
+  template <typename T = ProfilePacket_HeapSample> T* add_samples() {
+    return BeginNestedMessage<T>(2);
+  }
+
+};
+
+class ProfilePacket_ProcessStats_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ProfilePacket_ProcessStats_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProfilePacket_ProcessStats_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProfilePacket_ProcessStats_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_unwinding_errors() const { return at<1>().valid(); }
+  uint64_t unwinding_errors() const { return at<1>().as_uint64(); }
+  bool has_heap_samples() const { return at<2>().valid(); }
+  uint64_t heap_samples() const { return at<2>().as_uint64(); }
+  bool has_map_reparses() const { return at<3>().valid(); }
+  uint64_t map_reparses() const { return at<3>().as_uint64(); }
+  bool has_unwinding_time_us() const { return at<4>().valid(); }
+  ::protozero::ConstBytes unwinding_time_us() const { return at<4>().as_bytes(); }
+  bool has_total_unwinding_time_us() const { return at<5>().valid(); }
+  uint64_t total_unwinding_time_us() const { return at<5>().as_uint64(); }
+  bool has_client_spinlock_blocked_us() const { return at<6>().valid(); }
+  uint64_t client_spinlock_blocked_us() const { return at<6>().as_uint64(); }
+};
+
+class ProfilePacket_ProcessStats : public ::protozero::Message {
+ public:
+  using Decoder = ProfilePacket_ProcessStats_Decoder;
+  enum : int32_t {
+    kUnwindingErrorsFieldNumber = 1,
+    kHeapSamplesFieldNumber = 2,
+    kMapReparsesFieldNumber = 3,
+    kUnwindingTimeUsFieldNumber = 4,
+    kTotalUnwindingTimeUsFieldNumber = 5,
+    kClientSpinlockBlockedUsFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProfilePacket.ProcessStats"; }
+
+
+  using FieldMetadata_UnwindingErrors =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_ProcessStats>;
+
+  static constexpr FieldMetadata_UnwindingErrors kUnwindingErrors{};
+  void set_unwinding_errors(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UnwindingErrors::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_HeapSamples =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_ProcessStats>;
+
+  static constexpr FieldMetadata_HeapSamples kHeapSamples{};
+  void set_heap_samples(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_HeapSamples::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_MapReparses =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_ProcessStats>;
+
+  static constexpr FieldMetadata_MapReparses kMapReparses{};
+  void set_map_reparses(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MapReparses::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_UnwindingTimeUs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProfilePacket_Histogram,
+      ProfilePacket_ProcessStats>;
+
+  static constexpr FieldMetadata_UnwindingTimeUs kUnwindingTimeUs{};
+  template <typename T = ProfilePacket_Histogram> T* set_unwinding_time_us() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_TotalUnwindingTimeUs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_ProcessStats>;
+
+  static constexpr FieldMetadata_TotalUnwindingTimeUs kTotalUnwindingTimeUs{};
+  void set_total_unwinding_time_us(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TotalUnwindingTimeUs::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_ClientSpinlockBlockedUs =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_ProcessStats>;
+
+  static constexpr FieldMetadata_ClientSpinlockBlockedUs kClientSpinlockBlockedUs{};
+  void set_client_spinlock_blocked_us(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ClientSpinlockBlockedUs::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 ProfilePacket_Histogram_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ProfilePacket_Histogram_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProfilePacket_Histogram_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProfilePacket_Histogram_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_buckets() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> buckets() const { return GetRepeated<::protozero::ConstBytes>(1); }
+};
+
+class ProfilePacket_Histogram : public ::protozero::Message {
+ public:
+  using Decoder = ProfilePacket_Histogram_Decoder;
+  enum : int32_t {
+    kBucketsFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProfilePacket.Histogram"; }
+
+  using Bucket = ::perfetto::protos::pbzero::ProfilePacket_Histogram_Bucket;
+
+  using FieldMetadata_Buckets =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProfilePacket_Histogram_Bucket,
+      ProfilePacket_Histogram>;
+
+  static constexpr FieldMetadata_Buckets kBuckets{};
+  template <typename T = ProfilePacket_Histogram_Bucket> T* add_buckets() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+class ProfilePacket_Histogram_Bucket_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ProfilePacket_Histogram_Bucket_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProfilePacket_Histogram_Bucket_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProfilePacket_Histogram_Bucket_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_upper_limit() const { return at<1>().valid(); }
+  uint64_t upper_limit() const { return at<1>().as_uint64(); }
+  bool has_max_bucket() const { return at<2>().valid(); }
+  bool max_bucket() const { return at<2>().as_bool(); }
+  bool has_count() const { return at<3>().valid(); }
+  uint64_t count() const { return at<3>().as_uint64(); }
+};
+
+class ProfilePacket_Histogram_Bucket : public ::protozero::Message {
+ public:
+  using Decoder = ProfilePacket_Histogram_Bucket_Decoder;
+  enum : int32_t {
+    kUpperLimitFieldNumber = 1,
+    kMaxBucketFieldNumber = 2,
+    kCountFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProfilePacket.Histogram.Bucket"; }
+
+
+  using FieldMetadata_UpperLimit =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_Histogram_Bucket>;
+
+  static constexpr FieldMetadata_UpperLimit kUpperLimit{};
+  void set_upper_limit(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UpperLimit::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_MaxBucket =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ProfilePacket_Histogram_Bucket>;
+
+  static constexpr FieldMetadata_MaxBucket kMaxBucket{};
+  void set_max_bucket(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_MaxBucket::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_Count =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_Histogram_Bucket>;
+
+  static constexpr FieldMetadata_Count kCount{};
+  void set_count(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Count::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 ProfilePacket_HeapSample_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ProfilePacket_HeapSample_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProfilePacket_HeapSample_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProfilePacket_HeapSample_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_callstack_id() const { return at<1>().valid(); }
+  uint64_t callstack_id() const { return at<1>().as_uint64(); }
+  bool has_self_allocated() const { return at<2>().valid(); }
+  uint64_t self_allocated() const { return at<2>().as_uint64(); }
+  bool has_self_freed() const { return at<3>().valid(); }
+  uint64_t self_freed() const { return at<3>().as_uint64(); }
+  bool has_self_max() const { return at<8>().valid(); }
+  uint64_t self_max() const { return at<8>().as_uint64(); }
+  bool has_self_max_count() const { return at<9>().valid(); }
+  uint64_t self_max_count() const { return at<9>().as_uint64(); }
+  bool has_timestamp() const { return at<4>().valid(); }
+  uint64_t timestamp() const { return at<4>().as_uint64(); }
+  bool has_alloc_count() const { return at<5>().valid(); }
+  uint64_t alloc_count() const { return at<5>().as_uint64(); }
+  bool has_free_count() const { return at<6>().valid(); }
+  uint64_t free_count() const { return at<6>().as_uint64(); }
+};
+
+class ProfilePacket_HeapSample : public ::protozero::Message {
+ public:
+  using Decoder = ProfilePacket_HeapSample_Decoder;
+  enum : int32_t {
+    kCallstackIdFieldNumber = 1,
+    kSelfAllocatedFieldNumber = 2,
+    kSelfFreedFieldNumber = 3,
+    kSelfMaxFieldNumber = 8,
+    kSelfMaxCountFieldNumber = 9,
+    kTimestampFieldNumber = 4,
+    kAllocCountFieldNumber = 5,
+    kFreeCountFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProfilePacket.HeapSample"; }
+
+
+  using FieldMetadata_CallstackId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_HeapSample>;
+
+  static constexpr FieldMetadata_CallstackId kCallstackId{};
+  void set_callstack_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CallstackId::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_SelfAllocated =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_HeapSample>;
+
+  static constexpr FieldMetadata_SelfAllocated kSelfAllocated{};
+  void set_self_allocated(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SelfAllocated::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_SelfFreed =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_HeapSample>;
+
+  static constexpr FieldMetadata_SelfFreed kSelfFreed{};
+  void set_self_freed(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SelfFreed::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_SelfMax =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_HeapSample>;
+
+  static constexpr FieldMetadata_SelfMax kSelfMax{};
+  void set_self_max(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SelfMax::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_SelfMaxCount =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_HeapSample>;
+
+  static constexpr FieldMetadata_SelfMaxCount kSelfMaxCount{};
+  void set_self_max_count(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SelfMaxCount::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_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_HeapSample>;
+
+  static constexpr FieldMetadata_Timestamp kTimestamp{};
+  void set_timestamp(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timestamp::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_AllocCount =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_HeapSample>;
+
+  static constexpr FieldMetadata_AllocCount kAllocCount{};
+  void set_alloc_count(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AllocCount::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_FreeCount =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_HeapSample>;
+
+  static constexpr FieldMetadata_FreeCount kFreeCount{};
+  void set_free_count(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FreeCount::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/profiling/smaps.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PROFILING_SMAPS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PROFILING_SMAPS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class SmapsEntry;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class SmapsPacket_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  SmapsPacket_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SmapsPacket_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SmapsPacket_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  uint32_t pid() const { return at<1>().as_uint32(); }
+  bool has_entries() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> entries() const { return GetRepeated<::protozero::ConstBytes>(2); }
+};
+
+class SmapsPacket : public ::protozero::Message {
+ public:
+  using Decoder = SmapsPacket_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kEntriesFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SmapsPacket"; }
+
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmapsPacket>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_Entries =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SmapsEntry,
+      SmapsPacket>;
+
+  static constexpr FieldMetadata_Entries kEntries{};
+  template <typename T = SmapsEntry> T* add_entries() {
+    return BeginNestedMessage<T>(2);
+  }
+
+};
+
+class SmapsEntry_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/15, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SmapsEntry_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SmapsEntry_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SmapsEntry_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_path() const { return at<1>().valid(); }
+  ::protozero::ConstChars path() const { return at<1>().as_string(); }
+  bool has_size_kb() const { return at<2>().valid(); }
+  uint64_t size_kb() const { return at<2>().as_uint64(); }
+  bool has_private_dirty_kb() const { return at<3>().valid(); }
+  uint64_t private_dirty_kb() const { return at<3>().as_uint64(); }
+  bool has_swap_kb() const { return at<4>().valid(); }
+  uint64_t swap_kb() const { return at<4>().as_uint64(); }
+  bool has_file_name() const { return at<5>().valid(); }
+  ::protozero::ConstChars file_name() const { return at<5>().as_string(); }
+  bool has_start_address() const { return at<6>().valid(); }
+  uint64_t start_address() const { return at<6>().as_uint64(); }
+  bool has_module_timestamp() const { return at<7>().valid(); }
+  uint64_t module_timestamp() const { return at<7>().as_uint64(); }
+  bool has_module_debugid() const { return at<8>().valid(); }
+  ::protozero::ConstChars module_debugid() const { return at<8>().as_string(); }
+  bool has_module_debug_path() const { return at<9>().valid(); }
+  ::protozero::ConstChars module_debug_path() const { return at<9>().as_string(); }
+  bool has_protection_flags() const { return at<10>().valid(); }
+  uint32_t protection_flags() const { return at<10>().as_uint32(); }
+  bool has_private_clean_resident_kb() const { return at<11>().valid(); }
+  uint64_t private_clean_resident_kb() const { return at<11>().as_uint64(); }
+  bool has_shared_dirty_resident_kb() const { return at<12>().valid(); }
+  uint64_t shared_dirty_resident_kb() const { return at<12>().as_uint64(); }
+  bool has_shared_clean_resident_kb() const { return at<13>().valid(); }
+  uint64_t shared_clean_resident_kb() const { return at<13>().as_uint64(); }
+  bool has_locked_kb() const { return at<14>().valid(); }
+  uint64_t locked_kb() const { return at<14>().as_uint64(); }
+  bool has_proportional_resident_kb() const { return at<15>().valid(); }
+  uint64_t proportional_resident_kb() const { return at<15>().as_uint64(); }
+};
+
+class SmapsEntry : public ::protozero::Message {
+ public:
+  using Decoder = SmapsEntry_Decoder;
+  enum : int32_t {
+    kPathFieldNumber = 1,
+    kSizeKbFieldNumber = 2,
+    kPrivateDirtyKbFieldNumber = 3,
+    kSwapKbFieldNumber = 4,
+    kFileNameFieldNumber = 5,
+    kStartAddressFieldNumber = 6,
+    kModuleTimestampFieldNumber = 7,
+    kModuleDebugidFieldNumber = 8,
+    kModuleDebugPathFieldNumber = 9,
+    kProtectionFlagsFieldNumber = 10,
+    kPrivateCleanResidentKbFieldNumber = 11,
+    kSharedDirtyResidentKbFieldNumber = 12,
+    kSharedCleanResidentKbFieldNumber = 13,
+    kLockedKbFieldNumber = 14,
+    kProportionalResidentKbFieldNumber = 15,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SmapsEntry"; }
+
+
+  using FieldMetadata_Path =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SmapsEntry>;
+
+  static constexpr FieldMetadata_Path kPath{};
+  void set_path(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Path::kFieldId, data, size);
+  }
+  void set_path(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Path::kFieldId, chars.data, chars.size);
+  }
+  void set_path(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Path::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_SizeKb =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SmapsEntry>;
+
+  static constexpr FieldMetadata_SizeKb kSizeKb{};
+  void set_size_kb(uint64_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::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PrivateDirtyKb =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SmapsEntry>;
+
+  static constexpr FieldMetadata_PrivateDirtyKb kPrivateDirtyKb{};
+  void set_private_dirty_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PrivateDirtyKb::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_SwapKb =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SmapsEntry>;
+
+  static constexpr FieldMetadata_SwapKb kSwapKb{};
+  void set_swap_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SwapKb::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_FileName =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SmapsEntry>;
+
+  static constexpr FieldMetadata_FileName kFileName{};
+  void set_file_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_FileName::kFieldId, data, size);
+  }
+  void set_file_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_FileName::kFieldId, chars.data, chars.size);
+  }
+  void set_file_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_FileName::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_StartAddress =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SmapsEntry>;
+
+  static constexpr FieldMetadata_StartAddress kStartAddress{};
+  void set_start_address(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StartAddress::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_ModuleTimestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SmapsEntry>;
+
+  static constexpr FieldMetadata_ModuleTimestamp kModuleTimestamp{};
+  void set_module_timestamp(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ModuleTimestamp::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_ModuleDebugid =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SmapsEntry>;
+
+  static constexpr FieldMetadata_ModuleDebugid kModuleDebugid{};
+  void set_module_debugid(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ModuleDebugid::kFieldId, data, size);
+  }
+  void set_module_debugid(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ModuleDebugid::kFieldId, chars.data, chars.size);
+  }
+  void set_module_debugid(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ModuleDebugid::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_ModuleDebugPath =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SmapsEntry>;
+
+  static constexpr FieldMetadata_ModuleDebugPath kModuleDebugPath{};
+  void set_module_debug_path(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ModuleDebugPath::kFieldId, data, size);
+  }
+  void set_module_debug_path(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ModuleDebugPath::kFieldId, chars.data, chars.size);
+  }
+  void set_module_debug_path(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ModuleDebugPath::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_ProtectionFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmapsEntry>;
+
+  static constexpr FieldMetadata_ProtectionFlags kProtectionFlags{};
+  void set_protection_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProtectionFlags::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_PrivateCleanResidentKb =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SmapsEntry>;
+
+  static constexpr FieldMetadata_PrivateCleanResidentKb kPrivateCleanResidentKb{};
+  void set_private_clean_resident_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PrivateCleanResidentKb::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_SharedDirtyResidentKb =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SmapsEntry>;
+
+  static constexpr FieldMetadata_SharedDirtyResidentKb kSharedDirtyResidentKb{};
+  void set_shared_dirty_resident_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SharedDirtyResidentKb::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_SharedCleanResidentKb =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SmapsEntry>;
+
+  static constexpr FieldMetadata_SharedCleanResidentKb kSharedCleanResidentKb{};
+  void set_shared_clean_resident_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SharedCleanResidentKb::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_LockedKb =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SmapsEntry>;
+
+  static constexpr FieldMetadata_LockedKb kLockedKb{};
+  void set_locked_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LockedKb::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_ProportionalResidentKb =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SmapsEntry>;
+
+  static constexpr FieldMetadata_ProportionalResidentKb kProportionalResidentKb{};
+  void set_proportional_resident_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProportionalResidentKb::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_active_processes.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_ACTIVE_PROCESSES_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_ACTIVE_PROCESSES_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class ChromeActiveProcesses_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ChromeActiveProcesses_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeActiveProcesses_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeActiveProcesses_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> pid() const { return GetRepeated<int32_t>(1); }
+};
+
+class ChromeActiveProcesses : public ::protozero::Message {
+ public:
+  using Decoder = ChromeActiveProcesses_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeActiveProcesses"; }
+
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeActiveProcesses>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void add_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_application_state_info.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_APPLICATION_STATE_INFO_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_APPLICATION_STATE_INFO_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+namespace perfetto_pbzero_enum_ChromeApplicationStateInfo {
+enum ChromeApplicationState : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeApplicationStateInfo
+using ChromeApplicationStateInfo_ChromeApplicationState = perfetto_pbzero_enum_ChromeApplicationStateInfo::ChromeApplicationState;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_ChromeApplicationStateInfo {
+enum ChromeApplicationState : int32_t {
+  APPLICATION_STATE_UNKNOWN = 0,
+  APPLICATION_STATE_HAS_RUNNING_ACTIVITIES = 1,
+  APPLICATION_STATE_HAS_PAUSED_ACTIVITIES = 2,
+  APPLICATION_STATE_HAS_STOPPED_ACTIVITIES = 3,
+  APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES = 4,
+};
+} // namespace perfetto_pbzero_enum_ChromeApplicationStateInfo
+using ChromeApplicationStateInfo_ChromeApplicationState = perfetto_pbzero_enum_ChromeApplicationStateInfo::ChromeApplicationState;
+
+
+constexpr ChromeApplicationStateInfo_ChromeApplicationState ChromeApplicationStateInfo_ChromeApplicationState_MIN = ChromeApplicationStateInfo_ChromeApplicationState::APPLICATION_STATE_UNKNOWN;
+constexpr ChromeApplicationStateInfo_ChromeApplicationState ChromeApplicationStateInfo_ChromeApplicationState_MAX = ChromeApplicationStateInfo_ChromeApplicationState::APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeApplicationStateInfo_ChromeApplicationState_Name(::perfetto::protos::pbzero::ChromeApplicationStateInfo_ChromeApplicationState value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeApplicationStateInfo_ChromeApplicationState::APPLICATION_STATE_UNKNOWN:
+    return "APPLICATION_STATE_UNKNOWN";
+
+  case ::perfetto::protos::pbzero::ChromeApplicationStateInfo_ChromeApplicationState::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES:
+    return "APPLICATION_STATE_HAS_RUNNING_ACTIVITIES";
+
+  case ::perfetto::protos::pbzero::ChromeApplicationStateInfo_ChromeApplicationState::APPLICATION_STATE_HAS_PAUSED_ACTIVITIES:
+    return "APPLICATION_STATE_HAS_PAUSED_ACTIVITIES";
+
+  case ::perfetto::protos::pbzero::ChromeApplicationStateInfo_ChromeApplicationState::APPLICATION_STATE_HAS_STOPPED_ACTIVITIES:
+    return "APPLICATION_STATE_HAS_STOPPED_ACTIVITIES";
+
+  case ::perfetto::protos::pbzero::ChromeApplicationStateInfo_ChromeApplicationState::APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES:
+    return "APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class ChromeApplicationStateInfo_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeApplicationStateInfo_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeApplicationStateInfo_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeApplicationStateInfo_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_application_state() const { return at<1>().valid(); }
+  int32_t application_state() const { return at<1>().as_int32(); }
+};
+
+class ChromeApplicationStateInfo : public ::protozero::Message {
+ public:
+  using Decoder = ChromeApplicationStateInfo_Decoder;
+  enum : int32_t {
+    kApplicationStateFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeApplicationStateInfo"; }
+
+
+  using ChromeApplicationState = ::perfetto::protos::pbzero::ChromeApplicationStateInfo_ChromeApplicationState;
+  static inline const char* ChromeApplicationState_Name(ChromeApplicationState value) {
+    return ::perfetto::protos::pbzero::ChromeApplicationStateInfo_ChromeApplicationState_Name(value);
+  }
+  static inline const ChromeApplicationState APPLICATION_STATE_UNKNOWN = ChromeApplicationState::APPLICATION_STATE_UNKNOWN;
+  static inline const ChromeApplicationState APPLICATION_STATE_HAS_RUNNING_ACTIVITIES = ChromeApplicationState::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES;
+  static inline const ChromeApplicationState APPLICATION_STATE_HAS_PAUSED_ACTIVITIES = ChromeApplicationState::APPLICATION_STATE_HAS_PAUSED_ACTIVITIES;
+  static inline const ChromeApplicationState APPLICATION_STATE_HAS_STOPPED_ACTIVITIES = ChromeApplicationState::APPLICATION_STATE_HAS_STOPPED_ACTIVITIES;
+  static inline const ChromeApplicationState APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES = ChromeApplicationState::APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES;
+
+  using FieldMetadata_ApplicationState =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ChromeApplicationStateInfo_ChromeApplicationState,
+      ChromeApplicationStateInfo>;
+
+  static constexpr FieldMetadata_ApplicationState kApplicationState{};
+  void set_application_state(ChromeApplicationStateInfo_ChromeApplicationState value) {
+    static constexpr uint32_t field_id = FieldMetadata_ApplicationState::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.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_COMPOSITOR_SCHEDULER_STATE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_COMPOSITOR_SCHEDULER_STATE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class BeginFrameArgs;
+class BeginFrameObserverState;
+class BeginFrameSourceState;
+class BeginImplFrameArgs;
+class BeginImplFrameArgs_TimestampsInUs;
+class ChromeCompositorStateMachine;
+class ChromeCompositorStateMachine_MajorState;
+class ChromeCompositorStateMachine_MinorState;
+class CompositorTimingHistory;
+class SourceLocation;
+namespace perfetto_pbzero_enum_BeginFrameArgs {
+enum BeginFrameArgsType : int32_t;
+}  // namespace perfetto_pbzero_enum_BeginFrameArgs
+using BeginFrameArgs_BeginFrameArgsType = perfetto_pbzero_enum_BeginFrameArgs::BeginFrameArgsType;
+namespace perfetto_pbzero_enum_BeginImplFrameArgs {
+enum State : int32_t;
+}  // namespace perfetto_pbzero_enum_BeginImplFrameArgs
+using BeginImplFrameArgs_State = perfetto_pbzero_enum_BeginImplFrameArgs::State;
+enum ChromeCompositorSchedulerAction : int32_t;
+namespace perfetto_pbzero_enum_ChromeCompositorSchedulerState {
+enum BeginImplFrameDeadlineMode : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeCompositorSchedulerState
+using ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode = perfetto_pbzero_enum_ChromeCompositorSchedulerState::BeginImplFrameDeadlineMode;
+namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState {
+enum BeginImplFrameState : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState
+using ChromeCompositorStateMachine_MajorState_BeginImplFrameState = perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState::BeginImplFrameState;
+namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState {
+enum BeginMainFrameState : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState
+using ChromeCompositorStateMachine_MajorState_BeginMainFrameState = perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState::BeginMainFrameState;
+namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState {
+enum ForcedRedrawOnTimeoutState : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState
+using ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState = perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState::ForcedRedrawOnTimeoutState;
+namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState {
+enum LayerTreeFrameSinkState : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState
+using ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState = perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState::LayerTreeFrameSinkState;
+namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MinorState {
+enum ScrollHandlerState : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MinorState
+using ChromeCompositorStateMachine_MinorState_ScrollHandlerState = perfetto_pbzero_enum_ChromeCompositorStateMachine_MinorState::ScrollHandlerState;
+namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MinorState {
+enum TreePriority : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MinorState
+using ChromeCompositorStateMachine_MinorState_TreePriority = perfetto_pbzero_enum_ChromeCompositorStateMachine_MinorState::TreePriority;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+enum ChromeCompositorSchedulerAction : int32_t {
+  CC_SCHEDULER_ACTION_UNSPECIFIED = 0,
+  CC_SCHEDULER_ACTION_NONE = 1,
+  CC_SCHEDULER_ACTION_SEND_BEGIN_MAIN_FRAME = 2,
+  CC_SCHEDULER_ACTION_COMMIT = 3,
+  CC_SCHEDULER_ACTION_ACTIVATE_SYNC_TREE = 4,
+  CC_SCHEDULER_ACTION_DRAW_IF_POSSIBLE = 5,
+  CC_SCHEDULER_ACTION_DRAW_FORCED = 6,
+  CC_SCHEDULER_ACTION_DRAW_ABORT = 7,
+  CC_SCHEDULER_ACTION_BEGIN_LAYER_TREE_FRAME_SINK_CREATION = 8,
+  CC_SCHEDULER_ACTION_PREPARE_TILES = 9,
+  CC_SCHEDULER_ACTION_INVALIDATE_LAYER_TREE_FRAME_SINK = 10,
+  CC_SCHEDULER_ACTION_PERFORM_IMPL_SIDE_INVALIDATION = 11,
+  CC_SCHEDULER_ACTION_NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_UNTIL = 12,
+  CC_SCHEDULER_ACTION_NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_SOON = 13,
+};
+
+constexpr ChromeCompositorSchedulerAction ChromeCompositorSchedulerAction_MIN = ChromeCompositorSchedulerAction::CC_SCHEDULER_ACTION_UNSPECIFIED;
+constexpr ChromeCompositorSchedulerAction ChromeCompositorSchedulerAction_MAX = ChromeCompositorSchedulerAction::CC_SCHEDULER_ACTION_NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_SOON;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeCompositorSchedulerAction_Name(::perfetto::protos::pbzero::ChromeCompositorSchedulerAction value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerAction::CC_SCHEDULER_ACTION_UNSPECIFIED:
+    return "CC_SCHEDULER_ACTION_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerAction::CC_SCHEDULER_ACTION_NONE:
+    return "CC_SCHEDULER_ACTION_NONE";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerAction::CC_SCHEDULER_ACTION_SEND_BEGIN_MAIN_FRAME:
+    return "CC_SCHEDULER_ACTION_SEND_BEGIN_MAIN_FRAME";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerAction::CC_SCHEDULER_ACTION_COMMIT:
+    return "CC_SCHEDULER_ACTION_COMMIT";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerAction::CC_SCHEDULER_ACTION_ACTIVATE_SYNC_TREE:
+    return "CC_SCHEDULER_ACTION_ACTIVATE_SYNC_TREE";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerAction::CC_SCHEDULER_ACTION_DRAW_IF_POSSIBLE:
+    return "CC_SCHEDULER_ACTION_DRAW_IF_POSSIBLE";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerAction::CC_SCHEDULER_ACTION_DRAW_FORCED:
+    return "CC_SCHEDULER_ACTION_DRAW_FORCED";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerAction::CC_SCHEDULER_ACTION_DRAW_ABORT:
+    return "CC_SCHEDULER_ACTION_DRAW_ABORT";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerAction::CC_SCHEDULER_ACTION_BEGIN_LAYER_TREE_FRAME_SINK_CREATION:
+    return "CC_SCHEDULER_ACTION_BEGIN_LAYER_TREE_FRAME_SINK_CREATION";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerAction::CC_SCHEDULER_ACTION_PREPARE_TILES:
+    return "CC_SCHEDULER_ACTION_PREPARE_TILES";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerAction::CC_SCHEDULER_ACTION_INVALIDATE_LAYER_TREE_FRAME_SINK:
+    return "CC_SCHEDULER_ACTION_INVALIDATE_LAYER_TREE_FRAME_SINK";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerAction::CC_SCHEDULER_ACTION_PERFORM_IMPL_SIDE_INVALIDATION:
+    return "CC_SCHEDULER_ACTION_PERFORM_IMPL_SIDE_INVALIDATION";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerAction::CC_SCHEDULER_ACTION_NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_UNTIL:
+    return "CC_SCHEDULER_ACTION_NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_UNTIL";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerAction::CC_SCHEDULER_ACTION_NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_SOON:
+    return "CC_SCHEDULER_ACTION_NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_SOON";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_BeginImplFrameArgs {
+enum State : int32_t {
+  BEGIN_FRAME_FINISHED = 0,
+  BEGIN_FRAME_USING = 1,
+};
+} // namespace perfetto_pbzero_enum_BeginImplFrameArgs
+using BeginImplFrameArgs_State = perfetto_pbzero_enum_BeginImplFrameArgs::State;
+
+
+constexpr BeginImplFrameArgs_State BeginImplFrameArgs_State_MIN = BeginImplFrameArgs_State::BEGIN_FRAME_FINISHED;
+constexpr BeginImplFrameArgs_State BeginImplFrameArgs_State_MAX = BeginImplFrameArgs_State::BEGIN_FRAME_USING;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* BeginImplFrameArgs_State_Name(::perfetto::protos::pbzero::BeginImplFrameArgs_State value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::BeginImplFrameArgs_State::BEGIN_FRAME_FINISHED:
+    return "BEGIN_FRAME_FINISHED";
+
+  case ::perfetto::protos::pbzero::BeginImplFrameArgs_State::BEGIN_FRAME_USING:
+    return "BEGIN_FRAME_USING";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_BeginFrameArgs {
+enum BeginFrameArgsType : int32_t {
+  BEGIN_FRAME_ARGS_TYPE_UNSPECIFIED = 0,
+  BEGIN_FRAME_ARGS_TYPE_INVALID = 1,
+  BEGIN_FRAME_ARGS_TYPE_NORMAL = 2,
+  BEGIN_FRAME_ARGS_TYPE_MISSED = 3,
+};
+} // namespace perfetto_pbzero_enum_BeginFrameArgs
+using BeginFrameArgs_BeginFrameArgsType = perfetto_pbzero_enum_BeginFrameArgs::BeginFrameArgsType;
+
+
+constexpr BeginFrameArgs_BeginFrameArgsType BeginFrameArgs_BeginFrameArgsType_MIN = BeginFrameArgs_BeginFrameArgsType::BEGIN_FRAME_ARGS_TYPE_UNSPECIFIED;
+constexpr BeginFrameArgs_BeginFrameArgsType BeginFrameArgs_BeginFrameArgsType_MAX = BeginFrameArgs_BeginFrameArgsType::BEGIN_FRAME_ARGS_TYPE_MISSED;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* BeginFrameArgs_BeginFrameArgsType_Name(::perfetto::protos::pbzero::BeginFrameArgs_BeginFrameArgsType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::BeginFrameArgs_BeginFrameArgsType::BEGIN_FRAME_ARGS_TYPE_UNSPECIFIED:
+    return "BEGIN_FRAME_ARGS_TYPE_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::BeginFrameArgs_BeginFrameArgsType::BEGIN_FRAME_ARGS_TYPE_INVALID:
+    return "BEGIN_FRAME_ARGS_TYPE_INVALID";
+
+  case ::perfetto::protos::pbzero::BeginFrameArgs_BeginFrameArgsType::BEGIN_FRAME_ARGS_TYPE_NORMAL:
+    return "BEGIN_FRAME_ARGS_TYPE_NORMAL";
+
+  case ::perfetto::protos::pbzero::BeginFrameArgs_BeginFrameArgsType::BEGIN_FRAME_ARGS_TYPE_MISSED:
+    return "BEGIN_FRAME_ARGS_TYPE_MISSED";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MinorState {
+enum TreePriority : int32_t {
+  TREE_PRIORITY_UNSPECIFIED = 0,
+  TREE_PRIORITY_SAME_PRIORITY_FOR_BOTH_TREES = 1,
+  TREE_PRIORITY_SMOOTHNESS_TAKES_PRIORITY = 2,
+  TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY = 3,
+};
+} // namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MinorState
+using ChromeCompositorStateMachine_MinorState_TreePriority = perfetto_pbzero_enum_ChromeCompositorStateMachine_MinorState::TreePriority;
+
+
+constexpr ChromeCompositorStateMachine_MinorState_TreePriority ChromeCompositorStateMachine_MinorState_TreePriority_MIN = ChromeCompositorStateMachine_MinorState_TreePriority::TREE_PRIORITY_UNSPECIFIED;
+constexpr ChromeCompositorStateMachine_MinorState_TreePriority ChromeCompositorStateMachine_MinorState_TreePriority_MAX = ChromeCompositorStateMachine_MinorState_TreePriority::TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeCompositorStateMachine_MinorState_TreePriority_Name(::perfetto::protos::pbzero::ChromeCompositorStateMachine_MinorState_TreePriority value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MinorState_TreePriority::TREE_PRIORITY_UNSPECIFIED:
+    return "TREE_PRIORITY_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MinorState_TreePriority::TREE_PRIORITY_SAME_PRIORITY_FOR_BOTH_TREES:
+    return "TREE_PRIORITY_SAME_PRIORITY_FOR_BOTH_TREES";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MinorState_TreePriority::TREE_PRIORITY_SMOOTHNESS_TAKES_PRIORITY:
+    return "TREE_PRIORITY_SMOOTHNESS_TAKES_PRIORITY";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MinorState_TreePriority::TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY:
+    return "TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MinorState {
+enum ScrollHandlerState : int32_t {
+  SCROLL_HANDLER_UNSPECIFIED = 0,
+  SCROLL_AFFECTS_SCROLL_HANDLER = 1,
+  SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER = 2,
+};
+} // namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MinorState
+using ChromeCompositorStateMachine_MinorState_ScrollHandlerState = perfetto_pbzero_enum_ChromeCompositorStateMachine_MinorState::ScrollHandlerState;
+
+
+constexpr ChromeCompositorStateMachine_MinorState_ScrollHandlerState ChromeCompositorStateMachine_MinorState_ScrollHandlerState_MIN = ChromeCompositorStateMachine_MinorState_ScrollHandlerState::SCROLL_HANDLER_UNSPECIFIED;
+constexpr ChromeCompositorStateMachine_MinorState_ScrollHandlerState ChromeCompositorStateMachine_MinorState_ScrollHandlerState_MAX = ChromeCompositorStateMachine_MinorState_ScrollHandlerState::SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeCompositorStateMachine_MinorState_ScrollHandlerState_Name(::perfetto::protos::pbzero::ChromeCompositorStateMachine_MinorState_ScrollHandlerState value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MinorState_ScrollHandlerState::SCROLL_HANDLER_UNSPECIFIED:
+    return "SCROLL_HANDLER_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MinorState_ScrollHandlerState::SCROLL_AFFECTS_SCROLL_HANDLER:
+    return "SCROLL_AFFECTS_SCROLL_HANDLER";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MinorState_ScrollHandlerState::SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER:
+    return "SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState {
+enum BeginImplFrameState : int32_t {
+  BEGIN_IMPL_FRAME_UNSPECIFIED = 0,
+  BEGIN_IMPL_FRAME_IDLE = 1,
+  BEGIN_IMPL_FRAME_INSIDE_BEGIN_FRAME = 2,
+  BEGIN_IMPL_FRAME_INSIDE_DEADLINE = 3,
+};
+} // namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState
+using ChromeCompositorStateMachine_MajorState_BeginImplFrameState = perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState::BeginImplFrameState;
+
+
+constexpr ChromeCompositorStateMachine_MajorState_BeginImplFrameState ChromeCompositorStateMachine_MajorState_BeginImplFrameState_MIN = ChromeCompositorStateMachine_MajorState_BeginImplFrameState::BEGIN_IMPL_FRAME_UNSPECIFIED;
+constexpr ChromeCompositorStateMachine_MajorState_BeginImplFrameState ChromeCompositorStateMachine_MajorState_BeginImplFrameState_MAX = ChromeCompositorStateMachine_MajorState_BeginImplFrameState::BEGIN_IMPL_FRAME_INSIDE_DEADLINE;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeCompositorStateMachine_MajorState_BeginImplFrameState_Name(::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_BeginImplFrameState value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_BeginImplFrameState::BEGIN_IMPL_FRAME_UNSPECIFIED:
+    return "BEGIN_IMPL_FRAME_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_BeginImplFrameState::BEGIN_IMPL_FRAME_IDLE:
+    return "BEGIN_IMPL_FRAME_IDLE";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_BeginImplFrameState::BEGIN_IMPL_FRAME_INSIDE_BEGIN_FRAME:
+    return "BEGIN_IMPL_FRAME_INSIDE_BEGIN_FRAME";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_BeginImplFrameState::BEGIN_IMPL_FRAME_INSIDE_DEADLINE:
+    return "BEGIN_IMPL_FRAME_INSIDE_DEADLINE";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState {
+enum BeginMainFrameState : int32_t {
+  BEGIN_MAIN_FRAME_UNSPECIFIED = 0,
+  BEGIN_MAIN_FRAME_IDLE = 1,
+  BEGIN_MAIN_FRAME_SENT = 2,
+  BEGIN_MAIN_FRAME_READY_TO_COMMIT = 3,
+};
+} // namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState
+using ChromeCompositorStateMachine_MajorState_BeginMainFrameState = perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState::BeginMainFrameState;
+
+
+constexpr ChromeCompositorStateMachine_MajorState_BeginMainFrameState ChromeCompositorStateMachine_MajorState_BeginMainFrameState_MIN = ChromeCompositorStateMachine_MajorState_BeginMainFrameState::BEGIN_MAIN_FRAME_UNSPECIFIED;
+constexpr ChromeCompositorStateMachine_MajorState_BeginMainFrameState ChromeCompositorStateMachine_MajorState_BeginMainFrameState_MAX = ChromeCompositorStateMachine_MajorState_BeginMainFrameState::BEGIN_MAIN_FRAME_READY_TO_COMMIT;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeCompositorStateMachine_MajorState_BeginMainFrameState_Name(::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_BeginMainFrameState value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_BeginMainFrameState::BEGIN_MAIN_FRAME_UNSPECIFIED:
+    return "BEGIN_MAIN_FRAME_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_BeginMainFrameState::BEGIN_MAIN_FRAME_IDLE:
+    return "BEGIN_MAIN_FRAME_IDLE";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_BeginMainFrameState::BEGIN_MAIN_FRAME_SENT:
+    return "BEGIN_MAIN_FRAME_SENT";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_BeginMainFrameState::BEGIN_MAIN_FRAME_READY_TO_COMMIT:
+    return "BEGIN_MAIN_FRAME_READY_TO_COMMIT";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState {
+enum LayerTreeFrameSinkState : int32_t {
+  LAYER_TREE_FRAME_UNSPECIFIED = 0,
+  LAYER_TREE_FRAME_NONE = 1,
+  LAYER_TREE_FRAME_ACTIVE = 2,
+  LAYER_TREE_FRAME_CREATING = 3,
+  LAYER_TREE_FRAME_WAITING_FOR_FIRST_COMMIT = 4,
+  LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION = 5,
+};
+} // namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState
+using ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState = perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState::LayerTreeFrameSinkState;
+
+
+constexpr ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_MIN = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState::LAYER_TREE_FRAME_UNSPECIFIED;
+constexpr ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_MAX = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState::LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_Name(::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState::LAYER_TREE_FRAME_UNSPECIFIED:
+    return "LAYER_TREE_FRAME_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState::LAYER_TREE_FRAME_NONE:
+    return "LAYER_TREE_FRAME_NONE";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState::LAYER_TREE_FRAME_ACTIVE:
+    return "LAYER_TREE_FRAME_ACTIVE";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState::LAYER_TREE_FRAME_CREATING:
+    return "LAYER_TREE_FRAME_CREATING";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState::LAYER_TREE_FRAME_WAITING_FOR_FIRST_COMMIT:
+    return "LAYER_TREE_FRAME_WAITING_FOR_FIRST_COMMIT";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState::LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION:
+    return "LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState {
+enum ForcedRedrawOnTimeoutState : int32_t {
+  FORCED_REDRAW_UNSPECIFIED = 0,
+  FORCED_REDRAW_IDLE = 1,
+  FORCED_REDRAW_WAITING_FOR_COMMIT = 2,
+  FORCED_REDRAW_WAITING_FOR_ACTIVATION = 3,
+  FORCED_REDRAW_WAITING_FOR_DRAW = 4,
+};
+} // namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState
+using ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState = perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState::ForcedRedrawOnTimeoutState;
+
+
+constexpr ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_MIN = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState::FORCED_REDRAW_UNSPECIFIED;
+constexpr ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_MAX = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState::FORCED_REDRAW_WAITING_FOR_DRAW;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_Name(::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState::FORCED_REDRAW_UNSPECIFIED:
+    return "FORCED_REDRAW_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState::FORCED_REDRAW_IDLE:
+    return "FORCED_REDRAW_IDLE";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState::FORCED_REDRAW_WAITING_FOR_COMMIT:
+    return "FORCED_REDRAW_WAITING_FOR_COMMIT";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState::FORCED_REDRAW_WAITING_FOR_ACTIVATION:
+    return "FORCED_REDRAW_WAITING_FOR_ACTIVATION";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState::FORCED_REDRAW_WAITING_FOR_DRAW:
+    return "FORCED_REDRAW_WAITING_FOR_DRAW";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_ChromeCompositorSchedulerState {
+enum BeginImplFrameDeadlineMode : int32_t {
+  DEADLINE_MODE_UNSPECIFIED = 0,
+  DEADLINE_MODE_NONE = 1,
+  DEADLINE_MODE_IMMEDIATE = 2,
+  DEADLINE_MODE_REGULAR = 3,
+  DEADLINE_MODE_LATE = 4,
+  DEADLINE_MODE_BLOCKED = 5,
+};
+} // namespace perfetto_pbzero_enum_ChromeCompositorSchedulerState
+using ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode = perfetto_pbzero_enum_ChromeCompositorSchedulerState::BeginImplFrameDeadlineMode;
+
+
+constexpr ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_MIN = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode::DEADLINE_MODE_UNSPECIFIED;
+constexpr ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_MAX = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode::DEADLINE_MODE_BLOCKED;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_Name(::perfetto::protos::pbzero::ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode::DEADLINE_MODE_UNSPECIFIED:
+    return "DEADLINE_MODE_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode::DEADLINE_MODE_NONE:
+    return "DEADLINE_MODE_NONE";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode::DEADLINE_MODE_IMMEDIATE:
+    return "DEADLINE_MODE_IMMEDIATE";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode::DEADLINE_MODE_REGULAR:
+    return "DEADLINE_MODE_REGULAR";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode::DEADLINE_MODE_LATE:
+    return "DEADLINE_MODE_LATE";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode::DEADLINE_MODE_BLOCKED:
+    return "DEADLINE_MODE_BLOCKED";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class CompositorTimingHistory_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CompositorTimingHistory_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CompositorTimingHistory_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CompositorTimingHistory_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_begin_main_frame_queue_critical_estimate_delta_us() const { return at<1>().valid(); }
+  int64_t begin_main_frame_queue_critical_estimate_delta_us() const { return at<1>().as_int64(); }
+  bool has_begin_main_frame_queue_not_critical_estimate_delta_us() const { return at<2>().valid(); }
+  int64_t begin_main_frame_queue_not_critical_estimate_delta_us() const { return at<2>().as_int64(); }
+  bool has_begin_main_frame_start_to_ready_to_commit_estimate_delta_us() const { return at<3>().valid(); }
+  int64_t begin_main_frame_start_to_ready_to_commit_estimate_delta_us() const { return at<3>().as_int64(); }
+  bool has_commit_to_ready_to_activate_estimate_delta_us() const { return at<4>().valid(); }
+  int64_t commit_to_ready_to_activate_estimate_delta_us() const { return at<4>().as_int64(); }
+  bool has_prepare_tiles_estimate_delta_us() const { return at<5>().valid(); }
+  int64_t prepare_tiles_estimate_delta_us() const { return at<5>().as_int64(); }
+  bool has_activate_estimate_delta_us() const { return at<6>().valid(); }
+  int64_t activate_estimate_delta_us() const { return at<6>().as_int64(); }
+  bool has_draw_estimate_delta_us() const { return at<7>().valid(); }
+  int64_t draw_estimate_delta_us() const { return at<7>().as_int64(); }
+};
+
+class CompositorTimingHistory : public ::protozero::Message {
+ public:
+  using Decoder = CompositorTimingHistory_Decoder;
+  enum : int32_t {
+    kBeginMainFrameQueueCriticalEstimateDeltaUsFieldNumber = 1,
+    kBeginMainFrameQueueNotCriticalEstimateDeltaUsFieldNumber = 2,
+    kBeginMainFrameStartToReadyToCommitEstimateDeltaUsFieldNumber = 3,
+    kCommitToReadyToActivateEstimateDeltaUsFieldNumber = 4,
+    kPrepareTilesEstimateDeltaUsFieldNumber = 5,
+    kActivateEstimateDeltaUsFieldNumber = 6,
+    kDrawEstimateDeltaUsFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CompositorTimingHistory"; }
+
+
+  using FieldMetadata_BeginMainFrameQueueCriticalEstimateDeltaUs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      CompositorTimingHistory>;
+
+  static constexpr FieldMetadata_BeginMainFrameQueueCriticalEstimateDeltaUs kBeginMainFrameQueueCriticalEstimateDeltaUs{};
+  void set_begin_main_frame_queue_critical_estimate_delta_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BeginMainFrameQueueCriticalEstimateDeltaUs::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_BeginMainFrameQueueNotCriticalEstimateDeltaUs =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      CompositorTimingHistory>;
+
+  static constexpr FieldMetadata_BeginMainFrameQueueNotCriticalEstimateDeltaUs kBeginMainFrameQueueNotCriticalEstimateDeltaUs{};
+  void set_begin_main_frame_queue_not_critical_estimate_delta_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BeginMainFrameQueueNotCriticalEstimateDeltaUs::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_BeginMainFrameStartToReadyToCommitEstimateDeltaUs =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      CompositorTimingHistory>;
+
+  static constexpr FieldMetadata_BeginMainFrameStartToReadyToCommitEstimateDeltaUs kBeginMainFrameStartToReadyToCommitEstimateDeltaUs{};
+  void set_begin_main_frame_start_to_ready_to_commit_estimate_delta_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BeginMainFrameStartToReadyToCommitEstimateDeltaUs::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_CommitToReadyToActivateEstimateDeltaUs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      CompositorTimingHistory>;
+
+  static constexpr FieldMetadata_CommitToReadyToActivateEstimateDeltaUs kCommitToReadyToActivateEstimateDeltaUs{};
+  void set_commit_to_ready_to_activate_estimate_delta_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CommitToReadyToActivateEstimateDeltaUs::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_PrepareTilesEstimateDeltaUs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      CompositorTimingHistory>;
+
+  static constexpr FieldMetadata_PrepareTilesEstimateDeltaUs kPrepareTilesEstimateDeltaUs{};
+  void set_prepare_tiles_estimate_delta_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PrepareTilesEstimateDeltaUs::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_ActivateEstimateDeltaUs =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      CompositorTimingHistory>;
+
+  static constexpr FieldMetadata_ActivateEstimateDeltaUs kActivateEstimateDeltaUs{};
+  void set_activate_estimate_delta_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ActivateEstimateDeltaUs::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_DrawEstimateDeltaUs =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      CompositorTimingHistory>;
+
+  static constexpr FieldMetadata_DrawEstimateDeltaUs kDrawEstimateDeltaUs{};
+  void set_draw_estimate_delta_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DrawEstimateDeltaUs::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 BeginFrameSourceState_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BeginFrameSourceState_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BeginFrameSourceState_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BeginFrameSourceState_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_source_id() const { return at<1>().valid(); }
+  uint32_t source_id() const { return at<1>().as_uint32(); }
+  bool has_paused() const { return at<2>().valid(); }
+  bool paused() const { return at<2>().as_bool(); }
+  bool has_num_observers() const { return at<3>().valid(); }
+  uint32_t num_observers() const { return at<3>().as_uint32(); }
+  bool has_last_begin_frame_args() const { return at<4>().valid(); }
+  ::protozero::ConstBytes last_begin_frame_args() const { return at<4>().as_bytes(); }
+};
+
+class BeginFrameSourceState : public ::protozero::Message {
+ public:
+  using Decoder = BeginFrameSourceState_Decoder;
+  enum : int32_t {
+    kSourceIdFieldNumber = 1,
+    kPausedFieldNumber = 2,
+    kNumObserversFieldNumber = 3,
+    kLastBeginFrameArgsFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BeginFrameSourceState"; }
+
+
+  using FieldMetadata_SourceId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BeginFrameSourceState>;
+
+  static constexpr FieldMetadata_SourceId kSourceId{};
+  void set_source_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SourceId::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_Paused =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      BeginFrameSourceState>;
+
+  static constexpr FieldMetadata_Paused kPaused{};
+  void set_paused(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_Paused::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_NumObservers =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BeginFrameSourceState>;
+
+  static constexpr FieldMetadata_NumObservers kNumObservers{};
+  void set_num_observers(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NumObservers::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_LastBeginFrameArgs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BeginFrameArgs,
+      BeginFrameSourceState>;
+
+  static constexpr FieldMetadata_LastBeginFrameArgs kLastBeginFrameArgs{};
+  template <typename T = BeginFrameArgs> T* set_last_begin_frame_args() {
+    return BeginNestedMessage<T>(4);
+  }
+
+};
+
+class BeginFrameObserverState_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BeginFrameObserverState_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BeginFrameObserverState_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BeginFrameObserverState_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dropped_begin_frame_args() const { return at<1>().valid(); }
+  int64_t dropped_begin_frame_args() const { return at<1>().as_int64(); }
+  bool has_last_begin_frame_args() const { return at<2>().valid(); }
+  ::protozero::ConstBytes last_begin_frame_args() const { return at<2>().as_bytes(); }
+};
+
+class BeginFrameObserverState : public ::protozero::Message {
+ public:
+  using Decoder = BeginFrameObserverState_Decoder;
+  enum : int32_t {
+    kDroppedBeginFrameArgsFieldNumber = 1,
+    kLastBeginFrameArgsFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BeginFrameObserverState"; }
+
+
+  using FieldMetadata_DroppedBeginFrameArgs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BeginFrameObserverState>;
+
+  static constexpr FieldMetadata_DroppedBeginFrameArgs kDroppedBeginFrameArgs{};
+  void set_dropped_begin_frame_args(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DroppedBeginFrameArgs::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_LastBeginFrameArgs =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BeginFrameArgs,
+      BeginFrameObserverState>;
+
+  static constexpr FieldMetadata_LastBeginFrameArgs kLastBeginFrameArgs{};
+  template <typename T = BeginFrameArgs> T* set_last_begin_frame_args() {
+    return BeginNestedMessage<T>(2);
+  }
+
+};
+
+class BeginImplFrameArgs_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BeginImplFrameArgs_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BeginImplFrameArgs_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BeginImplFrameArgs_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_updated_at_us() const { return at<1>().valid(); }
+  int64_t updated_at_us() const { return at<1>().as_int64(); }
+  bool has_finished_at_us() const { return at<2>().valid(); }
+  int64_t finished_at_us() const { return at<2>().as_int64(); }
+  bool has_state() const { return at<3>().valid(); }
+  int32_t state() const { return at<3>().as_int32(); }
+  bool has_current_args() const { return at<4>().valid(); }
+  ::protozero::ConstBytes current_args() const { return at<4>().as_bytes(); }
+  bool has_last_args() const { return at<5>().valid(); }
+  ::protozero::ConstBytes last_args() const { return at<5>().as_bytes(); }
+  bool has_timestamps_in_us() const { return at<6>().valid(); }
+  ::protozero::ConstBytes timestamps_in_us() const { return at<6>().as_bytes(); }
+};
+
+class BeginImplFrameArgs : public ::protozero::Message {
+ public:
+  using Decoder = BeginImplFrameArgs_Decoder;
+  enum : int32_t {
+    kUpdatedAtUsFieldNumber = 1,
+    kFinishedAtUsFieldNumber = 2,
+    kStateFieldNumber = 3,
+    kCurrentArgsFieldNumber = 4,
+    kLastArgsFieldNumber = 5,
+    kTimestampsInUsFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BeginImplFrameArgs"; }
+
+  using TimestampsInUs = ::perfetto::protos::pbzero::BeginImplFrameArgs_TimestampsInUs;
+
+  using State = ::perfetto::protos::pbzero::BeginImplFrameArgs_State;
+  static inline const char* State_Name(State value) {
+    return ::perfetto::protos::pbzero::BeginImplFrameArgs_State_Name(value);
+  }
+  static inline const State BEGIN_FRAME_FINISHED = State::BEGIN_FRAME_FINISHED;
+  static inline const State BEGIN_FRAME_USING = State::BEGIN_FRAME_USING;
+
+  using FieldMetadata_UpdatedAtUs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BeginImplFrameArgs>;
+
+  static constexpr FieldMetadata_UpdatedAtUs kUpdatedAtUs{};
+  void set_updated_at_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UpdatedAtUs::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_FinishedAtUs =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BeginImplFrameArgs>;
+
+  static constexpr FieldMetadata_FinishedAtUs kFinishedAtUs{};
+  void set_finished_at_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FinishedAtUs::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_State =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      BeginImplFrameArgs_State,
+      BeginImplFrameArgs>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(BeginImplFrameArgs_State value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::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_CurrentArgs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BeginFrameArgs,
+      BeginImplFrameArgs>;
+
+  static constexpr FieldMetadata_CurrentArgs kCurrentArgs{};
+  template <typename T = BeginFrameArgs> T* set_current_args() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_LastArgs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BeginFrameArgs,
+      BeginImplFrameArgs>;
+
+  static constexpr FieldMetadata_LastArgs kLastArgs{};
+  template <typename T = BeginFrameArgs> T* set_last_args() {
+    return BeginNestedMessage<T>(5);
+  }
+
+
+  using FieldMetadata_TimestampsInUs =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BeginImplFrameArgs_TimestampsInUs,
+      BeginImplFrameArgs>;
+
+  static constexpr FieldMetadata_TimestampsInUs kTimestampsInUs{};
+  template <typename T = BeginImplFrameArgs_TimestampsInUs> T* set_timestamps_in_us() {
+    return BeginNestedMessage<T>(6);
+  }
+
+};
+
+class BeginImplFrameArgs_TimestampsInUs_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BeginImplFrameArgs_TimestampsInUs_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BeginImplFrameArgs_TimestampsInUs_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BeginImplFrameArgs_TimestampsInUs_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_interval_delta() const { return at<1>().valid(); }
+  int64_t interval_delta() const { return at<1>().as_int64(); }
+  bool has_now_to_deadline_delta() const { return at<2>().valid(); }
+  int64_t now_to_deadline_delta() const { return at<2>().as_int64(); }
+  bool has_frame_time_to_now_delta() const { return at<3>().valid(); }
+  int64_t frame_time_to_now_delta() const { return at<3>().as_int64(); }
+  bool has_frame_time_to_deadline_delta() const { return at<4>().valid(); }
+  int64_t frame_time_to_deadline_delta() const { return at<4>().as_int64(); }
+  bool has_now() const { return at<5>().valid(); }
+  int64_t now() const { return at<5>().as_int64(); }
+  bool has_frame_time() const { return at<6>().valid(); }
+  int64_t frame_time() const { return at<6>().as_int64(); }
+  bool has_deadline() const { return at<7>().valid(); }
+  int64_t deadline() const { return at<7>().as_int64(); }
+};
+
+class BeginImplFrameArgs_TimestampsInUs : public ::protozero::Message {
+ public:
+  using Decoder = BeginImplFrameArgs_TimestampsInUs_Decoder;
+  enum : int32_t {
+    kIntervalDeltaFieldNumber = 1,
+    kNowToDeadlineDeltaFieldNumber = 2,
+    kFrameTimeToNowDeltaFieldNumber = 3,
+    kFrameTimeToDeadlineDeltaFieldNumber = 4,
+    kNowFieldNumber = 5,
+    kFrameTimeFieldNumber = 6,
+    kDeadlineFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BeginImplFrameArgs.TimestampsInUs"; }
+
+
+  using FieldMetadata_IntervalDelta =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BeginImplFrameArgs_TimestampsInUs>;
+
+  static constexpr FieldMetadata_IntervalDelta kIntervalDelta{};
+  void set_interval_delta(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IntervalDelta::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_NowToDeadlineDelta =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BeginImplFrameArgs_TimestampsInUs>;
+
+  static constexpr FieldMetadata_NowToDeadlineDelta kNowToDeadlineDelta{};
+  void set_now_to_deadline_delta(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NowToDeadlineDelta::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_FrameTimeToNowDelta =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BeginImplFrameArgs_TimestampsInUs>;
+
+  static constexpr FieldMetadata_FrameTimeToNowDelta kFrameTimeToNowDelta{};
+  void set_frame_time_to_now_delta(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FrameTimeToNowDelta::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_FrameTimeToDeadlineDelta =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BeginImplFrameArgs_TimestampsInUs>;
+
+  static constexpr FieldMetadata_FrameTimeToDeadlineDelta kFrameTimeToDeadlineDelta{};
+  void set_frame_time_to_deadline_delta(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FrameTimeToDeadlineDelta::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_Now =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BeginImplFrameArgs_TimestampsInUs>;
+
+  static constexpr FieldMetadata_Now kNow{};
+  void set_now(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Now::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_FrameTime =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BeginImplFrameArgs_TimestampsInUs>;
+
+  static constexpr FieldMetadata_FrameTime kFrameTime{};
+  void set_frame_time(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FrameTime::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_Deadline =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BeginImplFrameArgs_TimestampsInUs>;
+
+  static constexpr FieldMetadata_Deadline kDeadline{};
+  void set_deadline(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Deadline::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 BeginFrameArgs_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/12, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BeginFrameArgs_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BeginFrameArgs_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BeginFrameArgs_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_type() const { return at<1>().valid(); }
+  int32_t type() const { return at<1>().as_int32(); }
+  bool has_source_id() const { return at<2>().valid(); }
+  uint64_t source_id() const { return at<2>().as_uint64(); }
+  bool has_sequence_number() const { return at<3>().valid(); }
+  uint64_t sequence_number() const { return at<3>().as_uint64(); }
+  bool has_frame_time_us() const { return at<4>().valid(); }
+  int64_t frame_time_us() const { return at<4>().as_int64(); }
+  bool has_deadline_us() const { return at<5>().valid(); }
+  int64_t deadline_us() const { return at<5>().as_int64(); }
+  bool has_interval_delta_us() const { return at<6>().valid(); }
+  int64_t interval_delta_us() const { return at<6>().as_int64(); }
+  bool has_on_critical_path() const { return at<7>().valid(); }
+  bool on_critical_path() const { return at<7>().as_bool(); }
+  bool has_animate_only() const { return at<8>().valid(); }
+  bool animate_only() const { return at<8>().as_bool(); }
+  bool has_source_location_iid() const { return at<9>().valid(); }
+  uint64_t source_location_iid() const { return at<9>().as_uint64(); }
+  bool has_source_location() const { return at<10>().valid(); }
+  ::protozero::ConstBytes source_location() const { return at<10>().as_bytes(); }
+  bool has_frames_throttled_since_last() const { return at<12>().valid(); }
+  int64_t frames_throttled_since_last() const { return at<12>().as_int64(); }
+};
+
+class BeginFrameArgs : public ::protozero::Message {
+ public:
+  using Decoder = BeginFrameArgs_Decoder;
+  enum : int32_t {
+    kTypeFieldNumber = 1,
+    kSourceIdFieldNumber = 2,
+    kSequenceNumberFieldNumber = 3,
+    kFrameTimeUsFieldNumber = 4,
+    kDeadlineUsFieldNumber = 5,
+    kIntervalDeltaUsFieldNumber = 6,
+    kOnCriticalPathFieldNumber = 7,
+    kAnimateOnlyFieldNumber = 8,
+    kSourceLocationIidFieldNumber = 9,
+    kSourceLocationFieldNumber = 10,
+    kFramesThrottledSinceLastFieldNumber = 12,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BeginFrameArgs"; }
+
+
+  using BeginFrameArgsType = ::perfetto::protos::pbzero::BeginFrameArgs_BeginFrameArgsType;
+  static inline const char* BeginFrameArgsType_Name(BeginFrameArgsType value) {
+    return ::perfetto::protos::pbzero::BeginFrameArgs_BeginFrameArgsType_Name(value);
+  }
+  static inline const BeginFrameArgsType BEGIN_FRAME_ARGS_TYPE_UNSPECIFIED = BeginFrameArgsType::BEGIN_FRAME_ARGS_TYPE_UNSPECIFIED;
+  static inline const BeginFrameArgsType BEGIN_FRAME_ARGS_TYPE_INVALID = BeginFrameArgsType::BEGIN_FRAME_ARGS_TYPE_INVALID;
+  static inline const BeginFrameArgsType BEGIN_FRAME_ARGS_TYPE_NORMAL = BeginFrameArgsType::BEGIN_FRAME_ARGS_TYPE_NORMAL;
+  static inline const BeginFrameArgsType BEGIN_FRAME_ARGS_TYPE_MISSED = BeginFrameArgsType::BEGIN_FRAME_ARGS_TYPE_MISSED;
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      BeginFrameArgs_BeginFrameArgsType,
+      BeginFrameArgs>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(BeginFrameArgs_BeginFrameArgsType value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::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_SourceId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BeginFrameArgs>;
+
+  static constexpr FieldMetadata_SourceId kSourceId{};
+  void set_source_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SourceId::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_SequenceNumber =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BeginFrameArgs>;
+
+  static constexpr FieldMetadata_SequenceNumber kSequenceNumber{};
+  void set_sequence_number(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SequenceNumber::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_FrameTimeUs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BeginFrameArgs>;
+
+  static constexpr FieldMetadata_FrameTimeUs kFrameTimeUs{};
+  void set_frame_time_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FrameTimeUs::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_DeadlineUs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BeginFrameArgs>;
+
+  static constexpr FieldMetadata_DeadlineUs kDeadlineUs{};
+  void set_deadline_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DeadlineUs::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_IntervalDeltaUs =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BeginFrameArgs>;
+
+  static constexpr FieldMetadata_IntervalDeltaUs kIntervalDeltaUs{};
+  void set_interval_delta_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IntervalDeltaUs::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_OnCriticalPath =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      BeginFrameArgs>;
+
+  static constexpr FieldMetadata_OnCriticalPath kOnCriticalPath{};
+  void set_on_critical_path(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_OnCriticalPath::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_AnimateOnly =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      BeginFrameArgs>;
+
+  static constexpr FieldMetadata_AnimateOnly kAnimateOnly{};
+  void set_animate_only(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_AnimateOnly::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_SourceLocationIid =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BeginFrameArgs>;
+
+  static constexpr FieldMetadata_SourceLocationIid kSourceLocationIid{};
+  void set_source_location_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SourceLocationIid::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_SourceLocation =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SourceLocation,
+      BeginFrameArgs>;
+
+  static constexpr FieldMetadata_SourceLocation kSourceLocation{};
+  template <typename T = SourceLocation> T* set_source_location() {
+    return BeginNestedMessage<T>(10);
+  }
+
+
+  using FieldMetadata_FramesThrottledSinceLast =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BeginFrameArgs>;
+
+  static constexpr FieldMetadata_FramesThrottledSinceLast kFramesThrottledSinceLast{};
+  void set_frames_throttled_since_last(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FramesThrottledSinceLast::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 ChromeCompositorStateMachine_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeCompositorStateMachine_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeCompositorStateMachine_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeCompositorStateMachine_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_major_state() const { return at<1>().valid(); }
+  ::protozero::ConstBytes major_state() const { return at<1>().as_bytes(); }
+  bool has_minor_state() const { return at<2>().valid(); }
+  ::protozero::ConstBytes minor_state() const { return at<2>().as_bytes(); }
+};
+
+class ChromeCompositorStateMachine : public ::protozero::Message {
+ public:
+  using Decoder = ChromeCompositorStateMachine_Decoder;
+  enum : int32_t {
+    kMajorStateFieldNumber = 1,
+    kMinorStateFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeCompositorStateMachine"; }
+
+  using MajorState = ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState;
+  using MinorState = ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MinorState;
+
+  using FieldMetadata_MajorState =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeCompositorStateMachine_MajorState,
+      ChromeCompositorStateMachine>;
+
+  static constexpr FieldMetadata_MajorState kMajorState{};
+  template <typename T = ChromeCompositorStateMachine_MajorState> T* set_major_state() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_MinorState =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeCompositorStateMachine_MinorState,
+      ChromeCompositorStateMachine>;
+
+  static constexpr FieldMetadata_MinorState kMinorState{};
+  template <typename T = ChromeCompositorStateMachine_MinorState> T* set_minor_state() {
+    return BeginNestedMessage<T>(2);
+  }
+
+};
+
+class ChromeCompositorStateMachine_MinorState_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/46, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeCompositorStateMachine_MinorState_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeCompositorStateMachine_MinorState_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeCompositorStateMachine_MinorState_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_commit_count() const { return at<1>().valid(); }
+  int32_t commit_count() const { return at<1>().as_int32(); }
+  bool has_current_frame_number() const { return at<2>().valid(); }
+  int32_t current_frame_number() const { return at<2>().as_int32(); }
+  bool has_last_frame_number_submit_performed() const { return at<3>().valid(); }
+  int32_t last_frame_number_submit_performed() const { return at<3>().as_int32(); }
+  bool has_last_frame_number_draw_performed() const { return at<4>().valid(); }
+  int32_t last_frame_number_draw_performed() const { return at<4>().as_int32(); }
+  bool has_last_frame_number_begin_main_frame_sent() const { return at<5>().valid(); }
+  int32_t last_frame_number_begin_main_frame_sent() const { return at<5>().as_int32(); }
+  bool has_did_draw() const { return at<6>().valid(); }
+  bool did_draw() const { return at<6>().as_bool(); }
+  bool has_did_send_begin_main_frame_for_current_frame() const { return at<7>().valid(); }
+  bool did_send_begin_main_frame_for_current_frame() const { return at<7>().as_bool(); }
+  bool has_did_notify_begin_main_frame_not_expected_until() const { return at<8>().valid(); }
+  bool did_notify_begin_main_frame_not_expected_until() const { return at<8>().as_bool(); }
+  bool has_did_notify_begin_main_frame_not_expected_soon() const { return at<9>().valid(); }
+  bool did_notify_begin_main_frame_not_expected_soon() const { return at<9>().as_bool(); }
+  bool has_wants_begin_main_frame_not_expected() const { return at<10>().valid(); }
+  bool wants_begin_main_frame_not_expected() const { return at<10>().as_bool(); }
+  bool has_did_commit_during_frame() const { return at<11>().valid(); }
+  bool did_commit_during_frame() const { return at<11>().as_bool(); }
+  bool has_did_invalidate_layer_tree_frame_sink() const { return at<12>().valid(); }
+  bool did_invalidate_layer_tree_frame_sink() const { return at<12>().as_bool(); }
+  bool has_did_perform_impl_side_invalidaion() const { return at<13>().valid(); }
+  bool did_perform_impl_side_invalidaion() const { return at<13>().as_bool(); }
+  bool has_did_prepare_tiles() const { return at<14>().valid(); }
+  bool did_prepare_tiles() const { return at<14>().as_bool(); }
+  bool has_consecutive_checkerboard_animations() const { return at<15>().valid(); }
+  int32_t consecutive_checkerboard_animations() const { return at<15>().as_int32(); }
+  bool has_pending_submit_frames() const { return at<16>().valid(); }
+  int32_t pending_submit_frames() const { return at<16>().as_int32(); }
+  bool has_submit_frames_with_current_layer_tree_frame_sink() const { return at<17>().valid(); }
+  int32_t submit_frames_with_current_layer_tree_frame_sink() const { return at<17>().as_int32(); }
+  bool has_needs_redraw() const { return at<18>().valid(); }
+  bool needs_redraw() const { return at<18>().as_bool(); }
+  bool has_needs_prepare_tiles() const { return at<19>().valid(); }
+  bool needs_prepare_tiles() const { return at<19>().as_bool(); }
+  bool has_needs_begin_main_frame() const { return at<20>().valid(); }
+  bool needs_begin_main_frame() const { return at<20>().as_bool(); }
+  bool has_needs_one_begin_impl_frame() const { return at<21>().valid(); }
+  bool needs_one_begin_impl_frame() const { return at<21>().as_bool(); }
+  bool has_visible() const { return at<22>().valid(); }
+  bool visible() const { return at<22>().as_bool(); }
+  bool has_begin_frame_source_paused() const { return at<23>().valid(); }
+  bool begin_frame_source_paused() const { return at<23>().as_bool(); }
+  bool has_can_draw() const { return at<24>().valid(); }
+  bool can_draw() const { return at<24>().as_bool(); }
+  bool has_resourceless_draw() const { return at<25>().valid(); }
+  bool resourceless_draw() const { return at<25>().as_bool(); }
+  bool has_has_pending_tree() const { return at<26>().valid(); }
+  bool has_pending_tree() const { return at<26>().as_bool(); }
+  bool has_pending_tree_is_ready_for_activation() const { return at<27>().valid(); }
+  bool pending_tree_is_ready_for_activation() const { return at<27>().as_bool(); }
+  bool has_active_tree_needs_first_draw() const { return at<28>().valid(); }
+  bool active_tree_needs_first_draw() const { return at<28>().as_bool(); }
+  bool has_active_tree_is_ready_to_draw() const { return at<29>().valid(); }
+  bool active_tree_is_ready_to_draw() const { return at<29>().as_bool(); }
+  bool has_did_create_and_initialize_first_layer_tree_frame_sink() const { return at<30>().valid(); }
+  bool did_create_and_initialize_first_layer_tree_frame_sink() const { return at<30>().as_bool(); }
+  bool has_tree_priority() const { return at<31>().valid(); }
+  int32_t tree_priority() const { return at<31>().as_int32(); }
+  bool has_scroll_handler_state() const { return at<32>().valid(); }
+  int32_t scroll_handler_state() const { return at<32>().as_int32(); }
+  bool has_critical_begin_main_frame_to_activate_is_fast() const { return at<33>().valid(); }
+  bool critical_begin_main_frame_to_activate_is_fast() const { return at<33>().as_bool(); }
+  bool has_main_thread_missed_last_deadline() const { return at<34>().valid(); }
+  bool main_thread_missed_last_deadline() const { return at<34>().as_bool(); }
+  bool has_video_needs_begin_frames() const { return at<36>().valid(); }
+  bool video_needs_begin_frames() const { return at<36>().as_bool(); }
+  bool has_defer_begin_main_frame() const { return at<37>().valid(); }
+  bool defer_begin_main_frame() const { return at<37>().as_bool(); }
+  bool has_last_commit_had_no_updates() const { return at<38>().valid(); }
+  bool last_commit_had_no_updates() const { return at<38>().as_bool(); }
+  bool has_did_draw_in_last_frame() const { return at<39>().valid(); }
+  bool did_draw_in_last_frame() const { return at<39>().as_bool(); }
+  bool has_did_submit_in_last_frame() const { return at<40>().valid(); }
+  bool did_submit_in_last_frame() const { return at<40>().as_bool(); }
+  bool has_needs_impl_side_invalidation() const { return at<41>().valid(); }
+  bool needs_impl_side_invalidation() const { return at<41>().as_bool(); }
+  bool has_current_pending_tree_is_impl_side() const { return at<42>().valid(); }
+  bool current_pending_tree_is_impl_side() const { return at<42>().as_bool(); }
+  bool has_previous_pending_tree_was_impl_side() const { return at<43>().valid(); }
+  bool previous_pending_tree_was_impl_side() const { return at<43>().as_bool(); }
+  bool has_processing_animation_worklets_for_active_tree() const { return at<44>().valid(); }
+  bool processing_animation_worklets_for_active_tree() const { return at<44>().as_bool(); }
+  bool has_processing_animation_worklets_for_pending_tree() const { return at<45>().valid(); }
+  bool processing_animation_worklets_for_pending_tree() const { return at<45>().as_bool(); }
+  bool has_processing_paint_worklets_for_pending_tree() const { return at<46>().valid(); }
+  bool processing_paint_worklets_for_pending_tree() const { return at<46>().as_bool(); }
+};
+
+class ChromeCompositorStateMachine_MinorState : public ::protozero::Message {
+ public:
+  using Decoder = ChromeCompositorStateMachine_MinorState_Decoder;
+  enum : int32_t {
+    kCommitCountFieldNumber = 1,
+    kCurrentFrameNumberFieldNumber = 2,
+    kLastFrameNumberSubmitPerformedFieldNumber = 3,
+    kLastFrameNumberDrawPerformedFieldNumber = 4,
+    kLastFrameNumberBeginMainFrameSentFieldNumber = 5,
+    kDidDrawFieldNumber = 6,
+    kDidSendBeginMainFrameForCurrentFrameFieldNumber = 7,
+    kDidNotifyBeginMainFrameNotExpectedUntilFieldNumber = 8,
+    kDidNotifyBeginMainFrameNotExpectedSoonFieldNumber = 9,
+    kWantsBeginMainFrameNotExpectedFieldNumber = 10,
+    kDidCommitDuringFrameFieldNumber = 11,
+    kDidInvalidateLayerTreeFrameSinkFieldNumber = 12,
+    kDidPerformImplSideInvalidaionFieldNumber = 13,
+    kDidPrepareTilesFieldNumber = 14,
+    kConsecutiveCheckerboardAnimationsFieldNumber = 15,
+    kPendingSubmitFramesFieldNumber = 16,
+    kSubmitFramesWithCurrentLayerTreeFrameSinkFieldNumber = 17,
+    kNeedsRedrawFieldNumber = 18,
+    kNeedsPrepareTilesFieldNumber = 19,
+    kNeedsBeginMainFrameFieldNumber = 20,
+    kNeedsOneBeginImplFrameFieldNumber = 21,
+    kVisibleFieldNumber = 22,
+    kBeginFrameSourcePausedFieldNumber = 23,
+    kCanDrawFieldNumber = 24,
+    kResourcelessDrawFieldNumber = 25,
+    kHasPendingTreeFieldNumber = 26,
+    kPendingTreeIsReadyForActivationFieldNumber = 27,
+    kActiveTreeNeedsFirstDrawFieldNumber = 28,
+    kActiveTreeIsReadyToDrawFieldNumber = 29,
+    kDidCreateAndInitializeFirstLayerTreeFrameSinkFieldNumber = 30,
+    kTreePriorityFieldNumber = 31,
+    kScrollHandlerStateFieldNumber = 32,
+    kCriticalBeginMainFrameToActivateIsFastFieldNumber = 33,
+    kMainThreadMissedLastDeadlineFieldNumber = 34,
+    kVideoNeedsBeginFramesFieldNumber = 36,
+    kDeferBeginMainFrameFieldNumber = 37,
+    kLastCommitHadNoUpdatesFieldNumber = 38,
+    kDidDrawInLastFrameFieldNumber = 39,
+    kDidSubmitInLastFrameFieldNumber = 40,
+    kNeedsImplSideInvalidationFieldNumber = 41,
+    kCurrentPendingTreeIsImplSideFieldNumber = 42,
+    kPreviousPendingTreeWasImplSideFieldNumber = 43,
+    kProcessingAnimationWorkletsForActiveTreeFieldNumber = 44,
+    kProcessingAnimationWorkletsForPendingTreeFieldNumber = 45,
+    kProcessingPaintWorkletsForPendingTreeFieldNumber = 46,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeCompositorStateMachine.MinorState"; }
+
+
+  using TreePriority = ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MinorState_TreePriority;
+  static inline const char* TreePriority_Name(TreePriority value) {
+    return ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MinorState_TreePriority_Name(value);
+  }
+
+  using ScrollHandlerState = ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MinorState_ScrollHandlerState;
+  static inline const char* ScrollHandlerState_Name(ScrollHandlerState value) {
+    return ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MinorState_ScrollHandlerState_Name(value);
+  }
+  static inline const TreePriority TREE_PRIORITY_UNSPECIFIED = TreePriority::TREE_PRIORITY_UNSPECIFIED;
+  static inline const TreePriority TREE_PRIORITY_SAME_PRIORITY_FOR_BOTH_TREES = TreePriority::TREE_PRIORITY_SAME_PRIORITY_FOR_BOTH_TREES;
+  static inline const TreePriority TREE_PRIORITY_SMOOTHNESS_TAKES_PRIORITY = TreePriority::TREE_PRIORITY_SMOOTHNESS_TAKES_PRIORITY;
+  static inline const TreePriority TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY = TreePriority::TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY;
+  static inline const ScrollHandlerState SCROLL_HANDLER_UNSPECIFIED = ScrollHandlerState::SCROLL_HANDLER_UNSPECIFIED;
+  static inline const ScrollHandlerState SCROLL_AFFECTS_SCROLL_HANDLER = ScrollHandlerState::SCROLL_AFFECTS_SCROLL_HANDLER;
+  static inline const ScrollHandlerState SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER = ScrollHandlerState::SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER;
+
+  using FieldMetadata_CommitCount =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_CommitCount kCommitCount{};
+  void set_commit_count(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CommitCount::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_CurrentFrameNumber =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_CurrentFrameNumber kCurrentFrameNumber{};
+  void set_current_frame_number(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CurrentFrameNumber::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_LastFrameNumberSubmitPerformed =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_LastFrameNumberSubmitPerformed kLastFrameNumberSubmitPerformed{};
+  void set_last_frame_number_submit_performed(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LastFrameNumberSubmitPerformed::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_LastFrameNumberDrawPerformed =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_LastFrameNumberDrawPerformed kLastFrameNumberDrawPerformed{};
+  void set_last_frame_number_draw_performed(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LastFrameNumberDrawPerformed::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_LastFrameNumberBeginMainFrameSent =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_LastFrameNumberBeginMainFrameSent kLastFrameNumberBeginMainFrameSent{};
+  void set_last_frame_number_begin_main_frame_sent(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LastFrameNumberBeginMainFrameSent::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_DidDraw =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_DidDraw kDidDraw{};
+  void set_did_draw(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DidDraw::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_DidSendBeginMainFrameForCurrentFrame =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_DidSendBeginMainFrameForCurrentFrame kDidSendBeginMainFrameForCurrentFrame{};
+  void set_did_send_begin_main_frame_for_current_frame(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DidSendBeginMainFrameForCurrentFrame::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_DidNotifyBeginMainFrameNotExpectedUntil =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_DidNotifyBeginMainFrameNotExpectedUntil kDidNotifyBeginMainFrameNotExpectedUntil{};
+  void set_did_notify_begin_main_frame_not_expected_until(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DidNotifyBeginMainFrameNotExpectedUntil::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_DidNotifyBeginMainFrameNotExpectedSoon =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_DidNotifyBeginMainFrameNotExpectedSoon kDidNotifyBeginMainFrameNotExpectedSoon{};
+  void set_did_notify_begin_main_frame_not_expected_soon(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DidNotifyBeginMainFrameNotExpectedSoon::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_WantsBeginMainFrameNotExpected =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_WantsBeginMainFrameNotExpected kWantsBeginMainFrameNotExpected{};
+  void set_wants_begin_main_frame_not_expected(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_WantsBeginMainFrameNotExpected::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_DidCommitDuringFrame =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_DidCommitDuringFrame kDidCommitDuringFrame{};
+  void set_did_commit_during_frame(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DidCommitDuringFrame::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_DidInvalidateLayerTreeFrameSink =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_DidInvalidateLayerTreeFrameSink kDidInvalidateLayerTreeFrameSink{};
+  void set_did_invalidate_layer_tree_frame_sink(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DidInvalidateLayerTreeFrameSink::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_DidPerformImplSideInvalidaion =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_DidPerformImplSideInvalidaion kDidPerformImplSideInvalidaion{};
+  void set_did_perform_impl_side_invalidaion(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DidPerformImplSideInvalidaion::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_DidPrepareTiles =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_DidPrepareTiles kDidPrepareTiles{};
+  void set_did_prepare_tiles(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DidPrepareTiles::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_ConsecutiveCheckerboardAnimations =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_ConsecutiveCheckerboardAnimations kConsecutiveCheckerboardAnimations{};
+  void set_consecutive_checkerboard_animations(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ConsecutiveCheckerboardAnimations::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_PendingSubmitFrames =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_PendingSubmitFrames kPendingSubmitFrames{};
+  void set_pending_submit_frames(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PendingSubmitFrames::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_SubmitFramesWithCurrentLayerTreeFrameSink =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_SubmitFramesWithCurrentLayerTreeFrameSink kSubmitFramesWithCurrentLayerTreeFrameSink{};
+  void set_submit_frames_with_current_layer_tree_frame_sink(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SubmitFramesWithCurrentLayerTreeFrameSink::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_NeedsRedraw =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_NeedsRedraw kNeedsRedraw{};
+  void set_needs_redraw(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_NeedsRedraw::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_NeedsPrepareTiles =
+    ::protozero::proto_utils::FieldMetadata<
+      19,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_NeedsPrepareTiles kNeedsPrepareTiles{};
+  void set_needs_prepare_tiles(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_NeedsPrepareTiles::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_NeedsBeginMainFrame =
+    ::protozero::proto_utils::FieldMetadata<
+      20,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_NeedsBeginMainFrame kNeedsBeginMainFrame{};
+  void set_needs_begin_main_frame(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_NeedsBeginMainFrame::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_NeedsOneBeginImplFrame =
+    ::protozero::proto_utils::FieldMetadata<
+      21,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_NeedsOneBeginImplFrame kNeedsOneBeginImplFrame{};
+  void set_needs_one_begin_impl_frame(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_NeedsOneBeginImplFrame::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_Visible =
+    ::protozero::proto_utils::FieldMetadata<
+      22,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_Visible kVisible{};
+  void set_visible(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_Visible::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_BeginFrameSourcePaused =
+    ::protozero::proto_utils::FieldMetadata<
+      23,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_BeginFrameSourcePaused kBeginFrameSourcePaused{};
+  void set_begin_frame_source_paused(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_BeginFrameSourcePaused::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_CanDraw =
+    ::protozero::proto_utils::FieldMetadata<
+      24,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_CanDraw kCanDraw{};
+  void set_can_draw(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_CanDraw::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_ResourcelessDraw =
+    ::protozero::proto_utils::FieldMetadata<
+      25,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_ResourcelessDraw kResourcelessDraw{};
+  void set_resourceless_draw(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResourcelessDraw::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_HasPendingTree =
+    ::protozero::proto_utils::FieldMetadata<
+      26,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_HasPendingTree kHasPendingTree{};
+  void set_has_pending_tree(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_HasPendingTree::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_PendingTreeIsReadyForActivation =
+    ::protozero::proto_utils::FieldMetadata<
+      27,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_PendingTreeIsReadyForActivation kPendingTreeIsReadyForActivation{};
+  void set_pending_tree_is_ready_for_activation(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_PendingTreeIsReadyForActivation::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_ActiveTreeNeedsFirstDraw =
+    ::protozero::proto_utils::FieldMetadata<
+      28,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_ActiveTreeNeedsFirstDraw kActiveTreeNeedsFirstDraw{};
+  void set_active_tree_needs_first_draw(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ActiveTreeNeedsFirstDraw::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_ActiveTreeIsReadyToDraw =
+    ::protozero::proto_utils::FieldMetadata<
+      29,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_ActiveTreeIsReadyToDraw kActiveTreeIsReadyToDraw{};
+  void set_active_tree_is_ready_to_draw(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ActiveTreeIsReadyToDraw::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_DidCreateAndInitializeFirstLayerTreeFrameSink =
+    ::protozero::proto_utils::FieldMetadata<
+      30,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_DidCreateAndInitializeFirstLayerTreeFrameSink kDidCreateAndInitializeFirstLayerTreeFrameSink{};
+  void set_did_create_and_initialize_first_layer_tree_frame_sink(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DidCreateAndInitializeFirstLayerTreeFrameSink::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_TreePriority =
+    ::protozero::proto_utils::FieldMetadata<
+      31,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ChromeCompositorStateMachine_MinorState_TreePriority,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_TreePriority kTreePriority{};
+  void set_tree_priority(ChromeCompositorStateMachine_MinorState_TreePriority value) {
+    static constexpr uint32_t field_id = FieldMetadata_TreePriority::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_ScrollHandlerState =
+    ::protozero::proto_utils::FieldMetadata<
+      32,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ChromeCompositorStateMachine_MinorState_ScrollHandlerState,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_ScrollHandlerState kScrollHandlerState{};
+  void set_scroll_handler_state(ChromeCompositorStateMachine_MinorState_ScrollHandlerState value) {
+    static constexpr uint32_t field_id = FieldMetadata_ScrollHandlerState::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_CriticalBeginMainFrameToActivateIsFast =
+    ::protozero::proto_utils::FieldMetadata<
+      33,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_CriticalBeginMainFrameToActivateIsFast kCriticalBeginMainFrameToActivateIsFast{};
+  void set_critical_begin_main_frame_to_activate_is_fast(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_CriticalBeginMainFrameToActivateIsFast::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_MainThreadMissedLastDeadline =
+    ::protozero::proto_utils::FieldMetadata<
+      34,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_MainThreadMissedLastDeadline kMainThreadMissedLastDeadline{};
+  void set_main_thread_missed_last_deadline(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_MainThreadMissedLastDeadline::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_VideoNeedsBeginFrames =
+    ::protozero::proto_utils::FieldMetadata<
+      36,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_VideoNeedsBeginFrames kVideoNeedsBeginFrames{};
+  void set_video_needs_begin_frames(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_VideoNeedsBeginFrames::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_DeferBeginMainFrame =
+    ::protozero::proto_utils::FieldMetadata<
+      37,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_DeferBeginMainFrame kDeferBeginMainFrame{};
+  void set_defer_begin_main_frame(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DeferBeginMainFrame::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_LastCommitHadNoUpdates =
+    ::protozero::proto_utils::FieldMetadata<
+      38,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_LastCommitHadNoUpdates kLastCommitHadNoUpdates{};
+  void set_last_commit_had_no_updates(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_LastCommitHadNoUpdates::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_DidDrawInLastFrame =
+    ::protozero::proto_utils::FieldMetadata<
+      39,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_DidDrawInLastFrame kDidDrawInLastFrame{};
+  void set_did_draw_in_last_frame(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DidDrawInLastFrame::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_DidSubmitInLastFrame =
+    ::protozero::proto_utils::FieldMetadata<
+      40,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_DidSubmitInLastFrame kDidSubmitInLastFrame{};
+  void set_did_submit_in_last_frame(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DidSubmitInLastFrame::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_NeedsImplSideInvalidation =
+    ::protozero::proto_utils::FieldMetadata<
+      41,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_NeedsImplSideInvalidation kNeedsImplSideInvalidation{};
+  void set_needs_impl_side_invalidation(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_NeedsImplSideInvalidation::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_CurrentPendingTreeIsImplSide =
+    ::protozero::proto_utils::FieldMetadata<
+      42,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_CurrentPendingTreeIsImplSide kCurrentPendingTreeIsImplSide{};
+  void set_current_pending_tree_is_impl_side(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_CurrentPendingTreeIsImplSide::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_PreviousPendingTreeWasImplSide =
+    ::protozero::proto_utils::FieldMetadata<
+      43,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_PreviousPendingTreeWasImplSide kPreviousPendingTreeWasImplSide{};
+  void set_previous_pending_tree_was_impl_side(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_PreviousPendingTreeWasImplSide::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_ProcessingAnimationWorkletsForActiveTree =
+    ::protozero::proto_utils::FieldMetadata<
+      44,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_ProcessingAnimationWorkletsForActiveTree kProcessingAnimationWorkletsForActiveTree{};
+  void set_processing_animation_worklets_for_active_tree(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProcessingAnimationWorkletsForActiveTree::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_ProcessingAnimationWorkletsForPendingTree =
+    ::protozero::proto_utils::FieldMetadata<
+      45,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_ProcessingAnimationWorkletsForPendingTree kProcessingAnimationWorkletsForPendingTree{};
+  void set_processing_animation_worklets_for_pending_tree(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProcessingAnimationWorkletsForPendingTree::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_ProcessingPaintWorkletsForPendingTree =
+    ::protozero::proto_utils::FieldMetadata<
+      46,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_ProcessingPaintWorkletsForPendingTree kProcessingPaintWorkletsForPendingTree{};
+  void set_processing_paint_worklets_for_pending_tree(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProcessingPaintWorkletsForPendingTree::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 ChromeCompositorStateMachine_MajorState_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeCompositorStateMachine_MajorState_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeCompositorStateMachine_MajorState_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeCompositorStateMachine_MajorState_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_next_action() const { return at<1>().valid(); }
+  int32_t next_action() const { return at<1>().as_int32(); }
+  bool has_begin_impl_frame_state() const { return at<2>().valid(); }
+  int32_t begin_impl_frame_state() const { return at<2>().as_int32(); }
+  bool has_begin_main_frame_state() const { return at<3>().valid(); }
+  int32_t begin_main_frame_state() const { return at<3>().as_int32(); }
+  bool has_layer_tree_frame_sink_state() const { return at<4>().valid(); }
+  int32_t layer_tree_frame_sink_state() const { return at<4>().as_int32(); }
+  bool has_forced_redraw_state() const { return at<5>().valid(); }
+  int32_t forced_redraw_state() const { return at<5>().as_int32(); }
+};
+
+class ChromeCompositorStateMachine_MajorState : public ::protozero::Message {
+ public:
+  using Decoder = ChromeCompositorStateMachine_MajorState_Decoder;
+  enum : int32_t {
+    kNextActionFieldNumber = 1,
+    kBeginImplFrameStateFieldNumber = 2,
+    kBeginMainFrameStateFieldNumber = 3,
+    kLayerTreeFrameSinkStateFieldNumber = 4,
+    kForcedRedrawStateFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeCompositorStateMachine.MajorState"; }
+
+
+  using BeginImplFrameState = ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_BeginImplFrameState;
+  static inline const char* BeginImplFrameState_Name(BeginImplFrameState value) {
+    return ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_BeginImplFrameState_Name(value);
+  }
+
+  using BeginMainFrameState = ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_BeginMainFrameState;
+  static inline const char* BeginMainFrameState_Name(BeginMainFrameState value) {
+    return ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_BeginMainFrameState_Name(value);
+  }
+
+  using LayerTreeFrameSinkState = ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState;
+  static inline const char* LayerTreeFrameSinkState_Name(LayerTreeFrameSinkState value) {
+    return ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_Name(value);
+  }
+
+  using ForcedRedrawOnTimeoutState = ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState;
+  static inline const char* ForcedRedrawOnTimeoutState_Name(ForcedRedrawOnTimeoutState value) {
+    return ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_Name(value);
+  }
+  static inline const BeginImplFrameState BEGIN_IMPL_FRAME_UNSPECIFIED = BeginImplFrameState::BEGIN_IMPL_FRAME_UNSPECIFIED;
+  static inline const BeginImplFrameState BEGIN_IMPL_FRAME_IDLE = BeginImplFrameState::BEGIN_IMPL_FRAME_IDLE;
+  static inline const BeginImplFrameState BEGIN_IMPL_FRAME_INSIDE_BEGIN_FRAME = BeginImplFrameState::BEGIN_IMPL_FRAME_INSIDE_BEGIN_FRAME;
+  static inline const BeginImplFrameState BEGIN_IMPL_FRAME_INSIDE_DEADLINE = BeginImplFrameState::BEGIN_IMPL_FRAME_INSIDE_DEADLINE;
+  static inline const BeginMainFrameState BEGIN_MAIN_FRAME_UNSPECIFIED = BeginMainFrameState::BEGIN_MAIN_FRAME_UNSPECIFIED;
+  static inline const BeginMainFrameState BEGIN_MAIN_FRAME_IDLE = BeginMainFrameState::BEGIN_MAIN_FRAME_IDLE;
+  static inline const BeginMainFrameState BEGIN_MAIN_FRAME_SENT = BeginMainFrameState::BEGIN_MAIN_FRAME_SENT;
+  static inline const BeginMainFrameState BEGIN_MAIN_FRAME_READY_TO_COMMIT = BeginMainFrameState::BEGIN_MAIN_FRAME_READY_TO_COMMIT;
+  static inline const LayerTreeFrameSinkState LAYER_TREE_FRAME_UNSPECIFIED = LayerTreeFrameSinkState::LAYER_TREE_FRAME_UNSPECIFIED;
+  static inline const LayerTreeFrameSinkState LAYER_TREE_FRAME_NONE = LayerTreeFrameSinkState::LAYER_TREE_FRAME_NONE;
+  static inline const LayerTreeFrameSinkState LAYER_TREE_FRAME_ACTIVE = LayerTreeFrameSinkState::LAYER_TREE_FRAME_ACTIVE;
+  static inline const LayerTreeFrameSinkState LAYER_TREE_FRAME_CREATING = LayerTreeFrameSinkState::LAYER_TREE_FRAME_CREATING;
+  static inline const LayerTreeFrameSinkState LAYER_TREE_FRAME_WAITING_FOR_FIRST_COMMIT = LayerTreeFrameSinkState::LAYER_TREE_FRAME_WAITING_FOR_FIRST_COMMIT;
+  static inline const LayerTreeFrameSinkState LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION = LayerTreeFrameSinkState::LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION;
+  static inline const ForcedRedrawOnTimeoutState FORCED_REDRAW_UNSPECIFIED = ForcedRedrawOnTimeoutState::FORCED_REDRAW_UNSPECIFIED;
+  static inline const ForcedRedrawOnTimeoutState FORCED_REDRAW_IDLE = ForcedRedrawOnTimeoutState::FORCED_REDRAW_IDLE;
+  static inline const ForcedRedrawOnTimeoutState FORCED_REDRAW_WAITING_FOR_COMMIT = ForcedRedrawOnTimeoutState::FORCED_REDRAW_WAITING_FOR_COMMIT;
+  static inline const ForcedRedrawOnTimeoutState FORCED_REDRAW_WAITING_FOR_ACTIVATION = ForcedRedrawOnTimeoutState::FORCED_REDRAW_WAITING_FOR_ACTIVATION;
+  static inline const ForcedRedrawOnTimeoutState FORCED_REDRAW_WAITING_FOR_DRAW = ForcedRedrawOnTimeoutState::FORCED_REDRAW_WAITING_FOR_DRAW;
+
+  using FieldMetadata_NextAction =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ChromeCompositorSchedulerAction,
+      ChromeCompositorStateMachine_MajorState>;
+
+  static constexpr FieldMetadata_NextAction kNextAction{};
+  void set_next_action(ChromeCompositorSchedulerAction value) {
+    static constexpr uint32_t field_id = FieldMetadata_NextAction::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_BeginImplFrameState =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ChromeCompositorStateMachine_MajorState_BeginImplFrameState,
+      ChromeCompositorStateMachine_MajorState>;
+
+  static constexpr FieldMetadata_BeginImplFrameState kBeginImplFrameState{};
+  void set_begin_impl_frame_state(ChromeCompositorStateMachine_MajorState_BeginImplFrameState value) {
+    static constexpr uint32_t field_id = FieldMetadata_BeginImplFrameState::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_BeginMainFrameState =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ChromeCompositorStateMachine_MajorState_BeginMainFrameState,
+      ChromeCompositorStateMachine_MajorState>;
+
+  static constexpr FieldMetadata_BeginMainFrameState kBeginMainFrameState{};
+  void set_begin_main_frame_state(ChromeCompositorStateMachine_MajorState_BeginMainFrameState value) {
+    static constexpr uint32_t field_id = FieldMetadata_BeginMainFrameState::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_LayerTreeFrameSinkState =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState,
+      ChromeCompositorStateMachine_MajorState>;
+
+  static constexpr FieldMetadata_LayerTreeFrameSinkState kLayerTreeFrameSinkState{};
+  void set_layer_tree_frame_sink_state(ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState value) {
+    static constexpr uint32_t field_id = FieldMetadata_LayerTreeFrameSinkState::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_ForcedRedrawState =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState,
+      ChromeCompositorStateMachine_MajorState>;
+
+  static constexpr FieldMetadata_ForcedRedrawState kForcedRedrawState{};
+  void set_forced_redraw_state(ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState value) {
+    static constexpr uint32_t field_id = FieldMetadata_ForcedRedrawState::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);
+  }
+};
+
+class ChromeCompositorSchedulerState_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/17, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeCompositorSchedulerState_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeCompositorSchedulerState_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeCompositorSchedulerState_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_state_machine() const { return at<1>().valid(); }
+  ::protozero::ConstBytes state_machine() const { return at<1>().as_bytes(); }
+  bool has_observing_begin_frame_source() const { return at<2>().valid(); }
+  bool observing_begin_frame_source() const { return at<2>().as_bool(); }
+  bool has_begin_impl_frame_deadline_task() const { return at<3>().valid(); }
+  bool begin_impl_frame_deadline_task() const { return at<3>().as_bool(); }
+  bool has_pending_begin_frame_task() const { return at<4>().valid(); }
+  bool pending_begin_frame_task() const { return at<4>().as_bool(); }
+  bool has_skipped_last_frame_missed_exceeded_deadline() const { return at<5>().valid(); }
+  bool skipped_last_frame_missed_exceeded_deadline() const { return at<5>().as_bool(); }
+  bool has_inside_action() const { return at<7>().valid(); }
+  int32_t inside_action() const { return at<7>().as_int32(); }
+  bool has_deadline_mode() const { return at<8>().valid(); }
+  int32_t deadline_mode() const { return at<8>().as_int32(); }
+  bool has_deadline_us() const { return at<9>().valid(); }
+  int64_t deadline_us() const { return at<9>().as_int64(); }
+  bool has_deadline_scheduled_at_us() const { return at<10>().valid(); }
+  int64_t deadline_scheduled_at_us() const { return at<10>().as_int64(); }
+  bool has_now_us() const { return at<11>().valid(); }
+  int64_t now_us() const { return at<11>().as_int64(); }
+  bool has_now_to_deadline_delta_us() const { return at<12>().valid(); }
+  int64_t now_to_deadline_delta_us() const { return at<12>().as_int64(); }
+  bool has_now_to_deadline_scheduled_at_delta_us() const { return at<13>().valid(); }
+  int64_t now_to_deadline_scheduled_at_delta_us() const { return at<13>().as_int64(); }
+  bool has_begin_impl_frame_args() const { return at<14>().valid(); }
+  ::protozero::ConstBytes begin_impl_frame_args() const { return at<14>().as_bytes(); }
+  bool has_begin_frame_observer_state() const { return at<15>().valid(); }
+  ::protozero::ConstBytes begin_frame_observer_state() const { return at<15>().as_bytes(); }
+  bool has_begin_frame_source_state() const { return at<16>().valid(); }
+  ::protozero::ConstBytes begin_frame_source_state() const { return at<16>().as_bytes(); }
+  bool has_compositor_timing_history() const { return at<17>().valid(); }
+  ::protozero::ConstBytes compositor_timing_history() const { return at<17>().as_bytes(); }
+};
+
+class ChromeCompositorSchedulerState : public ::protozero::Message {
+ public:
+  using Decoder = ChromeCompositorSchedulerState_Decoder;
+  enum : int32_t {
+    kStateMachineFieldNumber = 1,
+    kObservingBeginFrameSourceFieldNumber = 2,
+    kBeginImplFrameDeadlineTaskFieldNumber = 3,
+    kPendingBeginFrameTaskFieldNumber = 4,
+    kSkippedLastFrameMissedExceededDeadlineFieldNumber = 5,
+    kInsideActionFieldNumber = 7,
+    kDeadlineModeFieldNumber = 8,
+    kDeadlineUsFieldNumber = 9,
+    kDeadlineScheduledAtUsFieldNumber = 10,
+    kNowUsFieldNumber = 11,
+    kNowToDeadlineDeltaUsFieldNumber = 12,
+    kNowToDeadlineScheduledAtDeltaUsFieldNumber = 13,
+    kBeginImplFrameArgsFieldNumber = 14,
+    kBeginFrameObserverStateFieldNumber = 15,
+    kBeginFrameSourceStateFieldNumber = 16,
+    kCompositorTimingHistoryFieldNumber = 17,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeCompositorSchedulerState"; }
+
+
+  using BeginImplFrameDeadlineMode = ::perfetto::protos::pbzero::ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode;
+  static inline const char* BeginImplFrameDeadlineMode_Name(BeginImplFrameDeadlineMode value) {
+    return ::perfetto::protos::pbzero::ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_Name(value);
+  }
+  static inline const BeginImplFrameDeadlineMode DEADLINE_MODE_UNSPECIFIED = BeginImplFrameDeadlineMode::DEADLINE_MODE_UNSPECIFIED;
+  static inline const BeginImplFrameDeadlineMode DEADLINE_MODE_NONE = BeginImplFrameDeadlineMode::DEADLINE_MODE_NONE;
+  static inline const BeginImplFrameDeadlineMode DEADLINE_MODE_IMMEDIATE = BeginImplFrameDeadlineMode::DEADLINE_MODE_IMMEDIATE;
+  static inline const BeginImplFrameDeadlineMode DEADLINE_MODE_REGULAR = BeginImplFrameDeadlineMode::DEADLINE_MODE_REGULAR;
+  static inline const BeginImplFrameDeadlineMode DEADLINE_MODE_LATE = BeginImplFrameDeadlineMode::DEADLINE_MODE_LATE;
+  static inline const BeginImplFrameDeadlineMode DEADLINE_MODE_BLOCKED = BeginImplFrameDeadlineMode::DEADLINE_MODE_BLOCKED;
+
+  using FieldMetadata_StateMachine =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeCompositorStateMachine,
+      ChromeCompositorSchedulerState>;
+
+  static constexpr FieldMetadata_StateMachine kStateMachine{};
+  template <typename T = ChromeCompositorStateMachine> T* set_state_machine() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_ObservingBeginFrameSource =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorSchedulerState>;
+
+  static constexpr FieldMetadata_ObservingBeginFrameSource kObservingBeginFrameSource{};
+  void set_observing_begin_frame_source(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ObservingBeginFrameSource::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_BeginImplFrameDeadlineTask =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorSchedulerState>;
+
+  static constexpr FieldMetadata_BeginImplFrameDeadlineTask kBeginImplFrameDeadlineTask{};
+  void set_begin_impl_frame_deadline_task(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_BeginImplFrameDeadlineTask::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_PendingBeginFrameTask =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorSchedulerState>;
+
+  static constexpr FieldMetadata_PendingBeginFrameTask kPendingBeginFrameTask{};
+  void set_pending_begin_frame_task(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_PendingBeginFrameTask::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_SkippedLastFrameMissedExceededDeadline =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorSchedulerState>;
+
+  static constexpr FieldMetadata_SkippedLastFrameMissedExceededDeadline kSkippedLastFrameMissedExceededDeadline{};
+  void set_skipped_last_frame_missed_exceeded_deadline(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_SkippedLastFrameMissedExceededDeadline::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_InsideAction =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ChromeCompositorSchedulerAction,
+      ChromeCompositorSchedulerState>;
+
+  static constexpr FieldMetadata_InsideAction kInsideAction{};
+  void set_inside_action(ChromeCompositorSchedulerAction value) {
+    static constexpr uint32_t field_id = FieldMetadata_InsideAction::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_DeadlineMode =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode,
+      ChromeCompositorSchedulerState>;
+
+  static constexpr FieldMetadata_DeadlineMode kDeadlineMode{};
+  void set_deadline_mode(ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode value) {
+    static constexpr uint32_t field_id = FieldMetadata_DeadlineMode::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_DeadlineUs =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ChromeCompositorSchedulerState>;
+
+  static constexpr FieldMetadata_DeadlineUs kDeadlineUs{};
+  void set_deadline_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DeadlineUs::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_DeadlineScheduledAtUs =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ChromeCompositorSchedulerState>;
+
+  static constexpr FieldMetadata_DeadlineScheduledAtUs kDeadlineScheduledAtUs{};
+  void set_deadline_scheduled_at_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DeadlineScheduledAtUs::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_NowUs =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ChromeCompositorSchedulerState>;
+
+  static constexpr FieldMetadata_NowUs kNowUs{};
+  void set_now_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NowUs::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_NowToDeadlineDeltaUs =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ChromeCompositorSchedulerState>;
+
+  static constexpr FieldMetadata_NowToDeadlineDeltaUs kNowToDeadlineDeltaUs{};
+  void set_now_to_deadline_delta_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NowToDeadlineDeltaUs::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_NowToDeadlineScheduledAtDeltaUs =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ChromeCompositorSchedulerState>;
+
+  static constexpr FieldMetadata_NowToDeadlineScheduledAtDeltaUs kNowToDeadlineScheduledAtDeltaUs{};
+  void set_now_to_deadline_scheduled_at_delta_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NowToDeadlineScheduledAtDeltaUs::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_BeginImplFrameArgs =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BeginImplFrameArgs,
+      ChromeCompositorSchedulerState>;
+
+  static constexpr FieldMetadata_BeginImplFrameArgs kBeginImplFrameArgs{};
+  template <typename T = BeginImplFrameArgs> T* set_begin_impl_frame_args() {
+    return BeginNestedMessage<T>(14);
+  }
+
+
+  using FieldMetadata_BeginFrameObserverState =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BeginFrameObserverState,
+      ChromeCompositorSchedulerState>;
+
+  static constexpr FieldMetadata_BeginFrameObserverState kBeginFrameObserverState{};
+  template <typename T = BeginFrameObserverState> T* set_begin_frame_observer_state() {
+    return BeginNestedMessage<T>(15);
+  }
+
+
+  using FieldMetadata_BeginFrameSourceState =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BeginFrameSourceState,
+      ChromeCompositorSchedulerState>;
+
+  static constexpr FieldMetadata_BeginFrameSourceState kBeginFrameSourceState{};
+  template <typename T = BeginFrameSourceState> T* set_begin_frame_source_state() {
+    return BeginNestedMessage<T>(16);
+  }
+
+
+  using FieldMetadata_CompositorTimingHistory =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CompositorTimingHistory,
+      ChromeCompositorSchedulerState>;
+
+  static constexpr FieldMetadata_CompositorTimingHistory kCompositorTimingHistory{};
+  template <typename T = CompositorTimingHistory> T* set_compositor_timing_history() {
+    return BeginNestedMessage<T>(17);
+  }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_content_settings_event_info.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_CONTENT_SETTINGS_EVENT_INFO_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_CONTENT_SETTINGS_EVENT_INFO_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class ChromeContentSettingsEventInfo_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeContentSettingsEventInfo_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeContentSettingsEventInfo_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeContentSettingsEventInfo_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_number_of_exceptions() const { return at<1>().valid(); }
+  uint32_t number_of_exceptions() const { return at<1>().as_uint32(); }
+};
+
+class ChromeContentSettingsEventInfo : public ::protozero::Message {
+ public:
+  using Decoder = ChromeContentSettingsEventInfo_Decoder;
+  enum : int32_t {
+    kNumberOfExceptionsFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeContentSettingsEventInfo"; }
+
+
+  using FieldMetadata_NumberOfExceptions =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ChromeContentSettingsEventInfo>;
+
+  static constexpr FieldMetadata_NumberOfExceptions kNumberOfExceptions{};
+  void set_number_of_exceptions(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NumberOfExceptions::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_frame_reporter.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_FRAME_REPORTER_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_FRAME_REPORTER_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+namespace perfetto_pbzero_enum_ChromeFrameReporter {
+enum FrameDropReason : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeFrameReporter
+using ChromeFrameReporter_FrameDropReason = perfetto_pbzero_enum_ChromeFrameReporter::FrameDropReason;
+namespace perfetto_pbzero_enum_ChromeFrameReporter {
+enum FrameType : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeFrameReporter
+using ChromeFrameReporter_FrameType = perfetto_pbzero_enum_ChromeFrameReporter::FrameType;
+namespace perfetto_pbzero_enum_ChromeFrameReporter {
+enum ScrollState : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeFrameReporter
+using ChromeFrameReporter_ScrollState = perfetto_pbzero_enum_ChromeFrameReporter::ScrollState;
+namespace perfetto_pbzero_enum_ChromeFrameReporter {
+enum State : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeFrameReporter
+using ChromeFrameReporter_State = perfetto_pbzero_enum_ChromeFrameReporter::State;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_ChromeFrameReporter {
+enum State : int32_t {
+  STATE_NO_UPDATE_DESIRED = 0,
+  STATE_PRESENTED_ALL = 1,
+  STATE_PRESENTED_PARTIAL = 2,
+  STATE_DROPPED = 3,
+};
+} // namespace perfetto_pbzero_enum_ChromeFrameReporter
+using ChromeFrameReporter_State = perfetto_pbzero_enum_ChromeFrameReporter::State;
+
+
+constexpr ChromeFrameReporter_State ChromeFrameReporter_State_MIN = ChromeFrameReporter_State::STATE_NO_UPDATE_DESIRED;
+constexpr ChromeFrameReporter_State ChromeFrameReporter_State_MAX = ChromeFrameReporter_State::STATE_DROPPED;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeFrameReporter_State_Name(::perfetto::protos::pbzero::ChromeFrameReporter_State value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeFrameReporter_State::STATE_NO_UPDATE_DESIRED:
+    return "STATE_NO_UPDATE_DESIRED";
+
+  case ::perfetto::protos::pbzero::ChromeFrameReporter_State::STATE_PRESENTED_ALL:
+    return "STATE_PRESENTED_ALL";
+
+  case ::perfetto::protos::pbzero::ChromeFrameReporter_State::STATE_PRESENTED_PARTIAL:
+    return "STATE_PRESENTED_PARTIAL";
+
+  case ::perfetto::protos::pbzero::ChromeFrameReporter_State::STATE_DROPPED:
+    return "STATE_DROPPED";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_ChromeFrameReporter {
+enum FrameDropReason : int32_t {
+  REASON_UNSPECIFIED = 0,
+  REASON_DISPLAY_COMPOSITOR = 1,
+  REASON_MAIN_THREAD = 2,
+  REASON_CLIENT_COMPOSITOR = 3,
+};
+} // namespace perfetto_pbzero_enum_ChromeFrameReporter
+using ChromeFrameReporter_FrameDropReason = perfetto_pbzero_enum_ChromeFrameReporter::FrameDropReason;
+
+
+constexpr ChromeFrameReporter_FrameDropReason ChromeFrameReporter_FrameDropReason_MIN = ChromeFrameReporter_FrameDropReason::REASON_UNSPECIFIED;
+constexpr ChromeFrameReporter_FrameDropReason ChromeFrameReporter_FrameDropReason_MAX = ChromeFrameReporter_FrameDropReason::REASON_CLIENT_COMPOSITOR;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeFrameReporter_FrameDropReason_Name(::perfetto::protos::pbzero::ChromeFrameReporter_FrameDropReason value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeFrameReporter_FrameDropReason::REASON_UNSPECIFIED:
+    return "REASON_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ChromeFrameReporter_FrameDropReason::REASON_DISPLAY_COMPOSITOR:
+    return "REASON_DISPLAY_COMPOSITOR";
+
+  case ::perfetto::protos::pbzero::ChromeFrameReporter_FrameDropReason::REASON_MAIN_THREAD:
+    return "REASON_MAIN_THREAD";
+
+  case ::perfetto::protos::pbzero::ChromeFrameReporter_FrameDropReason::REASON_CLIENT_COMPOSITOR:
+    return "REASON_CLIENT_COMPOSITOR";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_ChromeFrameReporter {
+enum ScrollState : int32_t {
+  SCROLL_NONE = 0,
+  SCROLL_MAIN_THREAD = 1,
+  SCROLL_COMPOSITOR_THREAD = 2,
+  SCROLL_UNKNOWN = 3,
+};
+} // namespace perfetto_pbzero_enum_ChromeFrameReporter
+using ChromeFrameReporter_ScrollState = perfetto_pbzero_enum_ChromeFrameReporter::ScrollState;
+
+
+constexpr ChromeFrameReporter_ScrollState ChromeFrameReporter_ScrollState_MIN = ChromeFrameReporter_ScrollState::SCROLL_NONE;
+constexpr ChromeFrameReporter_ScrollState ChromeFrameReporter_ScrollState_MAX = ChromeFrameReporter_ScrollState::SCROLL_UNKNOWN;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeFrameReporter_ScrollState_Name(::perfetto::protos::pbzero::ChromeFrameReporter_ScrollState value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeFrameReporter_ScrollState::SCROLL_NONE:
+    return "SCROLL_NONE";
+
+  case ::perfetto::protos::pbzero::ChromeFrameReporter_ScrollState::SCROLL_MAIN_THREAD:
+    return "SCROLL_MAIN_THREAD";
+
+  case ::perfetto::protos::pbzero::ChromeFrameReporter_ScrollState::SCROLL_COMPOSITOR_THREAD:
+    return "SCROLL_COMPOSITOR_THREAD";
+
+  case ::perfetto::protos::pbzero::ChromeFrameReporter_ScrollState::SCROLL_UNKNOWN:
+    return "SCROLL_UNKNOWN";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_ChromeFrameReporter {
+enum FrameType : int32_t {
+  FORKED = 0,
+  BACKFILL = 1,
+};
+} // namespace perfetto_pbzero_enum_ChromeFrameReporter
+using ChromeFrameReporter_FrameType = perfetto_pbzero_enum_ChromeFrameReporter::FrameType;
+
+
+constexpr ChromeFrameReporter_FrameType ChromeFrameReporter_FrameType_MIN = ChromeFrameReporter_FrameType::FORKED;
+constexpr ChromeFrameReporter_FrameType ChromeFrameReporter_FrameType_MAX = ChromeFrameReporter_FrameType::BACKFILL;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeFrameReporter_FrameType_Name(::perfetto::protos::pbzero::ChromeFrameReporter_FrameType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeFrameReporter_FrameType::FORKED:
+    return "FORKED";
+
+  case ::perfetto::protos::pbzero::ChromeFrameReporter_FrameType::BACKFILL:
+    return "BACKFILL";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class ChromeFrameReporter_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/14, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ChromeFrameReporter_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeFrameReporter_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeFrameReporter_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_state() const { return at<1>().valid(); }
+  int32_t state() const { return at<1>().as_int32(); }
+  bool has_reason() const { return at<2>().valid(); }
+  int32_t reason() const { return at<2>().as_int32(); }
+  bool has_frame_source() const { return at<3>().valid(); }
+  uint64_t frame_source() const { return at<3>().as_uint64(); }
+  bool has_frame_sequence() const { return at<4>().valid(); }
+  uint64_t frame_sequence() const { return at<4>().as_uint64(); }
+  bool has_affects_smoothness() const { return at<5>().valid(); }
+  bool affects_smoothness() const { return at<5>().as_bool(); }
+  bool has_scroll_state() const { return at<6>().valid(); }
+  int32_t scroll_state() const { return at<6>().as_int32(); }
+  bool has_has_main_animation() const { return at<7>().valid(); }
+  bool has_main_animation() const { return at<7>().as_bool(); }
+  bool has_has_compositor_animation() const { return at<8>().valid(); }
+  bool has_compositor_animation() const { return at<8>().as_bool(); }
+  bool has_has_smooth_input_main() const { return at<9>().valid(); }
+  bool has_smooth_input_main() const { return at<9>().as_bool(); }
+  bool has_has_missing_content() const { return at<10>().valid(); }
+  bool has_missing_content() const { return at<10>().as_bool(); }
+  bool has_layer_tree_host_id() const { return at<11>().valid(); }
+  uint64_t layer_tree_host_id() const { return at<11>().as_uint64(); }
+  bool has_has_high_latency() const { return at<12>().valid(); }
+  bool has_high_latency() const { return at<12>().as_bool(); }
+  bool has_frame_type() const { return at<13>().valid(); }
+  int32_t frame_type() const { return at<13>().as_int32(); }
+  bool has_high_latency_contribution_stage() const { return at<14>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> high_latency_contribution_stage() const { return GetRepeated<::protozero::ConstChars>(14); }
+};
+
+class ChromeFrameReporter : public ::protozero::Message {
+ public:
+  using Decoder = ChromeFrameReporter_Decoder;
+  enum : int32_t {
+    kStateFieldNumber = 1,
+    kReasonFieldNumber = 2,
+    kFrameSourceFieldNumber = 3,
+    kFrameSequenceFieldNumber = 4,
+    kAffectsSmoothnessFieldNumber = 5,
+    kScrollStateFieldNumber = 6,
+    kHasMainAnimationFieldNumber = 7,
+    kHasCompositorAnimationFieldNumber = 8,
+    kHasSmoothInputMainFieldNumber = 9,
+    kHasMissingContentFieldNumber = 10,
+    kLayerTreeHostIdFieldNumber = 11,
+    kHasHighLatencyFieldNumber = 12,
+    kFrameTypeFieldNumber = 13,
+    kHighLatencyContributionStageFieldNumber = 14,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeFrameReporter"; }
+
+
+  using State = ::perfetto::protos::pbzero::ChromeFrameReporter_State;
+  static inline const char* State_Name(State value) {
+    return ::perfetto::protos::pbzero::ChromeFrameReporter_State_Name(value);
+  }
+
+  using FrameDropReason = ::perfetto::protos::pbzero::ChromeFrameReporter_FrameDropReason;
+  static inline const char* FrameDropReason_Name(FrameDropReason value) {
+    return ::perfetto::protos::pbzero::ChromeFrameReporter_FrameDropReason_Name(value);
+  }
+
+  using ScrollState = ::perfetto::protos::pbzero::ChromeFrameReporter_ScrollState;
+  static inline const char* ScrollState_Name(ScrollState value) {
+    return ::perfetto::protos::pbzero::ChromeFrameReporter_ScrollState_Name(value);
+  }
+
+  using FrameType = ::perfetto::protos::pbzero::ChromeFrameReporter_FrameType;
+  static inline const char* FrameType_Name(FrameType value) {
+    return ::perfetto::protos::pbzero::ChromeFrameReporter_FrameType_Name(value);
+  }
+  static inline const State STATE_NO_UPDATE_DESIRED = State::STATE_NO_UPDATE_DESIRED;
+  static inline const State STATE_PRESENTED_ALL = State::STATE_PRESENTED_ALL;
+  static inline const State STATE_PRESENTED_PARTIAL = State::STATE_PRESENTED_PARTIAL;
+  static inline const State STATE_DROPPED = State::STATE_DROPPED;
+  static inline const FrameDropReason REASON_UNSPECIFIED = FrameDropReason::REASON_UNSPECIFIED;
+  static inline const FrameDropReason REASON_DISPLAY_COMPOSITOR = FrameDropReason::REASON_DISPLAY_COMPOSITOR;
+  static inline const FrameDropReason REASON_MAIN_THREAD = FrameDropReason::REASON_MAIN_THREAD;
+  static inline const FrameDropReason REASON_CLIENT_COMPOSITOR = FrameDropReason::REASON_CLIENT_COMPOSITOR;
+  static inline const ScrollState SCROLL_NONE = ScrollState::SCROLL_NONE;
+  static inline const ScrollState SCROLL_MAIN_THREAD = ScrollState::SCROLL_MAIN_THREAD;
+  static inline const ScrollState SCROLL_COMPOSITOR_THREAD = ScrollState::SCROLL_COMPOSITOR_THREAD;
+  static inline const ScrollState SCROLL_UNKNOWN = ScrollState::SCROLL_UNKNOWN;
+  static inline const FrameType FORKED = FrameType::FORKED;
+  static inline const FrameType BACKFILL = FrameType::BACKFILL;
+
+  using FieldMetadata_State =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ChromeFrameReporter_State,
+      ChromeFrameReporter>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(ChromeFrameReporter_State value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::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_Reason =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ChromeFrameReporter_FrameDropReason,
+      ChromeFrameReporter>;
+
+  static constexpr FieldMetadata_Reason kReason{};
+  void set_reason(ChromeFrameReporter_FrameDropReason value) {
+    static constexpr uint32_t field_id = FieldMetadata_Reason::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_FrameSource =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ChromeFrameReporter>;
+
+  static constexpr FieldMetadata_FrameSource kFrameSource{};
+  void set_frame_source(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FrameSource::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_FrameSequence =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ChromeFrameReporter>;
+
+  static constexpr FieldMetadata_FrameSequence kFrameSequence{};
+  void set_frame_sequence(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FrameSequence::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_AffectsSmoothness =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeFrameReporter>;
+
+  static constexpr FieldMetadata_AffectsSmoothness kAffectsSmoothness{};
+  void set_affects_smoothness(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_AffectsSmoothness::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_ScrollState =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ChromeFrameReporter_ScrollState,
+      ChromeFrameReporter>;
+
+  static constexpr FieldMetadata_ScrollState kScrollState{};
+  void set_scroll_state(ChromeFrameReporter_ScrollState value) {
+    static constexpr uint32_t field_id = FieldMetadata_ScrollState::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_HasMainAnimation =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeFrameReporter>;
+
+  static constexpr FieldMetadata_HasMainAnimation kHasMainAnimation{};
+  void set_has_main_animation(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_HasMainAnimation::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_HasCompositorAnimation =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeFrameReporter>;
+
+  static constexpr FieldMetadata_HasCompositorAnimation kHasCompositorAnimation{};
+  void set_has_compositor_animation(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_HasCompositorAnimation::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_HasSmoothInputMain =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeFrameReporter>;
+
+  static constexpr FieldMetadata_HasSmoothInputMain kHasSmoothInputMain{};
+  void set_has_smooth_input_main(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_HasSmoothInputMain::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_HasMissingContent =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeFrameReporter>;
+
+  static constexpr FieldMetadata_HasMissingContent kHasMissingContent{};
+  void set_has_missing_content(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_HasMissingContent::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_LayerTreeHostId =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ChromeFrameReporter>;
+
+  static constexpr FieldMetadata_LayerTreeHostId kLayerTreeHostId{};
+  void set_layer_tree_host_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LayerTreeHostId::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_HasHighLatency =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeFrameReporter>;
+
+  static constexpr FieldMetadata_HasHighLatency kHasHighLatency{};
+  void set_has_high_latency(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_HasHighLatency::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_FrameType =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ChromeFrameReporter_FrameType,
+      ChromeFrameReporter>;
+
+  static constexpr FieldMetadata_FrameType kFrameType{};
+  void set_frame_type(ChromeFrameReporter_FrameType value) {
+    static constexpr uint32_t field_id = FieldMetadata_FrameType::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_HighLatencyContributionStage =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeFrameReporter>;
+
+  static constexpr FieldMetadata_HighLatencyContributionStage kHighLatencyContributionStage{};
+  void add_high_latency_contribution_stage(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HighLatencyContributionStage::kFieldId, data, size);
+  }
+  void add_high_latency_contribution_stage(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_HighLatencyContributionStage::kFieldId, chars.data, chars.size);
+  }
+  void add_high_latency_contribution_stage(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_HighLatencyContributionStage::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_histogram_sample.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_HISTOGRAM_SAMPLE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_HISTOGRAM_SAMPLE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class ChromeHistogramSample_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeHistogramSample_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeHistogramSample_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeHistogramSample_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name_hash() const { return at<1>().valid(); }
+  uint64_t name_hash() const { return at<1>().as_uint64(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+  bool has_sample() const { return at<3>().valid(); }
+  int64_t sample() const { return at<3>().as_int64(); }
+  bool has_name_iid() const { return at<4>().valid(); }
+  uint64_t name_iid() const { return at<4>().as_uint64(); }
+};
+
+class ChromeHistogramSample : public ::protozero::Message {
+ public:
+  using Decoder = ChromeHistogramSample_Decoder;
+  enum : int32_t {
+    kNameHashFieldNumber = 1,
+    kNameFieldNumber = 2,
+    kSampleFieldNumber = 3,
+    kNameIidFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeHistogramSample"; }
+
+
+  using FieldMetadata_NameHash =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ChromeHistogramSample>;
+
+  static constexpr FieldMetadata_NameHash kNameHash{};
+  void set_name_hash(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NameHash::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeHistogramSample>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Sample =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ChromeHistogramSample>;
+
+  static constexpr FieldMetadata_Sample kSample{};
+  void set_sample(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sample::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_NameIid =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ChromeHistogramSample>;
+
+  static constexpr FieldMetadata_NameIid kNameIid{};
+  void set_name_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NameIid::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 HistogramName_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  HistogramName_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit HistogramName_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit HistogramName_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+};
+
+class HistogramName : public ::protozero::Message {
+ public:
+  using Decoder = HistogramName_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kNameFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.HistogramName"; }
+
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HistogramName>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      HistogramName>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_keyed_service.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_KEYED_SERVICE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_KEYED_SERVICE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class ChromeKeyedService_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeKeyedService_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeKeyedService_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeKeyedService_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(); }
+};
+
+class ChromeKeyedService : public ::protozero::Message {
+ public:
+  using Decoder = ChromeKeyedService_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeKeyedService"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeKeyedService>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_latency_info.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LATENCY_INFO_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LATENCY_INFO_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class ChromeLatencyInfo_ComponentInfo;
+namespace perfetto_pbzero_enum_ChromeLatencyInfo {
+enum LatencyComponentType : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeLatencyInfo
+using ChromeLatencyInfo_LatencyComponentType = perfetto_pbzero_enum_ChromeLatencyInfo::LatencyComponentType;
+namespace perfetto_pbzero_enum_ChromeLatencyInfo {
+enum Step : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeLatencyInfo
+using ChromeLatencyInfo_Step = perfetto_pbzero_enum_ChromeLatencyInfo::Step;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_ChromeLatencyInfo {
+enum Step : int32_t {
+  STEP_UNSPECIFIED = 0,
+  STEP_SEND_INPUT_EVENT_UI = 3,
+  STEP_HANDLE_INPUT_EVENT_IMPL = 5,
+  STEP_DID_HANDLE_INPUT_AND_OVERSCROLL = 8,
+  STEP_HANDLE_INPUT_EVENT_MAIN = 4,
+  STEP_MAIN_THREAD_SCROLL_UPDATE = 2,
+  STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT = 1,
+  STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL = 9,
+  STEP_HANDLED_INPUT_EVENT_IMPL = 10,
+  STEP_SWAP_BUFFERS = 6,
+  STEP_DRAW_AND_SWAP = 7,
+  STEP_FINISHED_SWAP_BUFFERS = 11,
+};
+} // namespace perfetto_pbzero_enum_ChromeLatencyInfo
+using ChromeLatencyInfo_Step = perfetto_pbzero_enum_ChromeLatencyInfo::Step;
+
+
+constexpr ChromeLatencyInfo_Step ChromeLatencyInfo_Step_MIN = ChromeLatencyInfo_Step::STEP_UNSPECIFIED;
+constexpr ChromeLatencyInfo_Step ChromeLatencyInfo_Step_MAX = ChromeLatencyInfo_Step::STEP_FINISHED_SWAP_BUFFERS;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeLatencyInfo_Step_Name(::perfetto::protos::pbzero::ChromeLatencyInfo_Step value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_Step::STEP_UNSPECIFIED:
+    return "STEP_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_Step::STEP_SEND_INPUT_EVENT_UI:
+    return "STEP_SEND_INPUT_EVENT_UI";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_Step::STEP_HANDLE_INPUT_EVENT_IMPL:
+    return "STEP_HANDLE_INPUT_EVENT_IMPL";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_Step::STEP_DID_HANDLE_INPUT_AND_OVERSCROLL:
+    return "STEP_DID_HANDLE_INPUT_AND_OVERSCROLL";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_Step::STEP_HANDLE_INPUT_EVENT_MAIN:
+    return "STEP_HANDLE_INPUT_EVENT_MAIN";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_Step::STEP_MAIN_THREAD_SCROLL_UPDATE:
+    return "STEP_MAIN_THREAD_SCROLL_UPDATE";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_Step::STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT:
+    return "STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_Step::STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL:
+    return "STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_Step::STEP_HANDLED_INPUT_EVENT_IMPL:
+    return "STEP_HANDLED_INPUT_EVENT_IMPL";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_Step::STEP_SWAP_BUFFERS:
+    return "STEP_SWAP_BUFFERS";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_Step::STEP_DRAW_AND_SWAP:
+    return "STEP_DRAW_AND_SWAP";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_Step::STEP_FINISHED_SWAP_BUFFERS:
+    return "STEP_FINISHED_SWAP_BUFFERS";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_ChromeLatencyInfo {
+enum LatencyComponentType : int32_t {
+  COMPONENT_UNSPECIFIED = 0,
+  COMPONENT_INPUT_EVENT_LATENCY_BEGIN_RWH = 1,
+  COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL = 2,
+  COMPONENT_INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL = 3,
+  COMPONENT_INPUT_EVENT_LATENCY_ORIGINAL = 4,
+  COMPONENT_INPUT_EVENT_LATENCY_UI = 5,
+  COMPONENT_INPUT_EVENT_LATENCY_RENDERER_MAIN = 6,
+  COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN = 7,
+  COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL = 8,
+  COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_LAST_EVENT = 9,
+  COMPONENT_INPUT_EVENT_LATENCY_ACK_RWH = 10,
+  COMPONENT_INPUT_EVENT_LATENCY_RENDERER_SWAP = 11,
+  COMPONENT_DISPLAY_COMPOSITOR_RECEIVED_FRAME = 12,
+  COMPONENT_INPUT_EVENT_GPU_SWAP_BUFFER = 13,
+  COMPONENT_INPUT_EVENT_LATENCY_FRAME_SWAP = 14,
+};
+} // namespace perfetto_pbzero_enum_ChromeLatencyInfo
+using ChromeLatencyInfo_LatencyComponentType = perfetto_pbzero_enum_ChromeLatencyInfo::LatencyComponentType;
+
+
+constexpr ChromeLatencyInfo_LatencyComponentType ChromeLatencyInfo_LatencyComponentType_MIN = ChromeLatencyInfo_LatencyComponentType::COMPONENT_UNSPECIFIED;
+constexpr ChromeLatencyInfo_LatencyComponentType ChromeLatencyInfo_LatencyComponentType_MAX = ChromeLatencyInfo_LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_FRAME_SWAP;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeLatencyInfo_LatencyComponentType_Name(::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType::COMPONENT_UNSPECIFIED:
+    return "COMPONENT_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_BEGIN_RWH:
+    return "COMPONENT_INPUT_EVENT_LATENCY_BEGIN_RWH";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL:
+    return "COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL:
+    return "COMPONENT_INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_ORIGINAL:
+    return "COMPONENT_INPUT_EVENT_LATENCY_ORIGINAL";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_UI:
+    return "COMPONENT_INPUT_EVENT_LATENCY_UI";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_RENDERER_MAIN:
+    return "COMPONENT_INPUT_EVENT_LATENCY_RENDERER_MAIN";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN:
+    return "COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL:
+    return "COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_LAST_EVENT:
+    return "COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_LAST_EVENT";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_ACK_RWH:
+    return "COMPONENT_INPUT_EVENT_LATENCY_ACK_RWH";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_RENDERER_SWAP:
+    return "COMPONENT_INPUT_EVENT_LATENCY_RENDERER_SWAP";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType::COMPONENT_DISPLAY_COMPOSITOR_RECEIVED_FRAME:
+    return "COMPONENT_DISPLAY_COMPOSITOR_RECEIVED_FRAME";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType::COMPONENT_INPUT_EVENT_GPU_SWAP_BUFFER:
+    return "COMPONENT_INPUT_EVENT_GPU_SWAP_BUFFER";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_FRAME_SWAP:
+    return "COMPONENT_INPUT_EVENT_LATENCY_FRAME_SWAP";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class ChromeLatencyInfo_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ChromeLatencyInfo_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeLatencyInfo_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeLatencyInfo_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_trace_id() const { return at<1>().valid(); }
+  int64_t trace_id() const { return at<1>().as_int64(); }
+  bool has_step() const { return at<2>().valid(); }
+  int32_t step() const { return at<2>().as_int32(); }
+  bool has_frame_tree_node_id() const { return at<3>().valid(); }
+  int32_t frame_tree_node_id() const { return at<3>().as_int32(); }
+  bool has_component_info() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> component_info() const { return GetRepeated<::protozero::ConstBytes>(4); }
+  bool has_is_coalesced() const { return at<5>().valid(); }
+  bool is_coalesced() const { return at<5>().as_bool(); }
+  bool has_gesture_scroll_id() const { return at<6>().valid(); }
+  int64_t gesture_scroll_id() const { return at<6>().as_int64(); }
+  bool has_touch_id() const { return at<7>().valid(); }
+  int64_t touch_id() const { return at<7>().as_int64(); }
+};
+
+class ChromeLatencyInfo : public ::protozero::Message {
+ public:
+  using Decoder = ChromeLatencyInfo_Decoder;
+  enum : int32_t {
+    kTraceIdFieldNumber = 1,
+    kStepFieldNumber = 2,
+    kFrameTreeNodeIdFieldNumber = 3,
+    kComponentInfoFieldNumber = 4,
+    kIsCoalescedFieldNumber = 5,
+    kGestureScrollIdFieldNumber = 6,
+    kTouchIdFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeLatencyInfo"; }
+
+  using ComponentInfo = ::perfetto::protos::pbzero::ChromeLatencyInfo_ComponentInfo;
+
+  using Step = ::perfetto::protos::pbzero::ChromeLatencyInfo_Step;
+  static inline const char* Step_Name(Step value) {
+    return ::perfetto::protos::pbzero::ChromeLatencyInfo_Step_Name(value);
+  }
+
+  using LatencyComponentType = ::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType;
+  static inline const char* LatencyComponentType_Name(LatencyComponentType value) {
+    return ::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType_Name(value);
+  }
+  static inline const Step STEP_UNSPECIFIED = Step::STEP_UNSPECIFIED;
+  static inline const Step STEP_SEND_INPUT_EVENT_UI = Step::STEP_SEND_INPUT_EVENT_UI;
+  static inline const Step STEP_HANDLE_INPUT_EVENT_IMPL = Step::STEP_HANDLE_INPUT_EVENT_IMPL;
+  static inline const Step STEP_DID_HANDLE_INPUT_AND_OVERSCROLL = Step::STEP_DID_HANDLE_INPUT_AND_OVERSCROLL;
+  static inline const Step STEP_HANDLE_INPUT_EVENT_MAIN = Step::STEP_HANDLE_INPUT_EVENT_MAIN;
+  static inline const Step STEP_MAIN_THREAD_SCROLL_UPDATE = Step::STEP_MAIN_THREAD_SCROLL_UPDATE;
+  static inline const Step STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT = Step::STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT;
+  static inline const Step STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL = Step::STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL;
+  static inline const Step STEP_HANDLED_INPUT_EVENT_IMPL = Step::STEP_HANDLED_INPUT_EVENT_IMPL;
+  static inline const Step STEP_SWAP_BUFFERS = Step::STEP_SWAP_BUFFERS;
+  static inline const Step STEP_DRAW_AND_SWAP = Step::STEP_DRAW_AND_SWAP;
+  static inline const Step STEP_FINISHED_SWAP_BUFFERS = Step::STEP_FINISHED_SWAP_BUFFERS;
+  static inline const LatencyComponentType COMPONENT_UNSPECIFIED = LatencyComponentType::COMPONENT_UNSPECIFIED;
+  static inline const LatencyComponentType COMPONENT_INPUT_EVENT_LATENCY_BEGIN_RWH = LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_BEGIN_RWH;
+  static inline const LatencyComponentType COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL = LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL;
+  static inline const LatencyComponentType COMPONENT_INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL = LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL;
+  static inline const LatencyComponentType COMPONENT_INPUT_EVENT_LATENCY_ORIGINAL = LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_ORIGINAL;
+  static inline const LatencyComponentType COMPONENT_INPUT_EVENT_LATENCY_UI = LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_UI;
+  static inline const LatencyComponentType COMPONENT_INPUT_EVENT_LATENCY_RENDERER_MAIN = LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_RENDERER_MAIN;
+  static inline const LatencyComponentType COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN = LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN;
+  static inline const LatencyComponentType COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL = LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL;
+  static inline const LatencyComponentType COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_LAST_EVENT = LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_LAST_EVENT;
+  static inline const LatencyComponentType COMPONENT_INPUT_EVENT_LATENCY_ACK_RWH = LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_ACK_RWH;
+  static inline const LatencyComponentType COMPONENT_INPUT_EVENT_LATENCY_RENDERER_SWAP = LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_RENDERER_SWAP;
+  static inline const LatencyComponentType COMPONENT_DISPLAY_COMPOSITOR_RECEIVED_FRAME = LatencyComponentType::COMPONENT_DISPLAY_COMPOSITOR_RECEIVED_FRAME;
+  static inline const LatencyComponentType COMPONENT_INPUT_EVENT_GPU_SWAP_BUFFER = LatencyComponentType::COMPONENT_INPUT_EVENT_GPU_SWAP_BUFFER;
+  static inline const LatencyComponentType COMPONENT_INPUT_EVENT_LATENCY_FRAME_SWAP = LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_FRAME_SWAP;
+
+  using FieldMetadata_TraceId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ChromeLatencyInfo>;
+
+  static constexpr FieldMetadata_TraceId kTraceId{};
+  void set_trace_id(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TraceId::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_Step =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ChromeLatencyInfo_Step,
+      ChromeLatencyInfo>;
+
+  static constexpr FieldMetadata_Step kStep{};
+  void set_step(ChromeLatencyInfo_Step value) {
+    static constexpr uint32_t field_id = FieldMetadata_Step::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_FrameTreeNodeId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeLatencyInfo>;
+
+  static constexpr FieldMetadata_FrameTreeNodeId kFrameTreeNodeId{};
+  void set_frame_tree_node_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FrameTreeNodeId::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_ComponentInfo =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeLatencyInfo_ComponentInfo,
+      ChromeLatencyInfo>;
+
+  static constexpr FieldMetadata_ComponentInfo kComponentInfo{};
+  template <typename T = ChromeLatencyInfo_ComponentInfo> T* add_component_info() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_IsCoalesced =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeLatencyInfo>;
+
+  static constexpr FieldMetadata_IsCoalesced kIsCoalesced{};
+  void set_is_coalesced(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsCoalesced::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_GestureScrollId =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ChromeLatencyInfo>;
+
+  static constexpr FieldMetadata_GestureScrollId kGestureScrollId{};
+  void set_gesture_scroll_id(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GestureScrollId::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_TouchId =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ChromeLatencyInfo>;
+
+  static constexpr FieldMetadata_TouchId kTouchId{};
+  void set_touch_id(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TouchId::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 ChromeLatencyInfo_ComponentInfo_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeLatencyInfo_ComponentInfo_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeLatencyInfo_ComponentInfo_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeLatencyInfo_ComponentInfo_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_component_type() const { return at<1>().valid(); }
+  int32_t component_type() const { return at<1>().as_int32(); }
+  bool has_time_us() const { return at<2>().valid(); }
+  uint64_t time_us() const { return at<2>().as_uint64(); }
+};
+
+class ChromeLatencyInfo_ComponentInfo : public ::protozero::Message {
+ public:
+  using Decoder = ChromeLatencyInfo_ComponentInfo_Decoder;
+  enum : int32_t {
+    kComponentTypeFieldNumber = 1,
+    kTimeUsFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeLatencyInfo.ComponentInfo"; }
+
+
+  using FieldMetadata_ComponentType =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ChromeLatencyInfo_LatencyComponentType,
+      ChromeLatencyInfo_ComponentInfo>;
+
+  static constexpr FieldMetadata_ComponentType kComponentType{};
+  void set_component_type(ChromeLatencyInfo_LatencyComponentType value) {
+    static constexpr uint32_t field_id = FieldMetadata_ComponentType::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_TimeUs =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ChromeLatencyInfo_ComponentInfo>;
+
+  static constexpr FieldMetadata_TimeUs kTimeUs{};
+  void set_time_us(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimeUs::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_legacy_ipc.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LEGACY_IPC_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LEGACY_IPC_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+namespace perfetto_pbzero_enum_ChromeLegacyIpc {
+enum MessageClass : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeLegacyIpc
+using ChromeLegacyIpc_MessageClass = perfetto_pbzero_enum_ChromeLegacyIpc::MessageClass;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_ChromeLegacyIpc {
+enum MessageClass : int32_t {
+  CLASS_UNSPECIFIED = 0,
+  CLASS_AUTOMATION = 1,
+  CLASS_FRAME = 2,
+  CLASS_PAGE = 3,
+  CLASS_VIEW = 4,
+  CLASS_WIDGET = 5,
+  CLASS_INPUT = 6,
+  CLASS_TEST = 7,
+  CLASS_WORKER = 8,
+  CLASS_NACL = 9,
+  CLASS_GPU_CHANNEL = 10,
+  CLASS_MEDIA = 11,
+  CLASS_PPAPI = 12,
+  CLASS_CHROME = 13,
+  CLASS_DRAG = 14,
+  CLASS_PRINT = 15,
+  CLASS_EXTENSION = 16,
+  CLASS_TEXT_INPUT_CLIENT = 17,
+  CLASS_BLINK_TEST = 18,
+  CLASS_ACCESSIBILITY = 19,
+  CLASS_PRERENDER = 20,
+  CLASS_CHROMOTING = 21,
+  CLASS_BROWSER_PLUGIN = 22,
+  CLASS_ANDROID_WEB_VIEW = 23,
+  CLASS_NACL_HOST = 24,
+  CLASS_ENCRYPTED_MEDIA = 25,
+  CLASS_CAST = 26,
+  CLASS_GIN_JAVA_BRIDGE = 27,
+  CLASS_CHROME_UTILITY_PRINTING = 28,
+  CLASS_OZONE_GPU = 29,
+  CLASS_WEB_TEST = 30,
+  CLASS_NETWORK_HINTS = 31,
+  CLASS_EXTENSIONS_GUEST_VIEW = 32,
+  CLASS_GUEST_VIEW = 33,
+  CLASS_MEDIA_PLAYER_DELEGATE = 34,
+  CLASS_EXTENSION_WORKER = 35,
+  CLASS_SUBRESOURCE_FILTER = 36,
+  CLASS_UNFREEZABLE_FRAME = 37,
+};
+} // namespace perfetto_pbzero_enum_ChromeLegacyIpc
+using ChromeLegacyIpc_MessageClass = perfetto_pbzero_enum_ChromeLegacyIpc::MessageClass;
+
+
+constexpr ChromeLegacyIpc_MessageClass ChromeLegacyIpc_MessageClass_MIN = ChromeLegacyIpc_MessageClass::CLASS_UNSPECIFIED;
+constexpr ChromeLegacyIpc_MessageClass ChromeLegacyIpc_MessageClass_MAX = ChromeLegacyIpc_MessageClass::CLASS_UNFREEZABLE_FRAME;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeLegacyIpc_MessageClass_Name(::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_UNSPECIFIED:
+    return "CLASS_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_AUTOMATION:
+    return "CLASS_AUTOMATION";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_FRAME:
+    return "CLASS_FRAME";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_PAGE:
+    return "CLASS_PAGE";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_VIEW:
+    return "CLASS_VIEW";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_WIDGET:
+    return "CLASS_WIDGET";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_INPUT:
+    return "CLASS_INPUT";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_TEST:
+    return "CLASS_TEST";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_WORKER:
+    return "CLASS_WORKER";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_NACL:
+    return "CLASS_NACL";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_GPU_CHANNEL:
+    return "CLASS_GPU_CHANNEL";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_MEDIA:
+    return "CLASS_MEDIA";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_PPAPI:
+    return "CLASS_PPAPI";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_CHROME:
+    return "CLASS_CHROME";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_DRAG:
+    return "CLASS_DRAG";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_PRINT:
+    return "CLASS_PRINT";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_EXTENSION:
+    return "CLASS_EXTENSION";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_TEXT_INPUT_CLIENT:
+    return "CLASS_TEXT_INPUT_CLIENT";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_BLINK_TEST:
+    return "CLASS_BLINK_TEST";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_ACCESSIBILITY:
+    return "CLASS_ACCESSIBILITY";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_PRERENDER:
+    return "CLASS_PRERENDER";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_CHROMOTING:
+    return "CLASS_CHROMOTING";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_BROWSER_PLUGIN:
+    return "CLASS_BROWSER_PLUGIN";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_ANDROID_WEB_VIEW:
+    return "CLASS_ANDROID_WEB_VIEW";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_NACL_HOST:
+    return "CLASS_NACL_HOST";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_ENCRYPTED_MEDIA:
+    return "CLASS_ENCRYPTED_MEDIA";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_CAST:
+    return "CLASS_CAST";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_GIN_JAVA_BRIDGE:
+    return "CLASS_GIN_JAVA_BRIDGE";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_CHROME_UTILITY_PRINTING:
+    return "CLASS_CHROME_UTILITY_PRINTING";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_OZONE_GPU:
+    return "CLASS_OZONE_GPU";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_WEB_TEST:
+    return "CLASS_WEB_TEST";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_NETWORK_HINTS:
+    return "CLASS_NETWORK_HINTS";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_EXTENSIONS_GUEST_VIEW:
+    return "CLASS_EXTENSIONS_GUEST_VIEW";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_GUEST_VIEW:
+    return "CLASS_GUEST_VIEW";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_MEDIA_PLAYER_DELEGATE:
+    return "CLASS_MEDIA_PLAYER_DELEGATE";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_EXTENSION_WORKER:
+    return "CLASS_EXTENSION_WORKER";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_SUBRESOURCE_FILTER:
+    return "CLASS_SUBRESOURCE_FILTER";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_UNFREEZABLE_FRAME:
+    return "CLASS_UNFREEZABLE_FRAME";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class ChromeLegacyIpc_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeLegacyIpc_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeLegacyIpc_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeLegacyIpc_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_message_class() const { return at<1>().valid(); }
+  int32_t message_class() const { return at<1>().as_int32(); }
+  bool has_message_line() const { return at<2>().valid(); }
+  uint32_t message_line() const { return at<2>().as_uint32(); }
+};
+
+class ChromeLegacyIpc : public ::protozero::Message {
+ public:
+  using Decoder = ChromeLegacyIpc_Decoder;
+  enum : int32_t {
+    kMessageClassFieldNumber = 1,
+    kMessageLineFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeLegacyIpc"; }
+
+
+  using MessageClass = ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass;
+  static inline const char* MessageClass_Name(MessageClass value) {
+    return ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass_Name(value);
+  }
+  static inline const MessageClass CLASS_UNSPECIFIED = MessageClass::CLASS_UNSPECIFIED;
+  static inline const MessageClass CLASS_AUTOMATION = MessageClass::CLASS_AUTOMATION;
+  static inline const MessageClass CLASS_FRAME = MessageClass::CLASS_FRAME;
+  static inline const MessageClass CLASS_PAGE = MessageClass::CLASS_PAGE;
+  static inline const MessageClass CLASS_VIEW = MessageClass::CLASS_VIEW;
+  static inline const MessageClass CLASS_WIDGET = MessageClass::CLASS_WIDGET;
+  static inline const MessageClass CLASS_INPUT = MessageClass::CLASS_INPUT;
+  static inline const MessageClass CLASS_TEST = MessageClass::CLASS_TEST;
+  static inline const MessageClass CLASS_WORKER = MessageClass::CLASS_WORKER;
+  static inline const MessageClass CLASS_NACL = MessageClass::CLASS_NACL;
+  static inline const MessageClass CLASS_GPU_CHANNEL = MessageClass::CLASS_GPU_CHANNEL;
+  static inline const MessageClass CLASS_MEDIA = MessageClass::CLASS_MEDIA;
+  static inline const MessageClass CLASS_PPAPI = MessageClass::CLASS_PPAPI;
+  static inline const MessageClass CLASS_CHROME = MessageClass::CLASS_CHROME;
+  static inline const MessageClass CLASS_DRAG = MessageClass::CLASS_DRAG;
+  static inline const MessageClass CLASS_PRINT = MessageClass::CLASS_PRINT;
+  static inline const MessageClass CLASS_EXTENSION = MessageClass::CLASS_EXTENSION;
+  static inline const MessageClass CLASS_TEXT_INPUT_CLIENT = MessageClass::CLASS_TEXT_INPUT_CLIENT;
+  static inline const MessageClass CLASS_BLINK_TEST = MessageClass::CLASS_BLINK_TEST;
+  static inline const MessageClass CLASS_ACCESSIBILITY = MessageClass::CLASS_ACCESSIBILITY;
+  static inline const MessageClass CLASS_PRERENDER = MessageClass::CLASS_PRERENDER;
+  static inline const MessageClass CLASS_CHROMOTING = MessageClass::CLASS_CHROMOTING;
+  static inline const MessageClass CLASS_BROWSER_PLUGIN = MessageClass::CLASS_BROWSER_PLUGIN;
+  static inline const MessageClass CLASS_ANDROID_WEB_VIEW = MessageClass::CLASS_ANDROID_WEB_VIEW;
+  static inline const MessageClass CLASS_NACL_HOST = MessageClass::CLASS_NACL_HOST;
+  static inline const MessageClass CLASS_ENCRYPTED_MEDIA = MessageClass::CLASS_ENCRYPTED_MEDIA;
+  static inline const MessageClass CLASS_CAST = MessageClass::CLASS_CAST;
+  static inline const MessageClass CLASS_GIN_JAVA_BRIDGE = MessageClass::CLASS_GIN_JAVA_BRIDGE;
+  static inline const MessageClass CLASS_CHROME_UTILITY_PRINTING = MessageClass::CLASS_CHROME_UTILITY_PRINTING;
+  static inline const MessageClass CLASS_OZONE_GPU = MessageClass::CLASS_OZONE_GPU;
+  static inline const MessageClass CLASS_WEB_TEST = MessageClass::CLASS_WEB_TEST;
+  static inline const MessageClass CLASS_NETWORK_HINTS = MessageClass::CLASS_NETWORK_HINTS;
+  static inline const MessageClass CLASS_EXTENSIONS_GUEST_VIEW = MessageClass::CLASS_EXTENSIONS_GUEST_VIEW;
+  static inline const MessageClass CLASS_GUEST_VIEW = MessageClass::CLASS_GUEST_VIEW;
+  static inline const MessageClass CLASS_MEDIA_PLAYER_DELEGATE = MessageClass::CLASS_MEDIA_PLAYER_DELEGATE;
+  static inline const MessageClass CLASS_EXTENSION_WORKER = MessageClass::CLASS_EXTENSION_WORKER;
+  static inline const MessageClass CLASS_SUBRESOURCE_FILTER = MessageClass::CLASS_SUBRESOURCE_FILTER;
+  static inline const MessageClass CLASS_UNFREEZABLE_FRAME = MessageClass::CLASS_UNFREEZABLE_FRAME;
+
+  using FieldMetadata_MessageClass =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ChromeLegacyIpc_MessageClass,
+      ChromeLegacyIpc>;
+
+  static constexpr FieldMetadata_MessageClass kMessageClass{};
+  void set_message_class(ChromeLegacyIpc_MessageClass value) {
+    static constexpr uint32_t field_id = FieldMetadata_MessageClass::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_MessageLine =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ChromeLegacyIpc>;
+
+  static constexpr FieldMetadata_MessageLine kMessageLine{};
+  void set_message_line(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MessageLine::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_message_pump.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_MESSAGE_PUMP_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_MESSAGE_PUMP_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class ChromeMessagePump_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeMessagePump_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeMessagePump_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeMessagePump_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_sent_messages_in_queue() const { return at<1>().valid(); }
+  bool sent_messages_in_queue() const { return at<1>().as_bool(); }
+  bool has_io_handler_location_iid() const { return at<2>().valid(); }
+  uint64_t io_handler_location_iid() const { return at<2>().as_uint64(); }
+};
+
+class ChromeMessagePump : public ::protozero::Message {
+ public:
+  using Decoder = ChromeMessagePump_Decoder;
+  enum : int32_t {
+    kSentMessagesInQueueFieldNumber = 1,
+    kIoHandlerLocationIidFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeMessagePump"; }
+
+
+  using FieldMetadata_SentMessagesInQueue =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeMessagePump>;
+
+  static constexpr FieldMetadata_SentMessagesInQueue kSentMessagesInQueue{};
+  void set_sent_messages_in_queue(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_SentMessagesInQueue::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_IoHandlerLocationIid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ChromeMessagePump>;
+
+  static constexpr FieldMetadata_IoHandlerLocationIid kIoHandlerLocationIid{};
+  void set_io_handler_location_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IoHandlerLocationIid::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_mojo_event_info.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_MOJO_EVENT_INFO_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_MOJO_EVENT_INFO_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class ChromeMojoEventInfo_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeMojoEventInfo_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeMojoEventInfo_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeMojoEventInfo_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_watcher_notify_interface_tag() const { return at<1>().valid(); }
+  ::protozero::ConstChars watcher_notify_interface_tag() const { return at<1>().as_string(); }
+  bool has_ipc_hash() const { return at<2>().valid(); }
+  uint32_t ipc_hash() const { return at<2>().as_uint32(); }
+  bool has_mojo_interface_tag() const { return at<3>().valid(); }
+  ::protozero::ConstChars mojo_interface_tag() const { return at<3>().as_string(); }
+  bool has_mojo_interface_method_iid() const { return at<4>().valid(); }
+  uint64_t mojo_interface_method_iid() const { return at<4>().as_uint64(); }
+  bool has_is_reply() const { return at<5>().valid(); }
+  bool is_reply() const { return at<5>().as_bool(); }
+  bool has_payload_size() const { return at<6>().valid(); }
+  uint64_t payload_size() const { return at<6>().as_uint64(); }
+  bool has_data_num_bytes() const { return at<7>().valid(); }
+  uint64_t data_num_bytes() const { return at<7>().as_uint64(); }
+};
+
+class ChromeMojoEventInfo : public ::protozero::Message {
+ public:
+  using Decoder = ChromeMojoEventInfo_Decoder;
+  enum : int32_t {
+    kWatcherNotifyInterfaceTagFieldNumber = 1,
+    kIpcHashFieldNumber = 2,
+    kMojoInterfaceTagFieldNumber = 3,
+    kMojoInterfaceMethodIidFieldNumber = 4,
+    kIsReplyFieldNumber = 5,
+    kPayloadSizeFieldNumber = 6,
+    kDataNumBytesFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeMojoEventInfo"; }
+
+
+  using FieldMetadata_WatcherNotifyInterfaceTag =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeMojoEventInfo>;
+
+  static constexpr FieldMetadata_WatcherNotifyInterfaceTag kWatcherNotifyInterfaceTag{};
+  void set_watcher_notify_interface_tag(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_WatcherNotifyInterfaceTag::kFieldId, data, size);
+  }
+  void set_watcher_notify_interface_tag(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_WatcherNotifyInterfaceTag::kFieldId, chars.data, chars.size);
+  }
+  void set_watcher_notify_interface_tag(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_WatcherNotifyInterfaceTag::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_IpcHash =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ChromeMojoEventInfo>;
+
+  static constexpr FieldMetadata_IpcHash kIpcHash{};
+  void set_ipc_hash(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IpcHash::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_MojoInterfaceTag =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeMojoEventInfo>;
+
+  static constexpr FieldMetadata_MojoInterfaceTag kMojoInterfaceTag{};
+  void set_mojo_interface_tag(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_MojoInterfaceTag::kFieldId, data, size);
+  }
+  void set_mojo_interface_tag(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_MojoInterfaceTag::kFieldId, chars.data, chars.size);
+  }
+  void set_mojo_interface_tag(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_MojoInterfaceTag::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_MojoInterfaceMethodIid =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ChromeMojoEventInfo>;
+
+  static constexpr FieldMetadata_MojoInterfaceMethodIid kMojoInterfaceMethodIid{};
+  void set_mojo_interface_method_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MojoInterfaceMethodIid::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_IsReply =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeMojoEventInfo>;
+
+  static constexpr FieldMetadata_IsReply kIsReply{};
+  void set_is_reply(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsReply::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_PayloadSize =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ChromeMojoEventInfo>;
+
+  static constexpr FieldMetadata_PayloadSize kPayloadSize{};
+  void set_payload_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PayloadSize::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_DataNumBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ChromeMojoEventInfo>;
+
+  static constexpr FieldMetadata_DataNumBytes kDataNumBytes{};
+  void set_data_num_bytes(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DataNumBytes::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_process_descriptor.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_PROCESS_DESCRIPTOR_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_PROCESS_DESCRIPTOR_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+namespace perfetto_pbzero_enum_ChromeProcessDescriptor {
+enum ProcessType : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeProcessDescriptor
+using ChromeProcessDescriptor_ProcessType = perfetto_pbzero_enum_ChromeProcessDescriptor::ProcessType;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_ChromeProcessDescriptor {
+enum ProcessType : int32_t {
+  PROCESS_UNSPECIFIED = 0,
+  PROCESS_BROWSER = 1,
+  PROCESS_RENDERER = 2,
+  PROCESS_UTILITY = 3,
+  PROCESS_ZYGOTE = 4,
+  PROCESS_SANDBOX_HELPER = 5,
+  PROCESS_GPU = 6,
+  PROCESS_PPAPI_PLUGIN = 7,
+  PROCESS_PPAPI_BROKER = 8,
+  PROCESS_SERVICE_NETWORK = 9,
+  PROCESS_SERVICE_TRACING = 10,
+  PROCESS_SERVICE_STORAGE = 11,
+  PROCESS_SERVICE_AUDIO = 12,
+  PROCESS_SERVICE_DATA_DECODER = 13,
+  PROCESS_SERVICE_UTIL_WIN = 14,
+  PROCESS_SERVICE_PROXY_RESOLVER = 15,
+  PROCESS_SERVICE_CDM = 16,
+  PROCESS_SERVICE_VIDEO_CAPTURE = 17,
+  PROCESS_SERVICE_UNZIPPER = 18,
+  PROCESS_SERVICE_MIRRORING = 19,
+  PROCESS_SERVICE_FILEPATCHER = 20,
+  PROCESS_SERVICE_TTS = 21,
+  PROCESS_SERVICE_PRINTING = 22,
+  PROCESS_SERVICE_QUARANTINE = 23,
+  PROCESS_SERVICE_CROS_LOCALSEARCH = 24,
+  PROCESS_SERVICE_CROS_ASSISTANT_AUDIO_DECODER = 25,
+  PROCESS_SERVICE_FILEUTIL = 26,
+  PROCESS_SERVICE_PRINTCOMPOSITOR = 27,
+  PROCESS_SERVICE_PAINTPREVIEW = 28,
+  PROCESS_SERVICE_SPEECHRECOGNITION = 29,
+  PROCESS_SERVICE_XRDEVICE = 30,
+  PROCESS_SERVICE_READICON = 31,
+  PROCESS_SERVICE_LANGUAGEDETECTION = 32,
+  PROCESS_SERVICE_SHARING = 33,
+  PROCESS_SERVICE_MEDIAPARSER = 34,
+  PROCESS_SERVICE_QRCODEGENERATOR = 35,
+  PROCESS_SERVICE_PROFILEIMPORT = 36,
+  PROCESS_SERVICE_IME = 37,
+  PROCESS_SERVICE_RECORDING = 38,
+  PROCESS_SERVICE_SHAPEDETECTION = 39,
+  PROCESS_RENDERER_EXTENSION = 40,
+  PROCESS_SERVICE_MEDIA_FOUNDATION = 41,
+};
+} // namespace perfetto_pbzero_enum_ChromeProcessDescriptor
+using ChromeProcessDescriptor_ProcessType = perfetto_pbzero_enum_ChromeProcessDescriptor::ProcessType;
+
+
+constexpr ChromeProcessDescriptor_ProcessType ChromeProcessDescriptor_ProcessType_MIN = ChromeProcessDescriptor_ProcessType::PROCESS_UNSPECIFIED;
+constexpr ChromeProcessDescriptor_ProcessType ChromeProcessDescriptor_ProcessType_MAX = ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_MEDIA_FOUNDATION;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeProcessDescriptor_ProcessType_Name(::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_UNSPECIFIED:
+    return "PROCESS_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_BROWSER:
+    return "PROCESS_BROWSER";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_RENDERER:
+    return "PROCESS_RENDERER";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_UTILITY:
+    return "PROCESS_UTILITY";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_ZYGOTE:
+    return "PROCESS_ZYGOTE";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SANDBOX_HELPER:
+    return "PROCESS_SANDBOX_HELPER";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_GPU:
+    return "PROCESS_GPU";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_PPAPI_PLUGIN:
+    return "PROCESS_PPAPI_PLUGIN";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_PPAPI_BROKER:
+    return "PROCESS_PPAPI_BROKER";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_NETWORK:
+    return "PROCESS_SERVICE_NETWORK";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_TRACING:
+    return "PROCESS_SERVICE_TRACING";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_STORAGE:
+    return "PROCESS_SERVICE_STORAGE";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_AUDIO:
+    return "PROCESS_SERVICE_AUDIO";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_DATA_DECODER:
+    return "PROCESS_SERVICE_DATA_DECODER";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_UTIL_WIN:
+    return "PROCESS_SERVICE_UTIL_WIN";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_PROXY_RESOLVER:
+    return "PROCESS_SERVICE_PROXY_RESOLVER";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_CDM:
+    return "PROCESS_SERVICE_CDM";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_VIDEO_CAPTURE:
+    return "PROCESS_SERVICE_VIDEO_CAPTURE";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_UNZIPPER:
+    return "PROCESS_SERVICE_UNZIPPER";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_MIRRORING:
+    return "PROCESS_SERVICE_MIRRORING";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_FILEPATCHER:
+    return "PROCESS_SERVICE_FILEPATCHER";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_TTS:
+    return "PROCESS_SERVICE_TTS";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_PRINTING:
+    return "PROCESS_SERVICE_PRINTING";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_QUARANTINE:
+    return "PROCESS_SERVICE_QUARANTINE";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_CROS_LOCALSEARCH:
+    return "PROCESS_SERVICE_CROS_LOCALSEARCH";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_CROS_ASSISTANT_AUDIO_DECODER:
+    return "PROCESS_SERVICE_CROS_ASSISTANT_AUDIO_DECODER";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_FILEUTIL:
+    return "PROCESS_SERVICE_FILEUTIL";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_PRINTCOMPOSITOR:
+    return "PROCESS_SERVICE_PRINTCOMPOSITOR";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_PAINTPREVIEW:
+    return "PROCESS_SERVICE_PAINTPREVIEW";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_SPEECHRECOGNITION:
+    return "PROCESS_SERVICE_SPEECHRECOGNITION";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_XRDEVICE:
+    return "PROCESS_SERVICE_XRDEVICE";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_READICON:
+    return "PROCESS_SERVICE_READICON";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_LANGUAGEDETECTION:
+    return "PROCESS_SERVICE_LANGUAGEDETECTION";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_SHARING:
+    return "PROCESS_SERVICE_SHARING";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_MEDIAPARSER:
+    return "PROCESS_SERVICE_MEDIAPARSER";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_QRCODEGENERATOR:
+    return "PROCESS_SERVICE_QRCODEGENERATOR";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_PROFILEIMPORT:
+    return "PROCESS_SERVICE_PROFILEIMPORT";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_IME:
+    return "PROCESS_SERVICE_IME";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_RECORDING:
+    return "PROCESS_SERVICE_RECORDING";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_SHAPEDETECTION:
+    return "PROCESS_SERVICE_SHAPEDETECTION";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_RENDERER_EXTENSION:
+    return "PROCESS_RENDERER_EXTENSION";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_MEDIA_FOUNDATION:
+    return "PROCESS_SERVICE_MEDIA_FOUNDATION";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class ChromeProcessDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeProcessDescriptor_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeProcessDescriptor_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeProcessDescriptor_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_process_type() const { return at<1>().valid(); }
+  int32_t process_type() const { return at<1>().as_int32(); }
+  bool has_process_priority() const { return at<2>().valid(); }
+  int32_t process_priority() const { return at<2>().as_int32(); }
+  bool has_legacy_sort_index() const { return at<3>().valid(); }
+  int32_t legacy_sort_index() const { return at<3>().as_int32(); }
+  bool has_host_app_package_name() const { return at<4>().valid(); }
+  ::protozero::ConstChars host_app_package_name() const { return at<4>().as_string(); }
+  bool has_crash_trace_id() const { return at<5>().valid(); }
+  uint64_t crash_trace_id() const { return at<5>().as_uint64(); }
+};
+
+class ChromeProcessDescriptor : public ::protozero::Message {
+ public:
+  using Decoder = ChromeProcessDescriptor_Decoder;
+  enum : int32_t {
+    kProcessTypeFieldNumber = 1,
+    kProcessPriorityFieldNumber = 2,
+    kLegacySortIndexFieldNumber = 3,
+    kHostAppPackageNameFieldNumber = 4,
+    kCrashTraceIdFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeProcessDescriptor"; }
+
+
+  using ProcessType = ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType;
+  static inline const char* ProcessType_Name(ProcessType value) {
+    return ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType_Name(value);
+  }
+  static inline const ProcessType PROCESS_UNSPECIFIED = ProcessType::PROCESS_UNSPECIFIED;
+  static inline const ProcessType PROCESS_BROWSER = ProcessType::PROCESS_BROWSER;
+  static inline const ProcessType PROCESS_RENDERER = ProcessType::PROCESS_RENDERER;
+  static inline const ProcessType PROCESS_UTILITY = ProcessType::PROCESS_UTILITY;
+  static inline const ProcessType PROCESS_ZYGOTE = ProcessType::PROCESS_ZYGOTE;
+  static inline const ProcessType PROCESS_SANDBOX_HELPER = ProcessType::PROCESS_SANDBOX_HELPER;
+  static inline const ProcessType PROCESS_GPU = ProcessType::PROCESS_GPU;
+  static inline const ProcessType PROCESS_PPAPI_PLUGIN = ProcessType::PROCESS_PPAPI_PLUGIN;
+  static inline const ProcessType PROCESS_PPAPI_BROKER = ProcessType::PROCESS_PPAPI_BROKER;
+  static inline const ProcessType PROCESS_SERVICE_NETWORK = ProcessType::PROCESS_SERVICE_NETWORK;
+  static inline const ProcessType PROCESS_SERVICE_TRACING = ProcessType::PROCESS_SERVICE_TRACING;
+  static inline const ProcessType PROCESS_SERVICE_STORAGE = ProcessType::PROCESS_SERVICE_STORAGE;
+  static inline const ProcessType PROCESS_SERVICE_AUDIO = ProcessType::PROCESS_SERVICE_AUDIO;
+  static inline const ProcessType PROCESS_SERVICE_DATA_DECODER = ProcessType::PROCESS_SERVICE_DATA_DECODER;
+  static inline const ProcessType PROCESS_SERVICE_UTIL_WIN = ProcessType::PROCESS_SERVICE_UTIL_WIN;
+  static inline const ProcessType PROCESS_SERVICE_PROXY_RESOLVER = ProcessType::PROCESS_SERVICE_PROXY_RESOLVER;
+  static inline const ProcessType PROCESS_SERVICE_CDM = ProcessType::PROCESS_SERVICE_CDM;
+  static inline const ProcessType PROCESS_SERVICE_VIDEO_CAPTURE = ProcessType::PROCESS_SERVICE_VIDEO_CAPTURE;
+  static inline const ProcessType PROCESS_SERVICE_UNZIPPER = ProcessType::PROCESS_SERVICE_UNZIPPER;
+  static inline const ProcessType PROCESS_SERVICE_MIRRORING = ProcessType::PROCESS_SERVICE_MIRRORING;
+  static inline const ProcessType PROCESS_SERVICE_FILEPATCHER = ProcessType::PROCESS_SERVICE_FILEPATCHER;
+  static inline const ProcessType PROCESS_SERVICE_TTS = ProcessType::PROCESS_SERVICE_TTS;
+  static inline const ProcessType PROCESS_SERVICE_PRINTING = ProcessType::PROCESS_SERVICE_PRINTING;
+  static inline const ProcessType PROCESS_SERVICE_QUARANTINE = ProcessType::PROCESS_SERVICE_QUARANTINE;
+  static inline const ProcessType PROCESS_SERVICE_CROS_LOCALSEARCH = ProcessType::PROCESS_SERVICE_CROS_LOCALSEARCH;
+  static inline const ProcessType PROCESS_SERVICE_CROS_ASSISTANT_AUDIO_DECODER = ProcessType::PROCESS_SERVICE_CROS_ASSISTANT_AUDIO_DECODER;
+  static inline const ProcessType PROCESS_SERVICE_FILEUTIL = ProcessType::PROCESS_SERVICE_FILEUTIL;
+  static inline const ProcessType PROCESS_SERVICE_PRINTCOMPOSITOR = ProcessType::PROCESS_SERVICE_PRINTCOMPOSITOR;
+  static inline const ProcessType PROCESS_SERVICE_PAINTPREVIEW = ProcessType::PROCESS_SERVICE_PAINTPREVIEW;
+  static inline const ProcessType PROCESS_SERVICE_SPEECHRECOGNITION = ProcessType::PROCESS_SERVICE_SPEECHRECOGNITION;
+  static inline const ProcessType PROCESS_SERVICE_XRDEVICE = ProcessType::PROCESS_SERVICE_XRDEVICE;
+  static inline const ProcessType PROCESS_SERVICE_READICON = ProcessType::PROCESS_SERVICE_READICON;
+  static inline const ProcessType PROCESS_SERVICE_LANGUAGEDETECTION = ProcessType::PROCESS_SERVICE_LANGUAGEDETECTION;
+  static inline const ProcessType PROCESS_SERVICE_SHARING = ProcessType::PROCESS_SERVICE_SHARING;
+  static inline const ProcessType PROCESS_SERVICE_MEDIAPARSER = ProcessType::PROCESS_SERVICE_MEDIAPARSER;
+  static inline const ProcessType PROCESS_SERVICE_QRCODEGENERATOR = ProcessType::PROCESS_SERVICE_QRCODEGENERATOR;
+  static inline const ProcessType PROCESS_SERVICE_PROFILEIMPORT = ProcessType::PROCESS_SERVICE_PROFILEIMPORT;
+  static inline const ProcessType PROCESS_SERVICE_IME = ProcessType::PROCESS_SERVICE_IME;
+  static inline const ProcessType PROCESS_SERVICE_RECORDING = ProcessType::PROCESS_SERVICE_RECORDING;
+  static inline const ProcessType PROCESS_SERVICE_SHAPEDETECTION = ProcessType::PROCESS_SERVICE_SHAPEDETECTION;
+  static inline const ProcessType PROCESS_RENDERER_EXTENSION = ProcessType::PROCESS_RENDERER_EXTENSION;
+  static inline const ProcessType PROCESS_SERVICE_MEDIA_FOUNDATION = ProcessType::PROCESS_SERVICE_MEDIA_FOUNDATION;
+
+  using FieldMetadata_ProcessType =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ChromeProcessDescriptor_ProcessType,
+      ChromeProcessDescriptor>;
+
+  static constexpr FieldMetadata_ProcessType kProcessType{};
+  void set_process_type(ChromeProcessDescriptor_ProcessType value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProcessType::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_ProcessPriority =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeProcessDescriptor>;
+
+  static constexpr FieldMetadata_ProcessPriority kProcessPriority{};
+  void set_process_priority(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProcessPriority::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_LegacySortIndex =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeProcessDescriptor>;
+
+  static constexpr FieldMetadata_LegacySortIndex kLegacySortIndex{};
+  void set_legacy_sort_index(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LegacySortIndex::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_HostAppPackageName =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeProcessDescriptor>;
+
+  static constexpr FieldMetadata_HostAppPackageName kHostAppPackageName{};
+  void set_host_app_package_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HostAppPackageName::kFieldId, data, size);
+  }
+  void set_host_app_package_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_HostAppPackageName::kFieldId, chars.data, chars.size);
+  }
+  void set_host_app_package_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_HostAppPackageName::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_CrashTraceId =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ChromeProcessDescriptor>;
+
+  static constexpr FieldMetadata_CrashTraceId kCrashTraceId{};
+  void set_crash_trace_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CrashTraceId::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_RENDERER_SCHEDULER_STATE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_RENDERER_SCHEDULER_STATE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+enum ChromeRAILMode : int32_t;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+enum ChromeRAILMode : int32_t {
+  RAIL_MODE_NONE = 0,
+  RAIL_MODE_RESPONSE = 1,
+  RAIL_MODE_ANIMATION = 2,
+  RAIL_MODE_IDLE = 3,
+  RAIL_MODE_LOAD = 4,
+};
+
+constexpr ChromeRAILMode ChromeRAILMode_MIN = ChromeRAILMode::RAIL_MODE_NONE;
+constexpr ChromeRAILMode ChromeRAILMode_MAX = ChromeRAILMode::RAIL_MODE_LOAD;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeRAILMode_Name(::perfetto::protos::pbzero::ChromeRAILMode value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeRAILMode::RAIL_MODE_NONE:
+    return "RAIL_MODE_NONE";
+
+  case ::perfetto::protos::pbzero::ChromeRAILMode::RAIL_MODE_RESPONSE:
+    return "RAIL_MODE_RESPONSE";
+
+  case ::perfetto::protos::pbzero::ChromeRAILMode::RAIL_MODE_ANIMATION:
+    return "RAIL_MODE_ANIMATION";
+
+  case ::perfetto::protos::pbzero::ChromeRAILMode::RAIL_MODE_IDLE:
+    return "RAIL_MODE_IDLE";
+
+  case ::perfetto::protos::pbzero::ChromeRAILMode::RAIL_MODE_LOAD:
+    return "RAIL_MODE_LOAD";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class ChromeRendererSchedulerState_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeRendererSchedulerState_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeRendererSchedulerState_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeRendererSchedulerState_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_rail_mode() const { return at<1>().valid(); }
+  int32_t rail_mode() const { return at<1>().as_int32(); }
+  bool has_is_backgrounded() const { return at<2>().valid(); }
+  bool is_backgrounded() const { return at<2>().as_bool(); }
+  bool has_is_hidden() const { return at<3>().valid(); }
+  bool is_hidden() const { return at<3>().as_bool(); }
+};
+
+class ChromeRendererSchedulerState : public ::protozero::Message {
+ public:
+  using Decoder = ChromeRendererSchedulerState_Decoder;
+  enum : int32_t {
+    kRailModeFieldNumber = 1,
+    kIsBackgroundedFieldNumber = 2,
+    kIsHiddenFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeRendererSchedulerState"; }
+
+
+  using FieldMetadata_RailMode =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ChromeRAILMode,
+      ChromeRendererSchedulerState>;
+
+  static constexpr FieldMetadata_RailMode kRailMode{};
+  void set_rail_mode(ChromeRAILMode value) {
+    static constexpr uint32_t field_id = FieldMetadata_RailMode::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_IsBackgrounded =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeRendererSchedulerState>;
+
+  static constexpr FieldMetadata_IsBackgrounded kIsBackgrounded{};
+  void set_is_backgrounded(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsBackgrounded::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_IsHidden =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeRendererSchedulerState>;
+
+  static constexpr FieldMetadata_IsHidden kIsHidden{};
+  void set_is_hidden(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsHidden::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_thread_descriptor.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_THREAD_DESCRIPTOR_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_THREAD_DESCRIPTOR_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+namespace perfetto_pbzero_enum_ChromeThreadDescriptor {
+enum ThreadType : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeThreadDescriptor
+using ChromeThreadDescriptor_ThreadType = perfetto_pbzero_enum_ChromeThreadDescriptor::ThreadType;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_ChromeThreadDescriptor {
+enum ThreadType : int32_t {
+  THREAD_UNSPECIFIED = 0,
+  THREAD_MAIN = 1,
+  THREAD_IO = 2,
+  THREAD_POOL_BG_WORKER = 3,
+  THREAD_POOL_FG_WORKER = 4,
+  THREAD_POOL_FG_BLOCKING = 5,
+  THREAD_POOL_BG_BLOCKING = 6,
+  THREAD_POOL_SERVICE = 7,
+  THREAD_COMPOSITOR = 8,
+  THREAD_VIZ_COMPOSITOR = 9,
+  THREAD_COMPOSITOR_WORKER = 10,
+  THREAD_SERVICE_WORKER = 11,
+  THREAD_NETWORK_SERVICE = 12,
+  THREAD_CHILD_IO = 13,
+  THREAD_BROWSER_IO = 14,
+  THREAD_BROWSER_MAIN = 15,
+  THREAD_RENDERER_MAIN = 16,
+  THREAD_UTILITY_MAIN = 17,
+  THREAD_GPU_MAIN = 18,
+  THREAD_CACHE_BLOCKFILE = 19,
+  THREAD_MEDIA = 20,
+  THREAD_AUDIO_OUTPUTDEVICE = 21,
+  THREAD_AUDIO_INPUTDEVICE = 22,
+  THREAD_GPU_MEMORY = 23,
+  THREAD_GPU_VSYNC = 24,
+  THREAD_DXA_VIDEODECODER = 25,
+  THREAD_BROWSER_WATCHDOG = 26,
+  THREAD_WEBRTC_NETWORK = 27,
+  THREAD_WINDOW_OWNER = 28,
+  THREAD_WEBRTC_SIGNALING = 29,
+  THREAD_WEBRTC_WORKER = 30,
+  THREAD_PPAPI_MAIN = 31,
+  THREAD_GPU_WATCHDOG = 32,
+  THREAD_SWAPPER = 33,
+  THREAD_GAMEPAD_POLLING = 34,
+  THREAD_WEBCRYPTO = 35,
+  THREAD_DATABASE = 36,
+  THREAD_PROXYRESOLVER = 37,
+  THREAD_DEVTOOLSADB = 38,
+  THREAD_NETWORKCONFIGWATCHER = 39,
+  THREAD_WASAPI_RENDER = 40,
+  THREAD_LOADER_LOCK_SAMPLER = 41,
+  THREAD_MEMORY_INFRA = 50,
+  THREAD_SAMPLING_PROFILER = 51,
+};
+} // namespace perfetto_pbzero_enum_ChromeThreadDescriptor
+using ChromeThreadDescriptor_ThreadType = perfetto_pbzero_enum_ChromeThreadDescriptor::ThreadType;
+
+
+constexpr ChromeThreadDescriptor_ThreadType ChromeThreadDescriptor_ThreadType_MIN = ChromeThreadDescriptor_ThreadType::THREAD_UNSPECIFIED;
+constexpr ChromeThreadDescriptor_ThreadType ChromeThreadDescriptor_ThreadType_MAX = ChromeThreadDescriptor_ThreadType::THREAD_SAMPLING_PROFILER;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeThreadDescriptor_ThreadType_Name(::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_UNSPECIFIED:
+    return "THREAD_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_MAIN:
+    return "THREAD_MAIN";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_IO:
+    return "THREAD_IO";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_POOL_BG_WORKER:
+    return "THREAD_POOL_BG_WORKER";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_POOL_FG_WORKER:
+    return "THREAD_POOL_FG_WORKER";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_POOL_FG_BLOCKING:
+    return "THREAD_POOL_FG_BLOCKING";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_POOL_BG_BLOCKING:
+    return "THREAD_POOL_BG_BLOCKING";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_POOL_SERVICE:
+    return "THREAD_POOL_SERVICE";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_COMPOSITOR:
+    return "THREAD_COMPOSITOR";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_VIZ_COMPOSITOR:
+    return "THREAD_VIZ_COMPOSITOR";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_COMPOSITOR_WORKER:
+    return "THREAD_COMPOSITOR_WORKER";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_SERVICE_WORKER:
+    return "THREAD_SERVICE_WORKER";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_NETWORK_SERVICE:
+    return "THREAD_NETWORK_SERVICE";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_CHILD_IO:
+    return "THREAD_CHILD_IO";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_BROWSER_IO:
+    return "THREAD_BROWSER_IO";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_BROWSER_MAIN:
+    return "THREAD_BROWSER_MAIN";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_RENDERER_MAIN:
+    return "THREAD_RENDERER_MAIN";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_UTILITY_MAIN:
+    return "THREAD_UTILITY_MAIN";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_GPU_MAIN:
+    return "THREAD_GPU_MAIN";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_CACHE_BLOCKFILE:
+    return "THREAD_CACHE_BLOCKFILE";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_MEDIA:
+    return "THREAD_MEDIA";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_AUDIO_OUTPUTDEVICE:
+    return "THREAD_AUDIO_OUTPUTDEVICE";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_AUDIO_INPUTDEVICE:
+    return "THREAD_AUDIO_INPUTDEVICE";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_GPU_MEMORY:
+    return "THREAD_GPU_MEMORY";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_GPU_VSYNC:
+    return "THREAD_GPU_VSYNC";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_DXA_VIDEODECODER:
+    return "THREAD_DXA_VIDEODECODER";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_BROWSER_WATCHDOG:
+    return "THREAD_BROWSER_WATCHDOG";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_WEBRTC_NETWORK:
+    return "THREAD_WEBRTC_NETWORK";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_WINDOW_OWNER:
+    return "THREAD_WINDOW_OWNER";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_WEBRTC_SIGNALING:
+    return "THREAD_WEBRTC_SIGNALING";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_WEBRTC_WORKER:
+    return "THREAD_WEBRTC_WORKER";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_PPAPI_MAIN:
+    return "THREAD_PPAPI_MAIN";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_GPU_WATCHDOG:
+    return "THREAD_GPU_WATCHDOG";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_SWAPPER:
+    return "THREAD_SWAPPER";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_GAMEPAD_POLLING:
+    return "THREAD_GAMEPAD_POLLING";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_WEBCRYPTO:
+    return "THREAD_WEBCRYPTO";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_DATABASE:
+    return "THREAD_DATABASE";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_PROXYRESOLVER:
+    return "THREAD_PROXYRESOLVER";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_DEVTOOLSADB:
+    return "THREAD_DEVTOOLSADB";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_NETWORKCONFIGWATCHER:
+    return "THREAD_NETWORKCONFIGWATCHER";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_WASAPI_RENDER:
+    return "THREAD_WASAPI_RENDER";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_LOADER_LOCK_SAMPLER:
+    return "THREAD_LOADER_LOCK_SAMPLER";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_MEMORY_INFRA:
+    return "THREAD_MEMORY_INFRA";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_SAMPLING_PROFILER:
+    return "THREAD_SAMPLING_PROFILER";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class ChromeThreadDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeThreadDescriptor_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeThreadDescriptor_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeThreadDescriptor_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_thread_type() const { return at<1>().valid(); }
+  int32_t thread_type() const { return at<1>().as_int32(); }
+  bool has_legacy_sort_index() const { return at<2>().valid(); }
+  int32_t legacy_sort_index() const { return at<2>().as_int32(); }
+};
+
+class ChromeThreadDescriptor : public ::protozero::Message {
+ public:
+  using Decoder = ChromeThreadDescriptor_Decoder;
+  enum : int32_t {
+    kThreadTypeFieldNumber = 1,
+    kLegacySortIndexFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeThreadDescriptor"; }
+
+
+  using ThreadType = ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType;
+  static inline const char* ThreadType_Name(ThreadType value) {
+    return ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType_Name(value);
+  }
+  static inline const ThreadType THREAD_UNSPECIFIED = ThreadType::THREAD_UNSPECIFIED;
+  static inline const ThreadType THREAD_MAIN = ThreadType::THREAD_MAIN;
+  static inline const ThreadType THREAD_IO = ThreadType::THREAD_IO;
+  static inline const ThreadType THREAD_POOL_BG_WORKER = ThreadType::THREAD_POOL_BG_WORKER;
+  static inline const ThreadType THREAD_POOL_FG_WORKER = ThreadType::THREAD_POOL_FG_WORKER;
+  static inline const ThreadType THREAD_POOL_FG_BLOCKING = ThreadType::THREAD_POOL_FG_BLOCKING;
+  static inline const ThreadType THREAD_POOL_BG_BLOCKING = ThreadType::THREAD_POOL_BG_BLOCKING;
+  static inline const ThreadType THREAD_POOL_SERVICE = ThreadType::THREAD_POOL_SERVICE;
+  static inline const ThreadType THREAD_COMPOSITOR = ThreadType::THREAD_COMPOSITOR;
+  static inline const ThreadType THREAD_VIZ_COMPOSITOR = ThreadType::THREAD_VIZ_COMPOSITOR;
+  static inline const ThreadType THREAD_COMPOSITOR_WORKER = ThreadType::THREAD_COMPOSITOR_WORKER;
+  static inline const ThreadType THREAD_SERVICE_WORKER = ThreadType::THREAD_SERVICE_WORKER;
+  static inline const ThreadType THREAD_NETWORK_SERVICE = ThreadType::THREAD_NETWORK_SERVICE;
+  static inline const ThreadType THREAD_CHILD_IO = ThreadType::THREAD_CHILD_IO;
+  static inline const ThreadType THREAD_BROWSER_IO = ThreadType::THREAD_BROWSER_IO;
+  static inline const ThreadType THREAD_BROWSER_MAIN = ThreadType::THREAD_BROWSER_MAIN;
+  static inline const ThreadType THREAD_RENDERER_MAIN = ThreadType::THREAD_RENDERER_MAIN;
+  static inline const ThreadType THREAD_UTILITY_MAIN = ThreadType::THREAD_UTILITY_MAIN;
+  static inline const ThreadType THREAD_GPU_MAIN = ThreadType::THREAD_GPU_MAIN;
+  static inline const ThreadType THREAD_CACHE_BLOCKFILE = ThreadType::THREAD_CACHE_BLOCKFILE;
+  static inline const ThreadType THREAD_MEDIA = ThreadType::THREAD_MEDIA;
+  static inline const ThreadType THREAD_AUDIO_OUTPUTDEVICE = ThreadType::THREAD_AUDIO_OUTPUTDEVICE;
+  static inline const ThreadType THREAD_AUDIO_INPUTDEVICE = ThreadType::THREAD_AUDIO_INPUTDEVICE;
+  static inline const ThreadType THREAD_GPU_MEMORY = ThreadType::THREAD_GPU_MEMORY;
+  static inline const ThreadType THREAD_GPU_VSYNC = ThreadType::THREAD_GPU_VSYNC;
+  static inline const ThreadType THREAD_DXA_VIDEODECODER = ThreadType::THREAD_DXA_VIDEODECODER;
+  static inline const ThreadType THREAD_BROWSER_WATCHDOG = ThreadType::THREAD_BROWSER_WATCHDOG;
+  static inline const ThreadType THREAD_WEBRTC_NETWORK = ThreadType::THREAD_WEBRTC_NETWORK;
+  static inline const ThreadType THREAD_WINDOW_OWNER = ThreadType::THREAD_WINDOW_OWNER;
+  static inline const ThreadType THREAD_WEBRTC_SIGNALING = ThreadType::THREAD_WEBRTC_SIGNALING;
+  static inline const ThreadType THREAD_WEBRTC_WORKER = ThreadType::THREAD_WEBRTC_WORKER;
+  static inline const ThreadType THREAD_PPAPI_MAIN = ThreadType::THREAD_PPAPI_MAIN;
+  static inline const ThreadType THREAD_GPU_WATCHDOG = ThreadType::THREAD_GPU_WATCHDOG;
+  static inline const ThreadType THREAD_SWAPPER = ThreadType::THREAD_SWAPPER;
+  static inline const ThreadType THREAD_GAMEPAD_POLLING = ThreadType::THREAD_GAMEPAD_POLLING;
+  static inline const ThreadType THREAD_WEBCRYPTO = ThreadType::THREAD_WEBCRYPTO;
+  static inline const ThreadType THREAD_DATABASE = ThreadType::THREAD_DATABASE;
+  static inline const ThreadType THREAD_PROXYRESOLVER = ThreadType::THREAD_PROXYRESOLVER;
+  static inline const ThreadType THREAD_DEVTOOLSADB = ThreadType::THREAD_DEVTOOLSADB;
+  static inline const ThreadType THREAD_NETWORKCONFIGWATCHER = ThreadType::THREAD_NETWORKCONFIGWATCHER;
+  static inline const ThreadType THREAD_WASAPI_RENDER = ThreadType::THREAD_WASAPI_RENDER;
+  static inline const ThreadType THREAD_LOADER_LOCK_SAMPLER = ThreadType::THREAD_LOADER_LOCK_SAMPLER;
+  static inline const ThreadType THREAD_MEMORY_INFRA = ThreadType::THREAD_MEMORY_INFRA;
+  static inline const ThreadType THREAD_SAMPLING_PROFILER = ThreadType::THREAD_SAMPLING_PROFILER;
+
+  using FieldMetadata_ThreadType =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ChromeThreadDescriptor_ThreadType,
+      ChromeThreadDescriptor>;
+
+  static constexpr FieldMetadata_ThreadType kThreadType{};
+  void set_thread_type(ChromeThreadDescriptor_ThreadType value) {
+    static constexpr uint32_t field_id = FieldMetadata_ThreadType::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_LegacySortIndex =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeThreadDescriptor>;
+
+  static constexpr FieldMetadata_LegacySortIndex kLegacySortIndex{};
+  void set_legacy_sort_index(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LegacySortIndex::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_user_event.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_USER_EVENT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_USER_EVENT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class ChromeUserEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeUserEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeUserEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeUserEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_action() const { return at<1>().valid(); }
+  ::protozero::ConstChars action() const { return at<1>().as_string(); }
+  bool has_action_hash() const { return at<2>().valid(); }
+  uint64_t action_hash() const { return at<2>().as_uint64(); }
+};
+
+class ChromeUserEvent : public ::protozero::Message {
+ public:
+  using Decoder = ChromeUserEvent_Decoder;
+  enum : int32_t {
+    kActionFieldNumber = 1,
+    kActionHashFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeUserEvent"; }
+
+
+  using FieldMetadata_Action =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeUserEvent>;
+
+  static constexpr FieldMetadata_Action kAction{};
+  void set_action(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Action::kFieldId, data, size);
+  }
+  void set_action(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Action::kFieldId, chars.data, chars.size);
+  }
+  void set_action(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Action::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_ActionHash =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ChromeUserEvent>;
+
+  static constexpr FieldMetadata_ActionHash kActionHash{};
+  void set_action_hash(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ActionHash::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_window_handle_event_info.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_WINDOW_HANDLE_EVENT_INFO_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_WINDOW_HANDLE_EVENT_INFO_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class ChromeWindowHandleEventInfo_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeWindowHandleEventInfo_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeWindowHandleEventInfo_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeWindowHandleEventInfo_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dpi() const { return at<1>().valid(); }
+  uint32_t dpi() const { return at<1>().as_uint32(); }
+  bool has_message_id() const { return at<2>().valid(); }
+  uint32_t message_id() const { return at<2>().as_uint32(); }
+  bool has_hwnd_ptr() const { return at<3>().valid(); }
+  uint64_t hwnd_ptr() const { return at<3>().as_uint64(); }
+};
+
+class ChromeWindowHandleEventInfo : public ::protozero::Message {
+ public:
+  using Decoder = ChromeWindowHandleEventInfo_Decoder;
+  enum : int32_t {
+    kDpiFieldNumber = 1,
+    kMessageIdFieldNumber = 2,
+    kHwndPtrFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeWindowHandleEventInfo"; }
+
+
+  using FieldMetadata_Dpi =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ChromeWindowHandleEventInfo>;
+
+  static constexpr FieldMetadata_Dpi kDpi{};
+  void set_dpi(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dpi::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_MessageId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ChromeWindowHandleEventInfo>;
+
+  static constexpr FieldMetadata_MessageId kMessageId{};
+  void set_message_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MessageId::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_HwndPtr =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64,
+      uint64_t,
+      ChromeWindowHandleEventInfo>;
+
+  static constexpr FieldMetadata_HwndPtr kHwndPtr{};
+  void set_hwnd_ptr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_HwndPtr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/log_message.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_LOG_MESSAGE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_LOG_MESSAGE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+namespace perfetto_pbzero_enum_LogMessage {
+enum Priority : int32_t;
+}  // namespace perfetto_pbzero_enum_LogMessage
+using LogMessage_Priority = perfetto_pbzero_enum_LogMessage::Priority;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_LogMessage {
+enum Priority : int32_t {
+  PRIO_UNSPECIFIED = 0,
+  PRIO_UNUSED = 1,
+  PRIO_VERBOSE = 2,
+  PRIO_DEBUG = 3,
+  PRIO_INFO = 4,
+  PRIO_WARN = 5,
+  PRIO_ERROR = 6,
+  PRIO_FATAL = 7,
+};
+} // namespace perfetto_pbzero_enum_LogMessage
+using LogMessage_Priority = perfetto_pbzero_enum_LogMessage::Priority;
+
+
+constexpr LogMessage_Priority LogMessage_Priority_MIN = LogMessage_Priority::PRIO_UNSPECIFIED;
+constexpr LogMessage_Priority LogMessage_Priority_MAX = LogMessage_Priority::PRIO_FATAL;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* LogMessage_Priority_Name(::perfetto::protos::pbzero::LogMessage_Priority value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::LogMessage_Priority::PRIO_UNSPECIFIED:
+    return "PRIO_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::LogMessage_Priority::PRIO_UNUSED:
+    return "PRIO_UNUSED";
+
+  case ::perfetto::protos::pbzero::LogMessage_Priority::PRIO_VERBOSE:
+    return "PRIO_VERBOSE";
+
+  case ::perfetto::protos::pbzero::LogMessage_Priority::PRIO_DEBUG:
+    return "PRIO_DEBUG";
+
+  case ::perfetto::protos::pbzero::LogMessage_Priority::PRIO_INFO:
+    return "PRIO_INFO";
+
+  case ::perfetto::protos::pbzero::LogMessage_Priority::PRIO_WARN:
+    return "PRIO_WARN";
+
+  case ::perfetto::protos::pbzero::LogMessage_Priority::PRIO_ERROR:
+    return "PRIO_ERROR";
+
+  case ::perfetto::protos::pbzero::LogMessage_Priority::PRIO_FATAL:
+    return "PRIO_FATAL";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class LogMessageBody_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  LogMessageBody_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit LogMessageBody_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit LogMessageBody_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_body() const { return at<2>().valid(); }
+  ::protozero::ConstChars body() const { return at<2>().as_string(); }
+};
+
+class LogMessageBody : public ::protozero::Message {
+ public:
+  using Decoder = LogMessageBody_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kBodyFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.LogMessageBody"; }
+
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      LogMessageBody>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::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_Body =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      LogMessageBody>;
+
+  static constexpr FieldMetadata_Body kBody{};
+  void set_body(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Body::kFieldId, data, size);
+  }
+  void set_body(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Body::kFieldId, chars.data, chars.size);
+  }
+  void set_body(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Body::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 LogMessage_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  LogMessage_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit LogMessage_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit LogMessage_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_source_location_iid() const { return at<1>().valid(); }
+  uint64_t source_location_iid() const { return at<1>().as_uint64(); }
+  bool has_body_iid() const { return at<2>().valid(); }
+  uint64_t body_iid() const { return at<2>().as_uint64(); }
+  bool has_prio() const { return at<3>().valid(); }
+  int32_t prio() const { return at<3>().as_int32(); }
+};
+
+class LogMessage : public ::protozero::Message {
+ public:
+  using Decoder = LogMessage_Decoder;
+  enum : int32_t {
+    kSourceLocationIidFieldNumber = 1,
+    kBodyIidFieldNumber = 2,
+    kPrioFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.LogMessage"; }
+
+
+  using Priority = ::perfetto::protos::pbzero::LogMessage_Priority;
+  static inline const char* Priority_Name(Priority value) {
+    return ::perfetto::protos::pbzero::LogMessage_Priority_Name(value);
+  }
+  static inline const Priority PRIO_UNSPECIFIED = Priority::PRIO_UNSPECIFIED;
+  static inline const Priority PRIO_UNUSED = Priority::PRIO_UNUSED;
+  static inline const Priority PRIO_VERBOSE = Priority::PRIO_VERBOSE;
+  static inline const Priority PRIO_DEBUG = Priority::PRIO_DEBUG;
+  static inline const Priority PRIO_INFO = Priority::PRIO_INFO;
+  static inline const Priority PRIO_WARN = Priority::PRIO_WARN;
+  static inline const Priority PRIO_ERROR = Priority::PRIO_ERROR;
+  static inline const Priority PRIO_FATAL = Priority::PRIO_FATAL;
+
+  using FieldMetadata_SourceLocationIid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      LogMessage>;
+
+  static constexpr FieldMetadata_SourceLocationIid kSourceLocationIid{};
+  void set_source_location_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SourceLocationIid::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_BodyIid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      LogMessage>;
+
+  static constexpr FieldMetadata_BodyIid kBodyIid{};
+  void set_body_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BodyIid::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_Prio =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      LogMessage_Priority,
+      LogMessage>;
+
+  static constexpr FieldMetadata_Prio kPrio{};
+  void set_prio(LogMessage_Priority value) {
+    static constexpr uint32_t field_id = FieldMetadata_Prio::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.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/pixel_modem.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_PIXEL_MODEM_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_PIXEL_MODEM_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class PixelModemEventInsight_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  PixelModemEventInsight_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PixelModemEventInsight_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PixelModemEventInsight_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_detokenized_message() const { return at<1>().valid(); }
+  ::protozero::ConstChars detokenized_message() const { return at<1>().as_string(); }
+};
+
+class PixelModemEventInsight : public ::protozero::Message {
+ public:
+  using Decoder = PixelModemEventInsight_Decoder;
+  enum : int32_t {
+    kDetokenizedMessageFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PixelModemEventInsight"; }
+
+
+  using FieldMetadata_DetokenizedMessage =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PixelModemEventInsight>;
+
+  static constexpr FieldMetadata_DetokenizedMessage kDetokenizedMessage{};
+  void set_detokenized_message(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DetokenizedMessage::kFieldId, data, size);
+  }
+  void set_detokenized_message(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_DetokenizedMessage::kFieldId, chars.data, chars.size);
+  }
+  void set_detokenized_message(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_DetokenizedMessage::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/process_descriptor.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_PROCESS_DESCRIPTOR_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_PROCESS_DESCRIPTOR_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+namespace perfetto_pbzero_enum_ProcessDescriptor {
+enum ChromeProcessType : int32_t;
+}  // namespace perfetto_pbzero_enum_ProcessDescriptor
+using ProcessDescriptor_ChromeProcessType = perfetto_pbzero_enum_ProcessDescriptor::ChromeProcessType;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_ProcessDescriptor {
+enum ChromeProcessType : int32_t {
+  PROCESS_UNSPECIFIED = 0,
+  PROCESS_BROWSER = 1,
+  PROCESS_RENDERER = 2,
+  PROCESS_UTILITY = 3,
+  PROCESS_ZYGOTE = 4,
+  PROCESS_SANDBOX_HELPER = 5,
+  PROCESS_GPU = 6,
+  PROCESS_PPAPI_PLUGIN = 7,
+  PROCESS_PPAPI_BROKER = 8,
+};
+} // namespace perfetto_pbzero_enum_ProcessDescriptor
+using ProcessDescriptor_ChromeProcessType = perfetto_pbzero_enum_ProcessDescriptor::ChromeProcessType;
+
+
+constexpr ProcessDescriptor_ChromeProcessType ProcessDescriptor_ChromeProcessType_MIN = ProcessDescriptor_ChromeProcessType::PROCESS_UNSPECIFIED;
+constexpr ProcessDescriptor_ChromeProcessType ProcessDescriptor_ChromeProcessType_MAX = ProcessDescriptor_ChromeProcessType::PROCESS_PPAPI_BROKER;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ProcessDescriptor_ChromeProcessType_Name(::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType::PROCESS_UNSPECIFIED:
+    return "PROCESS_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType::PROCESS_BROWSER:
+    return "PROCESS_BROWSER";
+
+  case ::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType::PROCESS_RENDERER:
+    return "PROCESS_RENDERER";
+
+  case ::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType::PROCESS_UTILITY:
+    return "PROCESS_UTILITY";
+
+  case ::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType::PROCESS_ZYGOTE:
+    return "PROCESS_ZYGOTE";
+
+  case ::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType::PROCESS_SANDBOX_HELPER:
+    return "PROCESS_SANDBOX_HELPER";
+
+  case ::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType::PROCESS_GPU:
+    return "PROCESS_GPU";
+
+  case ::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType::PROCESS_PPAPI_PLUGIN:
+    return "PROCESS_PPAPI_PLUGIN";
+
+  case ::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType::PROCESS_PPAPI_BROKER:
+    return "PROCESS_PPAPI_BROKER";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class ProcessDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ProcessDescriptor_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProcessDescriptor_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProcessDescriptor_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  int32_t pid() const { return at<1>().as_int32(); }
+  bool has_cmdline() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> cmdline() const { return GetRepeated<::protozero::ConstChars>(2); }
+  bool has_process_name() const { return at<6>().valid(); }
+  ::protozero::ConstChars process_name() const { return at<6>().as_string(); }
+  bool has_process_priority() const { return at<5>().valid(); }
+  int32_t process_priority() const { return at<5>().as_int32(); }
+  bool has_start_timestamp_ns() const { return at<7>().valid(); }
+  int64_t start_timestamp_ns() const { return at<7>().as_int64(); }
+  bool has_chrome_process_type() const { return at<4>().valid(); }
+  int32_t chrome_process_type() const { return at<4>().as_int32(); }
+  bool has_legacy_sort_index() const { return at<3>().valid(); }
+  int32_t legacy_sort_index() const { return at<3>().as_int32(); }
+  bool has_process_labels() const { return at<8>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> process_labels() const { return GetRepeated<::protozero::ConstChars>(8); }
+};
+
+class ProcessDescriptor : public ::protozero::Message {
+ public:
+  using Decoder = ProcessDescriptor_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kCmdlineFieldNumber = 2,
+    kProcessNameFieldNumber = 6,
+    kProcessPriorityFieldNumber = 5,
+    kStartTimestampNsFieldNumber = 7,
+    kChromeProcessTypeFieldNumber = 4,
+    kLegacySortIndexFieldNumber = 3,
+    kProcessLabelsFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProcessDescriptor"; }
+
+
+  using ChromeProcessType = ::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType;
+  static inline const char* ChromeProcessType_Name(ChromeProcessType value) {
+    return ::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType_Name(value);
+  }
+  static inline const ChromeProcessType PROCESS_UNSPECIFIED = ChromeProcessType::PROCESS_UNSPECIFIED;
+  static inline const ChromeProcessType PROCESS_BROWSER = ChromeProcessType::PROCESS_BROWSER;
+  static inline const ChromeProcessType PROCESS_RENDERER = ChromeProcessType::PROCESS_RENDERER;
+  static inline const ChromeProcessType PROCESS_UTILITY = ChromeProcessType::PROCESS_UTILITY;
+  static inline const ChromeProcessType PROCESS_ZYGOTE = ChromeProcessType::PROCESS_ZYGOTE;
+  static inline const ChromeProcessType PROCESS_SANDBOX_HELPER = ChromeProcessType::PROCESS_SANDBOX_HELPER;
+  static inline const ChromeProcessType PROCESS_GPU = ChromeProcessType::PROCESS_GPU;
+  static inline const ChromeProcessType PROCESS_PPAPI_PLUGIN = ChromeProcessType::PROCESS_PPAPI_PLUGIN;
+  static inline const ChromeProcessType PROCESS_PPAPI_BROKER = ChromeProcessType::PROCESS_PPAPI_BROKER;
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ProcessDescriptor>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_Cmdline =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ProcessDescriptor>;
+
+  static constexpr FieldMetadata_Cmdline kCmdline{};
+  void add_cmdline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cmdline::kFieldId, data, size);
+  }
+  void add_cmdline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Cmdline::kFieldId, chars.data, chars.size);
+  }
+  void add_cmdline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cmdline::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_ProcessName =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ProcessDescriptor>;
+
+  static constexpr FieldMetadata_ProcessName kProcessName{};
+  void set_process_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ProcessName::kFieldId, data, size);
+  }
+  void set_process_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ProcessName::kFieldId, chars.data, chars.size);
+  }
+  void set_process_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProcessName::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_ProcessPriority =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ProcessDescriptor>;
+
+  static constexpr FieldMetadata_ProcessPriority kProcessPriority{};
+  void set_process_priority(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProcessPriority::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_StartTimestampNs =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ProcessDescriptor>;
+
+  static constexpr FieldMetadata_StartTimestampNs kStartTimestampNs{};
+  void set_start_timestamp_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StartTimestampNs::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_ChromeProcessType =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ProcessDescriptor_ChromeProcessType,
+      ProcessDescriptor>;
+
+  static constexpr FieldMetadata_ChromeProcessType kChromeProcessType{};
+  void set_chrome_process_type(ProcessDescriptor_ChromeProcessType value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChromeProcessType::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_LegacySortIndex =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ProcessDescriptor>;
+
+  static constexpr FieldMetadata_LegacySortIndex kLegacySortIndex{};
+  void set_legacy_sort_index(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LegacySortIndex::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_ProcessLabels =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ProcessDescriptor>;
+
+  static constexpr FieldMetadata_ProcessLabels kProcessLabels{};
+  void add_process_labels(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ProcessLabels::kFieldId, data, size);
+  }
+  void add_process_labels(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ProcessLabels::kFieldId, chars.data, chars.size);
+  }
+  void add_process_labels(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProcessLabels::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/range_of_interest.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_RANGE_OF_INTEREST_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_RANGE_OF_INTEREST_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class TrackEventRangeOfInterest_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrackEventRangeOfInterest_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrackEventRangeOfInterest_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrackEventRangeOfInterest_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_start_us() const { return at<1>().valid(); }
+  int64_t start_us() const { return at<1>().as_int64(); }
+};
+
+class TrackEventRangeOfInterest : public ::protozero::Message {
+ public:
+  using Decoder = TrackEventRangeOfInterest_Decoder;
+  enum : int32_t {
+    kStartUsFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrackEventRangeOfInterest"; }
+
+
+  using FieldMetadata_StartUs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TrackEventRangeOfInterest>;
+
+  static constexpr FieldMetadata_StartUs kStartUs{};
+  void set_start_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StartUs::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/screenshot.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_SCREENSHOT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_SCREENSHOT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class Screenshot_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Screenshot_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Screenshot_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Screenshot_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_jpg_image() const { return at<1>().valid(); }
+  ::protozero::ConstBytes jpg_image() const { return at<1>().as_bytes(); }
+};
+
+class Screenshot : public ::protozero::Message {
+ public:
+  using Decoder = Screenshot_Decoder;
+  enum : int32_t {
+    kJpgImageFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Screenshot"; }
+
+
+  using FieldMetadata_JpgImage =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      Screenshot>;
+
+  static constexpr FieldMetadata_JpgImage kJpgImage{};
+  void set_jpg_image(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_JpgImage::kFieldId, data, size);
+  }
+  void set_jpg_image(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_JpgImage::kFieldId, bytes.data, bytes.size);
+  }
+  void set_jpg_image(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_JpgImage::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/source_location.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_SOURCE_LOCATION_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_SOURCE_LOCATION_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class SourceLocation_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SourceLocation_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SourceLocation_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SourceLocation_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_file_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars file_name() const { return at<2>().as_string(); }
+  bool has_function_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars function_name() const { return at<3>().as_string(); }
+  bool has_line_number() const { return at<4>().valid(); }
+  uint32_t line_number() const { return at<4>().as_uint32(); }
+};
+
+class SourceLocation : public ::protozero::Message {
+ public:
+  using Decoder = SourceLocation_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kFileNameFieldNumber = 2,
+    kFunctionNameFieldNumber = 3,
+    kLineNumberFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SourceLocation"; }
+
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SourceLocation>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::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_FileName =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SourceLocation>;
+
+  static constexpr FieldMetadata_FileName kFileName{};
+  void set_file_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_FileName::kFieldId, data, size);
+  }
+  void set_file_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_FileName::kFieldId, chars.data, chars.size);
+  }
+  void set_file_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_FileName::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_FunctionName =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SourceLocation>;
+
+  static constexpr FieldMetadata_FunctionName kFunctionName{};
+  void set_function_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_FunctionName::kFieldId, data, size);
+  }
+  void set_function_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_FunctionName::kFieldId, chars.data, chars.size);
+  }
+  void set_function_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_FunctionName::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_LineNumber =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SourceLocation>;
+
+  static constexpr FieldMetadata_LineNumber kLineNumber{};
+  void set_line_number(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LineNumber::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 UnsymbolizedSourceLocation_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  UnsymbolizedSourceLocation_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit UnsymbolizedSourceLocation_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit UnsymbolizedSourceLocation_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_mapping_id() const { return at<2>().valid(); }
+  uint64_t mapping_id() const { return at<2>().as_uint64(); }
+  bool has_rel_pc() const { return at<3>().valid(); }
+  uint64_t rel_pc() const { return at<3>().as_uint64(); }
+};
+
+class UnsymbolizedSourceLocation : public ::protozero::Message {
+ public:
+  using Decoder = UnsymbolizedSourceLocation_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kMappingIdFieldNumber = 2,
+    kRelPcFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.UnsymbolizedSourceLocation"; }
+
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      UnsymbolizedSourceLocation>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::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_MappingId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      UnsymbolizedSourceLocation>;
+
+  static constexpr FieldMetadata_MappingId kMappingId{};
+  void set_mapping_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MappingId::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_RelPc =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      UnsymbolizedSourceLocation>;
+
+  static constexpr FieldMetadata_RelPc kRelPc{};
+  void set_rel_pc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RelPc::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/task_execution.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TASK_EXECUTION_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TASK_EXECUTION_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class TaskExecution_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TaskExecution_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TaskExecution_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TaskExecution_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_posted_from_iid() const { return at<1>().valid(); }
+  uint64_t posted_from_iid() const { return at<1>().as_uint64(); }
+};
+
+class TaskExecution : public ::protozero::Message {
+ public:
+  using Decoder = TaskExecution_Decoder;
+  enum : int32_t {
+    kPostedFromIidFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TaskExecution"; }
+
+
+  using FieldMetadata_PostedFromIid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TaskExecution>;
+
+  static constexpr FieldMetadata_PostedFromIid kPostedFromIid{};
+  void set_posted_from_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PostedFromIid::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/thread_descriptor.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_THREAD_DESCRIPTOR_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_THREAD_DESCRIPTOR_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+namespace perfetto_pbzero_enum_ThreadDescriptor {
+enum ChromeThreadType : int32_t;
+}  // namespace perfetto_pbzero_enum_ThreadDescriptor
+using ThreadDescriptor_ChromeThreadType = perfetto_pbzero_enum_ThreadDescriptor::ChromeThreadType;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_ThreadDescriptor {
+enum ChromeThreadType : int32_t {
+  CHROME_THREAD_UNSPECIFIED = 0,
+  CHROME_THREAD_MAIN = 1,
+  CHROME_THREAD_IO = 2,
+  CHROME_THREAD_POOL_BG_WORKER = 3,
+  CHROME_THREAD_POOL_FG_WORKER = 4,
+  CHROME_THREAD_POOL_FB_BLOCKING = 5,
+  CHROME_THREAD_POOL_BG_BLOCKING = 6,
+  CHROME_THREAD_POOL_SERVICE = 7,
+  CHROME_THREAD_COMPOSITOR = 8,
+  CHROME_THREAD_VIZ_COMPOSITOR = 9,
+  CHROME_THREAD_COMPOSITOR_WORKER = 10,
+  CHROME_THREAD_SERVICE_WORKER = 11,
+  CHROME_THREAD_MEMORY_INFRA = 50,
+  CHROME_THREAD_SAMPLING_PROFILER = 51,
+};
+} // namespace perfetto_pbzero_enum_ThreadDescriptor
+using ThreadDescriptor_ChromeThreadType = perfetto_pbzero_enum_ThreadDescriptor::ChromeThreadType;
+
+
+constexpr ThreadDescriptor_ChromeThreadType ThreadDescriptor_ChromeThreadType_MIN = ThreadDescriptor_ChromeThreadType::CHROME_THREAD_UNSPECIFIED;
+constexpr ThreadDescriptor_ChromeThreadType ThreadDescriptor_ChromeThreadType_MAX = ThreadDescriptor_ChromeThreadType::CHROME_THREAD_SAMPLING_PROFILER;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ThreadDescriptor_ChromeThreadType_Name(::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType::CHROME_THREAD_UNSPECIFIED:
+    return "CHROME_THREAD_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType::CHROME_THREAD_MAIN:
+    return "CHROME_THREAD_MAIN";
+
+  case ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType::CHROME_THREAD_IO:
+    return "CHROME_THREAD_IO";
+
+  case ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType::CHROME_THREAD_POOL_BG_WORKER:
+    return "CHROME_THREAD_POOL_BG_WORKER";
+
+  case ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType::CHROME_THREAD_POOL_FG_WORKER:
+    return "CHROME_THREAD_POOL_FG_WORKER";
+
+  case ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType::CHROME_THREAD_POOL_FB_BLOCKING:
+    return "CHROME_THREAD_POOL_FB_BLOCKING";
+
+  case ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType::CHROME_THREAD_POOL_BG_BLOCKING:
+    return "CHROME_THREAD_POOL_BG_BLOCKING";
+
+  case ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType::CHROME_THREAD_POOL_SERVICE:
+    return "CHROME_THREAD_POOL_SERVICE";
+
+  case ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType::CHROME_THREAD_COMPOSITOR:
+    return "CHROME_THREAD_COMPOSITOR";
+
+  case ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType::CHROME_THREAD_VIZ_COMPOSITOR:
+    return "CHROME_THREAD_VIZ_COMPOSITOR";
+
+  case ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType::CHROME_THREAD_COMPOSITOR_WORKER:
+    return "CHROME_THREAD_COMPOSITOR_WORKER";
+
+  case ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType::CHROME_THREAD_SERVICE_WORKER:
+    return "CHROME_THREAD_SERVICE_WORKER";
+
+  case ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType::CHROME_THREAD_MEMORY_INFRA:
+    return "CHROME_THREAD_MEMORY_INFRA";
+
+  case ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType::CHROME_THREAD_SAMPLING_PROFILER:
+    return "CHROME_THREAD_SAMPLING_PROFILER";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class ThreadDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ThreadDescriptor_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ThreadDescriptor_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ThreadDescriptor_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  int32_t pid() const { return at<1>().as_int32(); }
+  bool has_tid() const { return at<2>().valid(); }
+  int32_t tid() const { return at<2>().as_int32(); }
+  bool has_thread_name() const { return at<5>().valid(); }
+  ::protozero::ConstChars thread_name() const { return at<5>().as_string(); }
+  bool has_chrome_thread_type() const { return at<4>().valid(); }
+  int32_t chrome_thread_type() const { return at<4>().as_int32(); }
+  bool has_reference_timestamp_us() const { return at<6>().valid(); }
+  int64_t reference_timestamp_us() const { return at<6>().as_int64(); }
+  bool has_reference_thread_time_us() const { return at<7>().valid(); }
+  int64_t reference_thread_time_us() const { return at<7>().as_int64(); }
+  bool has_reference_thread_instruction_count() const { return at<8>().valid(); }
+  int64_t reference_thread_instruction_count() const { return at<8>().as_int64(); }
+  bool has_legacy_sort_index() const { return at<3>().valid(); }
+  int32_t legacy_sort_index() const { return at<3>().as_int32(); }
+};
+
+class ThreadDescriptor : public ::protozero::Message {
+ public:
+  using Decoder = ThreadDescriptor_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kTidFieldNumber = 2,
+    kThreadNameFieldNumber = 5,
+    kChromeThreadTypeFieldNumber = 4,
+    kReferenceTimestampUsFieldNumber = 6,
+    kReferenceThreadTimeUsFieldNumber = 7,
+    kReferenceThreadInstructionCountFieldNumber = 8,
+    kLegacySortIndexFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ThreadDescriptor"; }
+
+
+  using ChromeThreadType = ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType;
+  static inline const char* ChromeThreadType_Name(ChromeThreadType value) {
+    return ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType_Name(value);
+  }
+  static inline const ChromeThreadType CHROME_THREAD_UNSPECIFIED = ChromeThreadType::CHROME_THREAD_UNSPECIFIED;
+  static inline const ChromeThreadType CHROME_THREAD_MAIN = ChromeThreadType::CHROME_THREAD_MAIN;
+  static inline const ChromeThreadType CHROME_THREAD_IO = ChromeThreadType::CHROME_THREAD_IO;
+  static inline const ChromeThreadType CHROME_THREAD_POOL_BG_WORKER = ChromeThreadType::CHROME_THREAD_POOL_BG_WORKER;
+  static inline const ChromeThreadType CHROME_THREAD_POOL_FG_WORKER = ChromeThreadType::CHROME_THREAD_POOL_FG_WORKER;
+  static inline const ChromeThreadType CHROME_THREAD_POOL_FB_BLOCKING = ChromeThreadType::CHROME_THREAD_POOL_FB_BLOCKING;
+  static inline const ChromeThreadType CHROME_THREAD_POOL_BG_BLOCKING = ChromeThreadType::CHROME_THREAD_POOL_BG_BLOCKING;
+  static inline const ChromeThreadType CHROME_THREAD_POOL_SERVICE = ChromeThreadType::CHROME_THREAD_POOL_SERVICE;
+  static inline const ChromeThreadType CHROME_THREAD_COMPOSITOR = ChromeThreadType::CHROME_THREAD_COMPOSITOR;
+  static inline const ChromeThreadType CHROME_THREAD_VIZ_COMPOSITOR = ChromeThreadType::CHROME_THREAD_VIZ_COMPOSITOR;
+  static inline const ChromeThreadType CHROME_THREAD_COMPOSITOR_WORKER = ChromeThreadType::CHROME_THREAD_COMPOSITOR_WORKER;
+  static inline const ChromeThreadType CHROME_THREAD_SERVICE_WORKER = ChromeThreadType::CHROME_THREAD_SERVICE_WORKER;
+  static inline const ChromeThreadType CHROME_THREAD_MEMORY_INFRA = ChromeThreadType::CHROME_THREAD_MEMORY_INFRA;
+  static inline const ChromeThreadType CHROME_THREAD_SAMPLING_PROFILER = ChromeThreadType::CHROME_THREAD_SAMPLING_PROFILER;
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ThreadDescriptor>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_Tid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ThreadDescriptor>;
+
+  static constexpr FieldMetadata_Tid kTid{};
+  void set_tid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tid::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_ThreadName =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ThreadDescriptor>;
+
+  static constexpr FieldMetadata_ThreadName kThreadName{};
+  void set_thread_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ThreadName::kFieldId, data, size);
+  }
+  void set_thread_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ThreadName::kFieldId, chars.data, chars.size);
+  }
+  void set_thread_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ThreadName::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_ChromeThreadType =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ThreadDescriptor_ChromeThreadType,
+      ThreadDescriptor>;
+
+  static constexpr FieldMetadata_ChromeThreadType kChromeThreadType{};
+  void set_chrome_thread_type(ThreadDescriptor_ChromeThreadType value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChromeThreadType::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_ReferenceTimestampUs =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ThreadDescriptor>;
+
+  static constexpr FieldMetadata_ReferenceTimestampUs kReferenceTimestampUs{};
+  void set_reference_timestamp_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReferenceTimestampUs::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_ReferenceThreadTimeUs =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ThreadDescriptor>;
+
+  static constexpr FieldMetadata_ReferenceThreadTimeUs kReferenceThreadTimeUs{};
+  void set_reference_thread_time_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReferenceThreadTimeUs::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_ReferenceThreadInstructionCount =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ThreadDescriptor>;
+
+  static constexpr FieldMetadata_ReferenceThreadInstructionCount kReferenceThreadInstructionCount{};
+  void set_reference_thread_instruction_count(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReferenceThreadInstructionCount::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_LegacySortIndex =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ThreadDescriptor>;
+
+  static constexpr FieldMetadata_LegacySortIndex kLegacySortIndex{};
+  void set_legacy_sort_index(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LegacySortIndex::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/perfetto/perfetto_metatrace.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PERFETTO_PERFETTO_METATRACE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PERFETTO_PERFETTO_METATRACE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class PerfettoMetatrace_Arg;
+class PerfettoMetatrace_InternedString;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class PerfettoMetatrace_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/11, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  PerfettoMetatrace_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PerfettoMetatrace_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PerfettoMetatrace_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_event_id() const { return at<1>().valid(); }
+  uint32_t event_id() const { return at<1>().as_uint32(); }
+  bool has_counter_id() const { return at<2>().valid(); }
+  uint32_t counter_id() const { return at<2>().as_uint32(); }
+  bool has_event_name() const { return at<8>().valid(); }
+  ::protozero::ConstChars event_name() const { return at<8>().as_string(); }
+  bool has_event_name_iid() const { return at<11>().valid(); }
+  uint64_t event_name_iid() const { return at<11>().as_uint64(); }
+  bool has_counter_name() const { return at<9>().valid(); }
+  ::protozero::ConstChars counter_name() const { return at<9>().as_string(); }
+  bool has_event_duration_ns() const { return at<3>().valid(); }
+  uint64_t event_duration_ns() const { return at<3>().as_uint64(); }
+  bool has_counter_value() const { return at<4>().valid(); }
+  int32_t counter_value() const { return at<4>().as_int32(); }
+  bool has_thread_id() const { return at<5>().valid(); }
+  uint32_t thread_id() const { return at<5>().as_uint32(); }
+  bool has_has_overruns() const { return at<6>().valid(); }
+  bool has_overruns() const { return at<6>().as_bool(); }
+  bool has_args() const { return at<7>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> args() const { return GetRepeated<::protozero::ConstBytes>(7); }
+  bool has_interned_strings() const { return at<10>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> interned_strings() const { return GetRepeated<::protozero::ConstBytes>(10); }
+};
+
+class PerfettoMetatrace : public ::protozero::Message {
+ public:
+  using Decoder = PerfettoMetatrace_Decoder;
+  enum : int32_t {
+    kEventIdFieldNumber = 1,
+    kCounterIdFieldNumber = 2,
+    kEventNameFieldNumber = 8,
+    kEventNameIidFieldNumber = 11,
+    kCounterNameFieldNumber = 9,
+    kEventDurationNsFieldNumber = 3,
+    kCounterValueFieldNumber = 4,
+    kThreadIdFieldNumber = 5,
+    kHasOverrunsFieldNumber = 6,
+    kArgsFieldNumber = 7,
+    kInternedStringsFieldNumber = 10,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PerfettoMetatrace"; }
+
+  using Arg = ::perfetto::protos::pbzero::PerfettoMetatrace_Arg;
+  using InternedString = ::perfetto::protos::pbzero::PerfettoMetatrace_InternedString;
+
+  using FieldMetadata_EventId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfettoMetatrace>;
+
+  static constexpr FieldMetadata_EventId kEventId{};
+  void set_event_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EventId::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_CounterId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfettoMetatrace>;
+
+  static constexpr FieldMetadata_CounterId kCounterId{};
+  void set_counter_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CounterId::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_EventName =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PerfettoMetatrace>;
+
+  static constexpr FieldMetadata_EventName kEventName{};
+  void set_event_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_EventName::kFieldId, data, size);
+  }
+  void set_event_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_EventName::kFieldId, chars.data, chars.size);
+  }
+  void set_event_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_EventName::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_EventNameIid =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PerfettoMetatrace>;
+
+  static constexpr FieldMetadata_EventNameIid kEventNameIid{};
+  void set_event_name_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EventNameIid::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_CounterName =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PerfettoMetatrace>;
+
+  static constexpr FieldMetadata_CounterName kCounterName{};
+  void set_counter_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_CounterName::kFieldId, data, size);
+  }
+  void set_counter_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_CounterName::kFieldId, chars.data, chars.size);
+  }
+  void set_counter_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_CounterName::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_EventDurationNs =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PerfettoMetatrace>;
+
+  static constexpr FieldMetadata_EventDurationNs kEventDurationNs{};
+  void set_event_duration_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EventDurationNs::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_CounterValue =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      PerfettoMetatrace>;
+
+  static constexpr FieldMetadata_CounterValue kCounterValue{};
+  void set_counter_value(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CounterValue::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_ThreadId =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfettoMetatrace>;
+
+  static constexpr FieldMetadata_ThreadId kThreadId{};
+  void set_thread_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ThreadId::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_HasOverruns =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      PerfettoMetatrace>;
+
+  static constexpr FieldMetadata_HasOverruns kHasOverruns{};
+  void set_has_overruns(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_HasOverruns::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_Args =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PerfettoMetatrace_Arg,
+      PerfettoMetatrace>;
+
+  static constexpr FieldMetadata_Args kArgs{};
+  template <typename T = PerfettoMetatrace_Arg> T* add_args() {
+    return BeginNestedMessage<T>(7);
+  }
+
+
+  using FieldMetadata_InternedStrings =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PerfettoMetatrace_InternedString,
+      PerfettoMetatrace>;
+
+  static constexpr FieldMetadata_InternedStrings kInternedStrings{};
+  template <typename T = PerfettoMetatrace_InternedString> T* add_interned_strings() {
+    return BeginNestedMessage<T>(10);
+  }
+
+};
+
+class PerfettoMetatrace_InternedString_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  PerfettoMetatrace_InternedString_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PerfettoMetatrace_InternedString_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PerfettoMetatrace_InternedString_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_value() const { return at<2>().valid(); }
+  ::protozero::ConstChars value() const { return at<2>().as_string(); }
+};
+
+class PerfettoMetatrace_InternedString : public ::protozero::Message {
+ public:
+  using Decoder = PerfettoMetatrace_InternedString_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kValueFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PerfettoMetatrace.InternedString"; }
+
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PerfettoMetatrace_InternedString>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::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_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PerfettoMetatrace_InternedString>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Value::kFieldId, data, size);
+  }
+  void set_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Value::kFieldId, chars.data, chars.size);
+  }
+  void set_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::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 PerfettoMetatrace_Arg_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  PerfettoMetatrace_Arg_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PerfettoMetatrace_Arg_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PerfettoMetatrace_Arg_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_key() const { return at<1>().valid(); }
+  ::protozero::ConstChars key() const { return at<1>().as_string(); }
+  bool has_key_iid() const { return at<3>().valid(); }
+  uint64_t key_iid() const { return at<3>().as_uint64(); }
+  bool has_value() const { return at<2>().valid(); }
+  ::protozero::ConstChars value() const { return at<2>().as_string(); }
+  bool has_value_iid() const { return at<4>().valid(); }
+  uint64_t value_iid() const { return at<4>().as_uint64(); }
+};
+
+class PerfettoMetatrace_Arg : public ::protozero::Message {
+ public:
+  using Decoder = PerfettoMetatrace_Arg_Decoder;
+  enum : int32_t {
+    kKeyFieldNumber = 1,
+    kKeyIidFieldNumber = 3,
+    kValueFieldNumber = 2,
+    kValueIidFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PerfettoMetatrace.Arg"; }
+
+
+  using FieldMetadata_Key =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PerfettoMetatrace_Arg>;
+
+  static constexpr FieldMetadata_Key kKey{};
+  void set_key(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Key::kFieldId, data, size);
+  }
+  void set_key(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Key::kFieldId, chars.data, chars.size);
+  }
+  void set_key(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Key::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_KeyIid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PerfettoMetatrace_Arg>;
+
+  static constexpr FieldMetadata_KeyIid kKeyIid{};
+  void set_key_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KeyIid::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_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PerfettoMetatrace_Arg>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Value::kFieldId, data, size);
+  }
+  void set_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Value::kFieldId, chars.data, chars.size);
+  }
+  void set_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::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_ValueIid =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PerfettoMetatrace_Arg>;
+
+  static constexpr FieldMetadata_ValueIid kValueIid{};
+  void set_value_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ValueIid::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/perfetto/tracing_service_event.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PERFETTO_TRACING_SERVICE_EVENT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PERFETTO_TRACING_SERVICE_EVENT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class TracingServiceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TracingServiceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TracingServiceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TracingServiceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_tracing_started() const { return at<2>().valid(); }
+  bool tracing_started() const { return at<2>().as_bool(); }
+  bool has_all_data_sources_started() const { return at<1>().valid(); }
+  bool all_data_sources_started() const { return at<1>().as_bool(); }
+  bool has_all_data_sources_flushed() const { return at<3>().valid(); }
+  bool all_data_sources_flushed() const { return at<3>().as_bool(); }
+  bool has_read_tracing_buffers_completed() const { return at<4>().valid(); }
+  bool read_tracing_buffers_completed() const { return at<4>().as_bool(); }
+  bool has_tracing_disabled() const { return at<5>().valid(); }
+  bool tracing_disabled() const { return at<5>().as_bool(); }
+  bool has_seized_for_bugreport() const { return at<6>().valid(); }
+  bool seized_for_bugreport() const { return at<6>().as_bool(); }
+};
+
+class TracingServiceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TracingServiceEvent_Decoder;
+  enum : int32_t {
+    kTracingStartedFieldNumber = 2,
+    kAllDataSourcesStartedFieldNumber = 1,
+    kAllDataSourcesFlushedFieldNumber = 3,
+    kReadTracingBuffersCompletedFieldNumber = 4,
+    kTracingDisabledFieldNumber = 5,
+    kSeizedForBugreportFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TracingServiceEvent"; }
+
+
+  using FieldMetadata_TracingStarted =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TracingServiceEvent>;
+
+  static constexpr FieldMetadata_TracingStarted kTracingStarted{};
+  void set_tracing_started(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_TracingStarted::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_AllDataSourcesStarted =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TracingServiceEvent>;
+
+  static constexpr FieldMetadata_AllDataSourcesStarted kAllDataSourcesStarted{};
+  void set_all_data_sources_started(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_AllDataSourcesStarted::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_AllDataSourcesFlushed =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TracingServiceEvent>;
+
+  static constexpr FieldMetadata_AllDataSourcesFlushed kAllDataSourcesFlushed{};
+  void set_all_data_sources_flushed(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_AllDataSourcesFlushed::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_ReadTracingBuffersCompleted =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TracingServiceEvent>;
+
+  static constexpr FieldMetadata_ReadTracingBuffersCompleted kReadTracingBuffersCompleted{};
+  void set_read_tracing_buffers_completed(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReadTracingBuffersCompleted::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_TracingDisabled =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TracingServiceEvent>;
+
+  static constexpr FieldMetadata_TracingDisabled kTracingDisabled{};
+  void set_tracing_disabled(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_TracingDisabled::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_SeizedForBugreport =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TracingServiceEvent>;
+
+  static constexpr FieldMetadata_SeizedForBugreport kSeizedForBugreport{};
+  void set_seized_for_bugreport(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_SeizedForBugreport::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/power/android_energy_estimation_breakdown.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_POWER_ANDROID_ENERGY_ESTIMATION_BREAKDOWN_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_POWER_ANDROID_ENERGY_ESTIMATION_BREAKDOWN_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class AndroidEnergyConsumerDescriptor;
+class AndroidEnergyEstimationBreakdown_EnergyUidBreakdown;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class AndroidEnergyEstimationBreakdown_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AndroidEnergyEstimationBreakdown_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidEnergyEstimationBreakdown_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidEnergyEstimationBreakdown_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_energy_consumer_descriptor() const { return at<1>().valid(); }
+  ::protozero::ConstBytes energy_consumer_descriptor() const { return at<1>().as_bytes(); }
+  bool has_energy_consumer_id() const { return at<2>().valid(); }
+  int32_t energy_consumer_id() const { return at<2>().as_int32(); }
+  bool has_energy_uws() const { return at<3>().valid(); }
+  int64_t energy_uws() const { return at<3>().as_int64(); }
+  bool has_per_uid_breakdown() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> per_uid_breakdown() const { return GetRepeated<::protozero::ConstBytes>(4); }
+};
+
+class AndroidEnergyEstimationBreakdown : public ::protozero::Message {
+ public:
+  using Decoder = AndroidEnergyEstimationBreakdown_Decoder;
+  enum : int32_t {
+    kEnergyConsumerDescriptorFieldNumber = 1,
+    kEnergyConsumerIdFieldNumber = 2,
+    kEnergyUwsFieldNumber = 3,
+    kPerUidBreakdownFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidEnergyEstimationBreakdown"; }
+
+  using EnergyUidBreakdown = ::perfetto::protos::pbzero::AndroidEnergyEstimationBreakdown_EnergyUidBreakdown;
+
+  using FieldMetadata_EnergyConsumerDescriptor =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidEnergyConsumerDescriptor,
+      AndroidEnergyEstimationBreakdown>;
+
+  static constexpr FieldMetadata_EnergyConsumerDescriptor kEnergyConsumerDescriptor{};
+  template <typename T = AndroidEnergyConsumerDescriptor> T* set_energy_consumer_descriptor() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_EnergyConsumerId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidEnergyEstimationBreakdown>;
+
+  static constexpr FieldMetadata_EnergyConsumerId kEnergyConsumerId{};
+  void set_energy_consumer_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EnergyConsumerId::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_EnergyUws =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidEnergyEstimationBreakdown>;
+
+  static constexpr FieldMetadata_EnergyUws kEnergyUws{};
+  void set_energy_uws(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EnergyUws::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_PerUidBreakdown =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidEnergyEstimationBreakdown_EnergyUidBreakdown,
+      AndroidEnergyEstimationBreakdown>;
+
+  static constexpr FieldMetadata_PerUidBreakdown kPerUidBreakdown{};
+  template <typename T = AndroidEnergyEstimationBreakdown_EnergyUidBreakdown> T* add_per_uid_breakdown() {
+    return BeginNestedMessage<T>(4);
+  }
+
+};
+
+class AndroidEnergyEstimationBreakdown_EnergyUidBreakdown_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AndroidEnergyEstimationBreakdown_EnergyUidBreakdown_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidEnergyEstimationBreakdown_EnergyUidBreakdown_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidEnergyEstimationBreakdown_EnergyUidBreakdown_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_uid() const { return at<1>().valid(); }
+  int32_t uid() const { return at<1>().as_int32(); }
+  bool has_energy_uws() const { return at<2>().valid(); }
+  int64_t energy_uws() const { return at<2>().as_int64(); }
+};
+
+class AndroidEnergyEstimationBreakdown_EnergyUidBreakdown : public ::protozero::Message {
+ public:
+  using Decoder = AndroidEnergyEstimationBreakdown_EnergyUidBreakdown_Decoder;
+  enum : int32_t {
+    kUidFieldNumber = 1,
+    kEnergyUwsFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidEnergyEstimationBreakdown.EnergyUidBreakdown"; }
+
+
+  using FieldMetadata_Uid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidEnergyEstimationBreakdown_EnergyUidBreakdown>;
+
+  static constexpr FieldMetadata_Uid kUid{};
+  void set_uid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Uid::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_EnergyUws =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidEnergyEstimationBreakdown_EnergyUidBreakdown>;
+
+  static constexpr FieldMetadata_EnergyUws kEnergyUws{};
+  void set_energy_uws(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EnergyUws::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/power/android_entity_state_residency.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_POWER_ANDROID_ENTITY_STATE_RESIDENCY_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_POWER_ANDROID_ENTITY_STATE_RESIDENCY_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class EntityStateResidency_PowerEntityState;
+class EntityStateResidency_StateResidency;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class EntityStateResidency_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  EntityStateResidency_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit EntityStateResidency_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit EntityStateResidency_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_power_entity_state() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> power_entity_state() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_residency() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> residency() const { return GetRepeated<::protozero::ConstBytes>(2); }
+};
+
+class EntityStateResidency : public ::protozero::Message {
+ public:
+  using Decoder = EntityStateResidency_Decoder;
+  enum : int32_t {
+    kPowerEntityStateFieldNumber = 1,
+    kResidencyFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.EntityStateResidency"; }
+
+  using PowerEntityState = ::perfetto::protos::pbzero::EntityStateResidency_PowerEntityState;
+  using StateResidency = ::perfetto::protos::pbzero::EntityStateResidency_StateResidency;
+
+  using FieldMetadata_PowerEntityState =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      EntityStateResidency_PowerEntityState,
+      EntityStateResidency>;
+
+  static constexpr FieldMetadata_PowerEntityState kPowerEntityState{};
+  template <typename T = EntityStateResidency_PowerEntityState> T* add_power_entity_state() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_Residency =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      EntityStateResidency_StateResidency,
+      EntityStateResidency>;
+
+  static constexpr FieldMetadata_Residency kResidency{};
+  template <typename T = EntityStateResidency_StateResidency> T* add_residency() {
+    return BeginNestedMessage<T>(2);
+  }
+
+};
+
+class EntityStateResidency_StateResidency_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  EntityStateResidency_StateResidency_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit EntityStateResidency_StateResidency_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit EntityStateResidency_StateResidency_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_entity_index() const { return at<1>().valid(); }
+  int32_t entity_index() const { return at<1>().as_int32(); }
+  bool has_state_index() const { return at<2>().valid(); }
+  int32_t state_index() const { return at<2>().as_int32(); }
+  bool has_total_time_in_state_ms() const { return at<3>().valid(); }
+  uint64_t total_time_in_state_ms() const { return at<3>().as_uint64(); }
+  bool has_total_state_entry_count() const { return at<4>().valid(); }
+  uint64_t total_state_entry_count() const { return at<4>().as_uint64(); }
+  bool has_last_entry_timestamp_ms() const { return at<5>().valid(); }
+  uint64_t last_entry_timestamp_ms() const { return at<5>().as_uint64(); }
+};
+
+class EntityStateResidency_StateResidency : public ::protozero::Message {
+ public:
+  using Decoder = EntityStateResidency_StateResidency_Decoder;
+  enum : int32_t {
+    kEntityIndexFieldNumber = 1,
+    kStateIndexFieldNumber = 2,
+    kTotalTimeInStateMsFieldNumber = 3,
+    kTotalStateEntryCountFieldNumber = 4,
+    kLastEntryTimestampMsFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.EntityStateResidency.StateResidency"; }
+
+
+  using FieldMetadata_EntityIndex =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      EntityStateResidency_StateResidency>;
+
+  static constexpr FieldMetadata_EntityIndex kEntityIndex{};
+  void set_entity_index(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EntityIndex::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_StateIndex =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      EntityStateResidency_StateResidency>;
+
+  static constexpr FieldMetadata_StateIndex kStateIndex{};
+  void set_state_index(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StateIndex::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_TotalTimeInStateMs =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      EntityStateResidency_StateResidency>;
+
+  static constexpr FieldMetadata_TotalTimeInStateMs kTotalTimeInStateMs{};
+  void set_total_time_in_state_ms(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TotalTimeInStateMs::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_TotalStateEntryCount =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      EntityStateResidency_StateResidency>;
+
+  static constexpr FieldMetadata_TotalStateEntryCount kTotalStateEntryCount{};
+  void set_total_state_entry_count(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TotalStateEntryCount::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_LastEntryTimestampMs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      EntityStateResidency_StateResidency>;
+
+  static constexpr FieldMetadata_LastEntryTimestampMs kLastEntryTimestampMs{};
+  void set_last_entry_timestamp_ms(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LastEntryTimestampMs::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 EntityStateResidency_PowerEntityState_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  EntityStateResidency_PowerEntityState_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit EntityStateResidency_PowerEntityState_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit EntityStateResidency_PowerEntityState_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_entity_index() const { return at<1>().valid(); }
+  int32_t entity_index() const { return at<1>().as_int32(); }
+  bool has_state_index() const { return at<2>().valid(); }
+  int32_t state_index() const { return at<2>().as_int32(); }
+  bool has_entity_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars entity_name() const { return at<3>().as_string(); }
+  bool has_state_name() const { return at<4>().valid(); }
+  ::protozero::ConstChars state_name() const { return at<4>().as_string(); }
+};
+
+class EntityStateResidency_PowerEntityState : public ::protozero::Message {
+ public:
+  using Decoder = EntityStateResidency_PowerEntityState_Decoder;
+  enum : int32_t {
+    kEntityIndexFieldNumber = 1,
+    kStateIndexFieldNumber = 2,
+    kEntityNameFieldNumber = 3,
+    kStateNameFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.EntityStateResidency.PowerEntityState"; }
+
+
+  using FieldMetadata_EntityIndex =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      EntityStateResidency_PowerEntityState>;
+
+  static constexpr FieldMetadata_EntityIndex kEntityIndex{};
+  void set_entity_index(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EntityIndex::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_StateIndex =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      EntityStateResidency_PowerEntityState>;
+
+  static constexpr FieldMetadata_StateIndex kStateIndex{};
+  void set_state_index(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StateIndex::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_EntityName =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      EntityStateResidency_PowerEntityState>;
+
+  static constexpr FieldMetadata_EntityName kEntityName{};
+  void set_entity_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_EntityName::kFieldId, data, size);
+  }
+  void set_entity_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_EntityName::kFieldId, chars.data, chars.size);
+  }
+  void set_entity_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_EntityName::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_StateName =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      EntityStateResidency_PowerEntityState>;
+
+  static constexpr FieldMetadata_StateName kStateName{};
+  void set_state_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_StateName::kFieldId, data, size);
+  }
+  void set_state_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_StateName::kFieldId, chars.data, chars.size);
+  }
+  void set_state_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_StateName::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/power/battery_counters.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_POWER_BATTERY_COUNTERS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_POWER_BATTERY_COUNTERS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class BatteryCounters_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BatteryCounters_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BatteryCounters_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BatteryCounters_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_charge_counter_uah() const { return at<1>().valid(); }
+  int64_t charge_counter_uah() const { return at<1>().as_int64(); }
+  bool has_capacity_percent() const { return at<2>().valid(); }
+  float capacity_percent() const { return at<2>().as_float(); }
+  bool has_current_ua() const { return at<3>().valid(); }
+  int64_t current_ua() const { return at<3>().as_int64(); }
+  bool has_current_avg_ua() const { return at<4>().valid(); }
+  int64_t current_avg_ua() const { return at<4>().as_int64(); }
+  bool has_name() const { return at<5>().valid(); }
+  ::protozero::ConstChars name() const { return at<5>().as_string(); }
+  bool has_energy_counter_uwh() const { return at<6>().valid(); }
+  int64_t energy_counter_uwh() const { return at<6>().as_int64(); }
+  bool has_voltage_uv() const { return at<7>().valid(); }
+  int64_t voltage_uv() const { return at<7>().as_int64(); }
+};
+
+class BatteryCounters : public ::protozero::Message {
+ public:
+  using Decoder = BatteryCounters_Decoder;
+  enum : int32_t {
+    kChargeCounterUahFieldNumber = 1,
+    kCapacityPercentFieldNumber = 2,
+    kCurrentUaFieldNumber = 3,
+    kCurrentAvgUaFieldNumber = 4,
+    kNameFieldNumber = 5,
+    kEnergyCounterUwhFieldNumber = 6,
+    kVoltageUvFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BatteryCounters"; }
+
+
+  using FieldMetadata_ChargeCounterUah =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BatteryCounters>;
+
+  static constexpr FieldMetadata_ChargeCounterUah kChargeCounterUah{};
+  void set_charge_counter_uah(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChargeCounterUah::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_CapacityPercent =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      BatteryCounters>;
+
+  static constexpr FieldMetadata_CapacityPercent kCapacityPercent{};
+  void set_capacity_percent(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_CapacityPercent::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CurrentUa =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BatteryCounters>;
+
+  static constexpr FieldMetadata_CurrentUa kCurrentUa{};
+  void set_current_ua(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CurrentUa::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_CurrentAvgUa =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BatteryCounters>;
+
+  static constexpr FieldMetadata_CurrentAvgUa kCurrentAvgUa{};
+  void set_current_avg_ua(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CurrentAvgUa::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BatteryCounters>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_EnergyCounterUwh =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BatteryCounters>;
+
+  static constexpr FieldMetadata_EnergyCounterUwh kEnergyCounterUwh{};
+  void set_energy_counter_uwh(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EnergyCounterUwh::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_VoltageUv =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BatteryCounters>;
+
+  static constexpr FieldMetadata_VoltageUv kVoltageUv{};
+  void set_voltage_uv(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VoltageUv::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/power/power_rails.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_POWER_POWER_RAILS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_POWER_POWER_RAILS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class PowerRails_EnergyData;
+class PowerRails_RailDescriptor;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class PowerRails_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  PowerRails_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PowerRails_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PowerRails_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_rail_descriptor() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> rail_descriptor() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_energy_data() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> energy_data() const { return GetRepeated<::protozero::ConstBytes>(2); }
+};
+
+class PowerRails : public ::protozero::Message {
+ public:
+  using Decoder = PowerRails_Decoder;
+  enum : int32_t {
+    kRailDescriptorFieldNumber = 1,
+    kEnergyDataFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PowerRails"; }
+
+  using RailDescriptor = ::perfetto::protos::pbzero::PowerRails_RailDescriptor;
+  using EnergyData = ::perfetto::protos::pbzero::PowerRails_EnergyData;
+
+  using FieldMetadata_RailDescriptor =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PowerRails_RailDescriptor,
+      PowerRails>;
+
+  static constexpr FieldMetadata_RailDescriptor kRailDescriptor{};
+  template <typename T = PowerRails_RailDescriptor> T* add_rail_descriptor() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_EnergyData =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PowerRails_EnergyData,
+      PowerRails>;
+
+  static constexpr FieldMetadata_EnergyData kEnergyData{};
+  template <typename T = PowerRails_EnergyData> T* add_energy_data() {
+    return BeginNestedMessage<T>(2);
+  }
+
+};
+
+class PowerRails_EnergyData_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  PowerRails_EnergyData_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PowerRails_EnergyData_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PowerRails_EnergyData_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_index() const { return at<1>().valid(); }
+  uint32_t index() const { return at<1>().as_uint32(); }
+  bool has_timestamp_ms() const { return at<2>().valid(); }
+  uint64_t timestamp_ms() const { return at<2>().as_uint64(); }
+  bool has_energy() const { return at<3>().valid(); }
+  uint64_t energy() const { return at<3>().as_uint64(); }
+};
+
+class PowerRails_EnergyData : public ::protozero::Message {
+ public:
+  using Decoder = PowerRails_EnergyData_Decoder;
+  enum : int32_t {
+    kIndexFieldNumber = 1,
+    kTimestampMsFieldNumber = 2,
+    kEnergyFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PowerRails.EnergyData"; }
+
+
+  using FieldMetadata_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PowerRails_EnergyData>;
+
+  static constexpr FieldMetadata_Index kIndex{};
+  void set_index(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Index::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_TimestampMs =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PowerRails_EnergyData>;
+
+  static constexpr FieldMetadata_TimestampMs kTimestampMs{};
+  void set_timestamp_ms(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimestampMs::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_Energy =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PowerRails_EnergyData>;
+
+  static constexpr FieldMetadata_Energy kEnergy{};
+  void set_energy(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Energy::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 PowerRails_RailDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  PowerRails_RailDescriptor_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PowerRails_RailDescriptor_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PowerRails_RailDescriptor_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_index() const { return at<1>().valid(); }
+  uint32_t index() const { return at<1>().as_uint32(); }
+  bool has_rail_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars rail_name() const { return at<2>().as_string(); }
+  bool has_subsys_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars subsys_name() const { return at<3>().as_string(); }
+  bool has_sampling_rate() const { return at<4>().valid(); }
+  uint32_t sampling_rate() const { return at<4>().as_uint32(); }
+};
+
+class PowerRails_RailDescriptor : public ::protozero::Message {
+ public:
+  using Decoder = PowerRails_RailDescriptor_Decoder;
+  enum : int32_t {
+    kIndexFieldNumber = 1,
+    kRailNameFieldNumber = 2,
+    kSubsysNameFieldNumber = 3,
+    kSamplingRateFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PowerRails.RailDescriptor"; }
+
+
+  using FieldMetadata_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PowerRails_RailDescriptor>;
+
+  static constexpr FieldMetadata_Index kIndex{};
+  void set_index(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Index::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_RailName =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PowerRails_RailDescriptor>;
+
+  static constexpr FieldMetadata_RailName kRailName{};
+  void set_rail_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_RailName::kFieldId, data, size);
+  }
+  void set_rail_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_RailName::kFieldId, chars.data, chars.size);
+  }
+  void set_rail_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_RailName::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_SubsysName =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PowerRails_RailDescriptor>;
+
+  static constexpr FieldMetadata_SubsysName kSubsysName{};
+  void set_subsys_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_SubsysName::kFieldId, data, size);
+  }
+  void set_subsys_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_SubsysName::kFieldId, chars.data, chars.size);
+  }
+  void set_subsys_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_SubsysName::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_SamplingRate =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PowerRails_RailDescriptor>;
+
+  static constexpr FieldMetadata_SamplingRate kSamplingRate{};
+  void set_sampling_rate(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SamplingRate::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ps/process_stats.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PS_PROCESS_STATS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PS_PROCESS_STATS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class ProcessStats_FDInfo;
+class ProcessStats_Process;
+class ProcessStats_Thread;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class ProcessStats_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ProcessStats_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProcessStats_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProcessStats_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_processes() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> processes() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_collection_end_timestamp() const { return at<2>().valid(); }
+  uint64_t collection_end_timestamp() const { return at<2>().as_uint64(); }
+};
+
+class ProcessStats : public ::protozero::Message {
+ public:
+  using Decoder = ProcessStats_Decoder;
+  enum : int32_t {
+    kProcessesFieldNumber = 1,
+    kCollectionEndTimestampFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProcessStats"; }
+
+  using Thread = ::perfetto::protos::pbzero::ProcessStats_Thread;
+  using FDInfo = ::perfetto::protos::pbzero::ProcessStats_FDInfo;
+  using Process = ::perfetto::protos::pbzero::ProcessStats_Process;
+
+  using FieldMetadata_Processes =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProcessStats_Process,
+      ProcessStats>;
+
+  static constexpr FieldMetadata_Processes kProcesses{};
+  template <typename T = ProcessStats_Process> T* add_processes() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_CollectionEndTimestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProcessStats>;
+
+  static constexpr FieldMetadata_CollectionEndTimestamp kCollectionEndTimestamp{};
+  void set_collection_end_timestamp(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CollectionEndTimestamp::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 ProcessStats_Process_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/22, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ProcessStats_Process_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProcessStats_Process_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProcessStats_Process_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  int32_t pid() const { return at<1>().as_int32(); }
+  bool has_threads() const { return at<11>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> threads() const { return GetRepeated<::protozero::ConstBytes>(11); }
+  bool has_vm_size_kb() const { return at<2>().valid(); }
+  uint64_t vm_size_kb() const { return at<2>().as_uint64(); }
+  bool has_vm_rss_kb() const { return at<3>().valid(); }
+  uint64_t vm_rss_kb() const { return at<3>().as_uint64(); }
+  bool has_rss_anon_kb() const { return at<4>().valid(); }
+  uint64_t rss_anon_kb() const { return at<4>().as_uint64(); }
+  bool has_rss_file_kb() const { return at<5>().valid(); }
+  uint64_t rss_file_kb() const { return at<5>().as_uint64(); }
+  bool has_rss_shmem_kb() const { return at<6>().valid(); }
+  uint64_t rss_shmem_kb() const { return at<6>().as_uint64(); }
+  bool has_vm_swap_kb() const { return at<7>().valid(); }
+  uint64_t vm_swap_kb() const { return at<7>().as_uint64(); }
+  bool has_vm_locked_kb() const { return at<8>().valid(); }
+  uint64_t vm_locked_kb() const { return at<8>().as_uint64(); }
+  bool has_vm_hwm_kb() const { return at<9>().valid(); }
+  uint64_t vm_hwm_kb() const { return at<9>().as_uint64(); }
+  bool has_oom_score_adj() const { return at<10>().valid(); }
+  int64_t oom_score_adj() const { return at<10>().as_int64(); }
+  bool has_is_peak_rss_resettable() const { return at<12>().valid(); }
+  bool is_peak_rss_resettable() const { return at<12>().as_bool(); }
+  bool has_chrome_private_footprint_kb() const { return at<13>().valid(); }
+  uint32_t chrome_private_footprint_kb() const { return at<13>().as_uint32(); }
+  bool has_chrome_peak_resident_set_kb() const { return at<14>().valid(); }
+  uint32_t chrome_peak_resident_set_kb() const { return at<14>().as_uint32(); }
+  bool has_fds() const { return at<15>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> fds() const { return GetRepeated<::protozero::ConstBytes>(15); }
+  bool has_smr_rss_kb() const { return at<16>().valid(); }
+  uint64_t smr_rss_kb() const { return at<16>().as_uint64(); }
+  bool has_smr_pss_kb() const { return at<17>().valid(); }
+  uint64_t smr_pss_kb() const { return at<17>().as_uint64(); }
+  bool has_smr_pss_anon_kb() const { return at<18>().valid(); }
+  uint64_t smr_pss_anon_kb() const { return at<18>().as_uint64(); }
+  bool has_smr_pss_file_kb() const { return at<19>().valid(); }
+  uint64_t smr_pss_file_kb() const { return at<19>().as_uint64(); }
+  bool has_smr_pss_shmem_kb() const { return at<20>().valid(); }
+  uint64_t smr_pss_shmem_kb() const { return at<20>().as_uint64(); }
+  bool has_runtime_user_mode() const { return at<21>().valid(); }
+  uint64_t runtime_user_mode() const { return at<21>().as_uint64(); }
+  bool has_runtime_kernel_mode() const { return at<22>().valid(); }
+  uint64_t runtime_kernel_mode() const { return at<22>().as_uint64(); }
+};
+
+class ProcessStats_Process : public ::protozero::Message {
+ public:
+  using Decoder = ProcessStats_Process_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kThreadsFieldNumber = 11,
+    kVmSizeKbFieldNumber = 2,
+    kVmRssKbFieldNumber = 3,
+    kRssAnonKbFieldNumber = 4,
+    kRssFileKbFieldNumber = 5,
+    kRssShmemKbFieldNumber = 6,
+    kVmSwapKbFieldNumber = 7,
+    kVmLockedKbFieldNumber = 8,
+    kVmHwmKbFieldNumber = 9,
+    kOomScoreAdjFieldNumber = 10,
+    kIsPeakRssResettableFieldNumber = 12,
+    kChromePrivateFootprintKbFieldNumber = 13,
+    kChromePeakResidentSetKbFieldNumber = 14,
+    kFdsFieldNumber = 15,
+    kSmrRssKbFieldNumber = 16,
+    kSmrPssKbFieldNumber = 17,
+    kSmrPssAnonKbFieldNumber = 18,
+    kSmrPssFileKbFieldNumber = 19,
+    kSmrPssShmemKbFieldNumber = 20,
+    kRuntimeUserModeFieldNumber = 21,
+    kRuntimeKernelModeFieldNumber = 22,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProcessStats.Process"; }
+
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_Threads =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProcessStats_Thread,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_Threads kThreads{};
+  template <typename T = ProcessStats_Thread> T* add_threads() {
+    return BeginNestedMessage<T>(11);
+  }
+
+
+  using FieldMetadata_VmSizeKb =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_VmSizeKb kVmSizeKb{};
+  void set_vm_size_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VmSizeKb::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_VmRssKb =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_VmRssKb kVmRssKb{};
+  void set_vm_rss_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VmRssKb::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_RssAnonKb =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_RssAnonKb kRssAnonKb{};
+  void set_rss_anon_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RssAnonKb::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_RssFileKb =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_RssFileKb kRssFileKb{};
+  void set_rss_file_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RssFileKb::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_RssShmemKb =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_RssShmemKb kRssShmemKb{};
+  void set_rss_shmem_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RssShmemKb::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_VmSwapKb =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_VmSwapKb kVmSwapKb{};
+  void set_vm_swap_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VmSwapKb::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_VmLockedKb =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_VmLockedKb kVmLockedKb{};
+  void set_vm_locked_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VmLockedKb::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_VmHwmKb =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_VmHwmKb kVmHwmKb{};
+  void set_vm_hwm_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VmHwmKb::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_OomScoreAdj =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_OomScoreAdj kOomScoreAdj{};
+  void set_oom_score_adj(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OomScoreAdj::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_IsPeakRssResettable =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_IsPeakRssResettable kIsPeakRssResettable{};
+  void set_is_peak_rss_resettable(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsPeakRssResettable::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_ChromePrivateFootprintKb =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_ChromePrivateFootprintKb kChromePrivateFootprintKb{};
+  void set_chrome_private_footprint_kb(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChromePrivateFootprintKb::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_ChromePeakResidentSetKb =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_ChromePeakResidentSetKb kChromePeakResidentSetKb{};
+  void set_chrome_peak_resident_set_kb(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChromePeakResidentSetKb::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_Fds =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProcessStats_FDInfo,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_Fds kFds{};
+  template <typename T = ProcessStats_FDInfo> T* add_fds() {
+    return BeginNestedMessage<T>(15);
+  }
+
+
+  using FieldMetadata_SmrRssKb =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_SmrRssKb kSmrRssKb{};
+  void set_smr_rss_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SmrRssKb::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_SmrPssKb =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_SmrPssKb kSmrPssKb{};
+  void set_smr_pss_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SmrPssKb::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_SmrPssAnonKb =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_SmrPssAnonKb kSmrPssAnonKb{};
+  void set_smr_pss_anon_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SmrPssAnonKb::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_SmrPssFileKb =
+    ::protozero::proto_utils::FieldMetadata<
+      19,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_SmrPssFileKb kSmrPssFileKb{};
+  void set_smr_pss_file_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SmrPssFileKb::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_SmrPssShmemKb =
+    ::protozero::proto_utils::FieldMetadata<
+      20,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_SmrPssShmemKb kSmrPssShmemKb{};
+  void set_smr_pss_shmem_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SmrPssShmemKb::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_RuntimeUserMode =
+    ::protozero::proto_utils::FieldMetadata<
+      21,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_RuntimeUserMode kRuntimeUserMode{};
+  void set_runtime_user_mode(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RuntimeUserMode::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_RuntimeKernelMode =
+    ::protozero::proto_utils::FieldMetadata<
+      22,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_RuntimeKernelMode kRuntimeKernelMode{};
+  void set_runtime_kernel_mode(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RuntimeKernelMode::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 ProcessStats_FDInfo_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ProcessStats_FDInfo_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProcessStats_FDInfo_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProcessStats_FDInfo_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_fd() const { return at<1>().valid(); }
+  uint64_t fd() const { return at<1>().as_uint64(); }
+  bool has_path() const { return at<2>().valid(); }
+  ::protozero::ConstChars path() const { return at<2>().as_string(); }
+};
+
+class ProcessStats_FDInfo : public ::protozero::Message {
+ public:
+  using Decoder = ProcessStats_FDInfo_Decoder;
+  enum : int32_t {
+    kFdFieldNumber = 1,
+    kPathFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProcessStats.FDInfo"; }
+
+
+  using FieldMetadata_Fd =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProcessStats_FDInfo>;
+
+  static constexpr FieldMetadata_Fd kFd{};
+  void set_fd(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Fd::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_Path =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ProcessStats_FDInfo>;
+
+  static constexpr FieldMetadata_Path kPath{};
+  void set_path(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Path::kFieldId, data, size);
+  }
+  void set_path(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Path::kFieldId, chars.data, chars.size);
+  }
+  void set_path(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Path::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 ProcessStats_Thread_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ProcessStats_Thread_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProcessStats_Thread_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProcessStats_Thread_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_tid() const { return at<1>().valid(); }
+  int32_t tid() const { return at<1>().as_int32(); }
+};
+
+class ProcessStats_Thread : public ::protozero::Message {
+ public:
+  using Decoder = ProcessStats_Thread_Decoder;
+  enum : int32_t {
+    kTidFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProcessStats.Thread"; }
+
+
+  using FieldMetadata_Tid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ProcessStats_Thread>;
+
+  static constexpr FieldMetadata_Tid kTid{};
+  void set_tid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tid::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ps/process_tree.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PS_PROCESS_TREE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PS_PROCESS_TREE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class ProcessTree_Process;
+class ProcessTree_Thread;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class ProcessTree_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ProcessTree_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProcessTree_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProcessTree_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_processes() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> processes() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_threads() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> threads() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_collection_end_timestamp() const { return at<3>().valid(); }
+  uint64_t collection_end_timestamp() const { return at<3>().as_uint64(); }
+};
+
+class ProcessTree : public ::protozero::Message {
+ public:
+  using Decoder = ProcessTree_Decoder;
+  enum : int32_t {
+    kProcessesFieldNumber = 1,
+    kThreadsFieldNumber = 2,
+    kCollectionEndTimestampFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProcessTree"; }
+
+  using Thread = ::perfetto::protos::pbzero::ProcessTree_Thread;
+  using Process = ::perfetto::protos::pbzero::ProcessTree_Process;
+
+  using FieldMetadata_Processes =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProcessTree_Process,
+      ProcessTree>;
+
+  static constexpr FieldMetadata_Processes kProcesses{};
+  template <typename T = ProcessTree_Process> T* add_processes() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_Threads =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProcessTree_Thread,
+      ProcessTree>;
+
+  static constexpr FieldMetadata_Threads kThreads{};
+  template <typename T = ProcessTree_Thread> T* add_threads() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_CollectionEndTimestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProcessTree>;
+
+  static constexpr FieldMetadata_CollectionEndTimestamp kCollectionEndTimestamp{};
+  void set_collection_end_timestamp(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CollectionEndTimestamp::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 ProcessTree_Process_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ProcessTree_Process_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProcessTree_Process_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProcessTree_Process_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  int32_t pid() const { return at<1>().as_int32(); }
+  bool has_ppid() const { return at<2>().valid(); }
+  int32_t ppid() const { return at<2>().as_int32(); }
+  bool has_cmdline() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> cmdline() const { return GetRepeated<::protozero::ConstChars>(3); }
+  bool has_uid() const { return at<5>().valid(); }
+  int32_t uid() const { return at<5>().as_int32(); }
+  bool has_nspid() const { return at<6>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> nspid() const { return GetRepeated<int32_t>(6); }
+  bool has_process_start_from_boot() const { return at<7>().valid(); }
+  uint64_t process_start_from_boot() const { return at<7>().as_uint64(); }
+};
+
+class ProcessTree_Process : public ::protozero::Message {
+ public:
+  using Decoder = ProcessTree_Process_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kPpidFieldNumber = 2,
+    kCmdlineFieldNumber = 3,
+    kUidFieldNumber = 5,
+    kNspidFieldNumber = 6,
+    kProcessStartFromBootFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProcessTree.Process"; }
+
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ProcessTree_Process>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_Ppid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ProcessTree_Process>;
+
+  static constexpr FieldMetadata_Ppid kPpid{};
+  void set_ppid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ppid::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_Cmdline =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ProcessTree_Process>;
+
+  static constexpr FieldMetadata_Cmdline kCmdline{};
+  void add_cmdline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cmdline::kFieldId, data, size);
+  }
+  void add_cmdline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Cmdline::kFieldId, chars.data, chars.size);
+  }
+  void add_cmdline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cmdline::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_Uid =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ProcessTree_Process>;
+
+  static constexpr FieldMetadata_Uid kUid{};
+  void set_uid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Uid::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_Nspid =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ProcessTree_Process>;
+
+  static constexpr FieldMetadata_Nspid kNspid{};
+  void add_nspid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nspid::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_ProcessStartFromBoot =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProcessTree_Process>;
+
+  static constexpr FieldMetadata_ProcessStartFromBoot kProcessStartFromBoot{};
+  void set_process_start_from_boot(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProcessStartFromBoot::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 ProcessTree_Thread_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ProcessTree_Thread_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProcessTree_Thread_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProcessTree_Thread_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_tid() const { return at<1>().valid(); }
+  int32_t tid() const { return at<1>().as_int32(); }
+  bool has_tgid() const { return at<3>().valid(); }
+  int32_t tgid() const { return at<3>().as_int32(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+  bool has_nstid() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> nstid() const { return GetRepeated<int32_t>(4); }
+};
+
+class ProcessTree_Thread : public ::protozero::Message {
+ public:
+  using Decoder = ProcessTree_Thread_Decoder;
+  enum : int32_t {
+    kTidFieldNumber = 1,
+    kTgidFieldNumber = 3,
+    kNameFieldNumber = 2,
+    kNstidFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProcessTree.Thread"; }
+
+
+  using FieldMetadata_Tid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ProcessTree_Thread>;
+
+  static constexpr FieldMetadata_Tid kTid{};
+  void set_tid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tid::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_Tgid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ProcessTree_Thread>;
+
+  static constexpr FieldMetadata_Tgid kTgid{};
+  void set_tgid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tgid::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_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ProcessTree_Thread>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Nstid =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ProcessTree_Thread>;
+
+  static constexpr FieldMetadata_Nstid kNstid{};
+  void add_nstid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nstid::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/statsd/statsd_atom.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_STATSD_STATSD_ATOM_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_STATSD_STATSD_ATOM_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class Atom;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class StatsdAtom_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  StatsdAtom_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit StatsdAtom_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit StatsdAtom_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_atom() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> atom() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_timestamp_nanos() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<int64_t> timestamp_nanos() const { return GetRepeated<int64_t>(2); }
+};
+
+class StatsdAtom : public ::protozero::Message {
+ public:
+  using Decoder = StatsdAtom_Decoder;
+  enum : int32_t {
+    kAtomFieldNumber = 1,
+    kTimestampNanosFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.StatsdAtom"; }
+
+
+  using FieldMetadata_Atom =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Atom,
+      StatsdAtom>;
+
+  static constexpr FieldMetadata_Atom kAtom{};
+  template <typename T = Atom> T* add_atom() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_TimestampNanos =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      StatsdAtom>;
+
+  static constexpr FieldMetadata_TimestampNanos kTimestampNanos{};
+  void add_timestamp_nanos(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimestampNanos::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 Atom_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/0, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Atom_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Atom_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Atom_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+};
+
+class Atom : public ::protozero::Message {
+ public:
+  using Decoder = Atom_Decoder;
+  static constexpr const char* GetName() { return ".perfetto.protos.Atom"; }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/sys_stats/sys_stats.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_SYS_STATS_SYS_STATS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_SYS_STATS_SYS_STATS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class SysStats_BuddyInfo;
+class SysStats_CpuTimes;
+class SysStats_DevfreqValue;
+class SysStats_DiskStat;
+class SysStats_InterruptCount;
+class SysStats_MeminfoValue;
+class SysStats_PsiSample;
+class SysStats_VmstatValue;
+enum MeminfoCounters : int32_t;
+namespace perfetto_pbzero_enum_SysStats_PsiSample {
+enum PsiResource : int32_t;
+}  // namespace perfetto_pbzero_enum_SysStats_PsiSample
+using SysStats_PsiSample_PsiResource = perfetto_pbzero_enum_SysStats_PsiSample::PsiResource;
+enum VmstatCounters : int32_t;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_SysStats_PsiSample {
+enum PsiResource : int32_t {
+  PSI_RESOURCE_UNSPECIFIED = 0,
+  PSI_RESOURCE_CPU_SOME = 1,
+  PSI_RESOURCE_CPU_FULL = 2,
+  PSI_RESOURCE_IO_SOME = 3,
+  PSI_RESOURCE_IO_FULL = 4,
+  PSI_RESOURCE_MEMORY_SOME = 5,
+  PSI_RESOURCE_MEMORY_FULL = 6,
+};
+} // namespace perfetto_pbzero_enum_SysStats_PsiSample
+using SysStats_PsiSample_PsiResource = perfetto_pbzero_enum_SysStats_PsiSample::PsiResource;
+
+
+constexpr SysStats_PsiSample_PsiResource SysStats_PsiSample_PsiResource_MIN = SysStats_PsiSample_PsiResource::PSI_RESOURCE_UNSPECIFIED;
+constexpr SysStats_PsiSample_PsiResource SysStats_PsiSample_PsiResource_MAX = SysStats_PsiSample_PsiResource::PSI_RESOURCE_MEMORY_FULL;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* SysStats_PsiSample_PsiResource_Name(::perfetto::protos::pbzero::SysStats_PsiSample_PsiResource value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::SysStats_PsiSample_PsiResource::PSI_RESOURCE_UNSPECIFIED:
+    return "PSI_RESOURCE_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::SysStats_PsiSample_PsiResource::PSI_RESOURCE_CPU_SOME:
+    return "PSI_RESOURCE_CPU_SOME";
+
+  case ::perfetto::protos::pbzero::SysStats_PsiSample_PsiResource::PSI_RESOURCE_CPU_FULL:
+    return "PSI_RESOURCE_CPU_FULL";
+
+  case ::perfetto::protos::pbzero::SysStats_PsiSample_PsiResource::PSI_RESOURCE_IO_SOME:
+    return "PSI_RESOURCE_IO_SOME";
+
+  case ::perfetto::protos::pbzero::SysStats_PsiSample_PsiResource::PSI_RESOURCE_IO_FULL:
+    return "PSI_RESOURCE_IO_FULL";
+
+  case ::perfetto::protos::pbzero::SysStats_PsiSample_PsiResource::PSI_RESOURCE_MEMORY_SOME:
+    return "PSI_RESOURCE_MEMORY_SOME";
+
+  case ::perfetto::protos::pbzero::SysStats_PsiSample_PsiResource::PSI_RESOURCE_MEMORY_FULL:
+    return "PSI_RESOURCE_MEMORY_FULL";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class SysStats_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/14, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  SysStats_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SysStats_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SysStats_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_meminfo() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> meminfo() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_vmstat() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> vmstat() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_cpu_stat() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> cpu_stat() const { return GetRepeated<::protozero::ConstBytes>(3); }
+  bool has_num_forks() const { return at<4>().valid(); }
+  uint64_t num_forks() const { return at<4>().as_uint64(); }
+  bool has_num_irq_total() const { return at<5>().valid(); }
+  uint64_t num_irq_total() const { return at<5>().as_uint64(); }
+  bool has_num_irq() const { return at<6>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> num_irq() const { return GetRepeated<::protozero::ConstBytes>(6); }
+  bool has_num_softirq_total() const { return at<7>().valid(); }
+  uint64_t num_softirq_total() const { return at<7>().as_uint64(); }
+  bool has_num_softirq() const { return at<8>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> num_softirq() const { return GetRepeated<::protozero::ConstBytes>(8); }
+  bool has_collection_end_timestamp() const { return at<9>().valid(); }
+  uint64_t collection_end_timestamp() const { return at<9>().as_uint64(); }
+  bool has_devfreq() const { return at<10>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> devfreq() const { return GetRepeated<::protozero::ConstBytes>(10); }
+  bool has_cpufreq_khz() const { return at<11>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint32_t> cpufreq_khz() const { return GetRepeated<uint32_t>(11); }
+  bool has_buddy_info() const { return at<12>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> buddy_info() const { return GetRepeated<::protozero::ConstBytes>(12); }
+  bool has_disk_stat() const { return at<13>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> disk_stat() const { return GetRepeated<::protozero::ConstBytes>(13); }
+  bool has_psi() const { return at<14>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> psi() const { return GetRepeated<::protozero::ConstBytes>(14); }
+};
+
+class SysStats : public ::protozero::Message {
+ public:
+  using Decoder = SysStats_Decoder;
+  enum : int32_t {
+    kMeminfoFieldNumber = 1,
+    kVmstatFieldNumber = 2,
+    kCpuStatFieldNumber = 3,
+    kNumForksFieldNumber = 4,
+    kNumIrqTotalFieldNumber = 5,
+    kNumIrqFieldNumber = 6,
+    kNumSoftirqTotalFieldNumber = 7,
+    kNumSoftirqFieldNumber = 8,
+    kCollectionEndTimestampFieldNumber = 9,
+    kDevfreqFieldNumber = 10,
+    kCpufreqKhzFieldNumber = 11,
+    kBuddyInfoFieldNumber = 12,
+    kDiskStatFieldNumber = 13,
+    kPsiFieldNumber = 14,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SysStats"; }
+
+  using MeminfoValue = ::perfetto::protos::pbzero::SysStats_MeminfoValue;
+  using VmstatValue = ::perfetto::protos::pbzero::SysStats_VmstatValue;
+  using CpuTimes = ::perfetto::protos::pbzero::SysStats_CpuTimes;
+  using InterruptCount = ::perfetto::protos::pbzero::SysStats_InterruptCount;
+  using DevfreqValue = ::perfetto::protos::pbzero::SysStats_DevfreqValue;
+  using BuddyInfo = ::perfetto::protos::pbzero::SysStats_BuddyInfo;
+  using DiskStat = ::perfetto::protos::pbzero::SysStats_DiskStat;
+  using PsiSample = ::perfetto::protos::pbzero::SysStats_PsiSample;
+
+  using FieldMetadata_Meminfo =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SysStats_MeminfoValue,
+      SysStats>;
+
+  static constexpr FieldMetadata_Meminfo kMeminfo{};
+  template <typename T = SysStats_MeminfoValue> T* add_meminfo() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_Vmstat =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SysStats_VmstatValue,
+      SysStats>;
+
+  static constexpr FieldMetadata_Vmstat kVmstat{};
+  template <typename T = SysStats_VmstatValue> T* add_vmstat() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_CpuStat =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SysStats_CpuTimes,
+      SysStats>;
+
+  static constexpr FieldMetadata_CpuStat kCpuStat{};
+  template <typename T = SysStats_CpuTimes> T* add_cpu_stat() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_NumForks =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats>;
+
+  static constexpr FieldMetadata_NumForks kNumForks{};
+  void set_num_forks(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NumForks::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_NumIrqTotal =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats>;
+
+  static constexpr FieldMetadata_NumIrqTotal kNumIrqTotal{};
+  void set_num_irq_total(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NumIrqTotal::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_NumIrq =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SysStats_InterruptCount,
+      SysStats>;
+
+  static constexpr FieldMetadata_NumIrq kNumIrq{};
+  template <typename T = SysStats_InterruptCount> T* add_num_irq() {
+    return BeginNestedMessage<T>(6);
+  }
+
+
+  using FieldMetadata_NumSoftirqTotal =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats>;
+
+  static constexpr FieldMetadata_NumSoftirqTotal kNumSoftirqTotal{};
+  void set_num_softirq_total(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NumSoftirqTotal::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_NumSoftirq =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SysStats_InterruptCount,
+      SysStats>;
+
+  static constexpr FieldMetadata_NumSoftirq kNumSoftirq{};
+  template <typename T = SysStats_InterruptCount> T* add_num_softirq() {
+    return BeginNestedMessage<T>(8);
+  }
+
+
+  using FieldMetadata_CollectionEndTimestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats>;
+
+  static constexpr FieldMetadata_CollectionEndTimestamp kCollectionEndTimestamp{};
+  void set_collection_end_timestamp(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CollectionEndTimestamp::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_Devfreq =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SysStats_DevfreqValue,
+      SysStats>;
+
+  static constexpr FieldMetadata_Devfreq kDevfreq{};
+  template <typename T = SysStats_DevfreqValue> T* add_devfreq() {
+    return BeginNestedMessage<T>(10);
+  }
+
+
+  using FieldMetadata_CpufreqKhz =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SysStats>;
+
+  static constexpr FieldMetadata_CpufreqKhz kCpufreqKhz{};
+  void add_cpufreq_khz(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CpufreqKhz::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_BuddyInfo =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SysStats_BuddyInfo,
+      SysStats>;
+
+  static constexpr FieldMetadata_BuddyInfo kBuddyInfo{};
+  template <typename T = SysStats_BuddyInfo> T* add_buddy_info() {
+    return BeginNestedMessage<T>(12);
+  }
+
+
+  using FieldMetadata_DiskStat =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SysStats_DiskStat,
+      SysStats>;
+
+  static constexpr FieldMetadata_DiskStat kDiskStat{};
+  template <typename T = SysStats_DiskStat> T* add_disk_stat() {
+    return BeginNestedMessage<T>(13);
+  }
+
+
+  using FieldMetadata_Psi =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SysStats_PsiSample,
+      SysStats>;
+
+  static constexpr FieldMetadata_Psi kPsi{};
+  template <typename T = SysStats_PsiSample> T* add_psi() {
+    return BeginNestedMessage<T>(14);
+  }
+
+};
+
+class SysStats_PsiSample_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SysStats_PsiSample_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SysStats_PsiSample_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SysStats_PsiSample_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_resource() const { return at<1>().valid(); }
+  int32_t resource() const { return at<1>().as_int32(); }
+  bool has_total_ns() const { return at<2>().valid(); }
+  uint64_t total_ns() const { return at<2>().as_uint64(); }
+};
+
+class SysStats_PsiSample : public ::protozero::Message {
+ public:
+  using Decoder = SysStats_PsiSample_Decoder;
+  enum : int32_t {
+    kResourceFieldNumber = 1,
+    kTotalNsFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SysStats.PsiSample"; }
+
+
+  using PsiResource = ::perfetto::protos::pbzero::SysStats_PsiSample_PsiResource;
+  static inline const char* PsiResource_Name(PsiResource value) {
+    return ::perfetto::protos::pbzero::SysStats_PsiSample_PsiResource_Name(value);
+  }
+  static inline const PsiResource PSI_RESOURCE_UNSPECIFIED = PsiResource::PSI_RESOURCE_UNSPECIFIED;
+  static inline const PsiResource PSI_RESOURCE_CPU_SOME = PsiResource::PSI_RESOURCE_CPU_SOME;
+  static inline const PsiResource PSI_RESOURCE_CPU_FULL = PsiResource::PSI_RESOURCE_CPU_FULL;
+  static inline const PsiResource PSI_RESOURCE_IO_SOME = PsiResource::PSI_RESOURCE_IO_SOME;
+  static inline const PsiResource PSI_RESOURCE_IO_FULL = PsiResource::PSI_RESOURCE_IO_FULL;
+  static inline const PsiResource PSI_RESOURCE_MEMORY_SOME = PsiResource::PSI_RESOURCE_MEMORY_SOME;
+  static inline const PsiResource PSI_RESOURCE_MEMORY_FULL = PsiResource::PSI_RESOURCE_MEMORY_FULL;
+
+  using FieldMetadata_Resource =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      SysStats_PsiSample_PsiResource,
+      SysStats_PsiSample>;
+
+  static constexpr FieldMetadata_Resource kResource{};
+  void set_resource(SysStats_PsiSample_PsiResource value) {
+    static constexpr uint32_t field_id = FieldMetadata_Resource::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_TotalNs =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_PsiSample>;
+
+  static constexpr FieldMetadata_TotalNs kTotalNs{};
+  void set_total_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TotalNs::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 SysStats_DiskStat_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SysStats_DiskStat_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SysStats_DiskStat_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SysStats_DiskStat_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_device_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars device_name() const { return at<1>().as_string(); }
+  bool has_read_sectors() const { return at<2>().valid(); }
+  uint64_t read_sectors() const { return at<2>().as_uint64(); }
+  bool has_read_time_ms() const { return at<3>().valid(); }
+  uint64_t read_time_ms() const { return at<3>().as_uint64(); }
+  bool has_write_sectors() const { return at<4>().valid(); }
+  uint64_t write_sectors() const { return at<4>().as_uint64(); }
+  bool has_write_time_ms() const { return at<5>().valid(); }
+  uint64_t write_time_ms() const { return at<5>().as_uint64(); }
+  bool has_discard_sectors() const { return at<6>().valid(); }
+  uint64_t discard_sectors() const { return at<6>().as_uint64(); }
+  bool has_discard_time_ms() const { return at<7>().valid(); }
+  uint64_t discard_time_ms() const { return at<7>().as_uint64(); }
+  bool has_flush_count() const { return at<8>().valid(); }
+  uint64_t flush_count() const { return at<8>().as_uint64(); }
+  bool has_flush_time_ms() const { return at<9>().valid(); }
+  uint64_t flush_time_ms() const { return at<9>().as_uint64(); }
+};
+
+class SysStats_DiskStat : public ::protozero::Message {
+ public:
+  using Decoder = SysStats_DiskStat_Decoder;
+  enum : int32_t {
+    kDeviceNameFieldNumber = 1,
+    kReadSectorsFieldNumber = 2,
+    kReadTimeMsFieldNumber = 3,
+    kWriteSectorsFieldNumber = 4,
+    kWriteTimeMsFieldNumber = 5,
+    kDiscardSectorsFieldNumber = 6,
+    kDiscardTimeMsFieldNumber = 7,
+    kFlushCountFieldNumber = 8,
+    kFlushTimeMsFieldNumber = 9,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SysStats.DiskStat"; }
+
+
+  using FieldMetadata_DeviceName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SysStats_DiskStat>;
+
+  static constexpr FieldMetadata_DeviceName kDeviceName{};
+  void set_device_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DeviceName::kFieldId, data, size);
+  }
+  void set_device_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_DeviceName::kFieldId, chars.data, chars.size);
+  }
+  void set_device_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_DeviceName::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_ReadSectors =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_DiskStat>;
+
+  static constexpr FieldMetadata_ReadSectors kReadSectors{};
+  void set_read_sectors(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReadSectors::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_ReadTimeMs =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_DiskStat>;
+
+  static constexpr FieldMetadata_ReadTimeMs kReadTimeMs{};
+  void set_read_time_ms(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReadTimeMs::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_WriteSectors =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_DiskStat>;
+
+  static constexpr FieldMetadata_WriteSectors kWriteSectors{};
+  void set_write_sectors(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_WriteSectors::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_WriteTimeMs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_DiskStat>;
+
+  static constexpr FieldMetadata_WriteTimeMs kWriteTimeMs{};
+  void set_write_time_ms(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_WriteTimeMs::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_DiscardSectors =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_DiskStat>;
+
+  static constexpr FieldMetadata_DiscardSectors kDiscardSectors{};
+  void set_discard_sectors(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DiscardSectors::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_DiscardTimeMs =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_DiskStat>;
+
+  static constexpr FieldMetadata_DiscardTimeMs kDiscardTimeMs{};
+  void set_discard_time_ms(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DiscardTimeMs::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_FlushCount =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_DiskStat>;
+
+  static constexpr FieldMetadata_FlushCount kFlushCount{};
+  void set_flush_count(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FlushCount::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_FlushTimeMs =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_DiskStat>;
+
+  static constexpr FieldMetadata_FlushTimeMs kFlushTimeMs{};
+  void set_flush_time_ms(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FlushTimeMs::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 SysStats_BuddyInfo_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  SysStats_BuddyInfo_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SysStats_BuddyInfo_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SysStats_BuddyInfo_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_node() const { return at<1>().valid(); }
+  ::protozero::ConstChars node() const { return at<1>().as_string(); }
+  bool has_zone() const { return at<2>().valid(); }
+  ::protozero::ConstChars zone() const { return at<2>().as_string(); }
+  bool has_order_pages() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint32_t> order_pages() const { return GetRepeated<uint32_t>(3); }
+};
+
+class SysStats_BuddyInfo : public ::protozero::Message {
+ public:
+  using Decoder = SysStats_BuddyInfo_Decoder;
+  enum : int32_t {
+    kNodeFieldNumber = 1,
+    kZoneFieldNumber = 2,
+    kOrderPagesFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SysStats.BuddyInfo"; }
+
+
+  using FieldMetadata_Node =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SysStats_BuddyInfo>;
+
+  static constexpr FieldMetadata_Node kNode{};
+  void set_node(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Node::kFieldId, data, size);
+  }
+  void set_node(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Node::kFieldId, chars.data, chars.size);
+  }
+  void set_node(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Node::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_Zone =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SysStats_BuddyInfo>;
+
+  static constexpr FieldMetadata_Zone kZone{};
+  void set_zone(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Zone::kFieldId, data, size);
+  }
+  void set_zone(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Zone::kFieldId, chars.data, chars.size);
+  }
+  void set_zone(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Zone::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_OrderPages =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SysStats_BuddyInfo>;
+
+  static constexpr FieldMetadata_OrderPages kOrderPages{};
+  void add_order_pages(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OrderPages::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 SysStats_DevfreqValue_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SysStats_DevfreqValue_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SysStats_DevfreqValue_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SysStats_DevfreqValue_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_key() const { return at<1>().valid(); }
+  ::protozero::ConstChars key() const { return at<1>().as_string(); }
+  bool has_value() const { return at<2>().valid(); }
+  uint64_t value() const { return at<2>().as_uint64(); }
+};
+
+class SysStats_DevfreqValue : public ::protozero::Message {
+ public:
+  using Decoder = SysStats_DevfreqValue_Decoder;
+  enum : int32_t {
+    kKeyFieldNumber = 1,
+    kValueFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SysStats.DevfreqValue"; }
+
+
+  using FieldMetadata_Key =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SysStats_DevfreqValue>;
+
+  static constexpr FieldMetadata_Key kKey{};
+  void set_key(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Key::kFieldId, data, size);
+  }
+  void set_key(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Key::kFieldId, chars.data, chars.size);
+  }
+  void set_key(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Key::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_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_DevfreqValue>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::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 SysStats_InterruptCount_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SysStats_InterruptCount_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SysStats_InterruptCount_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SysStats_InterruptCount_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_irq() const { return at<1>().valid(); }
+  int32_t irq() const { return at<1>().as_int32(); }
+  bool has_count() const { return at<2>().valid(); }
+  uint64_t count() const { return at<2>().as_uint64(); }
+};
+
+class SysStats_InterruptCount : public ::protozero::Message {
+ public:
+  using Decoder = SysStats_InterruptCount_Decoder;
+  enum : int32_t {
+    kIrqFieldNumber = 1,
+    kCountFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SysStats.InterruptCount"; }
+
+
+  using FieldMetadata_Irq =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SysStats_InterruptCount>;
+
+  static constexpr FieldMetadata_Irq kIrq{};
+  void set_irq(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Irq::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_Count =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_InterruptCount>;
+
+  static constexpr FieldMetadata_Count kCount{};
+  void set_count(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Count::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 SysStats_CpuTimes_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SysStats_CpuTimes_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SysStats_CpuTimes_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SysStats_CpuTimes_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cpu_id() const { return at<1>().valid(); }
+  uint32_t cpu_id() const { return at<1>().as_uint32(); }
+  bool has_user_ns() const { return at<2>().valid(); }
+  uint64_t user_ns() const { return at<2>().as_uint64(); }
+  bool has_user_nice_ns() const { return at<3>().valid(); }
+  uint64_t user_nice_ns() const { return at<3>().as_uint64(); }
+  bool has_system_mode_ns() const { return at<4>().valid(); }
+  uint64_t system_mode_ns() const { return at<4>().as_uint64(); }
+  bool has_idle_ns() const { return at<5>().valid(); }
+  uint64_t idle_ns() const { return at<5>().as_uint64(); }
+  bool has_io_wait_ns() const { return at<6>().valid(); }
+  uint64_t io_wait_ns() const { return at<6>().as_uint64(); }
+  bool has_irq_ns() const { return at<7>().valid(); }
+  uint64_t irq_ns() const { return at<7>().as_uint64(); }
+  bool has_softirq_ns() const { return at<8>().valid(); }
+  uint64_t softirq_ns() const { return at<8>().as_uint64(); }
+};
+
+class SysStats_CpuTimes : public ::protozero::Message {
+ public:
+  using Decoder = SysStats_CpuTimes_Decoder;
+  enum : int32_t {
+    kCpuIdFieldNumber = 1,
+    kUserNsFieldNumber = 2,
+    kUserNiceNsFieldNumber = 3,
+    kSystemModeNsFieldNumber = 4,
+    kIdleNsFieldNumber = 5,
+    kIoWaitNsFieldNumber = 6,
+    kIrqNsFieldNumber = 7,
+    kSoftirqNsFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SysStats.CpuTimes"; }
+
+
+  using FieldMetadata_CpuId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SysStats_CpuTimes>;
+
+  static constexpr FieldMetadata_CpuId kCpuId{};
+  void set_cpu_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CpuId::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_UserNs =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_CpuTimes>;
+
+  static constexpr FieldMetadata_UserNs kUserNs{};
+  void set_user_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UserNs::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_UserNiceNs =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_CpuTimes>;
+
+  static constexpr FieldMetadata_UserNiceNs kUserNiceNs{};
+  void set_user_nice_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UserNiceNs::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_SystemModeNs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_CpuTimes>;
+
+  static constexpr FieldMetadata_SystemModeNs kSystemModeNs{};
+  void set_system_mode_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SystemModeNs::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_IdleNs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_CpuTimes>;
+
+  static constexpr FieldMetadata_IdleNs kIdleNs{};
+  void set_idle_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IdleNs::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_IoWaitNs =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_CpuTimes>;
+
+  static constexpr FieldMetadata_IoWaitNs kIoWaitNs{};
+  void set_io_wait_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IoWaitNs::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_IrqNs =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_CpuTimes>;
+
+  static constexpr FieldMetadata_IrqNs kIrqNs{};
+  void set_irq_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IrqNs::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_SoftirqNs =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_CpuTimes>;
+
+  static constexpr FieldMetadata_SoftirqNs kSoftirqNs{};
+  void set_softirq_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SoftirqNs::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 SysStats_VmstatValue_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SysStats_VmstatValue_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SysStats_VmstatValue_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SysStats_VmstatValue_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_key() const { return at<1>().valid(); }
+  int32_t key() const { return at<1>().as_int32(); }
+  bool has_value() const { return at<2>().valid(); }
+  uint64_t value() const { return at<2>().as_uint64(); }
+};
+
+class SysStats_VmstatValue : public ::protozero::Message {
+ public:
+  using Decoder = SysStats_VmstatValue_Decoder;
+  enum : int32_t {
+    kKeyFieldNumber = 1,
+    kValueFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SysStats.VmstatValue"; }
+
+
+  using FieldMetadata_Key =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      VmstatCounters,
+      SysStats_VmstatValue>;
+
+  static constexpr FieldMetadata_Key kKey{};
+  void set_key(VmstatCounters value) {
+    static constexpr uint32_t field_id = FieldMetadata_Key::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_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_VmstatValue>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::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 SysStats_MeminfoValue_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SysStats_MeminfoValue_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SysStats_MeminfoValue_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SysStats_MeminfoValue_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_key() const { return at<1>().valid(); }
+  int32_t key() const { return at<1>().as_int32(); }
+  bool has_value() const { return at<2>().valid(); }
+  uint64_t value() const { return at<2>().as_uint64(); }
+};
+
+class SysStats_MeminfoValue : public ::protozero::Message {
+ public:
+  using Decoder = SysStats_MeminfoValue_Decoder;
+  enum : int32_t {
+    kKeyFieldNumber = 1,
+    kValueFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SysStats.MeminfoValue"; }
+
+
+  using FieldMetadata_Key =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      MeminfoCounters,
+      SysStats_MeminfoValue>;
+
+  static constexpr FieldMetadata_Key kKey{};
+  void set_key(MeminfoCounters value) {
+    static constexpr uint32_t field_id = FieldMetadata_Key::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_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_MeminfoValue>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/system_info/cpu_info.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_SYSTEM_INFO_CPU_INFO_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_SYSTEM_INFO_CPU_INFO_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class CpuInfo_Cpu;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class CpuInfo_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  CpuInfo_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CpuInfo_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CpuInfo_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cpus() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> cpus() const { return GetRepeated<::protozero::ConstBytes>(1); }
+};
+
+class CpuInfo : public ::protozero::Message {
+ public:
+  using Decoder = CpuInfo_Decoder;
+  enum : int32_t {
+    kCpusFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CpuInfo"; }
+
+  using Cpu = ::perfetto::protos::pbzero::CpuInfo_Cpu;
+
+  using FieldMetadata_Cpus =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CpuInfo_Cpu,
+      CpuInfo>;
+
+  static constexpr FieldMetadata_Cpus kCpus{};
+  template <typename T = CpuInfo_Cpu> T* add_cpus() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+class CpuInfo_Cpu_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  CpuInfo_Cpu_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CpuInfo_Cpu_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CpuInfo_Cpu_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_processor() const { return at<1>().valid(); }
+  ::protozero::ConstChars processor() const { return at<1>().as_string(); }
+  bool has_frequencies() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint32_t> frequencies() const { return GetRepeated<uint32_t>(2); }
+};
+
+class CpuInfo_Cpu : public ::protozero::Message {
+ public:
+  using Decoder = CpuInfo_Cpu_Decoder;
+  enum : int32_t {
+    kProcessorFieldNumber = 1,
+    kFrequenciesFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CpuInfo.Cpu"; }
+
+
+  using FieldMetadata_Processor =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CpuInfo_Cpu>;
+
+  static constexpr FieldMetadata_Processor kProcessor{};
+  void set_processor(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Processor::kFieldId, data, size);
+  }
+  void set_processor(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Processor::kFieldId, chars.data, chars.size);
+  }
+  void set_processor(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Processor::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_Frequencies =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuInfo_Cpu>;
+
+  static constexpr FieldMetadata_Frequencies kFrequencies{};
+  void add_frequencies(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Frequencies::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/translation/translation_table.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRANSLATION_TRANSLATION_TABLE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRANSLATION_TRANSLATION_TABLE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class ChromeHistorgramTranslationTable;
+class ChromeHistorgramTranslationTable_HashToNameEntry;
+class ChromePerformanceMarkTranslationTable;
+class ChromePerformanceMarkTranslationTable_MarkHashToNameEntry;
+class ChromePerformanceMarkTranslationTable_SiteHashToNameEntry;
+class ChromeUserEventTranslationTable;
+class ChromeUserEventTranslationTable_ActionHashToNameEntry;
+class SliceNameTranslationTable;
+class SliceNameTranslationTable_RawToDeobfuscatedNameEntry;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class SliceNameTranslationTable_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  SliceNameTranslationTable_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SliceNameTranslationTable_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SliceNameTranslationTable_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_raw_to_deobfuscated_name() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> raw_to_deobfuscated_name() const { return GetRepeated<::protozero::ConstBytes>(1); }
+};
+
+class SliceNameTranslationTable : public ::protozero::Message {
+ public:
+  using Decoder = SliceNameTranslationTable_Decoder;
+  enum : int32_t {
+    kRawToDeobfuscatedNameFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SliceNameTranslationTable"; }
+
+  using RawToDeobfuscatedNameEntry = ::perfetto::protos::pbzero::SliceNameTranslationTable_RawToDeobfuscatedNameEntry;
+
+  using FieldMetadata_RawToDeobfuscatedName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SliceNameTranslationTable_RawToDeobfuscatedNameEntry,
+      SliceNameTranslationTable>;
+
+  static constexpr FieldMetadata_RawToDeobfuscatedName kRawToDeobfuscatedName{};
+  template <typename T = SliceNameTranslationTable_RawToDeobfuscatedNameEntry> T* add_raw_to_deobfuscated_name() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+class SliceNameTranslationTable_RawToDeobfuscatedNameEntry_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SliceNameTranslationTable_RawToDeobfuscatedNameEntry_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SliceNameTranslationTable_RawToDeobfuscatedNameEntry_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SliceNameTranslationTable_RawToDeobfuscatedNameEntry_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_key() const { return at<1>().valid(); }
+  ::protozero::ConstChars key() const { return at<1>().as_string(); }
+  bool has_value() const { return at<2>().valid(); }
+  ::protozero::ConstChars value() const { return at<2>().as_string(); }
+};
+
+class SliceNameTranslationTable_RawToDeobfuscatedNameEntry : public ::protozero::Message {
+ public:
+  using Decoder = SliceNameTranslationTable_RawToDeobfuscatedNameEntry_Decoder;
+  enum : int32_t {
+    kKeyFieldNumber = 1,
+    kValueFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SliceNameTranslationTable.RawToDeobfuscatedNameEntry"; }
+
+
+  using FieldMetadata_Key =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SliceNameTranslationTable_RawToDeobfuscatedNameEntry>;
+
+  static constexpr FieldMetadata_Key kKey{};
+  void set_key(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Key::kFieldId, data, size);
+  }
+  void set_key(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Key::kFieldId, chars.data, chars.size);
+  }
+  void set_key(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Key::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_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SliceNameTranslationTable_RawToDeobfuscatedNameEntry>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Value::kFieldId, data, size);
+  }
+  void set_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Value::kFieldId, chars.data, chars.size);
+  }
+  void set_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::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 ChromePerformanceMarkTranslationTable_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ChromePerformanceMarkTranslationTable_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromePerformanceMarkTranslationTable_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromePerformanceMarkTranslationTable_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_site_hash_to_name() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> site_hash_to_name() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_mark_hash_to_name() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> mark_hash_to_name() const { return GetRepeated<::protozero::ConstBytes>(2); }
+};
+
+class ChromePerformanceMarkTranslationTable : public ::protozero::Message {
+ public:
+  using Decoder = ChromePerformanceMarkTranslationTable_Decoder;
+  enum : int32_t {
+    kSiteHashToNameFieldNumber = 1,
+    kMarkHashToNameFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromePerformanceMarkTranslationTable"; }
+
+  using SiteHashToNameEntry = ::perfetto::protos::pbzero::ChromePerformanceMarkTranslationTable_SiteHashToNameEntry;
+  using MarkHashToNameEntry = ::perfetto::protos::pbzero::ChromePerformanceMarkTranslationTable_MarkHashToNameEntry;
+
+  using FieldMetadata_SiteHashToName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromePerformanceMarkTranslationTable_SiteHashToNameEntry,
+      ChromePerformanceMarkTranslationTable>;
+
+  static constexpr FieldMetadata_SiteHashToName kSiteHashToName{};
+  template <typename T = ChromePerformanceMarkTranslationTable_SiteHashToNameEntry> T* add_site_hash_to_name() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_MarkHashToName =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromePerformanceMarkTranslationTable_MarkHashToNameEntry,
+      ChromePerformanceMarkTranslationTable>;
+
+  static constexpr FieldMetadata_MarkHashToName kMarkHashToName{};
+  template <typename T = ChromePerformanceMarkTranslationTable_MarkHashToNameEntry> T* add_mark_hash_to_name() {
+    return BeginNestedMessage<T>(2);
+  }
+
+};
+
+class ChromePerformanceMarkTranslationTable_MarkHashToNameEntry_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromePerformanceMarkTranslationTable_MarkHashToNameEntry_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromePerformanceMarkTranslationTable_MarkHashToNameEntry_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromePerformanceMarkTranslationTable_MarkHashToNameEntry_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_key() const { return at<1>().valid(); }
+  uint32_t key() const { return at<1>().as_uint32(); }
+  bool has_value() const { return at<2>().valid(); }
+  ::protozero::ConstChars value() const { return at<2>().as_string(); }
+};
+
+class ChromePerformanceMarkTranslationTable_MarkHashToNameEntry : public ::protozero::Message {
+ public:
+  using Decoder = ChromePerformanceMarkTranslationTable_MarkHashToNameEntry_Decoder;
+  enum : int32_t {
+    kKeyFieldNumber = 1,
+    kValueFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromePerformanceMarkTranslationTable.MarkHashToNameEntry"; }
+
+
+  using FieldMetadata_Key =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ChromePerformanceMarkTranslationTable_MarkHashToNameEntry>;
+
+  static constexpr FieldMetadata_Key kKey{};
+  void set_key(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Key::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_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromePerformanceMarkTranslationTable_MarkHashToNameEntry>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Value::kFieldId, data, size);
+  }
+  void set_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Value::kFieldId, chars.data, chars.size);
+  }
+  void set_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::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 ChromePerformanceMarkTranslationTable_SiteHashToNameEntry_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromePerformanceMarkTranslationTable_SiteHashToNameEntry_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromePerformanceMarkTranslationTable_SiteHashToNameEntry_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromePerformanceMarkTranslationTable_SiteHashToNameEntry_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_key() const { return at<1>().valid(); }
+  uint32_t key() const { return at<1>().as_uint32(); }
+  bool has_value() const { return at<2>().valid(); }
+  ::protozero::ConstChars value() const { return at<2>().as_string(); }
+};
+
+class ChromePerformanceMarkTranslationTable_SiteHashToNameEntry : public ::protozero::Message {
+ public:
+  using Decoder = ChromePerformanceMarkTranslationTable_SiteHashToNameEntry_Decoder;
+  enum : int32_t {
+    kKeyFieldNumber = 1,
+    kValueFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromePerformanceMarkTranslationTable.SiteHashToNameEntry"; }
+
+
+  using FieldMetadata_Key =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ChromePerformanceMarkTranslationTable_SiteHashToNameEntry>;
+
+  static constexpr FieldMetadata_Key kKey{};
+  void set_key(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Key::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_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromePerformanceMarkTranslationTable_SiteHashToNameEntry>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Value::kFieldId, data, size);
+  }
+  void set_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Value::kFieldId, chars.data, chars.size);
+  }
+  void set_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::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 ChromeUserEventTranslationTable_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ChromeUserEventTranslationTable_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeUserEventTranslationTable_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeUserEventTranslationTable_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_action_hash_to_name() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> action_hash_to_name() const { return GetRepeated<::protozero::ConstBytes>(1); }
+};
+
+class ChromeUserEventTranslationTable : public ::protozero::Message {
+ public:
+  using Decoder = ChromeUserEventTranslationTable_Decoder;
+  enum : int32_t {
+    kActionHashToNameFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeUserEventTranslationTable"; }
+
+  using ActionHashToNameEntry = ::perfetto::protos::pbzero::ChromeUserEventTranslationTable_ActionHashToNameEntry;
+
+  using FieldMetadata_ActionHashToName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeUserEventTranslationTable_ActionHashToNameEntry,
+      ChromeUserEventTranslationTable>;
+
+  static constexpr FieldMetadata_ActionHashToName kActionHashToName{};
+  template <typename T = ChromeUserEventTranslationTable_ActionHashToNameEntry> T* add_action_hash_to_name() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+class ChromeUserEventTranslationTable_ActionHashToNameEntry_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeUserEventTranslationTable_ActionHashToNameEntry_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeUserEventTranslationTable_ActionHashToNameEntry_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeUserEventTranslationTable_ActionHashToNameEntry_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_key() const { return at<1>().valid(); }
+  uint64_t key() const { return at<1>().as_uint64(); }
+  bool has_value() const { return at<2>().valid(); }
+  ::protozero::ConstChars value() const { return at<2>().as_string(); }
+};
+
+class ChromeUserEventTranslationTable_ActionHashToNameEntry : public ::protozero::Message {
+ public:
+  using Decoder = ChromeUserEventTranslationTable_ActionHashToNameEntry_Decoder;
+  enum : int32_t {
+    kKeyFieldNumber = 1,
+    kValueFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeUserEventTranslationTable.ActionHashToNameEntry"; }
+
+
+  using FieldMetadata_Key =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ChromeUserEventTranslationTable_ActionHashToNameEntry>;
+
+  static constexpr FieldMetadata_Key kKey{};
+  void set_key(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Key::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_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeUserEventTranslationTable_ActionHashToNameEntry>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Value::kFieldId, data, size);
+  }
+  void set_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Value::kFieldId, chars.data, chars.size);
+  }
+  void set_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::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 ChromeHistorgramTranslationTable_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ChromeHistorgramTranslationTable_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeHistorgramTranslationTable_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeHistorgramTranslationTable_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_hash_to_name() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> hash_to_name() const { return GetRepeated<::protozero::ConstBytes>(1); }
+};
+
+class ChromeHistorgramTranslationTable : public ::protozero::Message {
+ public:
+  using Decoder = ChromeHistorgramTranslationTable_Decoder;
+  enum : int32_t {
+    kHashToNameFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeHistorgramTranslationTable"; }
+
+  using HashToNameEntry = ::perfetto::protos::pbzero::ChromeHistorgramTranslationTable_HashToNameEntry;
+
+  using FieldMetadata_HashToName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeHistorgramTranslationTable_HashToNameEntry,
+      ChromeHistorgramTranslationTable>;
+
+  static constexpr FieldMetadata_HashToName kHashToName{};
+  template <typename T = ChromeHistorgramTranslationTable_HashToNameEntry> T* add_hash_to_name() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+class ChromeHistorgramTranslationTable_HashToNameEntry_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeHistorgramTranslationTable_HashToNameEntry_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeHistorgramTranslationTable_HashToNameEntry_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeHistorgramTranslationTable_HashToNameEntry_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_key() const { return at<1>().valid(); }
+  uint64_t key() const { return at<1>().as_uint64(); }
+  bool has_value() const { return at<2>().valid(); }
+  ::protozero::ConstChars value() const { return at<2>().as_string(); }
+};
+
+class ChromeHistorgramTranslationTable_HashToNameEntry : public ::protozero::Message {
+ public:
+  using Decoder = ChromeHistorgramTranslationTable_HashToNameEntry_Decoder;
+  enum : int32_t {
+    kKeyFieldNumber = 1,
+    kValueFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeHistorgramTranslationTable.HashToNameEntry"; }
+
+
+  using FieldMetadata_Key =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ChromeHistorgramTranslationTable_HashToNameEntry>;
+
+  static constexpr FieldMetadata_Key kKey{};
+  void set_key(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Key::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_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeHistorgramTranslationTable_HashToNameEntry>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Value::kFieldId, data, size);
+  }
+  void set_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Value::kFieldId, chars.data, chars.size);
+  }
+  void set_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::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 TranslationTable_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TranslationTable_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TranslationTable_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TranslationTable_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_chrome_histogram() const { return at<1>().valid(); }
+  ::protozero::ConstBytes chrome_histogram() const { return at<1>().as_bytes(); }
+  bool has_chrome_user_event() const { return at<2>().valid(); }
+  ::protozero::ConstBytes chrome_user_event() const { return at<2>().as_bytes(); }
+  bool has_chrome_performance_mark() const { return at<3>().valid(); }
+  ::protozero::ConstBytes chrome_performance_mark() const { return at<3>().as_bytes(); }
+  bool has_slice_name() const { return at<4>().valid(); }
+  ::protozero::ConstBytes slice_name() const { return at<4>().as_bytes(); }
+};
+
+class TranslationTable : public ::protozero::Message {
+ public:
+  using Decoder = TranslationTable_Decoder;
+  enum : int32_t {
+    kChromeHistogramFieldNumber = 1,
+    kChromeUserEventFieldNumber = 2,
+    kChromePerformanceMarkFieldNumber = 3,
+    kSliceNameFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TranslationTable"; }
+
+
+  using FieldMetadata_ChromeHistogram =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeHistorgramTranslationTable,
+      TranslationTable>;
+
+  static constexpr FieldMetadata_ChromeHistogram kChromeHistogram{};
+  template <typename T = ChromeHistorgramTranslationTable> T* set_chrome_histogram() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_ChromeUserEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeUserEventTranslationTable,
+      TranslationTable>;
+
+  static constexpr FieldMetadata_ChromeUserEvent kChromeUserEvent{};
+  template <typename T = ChromeUserEventTranslationTable> T* set_chrome_user_event() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_ChromePerformanceMark =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromePerformanceMarkTranslationTable,
+      TranslationTable>;
+
+  static constexpr FieldMetadata_ChromePerformanceMark kChromePerformanceMark{};
+  template <typename T = ChromePerformanceMarkTranslationTable> T* set_chrome_performance_mark() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_SliceName =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SliceNameTranslationTable,
+      TranslationTable>;
+
+  static constexpr FieldMetadata_SliceName kSliceName{};
+  template <typename T = SliceNameTranslationTable> T* set_slice_name() {
+    return BeginNestedMessage<T>(4);
+  }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/remote_clock_sync.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_REMOTE_CLOCK_SYNC_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_REMOTE_CLOCK_SYNC_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class ClockSnapshot;
+class RemoteClockSync_SyncedClocks;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class RemoteClockSync_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  RemoteClockSync_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit RemoteClockSync_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit RemoteClockSync_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_synced_clocks() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> synced_clocks() const { return GetRepeated<::protozero::ConstBytes>(1); }
+};
+
+class RemoteClockSync : public ::protozero::Message {
+ public:
+  using Decoder = RemoteClockSync_Decoder;
+  enum : int32_t {
+    kSyncedClocksFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.RemoteClockSync"; }
+
+  using SyncedClocks = ::perfetto::protos::pbzero::RemoteClockSync_SyncedClocks;
+
+  using FieldMetadata_SyncedClocks =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RemoteClockSync_SyncedClocks,
+      RemoteClockSync>;
+
+  static constexpr FieldMetadata_SyncedClocks kSyncedClocks{};
+  template <typename T = RemoteClockSync_SyncedClocks> T* add_synced_clocks() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+class RemoteClockSync_SyncedClocks_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  RemoteClockSync_SyncedClocks_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit RemoteClockSync_SyncedClocks_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit RemoteClockSync_SyncedClocks_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_client_clocks() const { return at<2>().valid(); }
+  ::protozero::ConstBytes client_clocks() const { return at<2>().as_bytes(); }
+  bool has_host_clocks() const { return at<3>().valid(); }
+  ::protozero::ConstBytes host_clocks() const { return at<3>().as_bytes(); }
+};
+
+class RemoteClockSync_SyncedClocks : public ::protozero::Message {
+ public:
+  using Decoder = RemoteClockSync_SyncedClocks_Decoder;
+  enum : int32_t {
+    kClientClocksFieldNumber = 2,
+    kHostClocksFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.RemoteClockSync.SyncedClocks"; }
+
+
+  using FieldMetadata_ClientClocks =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ClockSnapshot,
+      RemoteClockSync_SyncedClocks>;
+
+  static constexpr FieldMetadata_ClientClocks kClientClocks{};
+  template <typename T = ClockSnapshot> T* set_client_clocks() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_HostClocks =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ClockSnapshot,
+      RemoteClockSync_SyncedClocks>;
+
+  static constexpr FieldMetadata_HostClocks kHostClocks{};
+  template <typename T = ClockSnapshot> T* set_host_clocks() {
+    return BeginNestedMessage<T>(3);
+  }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/trace_packet_defaults.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACE_PACKET_DEFAULTS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACE_PACKET_DEFAULTS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class PerfSampleDefaults;
+class TrackEventDefaults;
+class V8CodeDefaults;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class TracePacketDefaults_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/99, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TracePacketDefaults_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TracePacketDefaults_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TracePacketDefaults_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_timestamp_clock_id() const { return at<58>().valid(); }
+  uint32_t timestamp_clock_id() const { return at<58>().as_uint32(); }
+  bool has_track_event_defaults() const { return at<11>().valid(); }
+  ::protozero::ConstBytes track_event_defaults() const { return at<11>().as_bytes(); }
+  bool has_perf_sample_defaults() const { return at<12>().valid(); }
+  ::protozero::ConstBytes perf_sample_defaults() const { return at<12>().as_bytes(); }
+  bool has_v8_code_defaults() const { return at<99>().valid(); }
+  ::protozero::ConstBytes v8_code_defaults() const { return at<99>().as_bytes(); }
+};
+
+class TracePacketDefaults : public ::protozero::Message {
+ public:
+  using Decoder = TracePacketDefaults_Decoder;
+  enum : int32_t {
+    kTimestampClockIdFieldNumber = 58,
+    kTrackEventDefaultsFieldNumber = 11,
+    kPerfSampleDefaultsFieldNumber = 12,
+    kV8CodeDefaultsFieldNumber = 99,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TracePacketDefaults"; }
+
+
+  using FieldMetadata_TimestampClockId =
+    ::protozero::proto_utils::FieldMetadata<
+      58,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TracePacketDefaults>;
+
+  static constexpr FieldMetadata_TimestampClockId kTimestampClockId{};
+  void set_timestamp_clock_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimestampClockId::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_TrackEventDefaults =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrackEventDefaults,
+      TracePacketDefaults>;
+
+  static constexpr FieldMetadata_TrackEventDefaults kTrackEventDefaults{};
+  template <typename T = TrackEventDefaults> T* set_track_event_defaults() {
+    return BeginNestedMessage<T>(11);
+  }
+
+
+  using FieldMetadata_PerfSampleDefaults =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PerfSampleDefaults,
+      TracePacketDefaults>;
+
+  static constexpr FieldMetadata_PerfSampleDefaults kPerfSampleDefaults{};
+  template <typename T = PerfSampleDefaults> T* set_perf_sample_defaults() {
+    return BeginNestedMessage<T>(12);
+  }
+
+
+  using FieldMetadata_V8CodeDefaults =
+    ::protozero::proto_utils::FieldMetadata<
+      99,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      V8CodeDefaults,
+      TracePacketDefaults>;
+
+  static constexpr FieldMetadata_V8CodeDefaults kV8CodeDefaults{};
+  template <typename T = V8CodeDefaults> T* set_v8_code_defaults() {
+    return BeginNestedMessage<T>(99);
+  }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/test_event.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TEST_EVENT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TEST_EVENT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class DebugAnnotation;
+class TestEvent_TestPayload;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class TestEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TestEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TestEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TestEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_str() const { return at<1>().valid(); }
+  ::protozero::ConstChars str() const { return at<1>().as_string(); }
+  bool has_seq_value() const { return at<2>().valid(); }
+  uint32_t seq_value() const { return at<2>().as_uint32(); }
+  bool has_counter() const { return at<3>().valid(); }
+  uint64_t counter() const { return at<3>().as_uint64(); }
+  bool has_is_last() const { return at<4>().valid(); }
+  bool is_last() const { return at<4>().as_bool(); }
+  bool has_payload() const { return at<5>().valid(); }
+  ::protozero::ConstBytes payload() const { return at<5>().as_bytes(); }
+};
+
+class TestEvent : public ::protozero::Message {
+ public:
+  using Decoder = TestEvent_Decoder;
+  enum : int32_t {
+    kStrFieldNumber = 1,
+    kSeqValueFieldNumber = 2,
+    kCounterFieldNumber = 3,
+    kIsLastFieldNumber = 4,
+    kPayloadFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TestEvent"; }
+
+  using TestPayload = ::perfetto::protos::pbzero::TestEvent_TestPayload;
+
+  using FieldMetadata_Str =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TestEvent>;
+
+  static constexpr FieldMetadata_Str kStr{};
+  void set_str(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Str::kFieldId, data, size);
+  }
+  void set_str(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Str::kFieldId, chars.data, chars.size);
+  }
+  void set_str(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Str::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_SeqValue =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TestEvent>;
+
+  static constexpr FieldMetadata_SeqValue kSeqValue{};
+  void set_seq_value(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SeqValue::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_Counter =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TestEvent>;
+
+  static constexpr FieldMetadata_Counter kCounter{};
+  void set_counter(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Counter::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_IsLast =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TestEvent>;
+
+  static constexpr FieldMetadata_IsLast kIsLast{};
+  void set_is_last(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsLast::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_Payload =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TestEvent_TestPayload,
+      TestEvent>;
+
+  static constexpr FieldMetadata_Payload kPayload{};
+  template <typename T = TestEvent_TestPayload> T* set_payload() {
+    return BeginNestedMessage<T>(5);
+  }
+
+};
+
+class TestEvent_TestPayload_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TestEvent_TestPayload_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TestEvent_TestPayload_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TestEvent_TestPayload_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_str() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> str() const { return GetRepeated<::protozero::ConstChars>(1); }
+  bool has_nested() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> nested() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_single_string() const { return at<4>().valid(); }
+  ::protozero::ConstChars single_string() const { return at<4>().as_string(); }
+  bool has_single_int() const { return at<5>().valid(); }
+  int32_t single_int() const { return at<5>().as_int32(); }
+  bool has_repeated_ints() const { return at<6>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> repeated_ints() const { return GetRepeated<int32_t>(6); }
+  bool has_remaining_nesting_depth() const { return at<3>().valid(); }
+  uint32_t remaining_nesting_depth() const { return at<3>().as_uint32(); }
+  bool has_debug_annotations() const { return at<7>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> debug_annotations() const { return GetRepeated<::protozero::ConstBytes>(7); }
+};
+
+class TestEvent_TestPayload : public ::protozero::Message {
+ public:
+  using Decoder = TestEvent_TestPayload_Decoder;
+  enum : int32_t {
+    kStrFieldNumber = 1,
+    kNestedFieldNumber = 2,
+    kSingleStringFieldNumber = 4,
+    kSingleIntFieldNumber = 5,
+    kRepeatedIntsFieldNumber = 6,
+    kRemainingNestingDepthFieldNumber = 3,
+    kDebugAnnotationsFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TestEvent.TestPayload"; }
+
+
+  using FieldMetadata_Str =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TestEvent_TestPayload>;
+
+  static constexpr FieldMetadata_Str kStr{};
+  void add_str(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Str::kFieldId, data, size);
+  }
+  void add_str(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Str::kFieldId, chars.data, chars.size);
+  }
+  void add_str(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Str::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_Nested =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TestEvent_TestPayload,
+      TestEvent_TestPayload>;
+
+  static constexpr FieldMetadata_Nested kNested{};
+  template <typename T = TestEvent_TestPayload> T* add_nested() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_SingleString =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TestEvent_TestPayload>;
+
+  static constexpr FieldMetadata_SingleString kSingleString{};
+  void set_single_string(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_SingleString::kFieldId, data, size);
+  }
+  void set_single_string(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_SingleString::kFieldId, chars.data, chars.size);
+  }
+  void set_single_string(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_SingleString::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_SingleInt =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TestEvent_TestPayload>;
+
+  static constexpr FieldMetadata_SingleInt kSingleInt{};
+  void set_single_int(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SingleInt::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_RepeatedInts =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TestEvent_TestPayload>;
+
+  static constexpr FieldMetadata_RepeatedInts kRepeatedInts{};
+  void add_repeated_ints(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RepeatedInts::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_RemainingNestingDepth =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TestEvent_TestPayload>;
+
+  static constexpr FieldMetadata_RemainingNestingDepth kRemainingNestingDepth{};
+  void set_remaining_nesting_depth(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RemainingNestingDepth::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_DebugAnnotations =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DebugAnnotation,
+      TestEvent_TestPayload>;
+
+  static constexpr FieldMetadata_DebugAnnotations kDebugAnnotations{};
+  template <typename T = DebugAnnotation> T* add_debug_annotations() {
+    return BeginNestedMessage<T>(7);
+  }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/test_extensions.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TEST_EXTENSIONS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TEST_EXTENSIONS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_event.pbzero.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class DebugAnnotation;
+class TestExtensionChild;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class TestExtensionChild_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/99, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TestExtensionChild_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TestExtensionChild_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TestExtensionChild_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_child_field_for_testing() const { return at<1>().valid(); }
+  ::protozero::ConstChars child_field_for_testing() const { return at<1>().as_string(); }
+  bool has_debug_annotations() const { return at<99>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> debug_annotations() const { return GetRepeated<::protozero::ConstBytes>(99); }
+};
+
+class TestExtensionChild : public ::protozero::Message {
+ public:
+  using Decoder = TestExtensionChild_Decoder;
+  enum : int32_t {
+    kChildFieldForTestingFieldNumber = 1,
+    kDebugAnnotationsFieldNumber = 99,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TestExtensionChild"; }
+
+
+  using FieldMetadata_ChildFieldForTesting =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TestExtensionChild>;
+
+  static constexpr FieldMetadata_ChildFieldForTesting kChildFieldForTesting{};
+  void set_child_field_for_testing(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ChildFieldForTesting::kFieldId, data, size);
+  }
+  void set_child_field_for_testing(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ChildFieldForTesting::kFieldId, chars.data, chars.size);
+  }
+  void set_child_field_for_testing(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChildFieldForTesting::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_DebugAnnotations =
+    ::protozero::proto_utils::FieldMetadata<
+      99,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DebugAnnotation,
+      TestExtensionChild>;
+
+  static constexpr FieldMetadata_DebugAnnotations kDebugAnnotations{};
+  template <typename T = DebugAnnotation> T* add_debug_annotations() {
+    return BeginNestedMessage<T>(99);
+  }
+
+};
+
+class TestExtension : public ::perfetto::protos::pbzero::TrackEvent {
+ public:
+
+  using FieldMetadata_StringExtensionForTesting =
+    ::protozero::proto_utils::FieldMetadata<
+      9900,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TestExtension>;
+
+  static constexpr FieldMetadata_StringExtensionForTesting kStringExtensionForTesting{};
+  void set_string_extension_for_testing(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_StringExtensionForTesting::kFieldId, data, size);
+  }
+  void set_string_extension_for_testing(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_StringExtensionForTesting::kFieldId, chars.data, chars.size);
+  }
+  void set_string_extension_for_testing(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_StringExtensionForTesting::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_StringExtensionForTesting2 =
+    ::protozero::proto_utils::FieldMetadata<
+      9905,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TestExtension>;
+
+  static constexpr FieldMetadata_StringExtensionForTesting2 kStringExtensionForTesting2{};
+  void set_string_extension_for_testing2(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_StringExtensionForTesting2::kFieldId, data, size);
+  }
+  void set_string_extension_for_testing2(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_StringExtensionForTesting2::kFieldId, chars.data, chars.size);
+  }
+  void set_string_extension_for_testing2(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_StringExtensionForTesting2::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_IntExtensionForTesting =
+    ::protozero::proto_utils::FieldMetadata<
+      9901,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TestExtension>;
+
+  static constexpr FieldMetadata_IntExtensionForTesting kIntExtensionForTesting{};
+  void add_int_extension_for_testing(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IntExtensionForTesting::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_OmittedExtensionForTesting =
+    ::protozero::proto_utils::FieldMetadata<
+      9902,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TestExtension>;
+
+  static constexpr FieldMetadata_OmittedExtensionForTesting kOmittedExtensionForTesting{};
+  void set_omitted_extension_for_testing(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_OmittedExtensionForTesting::kFieldId, data, size);
+  }
+  void set_omitted_extension_for_testing(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_OmittedExtensionForTesting::kFieldId, chars.data, chars.size);
+  }
+  void set_omitted_extension_for_testing(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_OmittedExtensionForTesting::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_NestedMessageExtensionForTesting =
+    ::protozero::proto_utils::FieldMetadata<
+      9903,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TestExtensionChild,
+      TestExtension>;
+
+  static constexpr FieldMetadata_NestedMessageExtensionForTesting kNestedMessageExtensionForTesting{};
+  template <typename T = TestExtensionChild> T* set_nested_message_extension_for_testing() {
+    return BeginNestedMessage<T>(9903);
+  }
+
+
+  using FieldMetadata_UintExtensionForTesting =
+    ::protozero::proto_utils::FieldMetadata<
+      9904,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TestExtension>;
+
+  static constexpr FieldMetadata_UintExtensionForTesting kUintExtensionForTesting{};
+  void set_uint_extension_for_testing(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UintExtensionForTesting::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);
+  }
+  enum : int32_t {
+    kStringExtensionForTestingFieldNumber = 9900,
+    kStringExtensionForTesting2FieldNumber = 9905,
+    kIntExtensionForTestingFieldNumber = 9901,
+    kOmittedExtensionForTestingFieldNumber = 9902,
+    kNestedMessageExtensionForTestingFieldNumber = 9903,
+    kUintExtensionForTestingFieldNumber = 9904,
+  };
+};
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/trace.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class TracePacket;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class Trace_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  Trace_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Trace_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Trace_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_packet() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> packet() const { return GetRepeated<::protozero::ConstBytes>(1); }
+};
+
+class Trace : public ::protozero::Message {
+ public:
+  using Decoder = Trace_Decoder;
+  enum : int32_t {
+    kPacketFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Trace"; }
+
+
+  using FieldMetadata_Packet =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TracePacket,
+      Trace>;
+
+  static constexpr FieldMetadata_Packet kPacket{};
+  template <typename T = TracePacket> T* add_packet() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/extension_descriptor.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_EXTENSION_DESCRIPTOR_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_EXTENSION_DESCRIPTOR_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class FileDescriptorSet;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class ExtensionDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ExtensionDescriptor_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ExtensionDescriptor_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ExtensionDescriptor_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_extension_set() const { return at<1>().valid(); }
+  ::protozero::ConstBytes extension_set() const { return at<1>().as_bytes(); }
+};
+
+class ExtensionDescriptor : public ::protozero::Message {
+ public:
+  using Decoder = ExtensionDescriptor_Decoder;
+  enum : int32_t {
+    kExtensionSetFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ExtensionDescriptor"; }
+
+
+  using FieldMetadata_ExtensionSet =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FileDescriptorSet,
+      ExtensionDescriptor>;
+
+  static constexpr FieldMetadata_ExtensionSet kExtensionSet{};
+  template <typename T = FileDescriptorSet> T* set_extension_set() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/memory_graph.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_MEMORY_GRAPH_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_MEMORY_GRAPH_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class MemoryTrackerSnapshot_ProcessSnapshot;
+class MemoryTrackerSnapshot_ProcessSnapshot_MemoryEdge;
+class MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode;
+class MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry;
+namespace perfetto_pbzero_enum_MemoryTrackerSnapshot {
+enum LevelOfDetail : int32_t;
+}  // namespace perfetto_pbzero_enum_MemoryTrackerSnapshot
+using MemoryTrackerSnapshot_LevelOfDetail = perfetto_pbzero_enum_MemoryTrackerSnapshot::LevelOfDetail;
+namespace perfetto_pbzero_enum_MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry {
+enum Units : int32_t;
+}  // namespace perfetto_pbzero_enum_MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry
+using MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units = perfetto_pbzero_enum_MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry::Units;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_MemoryTrackerSnapshot {
+enum LevelOfDetail : int32_t {
+  DETAIL_FULL = 0,
+  DETAIL_LIGHT = 1,
+  DETAIL_BACKGROUND = 2,
+};
+} // namespace perfetto_pbzero_enum_MemoryTrackerSnapshot
+using MemoryTrackerSnapshot_LevelOfDetail = perfetto_pbzero_enum_MemoryTrackerSnapshot::LevelOfDetail;
+
+
+constexpr MemoryTrackerSnapshot_LevelOfDetail MemoryTrackerSnapshot_LevelOfDetail_MIN = MemoryTrackerSnapshot_LevelOfDetail::DETAIL_FULL;
+constexpr MemoryTrackerSnapshot_LevelOfDetail MemoryTrackerSnapshot_LevelOfDetail_MAX = MemoryTrackerSnapshot_LevelOfDetail::DETAIL_BACKGROUND;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* MemoryTrackerSnapshot_LevelOfDetail_Name(::perfetto::protos::pbzero::MemoryTrackerSnapshot_LevelOfDetail value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::MemoryTrackerSnapshot_LevelOfDetail::DETAIL_FULL:
+    return "DETAIL_FULL";
+
+  case ::perfetto::protos::pbzero::MemoryTrackerSnapshot_LevelOfDetail::DETAIL_LIGHT:
+    return "DETAIL_LIGHT";
+
+  case ::perfetto::protos::pbzero::MemoryTrackerSnapshot_LevelOfDetail::DETAIL_BACKGROUND:
+    return "DETAIL_BACKGROUND";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry {
+enum Units : int32_t {
+  UNSPECIFIED = 0,
+  BYTES = 1,
+  COUNT = 2,
+};
+} // namespace perfetto_pbzero_enum_MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry
+using MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units = perfetto_pbzero_enum_MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry::Units;
+
+
+constexpr MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units_MIN = MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units::UNSPECIFIED;
+constexpr MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units_MAX = MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units::COUNT;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units_Name(::perfetto::protos::pbzero::MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units::UNSPECIFIED:
+    return "UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units::BYTES:
+    return "BYTES";
+
+  case ::perfetto::protos::pbzero::MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units::COUNT:
+    return "COUNT";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class MemoryTrackerSnapshot_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  MemoryTrackerSnapshot_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MemoryTrackerSnapshot_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MemoryTrackerSnapshot_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_global_dump_id() const { return at<1>().valid(); }
+  uint64_t global_dump_id() const { return at<1>().as_uint64(); }
+  bool has_level_of_detail() const { return at<2>().valid(); }
+  int32_t level_of_detail() const { return at<2>().as_int32(); }
+  bool has_process_memory_dumps() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> process_memory_dumps() const { return GetRepeated<::protozero::ConstBytes>(3); }
+};
+
+class MemoryTrackerSnapshot : public ::protozero::Message {
+ public:
+  using Decoder = MemoryTrackerSnapshot_Decoder;
+  enum : int32_t {
+    kGlobalDumpIdFieldNumber = 1,
+    kLevelOfDetailFieldNumber = 2,
+    kProcessMemoryDumpsFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MemoryTrackerSnapshot"; }
+
+  using ProcessSnapshot = ::perfetto::protos::pbzero::MemoryTrackerSnapshot_ProcessSnapshot;
+
+  using LevelOfDetail = ::perfetto::protos::pbzero::MemoryTrackerSnapshot_LevelOfDetail;
+  static inline const char* LevelOfDetail_Name(LevelOfDetail value) {
+    return ::perfetto::protos::pbzero::MemoryTrackerSnapshot_LevelOfDetail_Name(value);
+  }
+  static inline const LevelOfDetail DETAIL_FULL = LevelOfDetail::DETAIL_FULL;
+  static inline const LevelOfDetail DETAIL_LIGHT = LevelOfDetail::DETAIL_LIGHT;
+  static inline const LevelOfDetail DETAIL_BACKGROUND = LevelOfDetail::DETAIL_BACKGROUND;
+
+  using FieldMetadata_GlobalDumpId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MemoryTrackerSnapshot>;
+
+  static constexpr FieldMetadata_GlobalDumpId kGlobalDumpId{};
+  void set_global_dump_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GlobalDumpId::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_LevelOfDetail =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      MemoryTrackerSnapshot_LevelOfDetail,
+      MemoryTrackerSnapshot>;
+
+  static constexpr FieldMetadata_LevelOfDetail kLevelOfDetail{};
+  void set_level_of_detail(MemoryTrackerSnapshot_LevelOfDetail value) {
+    static constexpr uint32_t field_id = FieldMetadata_LevelOfDetail::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_ProcessMemoryDumps =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MemoryTrackerSnapshot_ProcessSnapshot,
+      MemoryTrackerSnapshot>;
+
+  static constexpr FieldMetadata_ProcessMemoryDumps kProcessMemoryDumps{};
+  template <typename T = MemoryTrackerSnapshot_ProcessSnapshot> T* add_process_memory_dumps() {
+    return BeginNestedMessage<T>(3);
+  }
+
+};
+
+class MemoryTrackerSnapshot_ProcessSnapshot_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  MemoryTrackerSnapshot_ProcessSnapshot_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MemoryTrackerSnapshot_ProcessSnapshot_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MemoryTrackerSnapshot_ProcessSnapshot_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  int32_t pid() const { return at<1>().as_int32(); }
+  bool has_allocator_dumps() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> allocator_dumps() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_memory_edges() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> memory_edges() const { return GetRepeated<::protozero::ConstBytes>(3); }
+};
+
+class MemoryTrackerSnapshot_ProcessSnapshot : public ::protozero::Message {
+ public:
+  using Decoder = MemoryTrackerSnapshot_ProcessSnapshot_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kAllocatorDumpsFieldNumber = 2,
+    kMemoryEdgesFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MemoryTrackerSnapshot.ProcessSnapshot"; }
+
+  using MemoryNode = ::perfetto::protos::pbzero::MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode;
+  using MemoryEdge = ::perfetto::protos::pbzero::MemoryTrackerSnapshot_ProcessSnapshot_MemoryEdge;
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MemoryTrackerSnapshot_ProcessSnapshot>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_AllocatorDumps =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode,
+      MemoryTrackerSnapshot_ProcessSnapshot>;
+
+  static constexpr FieldMetadata_AllocatorDumps kAllocatorDumps{};
+  template <typename T = MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode> T* add_allocator_dumps() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_MemoryEdges =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MemoryTrackerSnapshot_ProcessSnapshot_MemoryEdge,
+      MemoryTrackerSnapshot_ProcessSnapshot>;
+
+  static constexpr FieldMetadata_MemoryEdges kMemoryEdges{};
+  template <typename T = MemoryTrackerSnapshot_ProcessSnapshot_MemoryEdge> T* add_memory_edges() {
+    return BeginNestedMessage<T>(3);
+  }
+
+};
+
+class MemoryTrackerSnapshot_ProcessSnapshot_MemoryEdge_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MemoryTrackerSnapshot_ProcessSnapshot_MemoryEdge_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MemoryTrackerSnapshot_ProcessSnapshot_MemoryEdge_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MemoryTrackerSnapshot_ProcessSnapshot_MemoryEdge_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_source_id() const { return at<1>().valid(); }
+  uint64_t source_id() const { return at<1>().as_uint64(); }
+  bool has_target_id() const { return at<2>().valid(); }
+  uint64_t target_id() const { return at<2>().as_uint64(); }
+  bool has_importance() const { return at<3>().valid(); }
+  uint32_t importance() const { return at<3>().as_uint32(); }
+  bool has_overridable() const { return at<4>().valid(); }
+  bool overridable() const { return at<4>().as_bool(); }
+};
+
+class MemoryTrackerSnapshot_ProcessSnapshot_MemoryEdge : public ::protozero::Message {
+ public:
+  using Decoder = MemoryTrackerSnapshot_ProcessSnapshot_MemoryEdge_Decoder;
+  enum : int32_t {
+    kSourceIdFieldNumber = 1,
+    kTargetIdFieldNumber = 2,
+    kImportanceFieldNumber = 3,
+    kOverridableFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MemoryTrackerSnapshot.ProcessSnapshot.MemoryEdge"; }
+
+
+  using FieldMetadata_SourceId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MemoryTrackerSnapshot_ProcessSnapshot_MemoryEdge>;
+
+  static constexpr FieldMetadata_SourceId kSourceId{};
+  void set_source_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SourceId::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_TargetId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MemoryTrackerSnapshot_ProcessSnapshot_MemoryEdge>;
+
+  static constexpr FieldMetadata_TargetId kTargetId{};
+  void set_target_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TargetId::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_Importance =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MemoryTrackerSnapshot_ProcessSnapshot_MemoryEdge>;
+
+  static constexpr FieldMetadata_Importance kImportance{};
+  void set_importance(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Importance::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_Overridable =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      MemoryTrackerSnapshot_ProcessSnapshot_MemoryEdge>;
+
+  static constexpr FieldMetadata_Overridable kOverridable{};
+  void set_overridable(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_Overridable::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 MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  uint64_t id() const { return at<1>().as_uint64(); }
+  bool has_absolute_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars absolute_name() const { return at<2>().as_string(); }
+  bool has_weak() const { return at<3>().valid(); }
+  bool weak() const { return at<3>().as_bool(); }
+  bool has_size_bytes() const { return at<4>().valid(); }
+  uint64_t size_bytes() const { return at<4>().as_uint64(); }
+  bool has_entries() const { return at<5>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> entries() const { return GetRepeated<::protozero::ConstBytes>(5); }
+};
+
+class MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode : public ::protozero::Message {
+ public:
+  using Decoder = MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kAbsoluteNameFieldNumber = 2,
+    kWeakFieldNumber = 3,
+    kSizeBytesFieldNumber = 4,
+    kEntriesFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MemoryTrackerSnapshot.ProcessSnapshot.MemoryNode"; }
+
+  using MemoryNodeEntry = ::perfetto::protos::pbzero::MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry;
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::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_AbsoluteName =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode>;
+
+  static constexpr FieldMetadata_AbsoluteName kAbsoluteName{};
+  void set_absolute_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_AbsoluteName::kFieldId, data, size);
+  }
+  void set_absolute_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_AbsoluteName::kFieldId, chars.data, chars.size);
+  }
+  void set_absolute_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_AbsoluteName::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_Weak =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode>;
+
+  static constexpr FieldMetadata_Weak kWeak{};
+  void set_weak(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_Weak::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_SizeBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode>;
+
+  static constexpr FieldMetadata_SizeBytes kSizeBytes{};
+  void set_size_bytes(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SizeBytes::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_Entries =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry,
+      MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode>;
+
+  static constexpr FieldMetadata_Entries kEntries{};
+  template <typename T = MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry> T* add_entries() {
+    return BeginNestedMessage<T>(5);
+  }
+
+};
+
+class MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_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_units() const { return at<2>().valid(); }
+  int32_t units() const { return at<2>().as_int32(); }
+  bool has_value_uint64() const { return at<3>().valid(); }
+  uint64_t value_uint64() const { return at<3>().as_uint64(); }
+  bool has_value_string() const { return at<4>().valid(); }
+  ::protozero::ConstChars value_string() const { return at<4>().as_string(); }
+};
+
+class MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry : public ::protozero::Message {
+ public:
+  using Decoder = MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kUnitsFieldNumber = 2,
+    kValueUint64FieldNumber = 3,
+    kValueStringFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MemoryTrackerSnapshot.ProcessSnapshot.MemoryNode.MemoryNodeEntry"; }
+
+
+  using Units = ::perfetto::protos::pbzero::MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units;
+  static inline const char* Units_Name(Units value) {
+    return ::perfetto::protos::pbzero::MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units_Name(value);
+  }
+  static inline const Units UNSPECIFIED = Units::UNSPECIFIED;
+  static inline const Units BYTES = Units::BYTES;
+  static inline const Units COUNT = Units::COUNT;
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.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_Units =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units,
+      MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry>;
+
+  static constexpr FieldMetadata_Units kUnits{};
+  void set_units(MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units value) {
+    static constexpr uint32_t field_id = FieldMetadata_Units::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_ValueUint64 =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry>;
+
+  static constexpr FieldMetadata_ValueUint64 kValueUint64{};
+  void set_value_uint64(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ValueUint64::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_ValueString =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry>;
+
+  static constexpr FieldMetadata_ValueString kValueString{};
+  void set_value_string(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ValueString::kFieldId, data, size);
+  }
+  void set_value_string(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ValueString::kFieldId, chars.data, chars.size);
+  }
+  void set_value_string(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ValueString::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ui_state.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_UI_STATE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_UI_STATE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class UiState_HighlightProcess;
+} // Namespace pbzero.
+} // Namespace protos.
+} // Namespace perfetto.
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class UiState_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  UiState_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit UiState_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit UiState_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_timeline_start_ts() const { return at<1>().valid(); }
+  int64_t timeline_start_ts() const { return at<1>().as_int64(); }
+  bool has_timeline_end_ts() const { return at<2>().valid(); }
+  int64_t timeline_end_ts() const { return at<2>().as_int64(); }
+  bool has_highlight_process() const { return at<3>().valid(); }
+  ::protozero::ConstBytes highlight_process() const { return at<3>().as_bytes(); }
+};
+
+class UiState : public ::protozero::Message {
+ public:
+  using Decoder = UiState_Decoder;
+  enum : int32_t {
+    kTimelineStartTsFieldNumber = 1,
+    kTimelineEndTsFieldNumber = 2,
+    kHighlightProcessFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.UiState"; }
+
+  using HighlightProcess = ::perfetto::protos::pbzero::UiState_HighlightProcess;
+
+  using FieldMetadata_TimelineStartTs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      UiState>;
+
+  static constexpr FieldMetadata_TimelineStartTs kTimelineStartTs{};
+  void set_timeline_start_ts(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimelineStartTs::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_TimelineEndTs =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      UiState>;
+
+  static constexpr FieldMetadata_TimelineEndTs kTimelineEndTs{};
+  void set_timeline_end_ts(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimelineEndTs::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_HighlightProcess =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      UiState_HighlightProcess,
+      UiState>;
+
+  static constexpr FieldMetadata_HighlightProcess kHighlightProcess{};
+  template <typename T = UiState_HighlightProcess> T* set_highlight_process() {
+    return BeginNestedMessage<T>(3);
+  }
+
+};
+
+class UiState_HighlightProcess_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  UiState_HighlightProcess_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit UiState_HighlightProcess_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit UiState_HighlightProcess_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  uint32_t pid() const { return at<1>().as_uint32(); }
+  bool has_cmdline() const { return at<2>().valid(); }
+  ::protozero::ConstChars cmdline() const { return at<2>().as_string(); }
+};
+
+class UiState_HighlightProcess : public ::protozero::Message {
+ public:
+  using Decoder = UiState_HighlightProcess_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kCmdlineFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.UiState.HighlightProcess"; }
+
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      UiState_HighlightProcess>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::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_Cmdline =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      UiState_HighlightProcess>;
+
+  static constexpr FieldMetadata_Cmdline kCmdline{};
+  void set_cmdline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cmdline::kFieldId, data, size);
+  }
+  void set_cmdline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Cmdline::kFieldId, chars.data, chars.size);
+  }
+  void set_cmdline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cmdline::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);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_active_processes.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_ACTIVE_PROCESSES_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_ACTIVE_PROCESSES_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ChromeActiveProcesses;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT ChromeActiveProcesses : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kPidFieldNumber = 1,
+  };
+
+  ChromeActiveProcesses();
+  ~ChromeActiveProcesses() override;
+  ChromeActiveProcesses(ChromeActiveProcesses&&) noexcept;
+  ChromeActiveProcesses& operator=(ChromeActiveProcesses&&);
+  ChromeActiveProcesses(const ChromeActiveProcesses&);
+  ChromeActiveProcesses& operator=(const ChromeActiveProcesses&);
+  bool operator==(const ChromeActiveProcesses&) const;
+  bool operator!=(const ChromeActiveProcesses& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<int32_t>& pid() const { return pid_; }
+  std::vector<int32_t>* mutable_pid() { return &pid_; }
+  int pid_size() const { return static_cast<int>(pid_.size()); }
+  void clear_pid() { pid_.clear(); }
+  void add_pid(int32_t value) { pid_.emplace_back(value); }
+  int32_t* add_pid() { pid_.emplace_back(); return &pid_.back(); }
+
+ private:
+  std::vector<int32_t> pid_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_ACTIVE_PROCESSES_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_application_state_info.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_APPLICATION_STATE_INFO_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_APPLICATION_STATE_INFO_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ChromeApplicationStateInfo;
+enum ChromeApplicationStateInfo_ChromeApplicationState : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum ChromeApplicationStateInfo_ChromeApplicationState : int {
+  ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_UNKNOWN = 0,
+  ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_RUNNING_ACTIVITIES = 1,
+  ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_PAUSED_ACTIVITIES = 2,
+  ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_STOPPED_ACTIVITIES = 3,
+  ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES = 4,
+};
+
+class PERFETTO_EXPORT_COMPONENT ChromeApplicationStateInfo : public ::protozero::CppMessageObj {
+ public:
+  using ChromeApplicationState = ChromeApplicationStateInfo_ChromeApplicationState;
+  static constexpr auto APPLICATION_STATE_UNKNOWN = ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_UNKNOWN;
+  static constexpr auto APPLICATION_STATE_HAS_RUNNING_ACTIVITIES = ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_RUNNING_ACTIVITIES;
+  static constexpr auto APPLICATION_STATE_HAS_PAUSED_ACTIVITIES = ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_PAUSED_ACTIVITIES;
+  static constexpr auto APPLICATION_STATE_HAS_STOPPED_ACTIVITIES = ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_STOPPED_ACTIVITIES;
+  static constexpr auto APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES = ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES;
+  static constexpr auto ChromeApplicationState_MIN = ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_UNKNOWN;
+  static constexpr auto ChromeApplicationState_MAX = ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES;
+  enum FieldNumbers {
+    kApplicationStateFieldNumber = 1,
+  };
+
+  ChromeApplicationStateInfo();
+  ~ChromeApplicationStateInfo() override;
+  ChromeApplicationStateInfo(ChromeApplicationStateInfo&&) noexcept;
+  ChromeApplicationStateInfo& operator=(ChromeApplicationStateInfo&&);
+  ChromeApplicationStateInfo(const ChromeApplicationStateInfo&);
+  ChromeApplicationStateInfo& operator=(const ChromeApplicationStateInfo&);
+  bool operator==(const ChromeApplicationStateInfo&) const;
+  bool operator!=(const ChromeApplicationStateInfo& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_application_state() const { return _has_field_[1]; }
+  ChromeApplicationStateInfo_ChromeApplicationState application_state() const { return application_state_; }
+  void set_application_state(ChromeApplicationStateInfo_ChromeApplicationState value) { application_state_ = value; _has_field_.set(1); }
+
+ private:
+  ChromeApplicationStateInfo_ChromeApplicationState application_state_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_APPLICATION_STATE_INFO_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_COMPOSITOR_SCHEDULER_STATE_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_COMPOSITOR_SCHEDULER_STATE_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class CompositorTimingHistory;
+class BeginFrameSourceState;
+class BeginFrameArgs;
+class SourceLocation;
+class BeginFrameObserverState;
+class BeginImplFrameArgs;
+class BeginImplFrameArgs_TimestampsInUs;
+class ChromeCompositorStateMachine;
+class ChromeCompositorStateMachine_MinorState;
+class ChromeCompositorStateMachine_MajorState;
+class ChromeCompositorSchedulerState;
+enum ChromeCompositorSchedulerAction : int;
+enum BeginFrameArgs_BeginFrameArgsType : int;
+enum BeginImplFrameArgs_State : int;
+enum ChromeCompositorStateMachine_MinorState_TreePriority : int;
+enum ChromeCompositorStateMachine_MinorState_ScrollHandlerState : int;
+enum ChromeCompositorStateMachine_MajorState_BeginImplFrameState : int;
+enum ChromeCompositorStateMachine_MajorState_BeginMainFrameState : int;
+enum ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState : int;
+enum ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState : int;
+enum ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum ChromeCompositorSchedulerAction : int {
+  CC_SCHEDULER_ACTION_UNSPECIFIED = 0,
+  CC_SCHEDULER_ACTION_NONE = 1,
+  CC_SCHEDULER_ACTION_SEND_BEGIN_MAIN_FRAME = 2,
+  CC_SCHEDULER_ACTION_COMMIT = 3,
+  CC_SCHEDULER_ACTION_ACTIVATE_SYNC_TREE = 4,
+  CC_SCHEDULER_ACTION_DRAW_IF_POSSIBLE = 5,
+  CC_SCHEDULER_ACTION_DRAW_FORCED = 6,
+  CC_SCHEDULER_ACTION_DRAW_ABORT = 7,
+  CC_SCHEDULER_ACTION_BEGIN_LAYER_TREE_FRAME_SINK_CREATION = 8,
+  CC_SCHEDULER_ACTION_PREPARE_TILES = 9,
+  CC_SCHEDULER_ACTION_INVALIDATE_LAYER_TREE_FRAME_SINK = 10,
+  CC_SCHEDULER_ACTION_PERFORM_IMPL_SIDE_INVALIDATION = 11,
+  CC_SCHEDULER_ACTION_NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_UNTIL = 12,
+  CC_SCHEDULER_ACTION_NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_SOON = 13,
+};
+enum BeginFrameArgs_BeginFrameArgsType : int {
+  BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_UNSPECIFIED = 0,
+  BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_INVALID = 1,
+  BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_NORMAL = 2,
+  BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_MISSED = 3,
+};
+enum BeginImplFrameArgs_State : int {
+  BeginImplFrameArgs_State_BEGIN_FRAME_FINISHED = 0,
+  BeginImplFrameArgs_State_BEGIN_FRAME_USING = 1,
+};
+enum ChromeCompositorStateMachine_MinorState_TreePriority : int {
+  ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_UNSPECIFIED = 0,
+  ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_SAME_PRIORITY_FOR_BOTH_TREES = 1,
+  ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_SMOOTHNESS_TAKES_PRIORITY = 2,
+  ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY = 3,
+};
+enum ChromeCompositorStateMachine_MinorState_ScrollHandlerState : int {
+  ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_HANDLER_UNSPECIFIED = 0,
+  ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_AFFECTS_SCROLL_HANDLER = 1,
+  ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER = 2,
+};
+enum ChromeCompositorStateMachine_MajorState_BeginImplFrameState : int {
+  ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_UNSPECIFIED = 0,
+  ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_IDLE = 1,
+  ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_INSIDE_BEGIN_FRAME = 2,
+  ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_INSIDE_DEADLINE = 3,
+};
+enum ChromeCompositorStateMachine_MajorState_BeginMainFrameState : int {
+  ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_UNSPECIFIED = 0,
+  ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_IDLE = 1,
+  ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_SENT = 2,
+  ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_READY_TO_COMMIT = 3,
+};
+enum ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState : int {
+  ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_UNSPECIFIED = 0,
+  ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_NONE = 1,
+  ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_ACTIVE = 2,
+  ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_CREATING = 3,
+  ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_WAITING_FOR_FIRST_COMMIT = 4,
+  ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION = 5,
+};
+enum ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState : int {
+  ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_UNSPECIFIED = 0,
+  ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_IDLE = 1,
+  ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_COMMIT = 2,
+  ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_ACTIVATION = 3,
+  ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_DRAW = 4,
+};
+enum ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode : int {
+  ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_UNSPECIFIED = 0,
+  ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_NONE = 1,
+  ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_IMMEDIATE = 2,
+  ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_REGULAR = 3,
+  ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_LATE = 4,
+  ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_BLOCKED = 5,
+};
+
+class PERFETTO_EXPORT_COMPONENT CompositorTimingHistory : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kBeginMainFrameQueueCriticalEstimateDeltaUsFieldNumber = 1,
+    kBeginMainFrameQueueNotCriticalEstimateDeltaUsFieldNumber = 2,
+    kBeginMainFrameStartToReadyToCommitEstimateDeltaUsFieldNumber = 3,
+    kCommitToReadyToActivateEstimateDeltaUsFieldNumber = 4,
+    kPrepareTilesEstimateDeltaUsFieldNumber = 5,
+    kActivateEstimateDeltaUsFieldNumber = 6,
+    kDrawEstimateDeltaUsFieldNumber = 7,
+  };
+
+  CompositorTimingHistory();
+  ~CompositorTimingHistory() override;
+  CompositorTimingHistory(CompositorTimingHistory&&) noexcept;
+  CompositorTimingHistory& operator=(CompositorTimingHistory&&);
+  CompositorTimingHistory(const CompositorTimingHistory&);
+  CompositorTimingHistory& operator=(const CompositorTimingHistory&);
+  bool operator==(const CompositorTimingHistory&) const;
+  bool operator!=(const CompositorTimingHistory& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_begin_main_frame_queue_critical_estimate_delta_us() const { return _has_field_[1]; }
+  int64_t begin_main_frame_queue_critical_estimate_delta_us() const { return begin_main_frame_queue_critical_estimate_delta_us_; }
+  void set_begin_main_frame_queue_critical_estimate_delta_us(int64_t value) { begin_main_frame_queue_critical_estimate_delta_us_ = value; _has_field_.set(1); }
+
+  bool has_begin_main_frame_queue_not_critical_estimate_delta_us() const { return _has_field_[2]; }
+  int64_t begin_main_frame_queue_not_critical_estimate_delta_us() const { return begin_main_frame_queue_not_critical_estimate_delta_us_; }
+  void set_begin_main_frame_queue_not_critical_estimate_delta_us(int64_t value) { begin_main_frame_queue_not_critical_estimate_delta_us_ = value; _has_field_.set(2); }
+
+  bool has_begin_main_frame_start_to_ready_to_commit_estimate_delta_us() const { return _has_field_[3]; }
+  int64_t begin_main_frame_start_to_ready_to_commit_estimate_delta_us() const { return begin_main_frame_start_to_ready_to_commit_estimate_delta_us_; }
+  void set_begin_main_frame_start_to_ready_to_commit_estimate_delta_us(int64_t value) { begin_main_frame_start_to_ready_to_commit_estimate_delta_us_ = value; _has_field_.set(3); }
+
+  bool has_commit_to_ready_to_activate_estimate_delta_us() const { return _has_field_[4]; }
+  int64_t commit_to_ready_to_activate_estimate_delta_us() const { return commit_to_ready_to_activate_estimate_delta_us_; }
+  void set_commit_to_ready_to_activate_estimate_delta_us(int64_t value) { commit_to_ready_to_activate_estimate_delta_us_ = value; _has_field_.set(4); }
+
+  bool has_prepare_tiles_estimate_delta_us() const { return _has_field_[5]; }
+  int64_t prepare_tiles_estimate_delta_us() const { return prepare_tiles_estimate_delta_us_; }
+  void set_prepare_tiles_estimate_delta_us(int64_t value) { prepare_tiles_estimate_delta_us_ = value; _has_field_.set(5); }
+
+  bool has_activate_estimate_delta_us() const { return _has_field_[6]; }
+  int64_t activate_estimate_delta_us() const { return activate_estimate_delta_us_; }
+  void set_activate_estimate_delta_us(int64_t value) { activate_estimate_delta_us_ = value; _has_field_.set(6); }
+
+  bool has_draw_estimate_delta_us() const { return _has_field_[7]; }
+  int64_t draw_estimate_delta_us() const { return draw_estimate_delta_us_; }
+  void set_draw_estimate_delta_us(int64_t value) { draw_estimate_delta_us_ = value; _has_field_.set(7); }
+
+ private:
+  int64_t begin_main_frame_queue_critical_estimate_delta_us_{};
+  int64_t begin_main_frame_queue_not_critical_estimate_delta_us_{};
+  int64_t begin_main_frame_start_to_ready_to_commit_estimate_delta_us_{};
+  int64_t commit_to_ready_to_activate_estimate_delta_us_{};
+  int64_t prepare_tiles_estimate_delta_us_{};
+  int64_t activate_estimate_delta_us_{};
+  int64_t draw_estimate_delta_us_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<8> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT BeginFrameSourceState : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kSourceIdFieldNumber = 1,
+    kPausedFieldNumber = 2,
+    kNumObserversFieldNumber = 3,
+    kLastBeginFrameArgsFieldNumber = 4,
+  };
+
+  BeginFrameSourceState();
+  ~BeginFrameSourceState() override;
+  BeginFrameSourceState(BeginFrameSourceState&&) noexcept;
+  BeginFrameSourceState& operator=(BeginFrameSourceState&&);
+  BeginFrameSourceState(const BeginFrameSourceState&);
+  BeginFrameSourceState& operator=(const BeginFrameSourceState&);
+  bool operator==(const BeginFrameSourceState&) const;
+  bool operator!=(const BeginFrameSourceState& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_source_id() const { return _has_field_[1]; }
+  uint32_t source_id() const { return source_id_; }
+  void set_source_id(uint32_t value) { source_id_ = value; _has_field_.set(1); }
+
+  bool has_paused() const { return _has_field_[2]; }
+  bool paused() const { return paused_; }
+  void set_paused(bool value) { paused_ = value; _has_field_.set(2); }
+
+  bool has_num_observers() const { return _has_field_[3]; }
+  uint32_t num_observers() const { return num_observers_; }
+  void set_num_observers(uint32_t value) { num_observers_ = value; _has_field_.set(3); }
+
+  bool has_last_begin_frame_args() const { return _has_field_[4]; }
+  const BeginFrameArgs& last_begin_frame_args() const { return *last_begin_frame_args_; }
+  BeginFrameArgs* mutable_last_begin_frame_args() { _has_field_.set(4); return last_begin_frame_args_.get(); }
+
+ private:
+  uint32_t source_id_{};
+  bool paused_{};
+  uint32_t num_observers_{};
+  ::protozero::CopyablePtr<BeginFrameArgs> last_begin_frame_args_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<5> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT BeginFrameArgs : public ::protozero::CppMessageObj {
+ public:
+  using BeginFrameArgsType = BeginFrameArgs_BeginFrameArgsType;
+  static constexpr auto BEGIN_FRAME_ARGS_TYPE_UNSPECIFIED = BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_UNSPECIFIED;
+  static constexpr auto BEGIN_FRAME_ARGS_TYPE_INVALID = BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_INVALID;
+  static constexpr auto BEGIN_FRAME_ARGS_TYPE_NORMAL = BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_NORMAL;
+  static constexpr auto BEGIN_FRAME_ARGS_TYPE_MISSED = BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_MISSED;
+  static constexpr auto BeginFrameArgsType_MIN = BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_UNSPECIFIED;
+  static constexpr auto BeginFrameArgsType_MAX = BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_MISSED;
+  enum FieldNumbers {
+    kTypeFieldNumber = 1,
+    kSourceIdFieldNumber = 2,
+    kSequenceNumberFieldNumber = 3,
+    kFrameTimeUsFieldNumber = 4,
+    kDeadlineUsFieldNumber = 5,
+    kIntervalDeltaUsFieldNumber = 6,
+    kOnCriticalPathFieldNumber = 7,
+    kAnimateOnlyFieldNumber = 8,
+    kSourceLocationIidFieldNumber = 9,
+    kSourceLocationFieldNumber = 10,
+    kFramesThrottledSinceLastFieldNumber = 12,
+  };
+
+  BeginFrameArgs();
+  ~BeginFrameArgs() override;
+  BeginFrameArgs(BeginFrameArgs&&) noexcept;
+  BeginFrameArgs& operator=(BeginFrameArgs&&);
+  BeginFrameArgs(const BeginFrameArgs&);
+  BeginFrameArgs& operator=(const BeginFrameArgs&);
+  bool operator==(const BeginFrameArgs&) const;
+  bool operator!=(const BeginFrameArgs& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_type() const { return _has_field_[1]; }
+  BeginFrameArgs_BeginFrameArgsType type() const { return type_; }
+  void set_type(BeginFrameArgs_BeginFrameArgsType value) { type_ = value; _has_field_.set(1); }
+
+  bool has_source_id() const { return _has_field_[2]; }
+  uint64_t source_id() const { return source_id_; }
+  void set_source_id(uint64_t value) { source_id_ = value; _has_field_.set(2); }
+
+  bool has_sequence_number() const { return _has_field_[3]; }
+  uint64_t sequence_number() const { return sequence_number_; }
+  void set_sequence_number(uint64_t value) { sequence_number_ = value; _has_field_.set(3); }
+
+  bool has_frame_time_us() const { return _has_field_[4]; }
+  int64_t frame_time_us() const { return frame_time_us_; }
+  void set_frame_time_us(int64_t value) { frame_time_us_ = value; _has_field_.set(4); }
+
+  bool has_deadline_us() const { return _has_field_[5]; }
+  int64_t deadline_us() const { return deadline_us_; }
+  void set_deadline_us(int64_t value) { deadline_us_ = value; _has_field_.set(5); }
+
+  bool has_interval_delta_us() const { return _has_field_[6]; }
+  int64_t interval_delta_us() const { return interval_delta_us_; }
+  void set_interval_delta_us(int64_t value) { interval_delta_us_ = value; _has_field_.set(6); }
+
+  bool has_on_critical_path() const { return _has_field_[7]; }
+  bool on_critical_path() const { return on_critical_path_; }
+  void set_on_critical_path(bool value) { on_critical_path_ = value; _has_field_.set(7); }
+
+  bool has_animate_only() const { return _has_field_[8]; }
+  bool animate_only() const { return animate_only_; }
+  void set_animate_only(bool value) { animate_only_ = value; _has_field_.set(8); }
+
+  bool has_source_location_iid() const { return _has_field_[9]; }
+  uint64_t source_location_iid() const { return source_location_iid_; }
+  void set_source_location_iid(uint64_t value) { source_location_iid_ = value; _has_field_.set(9); }
+
+  bool has_source_location() const { return _has_field_[10]; }
+  const SourceLocation& source_location() const { return *source_location_; }
+  SourceLocation* mutable_source_location() { _has_field_.set(10); return source_location_.get(); }
+
+  bool has_frames_throttled_since_last() const { return _has_field_[12]; }
+  int64_t frames_throttled_since_last() const { return frames_throttled_since_last_; }
+  void set_frames_throttled_since_last(int64_t value) { frames_throttled_since_last_ = value; _has_field_.set(12); }
+
+ private:
+  BeginFrameArgs_BeginFrameArgsType type_{};
+  uint64_t source_id_{};
+  uint64_t sequence_number_{};
+  int64_t frame_time_us_{};
+  int64_t deadline_us_{};
+  int64_t interval_delta_us_{};
+  bool on_critical_path_{};
+  bool animate_only_{};
+  uint64_t source_location_iid_{};
+  ::protozero::CopyablePtr<SourceLocation> source_location_;
+  int64_t frames_throttled_since_last_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<13> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT BeginFrameObserverState : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDroppedBeginFrameArgsFieldNumber = 1,
+    kLastBeginFrameArgsFieldNumber = 2,
+  };
+
+  BeginFrameObserverState();
+  ~BeginFrameObserverState() override;
+  BeginFrameObserverState(BeginFrameObserverState&&) noexcept;
+  BeginFrameObserverState& operator=(BeginFrameObserverState&&);
+  BeginFrameObserverState(const BeginFrameObserverState&);
+  BeginFrameObserverState& operator=(const BeginFrameObserverState&);
+  bool operator==(const BeginFrameObserverState&) const;
+  bool operator!=(const BeginFrameObserverState& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_dropped_begin_frame_args() const { return _has_field_[1]; }
+  int64_t dropped_begin_frame_args() const { return dropped_begin_frame_args_; }
+  void set_dropped_begin_frame_args(int64_t value) { dropped_begin_frame_args_ = value; _has_field_.set(1); }
+
+  bool has_last_begin_frame_args() const { return _has_field_[2]; }
+  const BeginFrameArgs& last_begin_frame_args() const { return *last_begin_frame_args_; }
+  BeginFrameArgs* mutable_last_begin_frame_args() { _has_field_.set(2); return last_begin_frame_args_.get(); }
+
+ private:
+  int64_t dropped_begin_frame_args_{};
+  ::protozero::CopyablePtr<BeginFrameArgs> last_begin_frame_args_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT BeginImplFrameArgs : public ::protozero::CppMessageObj {
+ public:
+  using TimestampsInUs = BeginImplFrameArgs_TimestampsInUs;
+  using State = BeginImplFrameArgs_State;
+  static constexpr auto BEGIN_FRAME_FINISHED = BeginImplFrameArgs_State_BEGIN_FRAME_FINISHED;
+  static constexpr auto BEGIN_FRAME_USING = BeginImplFrameArgs_State_BEGIN_FRAME_USING;
+  static constexpr auto State_MIN = BeginImplFrameArgs_State_BEGIN_FRAME_FINISHED;
+  static constexpr auto State_MAX = BeginImplFrameArgs_State_BEGIN_FRAME_USING;
+  enum FieldNumbers {
+    kUpdatedAtUsFieldNumber = 1,
+    kFinishedAtUsFieldNumber = 2,
+    kStateFieldNumber = 3,
+    kCurrentArgsFieldNumber = 4,
+    kLastArgsFieldNumber = 5,
+    kTimestampsInUsFieldNumber = 6,
+  };
+
+  BeginImplFrameArgs();
+  ~BeginImplFrameArgs() override;
+  BeginImplFrameArgs(BeginImplFrameArgs&&) noexcept;
+  BeginImplFrameArgs& operator=(BeginImplFrameArgs&&);
+  BeginImplFrameArgs(const BeginImplFrameArgs&);
+  BeginImplFrameArgs& operator=(const BeginImplFrameArgs&);
+  bool operator==(const BeginImplFrameArgs&) const;
+  bool operator!=(const BeginImplFrameArgs& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_updated_at_us() const { return _has_field_[1]; }
+  int64_t updated_at_us() const { return updated_at_us_; }
+  void set_updated_at_us(int64_t value) { updated_at_us_ = value; _has_field_.set(1); }
+
+  bool has_finished_at_us() const { return _has_field_[2]; }
+  int64_t finished_at_us() const { return finished_at_us_; }
+  void set_finished_at_us(int64_t value) { finished_at_us_ = value; _has_field_.set(2); }
+
+  bool has_state() const { return _has_field_[3]; }
+  BeginImplFrameArgs_State state() const { return state_; }
+  void set_state(BeginImplFrameArgs_State value) { state_ = value; _has_field_.set(3); }
+
+  bool has_current_args() const { return _has_field_[4]; }
+  const BeginFrameArgs& current_args() const { return *current_args_; }
+  BeginFrameArgs* mutable_current_args() { _has_field_.set(4); return current_args_.get(); }
+
+  bool has_last_args() const { return _has_field_[5]; }
+  const BeginFrameArgs& last_args() const { return *last_args_; }
+  BeginFrameArgs* mutable_last_args() { _has_field_.set(5); return last_args_.get(); }
+
+  bool has_timestamps_in_us() const { return _has_field_[6]; }
+  const BeginImplFrameArgs_TimestampsInUs& timestamps_in_us() const { return *timestamps_in_us_; }
+  BeginImplFrameArgs_TimestampsInUs* mutable_timestamps_in_us() { _has_field_.set(6); return timestamps_in_us_.get(); }
+
+ private:
+  int64_t updated_at_us_{};
+  int64_t finished_at_us_{};
+  BeginImplFrameArgs_State state_{};
+  ::protozero::CopyablePtr<BeginFrameArgs> current_args_;
+  ::protozero::CopyablePtr<BeginFrameArgs> last_args_;
+  ::protozero::CopyablePtr<BeginImplFrameArgs_TimestampsInUs> timestamps_in_us_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<7> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT BeginImplFrameArgs_TimestampsInUs : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kIntervalDeltaFieldNumber = 1,
+    kNowToDeadlineDeltaFieldNumber = 2,
+    kFrameTimeToNowDeltaFieldNumber = 3,
+    kFrameTimeToDeadlineDeltaFieldNumber = 4,
+    kNowFieldNumber = 5,
+    kFrameTimeFieldNumber = 6,
+    kDeadlineFieldNumber = 7,
+  };
+
+  BeginImplFrameArgs_TimestampsInUs();
+  ~BeginImplFrameArgs_TimestampsInUs() override;
+  BeginImplFrameArgs_TimestampsInUs(BeginImplFrameArgs_TimestampsInUs&&) noexcept;
+  BeginImplFrameArgs_TimestampsInUs& operator=(BeginImplFrameArgs_TimestampsInUs&&);
+  BeginImplFrameArgs_TimestampsInUs(const BeginImplFrameArgs_TimestampsInUs&);
+  BeginImplFrameArgs_TimestampsInUs& operator=(const BeginImplFrameArgs_TimestampsInUs&);
+  bool operator==(const BeginImplFrameArgs_TimestampsInUs&) const;
+  bool operator!=(const BeginImplFrameArgs_TimestampsInUs& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_interval_delta() const { return _has_field_[1]; }
+  int64_t interval_delta() const { return interval_delta_; }
+  void set_interval_delta(int64_t value) { interval_delta_ = value; _has_field_.set(1); }
+
+  bool has_now_to_deadline_delta() const { return _has_field_[2]; }
+  int64_t now_to_deadline_delta() const { return now_to_deadline_delta_; }
+  void set_now_to_deadline_delta(int64_t value) { now_to_deadline_delta_ = value; _has_field_.set(2); }
+
+  bool has_frame_time_to_now_delta() const { return _has_field_[3]; }
+  int64_t frame_time_to_now_delta() const { return frame_time_to_now_delta_; }
+  void set_frame_time_to_now_delta(int64_t value) { frame_time_to_now_delta_ = value; _has_field_.set(3); }
+
+  bool has_frame_time_to_deadline_delta() const { return _has_field_[4]; }
+  int64_t frame_time_to_deadline_delta() const { return frame_time_to_deadline_delta_; }
+  void set_frame_time_to_deadline_delta(int64_t value) { frame_time_to_deadline_delta_ = value; _has_field_.set(4); }
+
+  bool has_now() const { return _has_field_[5]; }
+  int64_t now() const { return now_; }
+  void set_now(int64_t value) { now_ = value; _has_field_.set(5); }
+
+  bool has_frame_time() const { return _has_field_[6]; }
+  int64_t frame_time() const { return frame_time_; }
+  void set_frame_time(int64_t value) { frame_time_ = value; _has_field_.set(6); }
+
+  bool has_deadline() const { return _has_field_[7]; }
+  int64_t deadline() const { return deadline_; }
+  void set_deadline(int64_t value) { deadline_ = value; _has_field_.set(7); }
+
+ private:
+  int64_t interval_delta_{};
+  int64_t now_to_deadline_delta_{};
+  int64_t frame_time_to_now_delta_{};
+  int64_t frame_time_to_deadline_delta_{};
+  int64_t now_{};
+  int64_t frame_time_{};
+  int64_t deadline_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<8> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT ChromeCompositorStateMachine : public ::protozero::CppMessageObj {
+ public:
+  using MajorState = ChromeCompositorStateMachine_MajorState;
+  using MinorState = ChromeCompositorStateMachine_MinorState;
+  enum FieldNumbers {
+    kMajorStateFieldNumber = 1,
+    kMinorStateFieldNumber = 2,
+  };
+
+  ChromeCompositorStateMachine();
+  ~ChromeCompositorStateMachine() override;
+  ChromeCompositorStateMachine(ChromeCompositorStateMachine&&) noexcept;
+  ChromeCompositorStateMachine& operator=(ChromeCompositorStateMachine&&);
+  ChromeCompositorStateMachine(const ChromeCompositorStateMachine&);
+  ChromeCompositorStateMachine& operator=(const ChromeCompositorStateMachine&);
+  bool operator==(const ChromeCompositorStateMachine&) const;
+  bool operator!=(const ChromeCompositorStateMachine& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_major_state() const { return _has_field_[1]; }
+  const ChromeCompositorStateMachine_MajorState& major_state() const { return *major_state_; }
+  ChromeCompositorStateMachine_MajorState* mutable_major_state() { _has_field_.set(1); return major_state_.get(); }
+
+  bool has_minor_state() const { return _has_field_[2]; }
+  const ChromeCompositorStateMachine_MinorState& minor_state() const { return *minor_state_; }
+  ChromeCompositorStateMachine_MinorState* mutable_minor_state() { _has_field_.set(2); return minor_state_.get(); }
+
+ private:
+  ::protozero::CopyablePtr<ChromeCompositorStateMachine_MajorState> major_state_;
+  ::protozero::CopyablePtr<ChromeCompositorStateMachine_MinorState> minor_state_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT ChromeCompositorStateMachine_MinorState : public ::protozero::CppMessageObj {
+ public:
+  using TreePriority = ChromeCompositorStateMachine_MinorState_TreePriority;
+  static constexpr auto TREE_PRIORITY_UNSPECIFIED = ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_UNSPECIFIED;
+  static constexpr auto TREE_PRIORITY_SAME_PRIORITY_FOR_BOTH_TREES = ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_SAME_PRIORITY_FOR_BOTH_TREES;
+  static constexpr auto TREE_PRIORITY_SMOOTHNESS_TAKES_PRIORITY = ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_SMOOTHNESS_TAKES_PRIORITY;
+  static constexpr auto TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY = ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY;
+  static constexpr auto TreePriority_MIN = ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_UNSPECIFIED;
+  static constexpr auto TreePriority_MAX = ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY;
+  using ScrollHandlerState = ChromeCompositorStateMachine_MinorState_ScrollHandlerState;
+  static constexpr auto SCROLL_HANDLER_UNSPECIFIED = ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_HANDLER_UNSPECIFIED;
+  static constexpr auto SCROLL_AFFECTS_SCROLL_HANDLER = ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_AFFECTS_SCROLL_HANDLER;
+  static constexpr auto SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER = ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER;
+  static constexpr auto ScrollHandlerState_MIN = ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_HANDLER_UNSPECIFIED;
+  static constexpr auto ScrollHandlerState_MAX = ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER;
+  enum FieldNumbers {
+    kCommitCountFieldNumber = 1,
+    kCurrentFrameNumberFieldNumber = 2,
+    kLastFrameNumberSubmitPerformedFieldNumber = 3,
+    kLastFrameNumberDrawPerformedFieldNumber = 4,
+    kLastFrameNumberBeginMainFrameSentFieldNumber = 5,
+    kDidDrawFieldNumber = 6,
+    kDidSendBeginMainFrameForCurrentFrameFieldNumber = 7,
+    kDidNotifyBeginMainFrameNotExpectedUntilFieldNumber = 8,
+    kDidNotifyBeginMainFrameNotExpectedSoonFieldNumber = 9,
+    kWantsBeginMainFrameNotExpectedFieldNumber = 10,
+    kDidCommitDuringFrameFieldNumber = 11,
+    kDidInvalidateLayerTreeFrameSinkFieldNumber = 12,
+    kDidPerformImplSideInvalidaionFieldNumber = 13,
+    kDidPrepareTilesFieldNumber = 14,
+    kConsecutiveCheckerboardAnimationsFieldNumber = 15,
+    kPendingSubmitFramesFieldNumber = 16,
+    kSubmitFramesWithCurrentLayerTreeFrameSinkFieldNumber = 17,
+    kNeedsRedrawFieldNumber = 18,
+    kNeedsPrepareTilesFieldNumber = 19,
+    kNeedsBeginMainFrameFieldNumber = 20,
+    kNeedsOneBeginImplFrameFieldNumber = 21,
+    kVisibleFieldNumber = 22,
+    kBeginFrameSourcePausedFieldNumber = 23,
+    kCanDrawFieldNumber = 24,
+    kResourcelessDrawFieldNumber = 25,
+    kHasPendingTreeFieldNumber = 26,
+    kPendingTreeIsReadyForActivationFieldNumber = 27,
+    kActiveTreeNeedsFirstDrawFieldNumber = 28,
+    kActiveTreeIsReadyToDrawFieldNumber = 29,
+    kDidCreateAndInitializeFirstLayerTreeFrameSinkFieldNumber = 30,
+    kTreePriorityFieldNumber = 31,
+    kScrollHandlerStateFieldNumber = 32,
+    kCriticalBeginMainFrameToActivateIsFastFieldNumber = 33,
+    kMainThreadMissedLastDeadlineFieldNumber = 34,
+    kVideoNeedsBeginFramesFieldNumber = 36,
+    kDeferBeginMainFrameFieldNumber = 37,
+    kLastCommitHadNoUpdatesFieldNumber = 38,
+    kDidDrawInLastFrameFieldNumber = 39,
+    kDidSubmitInLastFrameFieldNumber = 40,
+    kNeedsImplSideInvalidationFieldNumber = 41,
+    kCurrentPendingTreeIsImplSideFieldNumber = 42,
+    kPreviousPendingTreeWasImplSideFieldNumber = 43,
+    kProcessingAnimationWorkletsForActiveTreeFieldNumber = 44,
+    kProcessingAnimationWorkletsForPendingTreeFieldNumber = 45,
+    kProcessingPaintWorkletsForPendingTreeFieldNumber = 46,
+  };
+
+  ChromeCompositorStateMachine_MinorState();
+  ~ChromeCompositorStateMachine_MinorState() override;
+  ChromeCompositorStateMachine_MinorState(ChromeCompositorStateMachine_MinorState&&) noexcept;
+  ChromeCompositorStateMachine_MinorState& operator=(ChromeCompositorStateMachine_MinorState&&);
+  ChromeCompositorStateMachine_MinorState(const ChromeCompositorStateMachine_MinorState&);
+  ChromeCompositorStateMachine_MinorState& operator=(const ChromeCompositorStateMachine_MinorState&);
+  bool operator==(const ChromeCompositorStateMachine_MinorState&) const;
+  bool operator!=(const ChromeCompositorStateMachine_MinorState& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_commit_count() const { return _has_field_[1]; }
+  int32_t commit_count() const { return commit_count_; }
+  void set_commit_count(int32_t value) { commit_count_ = value; _has_field_.set(1); }
+
+  bool has_current_frame_number() const { return _has_field_[2]; }
+  int32_t current_frame_number() const { return current_frame_number_; }
+  void set_current_frame_number(int32_t value) { current_frame_number_ = value; _has_field_.set(2); }
+
+  bool has_last_frame_number_submit_performed() const { return _has_field_[3]; }
+  int32_t last_frame_number_submit_performed() const { return last_frame_number_submit_performed_; }
+  void set_last_frame_number_submit_performed(int32_t value) { last_frame_number_submit_performed_ = value; _has_field_.set(3); }
+
+  bool has_last_frame_number_draw_performed() const { return _has_field_[4]; }
+  int32_t last_frame_number_draw_performed() const { return last_frame_number_draw_performed_; }
+  void set_last_frame_number_draw_performed(int32_t value) { last_frame_number_draw_performed_ = value; _has_field_.set(4); }
+
+  bool has_last_frame_number_begin_main_frame_sent() const { return _has_field_[5]; }
+  int32_t last_frame_number_begin_main_frame_sent() const { return last_frame_number_begin_main_frame_sent_; }
+  void set_last_frame_number_begin_main_frame_sent(int32_t value) { last_frame_number_begin_main_frame_sent_ = value; _has_field_.set(5); }
+
+  bool has_did_draw() const { return _has_field_[6]; }
+  bool did_draw() const { return did_draw_; }
+  void set_did_draw(bool value) { did_draw_ = value; _has_field_.set(6); }
+
+  bool has_did_send_begin_main_frame_for_current_frame() const { return _has_field_[7]; }
+  bool did_send_begin_main_frame_for_current_frame() const { return did_send_begin_main_frame_for_current_frame_; }
+  void set_did_send_begin_main_frame_for_current_frame(bool value) { did_send_begin_main_frame_for_current_frame_ = value; _has_field_.set(7); }
+
+  bool has_did_notify_begin_main_frame_not_expected_until() const { return _has_field_[8]; }
+  bool did_notify_begin_main_frame_not_expected_until() const { return did_notify_begin_main_frame_not_expected_until_; }
+  void set_did_notify_begin_main_frame_not_expected_until(bool value) { did_notify_begin_main_frame_not_expected_until_ = value; _has_field_.set(8); }
+
+  bool has_did_notify_begin_main_frame_not_expected_soon() const { return _has_field_[9]; }
+  bool did_notify_begin_main_frame_not_expected_soon() const { return did_notify_begin_main_frame_not_expected_soon_; }
+  void set_did_notify_begin_main_frame_not_expected_soon(bool value) { did_notify_begin_main_frame_not_expected_soon_ = value; _has_field_.set(9); }
+
+  bool has_wants_begin_main_frame_not_expected() const { return _has_field_[10]; }
+  bool wants_begin_main_frame_not_expected() const { return wants_begin_main_frame_not_expected_; }
+  void set_wants_begin_main_frame_not_expected(bool value) { wants_begin_main_frame_not_expected_ = value; _has_field_.set(10); }
+
+  bool has_did_commit_during_frame() const { return _has_field_[11]; }
+  bool did_commit_during_frame() const { return did_commit_during_frame_; }
+  void set_did_commit_during_frame(bool value) { did_commit_during_frame_ = value; _has_field_.set(11); }
+
+  bool has_did_invalidate_layer_tree_frame_sink() const { return _has_field_[12]; }
+  bool did_invalidate_layer_tree_frame_sink() const { return did_invalidate_layer_tree_frame_sink_; }
+  void set_did_invalidate_layer_tree_frame_sink(bool value) { did_invalidate_layer_tree_frame_sink_ = value; _has_field_.set(12); }
+
+  bool has_did_perform_impl_side_invalidaion() const { return _has_field_[13]; }
+  bool did_perform_impl_side_invalidaion() const { return did_perform_impl_side_invalidaion_; }
+  void set_did_perform_impl_side_invalidaion(bool value) { did_perform_impl_side_invalidaion_ = value; _has_field_.set(13); }
+
+  bool has_did_prepare_tiles() const { return _has_field_[14]; }
+  bool did_prepare_tiles() const { return did_prepare_tiles_; }
+  void set_did_prepare_tiles(bool value) { did_prepare_tiles_ = value; _has_field_.set(14); }
+
+  bool has_consecutive_checkerboard_animations() const { return _has_field_[15]; }
+  int32_t consecutive_checkerboard_animations() const { return consecutive_checkerboard_animations_; }
+  void set_consecutive_checkerboard_animations(int32_t value) { consecutive_checkerboard_animations_ = value; _has_field_.set(15); }
+
+  bool has_pending_submit_frames() const { return _has_field_[16]; }
+  int32_t pending_submit_frames() const { return pending_submit_frames_; }
+  void set_pending_submit_frames(int32_t value) { pending_submit_frames_ = value; _has_field_.set(16); }
+
+  bool has_submit_frames_with_current_layer_tree_frame_sink() const { return _has_field_[17]; }
+  int32_t submit_frames_with_current_layer_tree_frame_sink() const { return submit_frames_with_current_layer_tree_frame_sink_; }
+  void set_submit_frames_with_current_layer_tree_frame_sink(int32_t value) { submit_frames_with_current_layer_tree_frame_sink_ = value; _has_field_.set(17); }
+
+  bool has_needs_redraw() const { return _has_field_[18]; }
+  bool needs_redraw() const { return needs_redraw_; }
+  void set_needs_redraw(bool value) { needs_redraw_ = value; _has_field_.set(18); }
+
+  bool has_needs_prepare_tiles() const { return _has_field_[19]; }
+  bool needs_prepare_tiles() const { return needs_prepare_tiles_; }
+  void set_needs_prepare_tiles(bool value) { needs_prepare_tiles_ = value; _has_field_.set(19); }
+
+  bool has_needs_begin_main_frame() const { return _has_field_[20]; }
+  bool needs_begin_main_frame() const { return needs_begin_main_frame_; }
+  void set_needs_begin_main_frame(bool value) { needs_begin_main_frame_ = value; _has_field_.set(20); }
+
+  bool has_needs_one_begin_impl_frame() const { return _has_field_[21]; }
+  bool needs_one_begin_impl_frame() const { return needs_one_begin_impl_frame_; }
+  void set_needs_one_begin_impl_frame(bool value) { needs_one_begin_impl_frame_ = value; _has_field_.set(21); }
+
+  bool has_visible() const { return _has_field_[22]; }
+  bool visible() const { return visible_; }
+  void set_visible(bool value) { visible_ = value; _has_field_.set(22); }
+
+  bool has_begin_frame_source_paused() const { return _has_field_[23]; }
+  bool begin_frame_source_paused() const { return begin_frame_source_paused_; }
+  void set_begin_frame_source_paused(bool value) { begin_frame_source_paused_ = value; _has_field_.set(23); }
+
+  bool has_can_draw() const { return _has_field_[24]; }
+  bool can_draw() const { return can_draw_; }
+  void set_can_draw(bool value) { can_draw_ = value; _has_field_.set(24); }
+
+  bool has_resourceless_draw() const { return _has_field_[25]; }
+  bool resourceless_draw() const { return resourceless_draw_; }
+  void set_resourceless_draw(bool value) { resourceless_draw_ = value; _has_field_.set(25); }
+
+  bool has_has_pending_tree() const { return _has_field_[26]; }
+  bool has_pending_tree() const { return has_pending_tree_; }
+  void set_has_pending_tree(bool value) { has_pending_tree_ = value; _has_field_.set(26); }
+
+  bool has_pending_tree_is_ready_for_activation() const { return _has_field_[27]; }
+  bool pending_tree_is_ready_for_activation() const { return pending_tree_is_ready_for_activation_; }
+  void set_pending_tree_is_ready_for_activation(bool value) { pending_tree_is_ready_for_activation_ = value; _has_field_.set(27); }
+
+  bool has_active_tree_needs_first_draw() const { return _has_field_[28]; }
+  bool active_tree_needs_first_draw() const { return active_tree_needs_first_draw_; }
+  void set_active_tree_needs_first_draw(bool value) { active_tree_needs_first_draw_ = value; _has_field_.set(28); }
+
+  bool has_active_tree_is_ready_to_draw() const { return _has_field_[29]; }
+  bool active_tree_is_ready_to_draw() const { return active_tree_is_ready_to_draw_; }
+  void set_active_tree_is_ready_to_draw(bool value) { active_tree_is_ready_to_draw_ = value; _has_field_.set(29); }
+
+  bool has_did_create_and_initialize_first_layer_tree_frame_sink() const { return _has_field_[30]; }
+  bool did_create_and_initialize_first_layer_tree_frame_sink() const { return did_create_and_initialize_first_layer_tree_frame_sink_; }
+  void set_did_create_and_initialize_first_layer_tree_frame_sink(bool value) { did_create_and_initialize_first_layer_tree_frame_sink_ = value; _has_field_.set(30); }
+
+  bool has_tree_priority() const { return _has_field_[31]; }
+  ChromeCompositorStateMachine_MinorState_TreePriority tree_priority() const { return tree_priority_; }
+  void set_tree_priority(ChromeCompositorStateMachine_MinorState_TreePriority value) { tree_priority_ = value; _has_field_.set(31); }
+
+  bool has_scroll_handler_state() const { return _has_field_[32]; }
+  ChromeCompositorStateMachine_MinorState_ScrollHandlerState scroll_handler_state() const { return scroll_handler_state_; }
+  void set_scroll_handler_state(ChromeCompositorStateMachine_MinorState_ScrollHandlerState value) { scroll_handler_state_ = value; _has_field_.set(32); }
+
+  bool has_critical_begin_main_frame_to_activate_is_fast() const { return _has_field_[33]; }
+  bool critical_begin_main_frame_to_activate_is_fast() const { return critical_begin_main_frame_to_activate_is_fast_; }
+  void set_critical_begin_main_frame_to_activate_is_fast(bool value) { critical_begin_main_frame_to_activate_is_fast_ = value; _has_field_.set(33); }
+
+  bool has_main_thread_missed_last_deadline() const { return _has_field_[34]; }
+  bool main_thread_missed_last_deadline() const { return main_thread_missed_last_deadline_; }
+  void set_main_thread_missed_last_deadline(bool value) { main_thread_missed_last_deadline_ = value; _has_field_.set(34); }
+
+  bool has_video_needs_begin_frames() const { return _has_field_[36]; }
+  bool video_needs_begin_frames() const { return video_needs_begin_frames_; }
+  void set_video_needs_begin_frames(bool value) { video_needs_begin_frames_ = value; _has_field_.set(36); }
+
+  bool has_defer_begin_main_frame() const { return _has_field_[37]; }
+  bool defer_begin_main_frame() const { return defer_begin_main_frame_; }
+  void set_defer_begin_main_frame(bool value) { defer_begin_main_frame_ = value; _has_field_.set(37); }
+
+  bool has_last_commit_had_no_updates() const { return _has_field_[38]; }
+  bool last_commit_had_no_updates() const { return last_commit_had_no_updates_; }
+  void set_last_commit_had_no_updates(bool value) { last_commit_had_no_updates_ = value; _has_field_.set(38); }
+
+  bool has_did_draw_in_last_frame() const { return _has_field_[39]; }
+  bool did_draw_in_last_frame() const { return did_draw_in_last_frame_; }
+  void set_did_draw_in_last_frame(bool value) { did_draw_in_last_frame_ = value; _has_field_.set(39); }
+
+  bool has_did_submit_in_last_frame() const { return _has_field_[40]; }
+  bool did_submit_in_last_frame() const { return did_submit_in_last_frame_; }
+  void set_did_submit_in_last_frame(bool value) { did_submit_in_last_frame_ = value; _has_field_.set(40); }
+
+  bool has_needs_impl_side_invalidation() const { return _has_field_[41]; }
+  bool needs_impl_side_invalidation() const { return needs_impl_side_invalidation_; }
+  void set_needs_impl_side_invalidation(bool value) { needs_impl_side_invalidation_ = value; _has_field_.set(41); }
+
+  bool has_current_pending_tree_is_impl_side() const { return _has_field_[42]; }
+  bool current_pending_tree_is_impl_side() const { return current_pending_tree_is_impl_side_; }
+  void set_current_pending_tree_is_impl_side(bool value) { current_pending_tree_is_impl_side_ = value; _has_field_.set(42); }
+
+  bool has_previous_pending_tree_was_impl_side() const { return _has_field_[43]; }
+  bool previous_pending_tree_was_impl_side() const { return previous_pending_tree_was_impl_side_; }
+  void set_previous_pending_tree_was_impl_side(bool value) { previous_pending_tree_was_impl_side_ = value; _has_field_.set(43); }
+
+  bool has_processing_animation_worklets_for_active_tree() const { return _has_field_[44]; }
+  bool processing_animation_worklets_for_active_tree() const { return processing_animation_worklets_for_active_tree_; }
+  void set_processing_animation_worklets_for_active_tree(bool value) { processing_animation_worklets_for_active_tree_ = value; _has_field_.set(44); }
+
+  bool has_processing_animation_worklets_for_pending_tree() const { return _has_field_[45]; }
+  bool processing_animation_worklets_for_pending_tree() const { return processing_animation_worklets_for_pending_tree_; }
+  void set_processing_animation_worklets_for_pending_tree(bool value) { processing_animation_worklets_for_pending_tree_ = value; _has_field_.set(45); }
+
+  bool has_processing_paint_worklets_for_pending_tree() const { return _has_field_[46]; }
+  bool processing_paint_worklets_for_pending_tree() const { return processing_paint_worklets_for_pending_tree_; }
+  void set_processing_paint_worklets_for_pending_tree(bool value) { processing_paint_worklets_for_pending_tree_ = value; _has_field_.set(46); }
+
+ private:
+  int32_t commit_count_{};
+  int32_t current_frame_number_{};
+  int32_t last_frame_number_submit_performed_{};
+  int32_t last_frame_number_draw_performed_{};
+  int32_t last_frame_number_begin_main_frame_sent_{};
+  bool did_draw_{};
+  bool did_send_begin_main_frame_for_current_frame_{};
+  bool did_notify_begin_main_frame_not_expected_until_{};
+  bool did_notify_begin_main_frame_not_expected_soon_{};
+  bool wants_begin_main_frame_not_expected_{};
+  bool did_commit_during_frame_{};
+  bool did_invalidate_layer_tree_frame_sink_{};
+  bool did_perform_impl_side_invalidaion_{};
+  bool did_prepare_tiles_{};
+  int32_t consecutive_checkerboard_animations_{};
+  int32_t pending_submit_frames_{};
+  int32_t submit_frames_with_current_layer_tree_frame_sink_{};
+  bool needs_redraw_{};
+  bool needs_prepare_tiles_{};
+  bool needs_begin_main_frame_{};
+  bool needs_one_begin_impl_frame_{};
+  bool visible_{};
+  bool begin_frame_source_paused_{};
+  bool can_draw_{};
+  bool resourceless_draw_{};
+  bool has_pending_tree_{};
+  bool pending_tree_is_ready_for_activation_{};
+  bool active_tree_needs_first_draw_{};
+  bool active_tree_is_ready_to_draw_{};
+  bool did_create_and_initialize_first_layer_tree_frame_sink_{};
+  ChromeCompositorStateMachine_MinorState_TreePriority tree_priority_{};
+  ChromeCompositorStateMachine_MinorState_ScrollHandlerState scroll_handler_state_{};
+  bool critical_begin_main_frame_to_activate_is_fast_{};
+  bool main_thread_missed_last_deadline_{};
+  bool video_needs_begin_frames_{};
+  bool defer_begin_main_frame_{};
+  bool last_commit_had_no_updates_{};
+  bool did_draw_in_last_frame_{};
+  bool did_submit_in_last_frame_{};
+  bool needs_impl_side_invalidation_{};
+  bool current_pending_tree_is_impl_side_{};
+  bool previous_pending_tree_was_impl_side_{};
+  bool processing_animation_worklets_for_active_tree_{};
+  bool processing_animation_worklets_for_pending_tree_{};
+  bool processing_paint_worklets_for_pending_tree_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<47> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT ChromeCompositorStateMachine_MajorState : public ::protozero::CppMessageObj {
+ public:
+  using BeginImplFrameState = ChromeCompositorStateMachine_MajorState_BeginImplFrameState;
+  static constexpr auto BEGIN_IMPL_FRAME_UNSPECIFIED = ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_UNSPECIFIED;
+  static constexpr auto BEGIN_IMPL_FRAME_IDLE = ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_IDLE;
+  static constexpr auto BEGIN_IMPL_FRAME_INSIDE_BEGIN_FRAME = ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_INSIDE_BEGIN_FRAME;
+  static constexpr auto BEGIN_IMPL_FRAME_INSIDE_DEADLINE = ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_INSIDE_DEADLINE;
+  static constexpr auto BeginImplFrameState_MIN = ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_UNSPECIFIED;
+  static constexpr auto BeginImplFrameState_MAX = ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_INSIDE_DEADLINE;
+  using BeginMainFrameState = ChromeCompositorStateMachine_MajorState_BeginMainFrameState;
+  static constexpr auto BEGIN_MAIN_FRAME_UNSPECIFIED = ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_UNSPECIFIED;
+  static constexpr auto BEGIN_MAIN_FRAME_IDLE = ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_IDLE;
+  static constexpr auto BEGIN_MAIN_FRAME_SENT = ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_SENT;
+  static constexpr auto BEGIN_MAIN_FRAME_READY_TO_COMMIT = ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_READY_TO_COMMIT;
+  static constexpr auto BeginMainFrameState_MIN = ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_UNSPECIFIED;
+  static constexpr auto BeginMainFrameState_MAX = ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_READY_TO_COMMIT;
+  using LayerTreeFrameSinkState = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState;
+  static constexpr auto LAYER_TREE_FRAME_UNSPECIFIED = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_UNSPECIFIED;
+  static constexpr auto LAYER_TREE_FRAME_NONE = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_NONE;
+  static constexpr auto LAYER_TREE_FRAME_ACTIVE = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_ACTIVE;
+  static constexpr auto LAYER_TREE_FRAME_CREATING = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_CREATING;
+  static constexpr auto LAYER_TREE_FRAME_WAITING_FOR_FIRST_COMMIT = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_WAITING_FOR_FIRST_COMMIT;
+  static constexpr auto LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION;
+  static constexpr auto LayerTreeFrameSinkState_MIN = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_UNSPECIFIED;
+  static constexpr auto LayerTreeFrameSinkState_MAX = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION;
+  using ForcedRedrawOnTimeoutState = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState;
+  static constexpr auto FORCED_REDRAW_UNSPECIFIED = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_UNSPECIFIED;
+  static constexpr auto FORCED_REDRAW_IDLE = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_IDLE;
+  static constexpr auto FORCED_REDRAW_WAITING_FOR_COMMIT = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_COMMIT;
+  static constexpr auto FORCED_REDRAW_WAITING_FOR_ACTIVATION = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_ACTIVATION;
+  static constexpr auto FORCED_REDRAW_WAITING_FOR_DRAW = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_DRAW;
+  static constexpr auto ForcedRedrawOnTimeoutState_MIN = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_UNSPECIFIED;
+  static constexpr auto ForcedRedrawOnTimeoutState_MAX = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_DRAW;
+  enum FieldNumbers {
+    kNextActionFieldNumber = 1,
+    kBeginImplFrameStateFieldNumber = 2,
+    kBeginMainFrameStateFieldNumber = 3,
+    kLayerTreeFrameSinkStateFieldNumber = 4,
+    kForcedRedrawStateFieldNumber = 5,
+  };
+
+  ChromeCompositorStateMachine_MajorState();
+  ~ChromeCompositorStateMachine_MajorState() override;
+  ChromeCompositorStateMachine_MajorState(ChromeCompositorStateMachine_MajorState&&) noexcept;
+  ChromeCompositorStateMachine_MajorState& operator=(ChromeCompositorStateMachine_MajorState&&);
+  ChromeCompositorStateMachine_MajorState(const ChromeCompositorStateMachine_MajorState&);
+  ChromeCompositorStateMachine_MajorState& operator=(const ChromeCompositorStateMachine_MajorState&);
+  bool operator==(const ChromeCompositorStateMachine_MajorState&) const;
+  bool operator!=(const ChromeCompositorStateMachine_MajorState& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_next_action() const { return _has_field_[1]; }
+  ChromeCompositorSchedulerAction next_action() const { return next_action_; }
+  void set_next_action(ChromeCompositorSchedulerAction value) { next_action_ = value; _has_field_.set(1); }
+
+  bool has_begin_impl_frame_state() const { return _has_field_[2]; }
+  ChromeCompositorStateMachine_MajorState_BeginImplFrameState begin_impl_frame_state() const { return begin_impl_frame_state_; }
+  void set_begin_impl_frame_state(ChromeCompositorStateMachine_MajorState_BeginImplFrameState value) { begin_impl_frame_state_ = value; _has_field_.set(2); }
+
+  bool has_begin_main_frame_state() const { return _has_field_[3]; }
+  ChromeCompositorStateMachine_MajorState_BeginMainFrameState begin_main_frame_state() const { return begin_main_frame_state_; }
+  void set_begin_main_frame_state(ChromeCompositorStateMachine_MajorState_BeginMainFrameState value) { begin_main_frame_state_ = value; _has_field_.set(3); }
+
+  bool has_layer_tree_frame_sink_state() const { return _has_field_[4]; }
+  ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState layer_tree_frame_sink_state() const { return layer_tree_frame_sink_state_; }
+  void set_layer_tree_frame_sink_state(ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState value) { layer_tree_frame_sink_state_ = value; _has_field_.set(4); }
+
+  bool has_forced_redraw_state() const { return _has_field_[5]; }
+  ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState forced_redraw_state() const { return forced_redraw_state_; }
+  void set_forced_redraw_state(ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState value) { forced_redraw_state_ = value; _has_field_.set(5); }
+
+ private:
+  ChromeCompositorSchedulerAction next_action_{};
+  ChromeCompositorStateMachine_MajorState_BeginImplFrameState begin_impl_frame_state_{};
+  ChromeCompositorStateMachine_MajorState_BeginMainFrameState begin_main_frame_state_{};
+  ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState layer_tree_frame_sink_state_{};
+  ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState forced_redraw_state_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<6> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT ChromeCompositorSchedulerState : public ::protozero::CppMessageObj {
+ public:
+  using BeginImplFrameDeadlineMode = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode;
+  static constexpr auto DEADLINE_MODE_UNSPECIFIED = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_UNSPECIFIED;
+  static constexpr auto DEADLINE_MODE_NONE = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_NONE;
+  static constexpr auto DEADLINE_MODE_IMMEDIATE = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_IMMEDIATE;
+  static constexpr auto DEADLINE_MODE_REGULAR = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_REGULAR;
+  static constexpr auto DEADLINE_MODE_LATE = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_LATE;
+  static constexpr auto DEADLINE_MODE_BLOCKED = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_BLOCKED;
+  static constexpr auto BeginImplFrameDeadlineMode_MIN = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_UNSPECIFIED;
+  static constexpr auto BeginImplFrameDeadlineMode_MAX = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_BLOCKED;
+  enum FieldNumbers {
+    kStateMachineFieldNumber = 1,
+    kObservingBeginFrameSourceFieldNumber = 2,
+    kBeginImplFrameDeadlineTaskFieldNumber = 3,
+    kPendingBeginFrameTaskFieldNumber = 4,
+    kSkippedLastFrameMissedExceededDeadlineFieldNumber = 5,
+    kInsideActionFieldNumber = 7,
+    kDeadlineModeFieldNumber = 8,
+    kDeadlineUsFieldNumber = 9,
+    kDeadlineScheduledAtUsFieldNumber = 10,
+    kNowUsFieldNumber = 11,
+    kNowToDeadlineDeltaUsFieldNumber = 12,
+    kNowToDeadlineScheduledAtDeltaUsFieldNumber = 13,
+    kBeginImplFrameArgsFieldNumber = 14,
+    kBeginFrameObserverStateFieldNumber = 15,
+    kBeginFrameSourceStateFieldNumber = 16,
+    kCompositorTimingHistoryFieldNumber = 17,
+  };
+
+  ChromeCompositorSchedulerState();
+  ~ChromeCompositorSchedulerState() override;
+  ChromeCompositorSchedulerState(ChromeCompositorSchedulerState&&) noexcept;
+  ChromeCompositorSchedulerState& operator=(ChromeCompositorSchedulerState&&);
+  ChromeCompositorSchedulerState(const ChromeCompositorSchedulerState&);
+  ChromeCompositorSchedulerState& operator=(const ChromeCompositorSchedulerState&);
+  bool operator==(const ChromeCompositorSchedulerState&) const;
+  bool operator!=(const ChromeCompositorSchedulerState& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_state_machine() const { return _has_field_[1]; }
+  const ChromeCompositorStateMachine& state_machine() const { return *state_machine_; }
+  ChromeCompositorStateMachine* mutable_state_machine() { _has_field_.set(1); return state_machine_.get(); }
+
+  bool has_observing_begin_frame_source() const { return _has_field_[2]; }
+  bool observing_begin_frame_source() const { return observing_begin_frame_source_; }
+  void set_observing_begin_frame_source(bool value) { observing_begin_frame_source_ = value; _has_field_.set(2); }
+
+  bool has_begin_impl_frame_deadline_task() const { return _has_field_[3]; }
+  bool begin_impl_frame_deadline_task() const { return begin_impl_frame_deadline_task_; }
+  void set_begin_impl_frame_deadline_task(bool value) { begin_impl_frame_deadline_task_ = value; _has_field_.set(3); }
+
+  bool has_pending_begin_frame_task() const { return _has_field_[4]; }
+  bool pending_begin_frame_task() const { return pending_begin_frame_task_; }
+  void set_pending_begin_frame_task(bool value) { pending_begin_frame_task_ = value; _has_field_.set(4); }
+
+  bool has_skipped_last_frame_missed_exceeded_deadline() const { return _has_field_[5]; }
+  bool skipped_last_frame_missed_exceeded_deadline() const { return skipped_last_frame_missed_exceeded_deadline_; }
+  void set_skipped_last_frame_missed_exceeded_deadline(bool value) { skipped_last_frame_missed_exceeded_deadline_ = value; _has_field_.set(5); }
+
+  bool has_inside_action() const { return _has_field_[7]; }
+  ChromeCompositorSchedulerAction inside_action() const { return inside_action_; }
+  void set_inside_action(ChromeCompositorSchedulerAction value) { inside_action_ = value; _has_field_.set(7); }
+
+  bool has_deadline_mode() const { return _has_field_[8]; }
+  ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode deadline_mode() const { return deadline_mode_; }
+  void set_deadline_mode(ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode value) { deadline_mode_ = value; _has_field_.set(8); }
+
+  bool has_deadline_us() const { return _has_field_[9]; }
+  int64_t deadline_us() const { return deadline_us_; }
+  void set_deadline_us(int64_t value) { deadline_us_ = value; _has_field_.set(9); }
+
+  bool has_deadline_scheduled_at_us() const { return _has_field_[10]; }
+  int64_t deadline_scheduled_at_us() const { return deadline_scheduled_at_us_; }
+  void set_deadline_scheduled_at_us(int64_t value) { deadline_scheduled_at_us_ = value; _has_field_.set(10); }
+
+  bool has_now_us() const { return _has_field_[11]; }
+  int64_t now_us() const { return now_us_; }
+  void set_now_us(int64_t value) { now_us_ = value; _has_field_.set(11); }
+
+  bool has_now_to_deadline_delta_us() const { return _has_field_[12]; }
+  int64_t now_to_deadline_delta_us() const { return now_to_deadline_delta_us_; }
+  void set_now_to_deadline_delta_us(int64_t value) { now_to_deadline_delta_us_ = value; _has_field_.set(12); }
+
+  bool has_now_to_deadline_scheduled_at_delta_us() const { return _has_field_[13]; }
+  int64_t now_to_deadline_scheduled_at_delta_us() const { return now_to_deadline_scheduled_at_delta_us_; }
+  void set_now_to_deadline_scheduled_at_delta_us(int64_t value) { now_to_deadline_scheduled_at_delta_us_ = value; _has_field_.set(13); }
+
+  bool has_begin_impl_frame_args() const { return _has_field_[14]; }
+  const BeginImplFrameArgs& begin_impl_frame_args() const { return *begin_impl_frame_args_; }
+  BeginImplFrameArgs* mutable_begin_impl_frame_args() { _has_field_.set(14); return begin_impl_frame_args_.get(); }
+
+  bool has_begin_frame_observer_state() const { return _has_field_[15]; }
+  const BeginFrameObserverState& begin_frame_observer_state() const { return *begin_frame_observer_state_; }
+  BeginFrameObserverState* mutable_begin_frame_observer_state() { _has_field_.set(15); return begin_frame_observer_state_.get(); }
+
+  bool has_begin_frame_source_state() const { return _has_field_[16]; }
+  const BeginFrameSourceState& begin_frame_source_state() const { return *begin_frame_source_state_; }
+  BeginFrameSourceState* mutable_begin_frame_source_state() { _has_field_.set(16); return begin_frame_source_state_.get(); }
+
+  bool has_compositor_timing_history() const { return _has_field_[17]; }
+  const CompositorTimingHistory& compositor_timing_history() const { return *compositor_timing_history_; }
+  CompositorTimingHistory* mutable_compositor_timing_history() { _has_field_.set(17); return compositor_timing_history_.get(); }
+
+ private:
+  ::protozero::CopyablePtr<ChromeCompositorStateMachine> state_machine_;
+  bool observing_begin_frame_source_{};
+  bool begin_impl_frame_deadline_task_{};
+  bool pending_begin_frame_task_{};
+  bool skipped_last_frame_missed_exceeded_deadline_{};
+  ChromeCompositorSchedulerAction inside_action_{};
+  ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode deadline_mode_{};
+  int64_t deadline_us_{};
+  int64_t deadline_scheduled_at_us_{};
+  int64_t now_us_{};
+  int64_t now_to_deadline_delta_us_{};
+  int64_t now_to_deadline_scheduled_at_delta_us_{};
+  ::protozero::CopyablePtr<BeginImplFrameArgs> begin_impl_frame_args_;
+  ::protozero::CopyablePtr<BeginFrameObserverState> begin_frame_observer_state_;
+  ::protozero::CopyablePtr<BeginFrameSourceState> begin_frame_source_state_;
+  ::protozero::CopyablePtr<CompositorTimingHistory> compositor_timing_history_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<18> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_COMPOSITOR_SCHEDULER_STATE_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_content_settings_event_info.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_CONTENT_SETTINGS_EVENT_INFO_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_CONTENT_SETTINGS_EVENT_INFO_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ChromeContentSettingsEventInfo;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT ChromeContentSettingsEventInfo : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kNumberOfExceptionsFieldNumber = 1,
+  };
+
+  ChromeContentSettingsEventInfo();
+  ~ChromeContentSettingsEventInfo() override;
+  ChromeContentSettingsEventInfo(ChromeContentSettingsEventInfo&&) noexcept;
+  ChromeContentSettingsEventInfo& operator=(ChromeContentSettingsEventInfo&&);
+  ChromeContentSettingsEventInfo(const ChromeContentSettingsEventInfo&);
+  ChromeContentSettingsEventInfo& operator=(const ChromeContentSettingsEventInfo&);
+  bool operator==(const ChromeContentSettingsEventInfo&) const;
+  bool operator!=(const ChromeContentSettingsEventInfo& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_number_of_exceptions() const { return _has_field_[1]; }
+  uint32_t number_of_exceptions() const { return number_of_exceptions_; }
+  void set_number_of_exceptions(uint32_t value) { number_of_exceptions_ = value; _has_field_.set(1); }
+
+ private:
+  uint32_t number_of_exceptions_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_CONTENT_SETTINGS_EVENT_INFO_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_frame_reporter.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_FRAME_REPORTER_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_FRAME_REPORTER_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ChromeFrameReporter;
+enum ChromeFrameReporter_State : int;
+enum ChromeFrameReporter_FrameDropReason : int;
+enum ChromeFrameReporter_ScrollState : int;
+enum ChromeFrameReporter_FrameType : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum ChromeFrameReporter_State : int {
+  ChromeFrameReporter_State_STATE_NO_UPDATE_DESIRED = 0,
+  ChromeFrameReporter_State_STATE_PRESENTED_ALL = 1,
+  ChromeFrameReporter_State_STATE_PRESENTED_PARTIAL = 2,
+  ChromeFrameReporter_State_STATE_DROPPED = 3,
+};
+enum ChromeFrameReporter_FrameDropReason : int {
+  ChromeFrameReporter_FrameDropReason_REASON_UNSPECIFIED = 0,
+  ChromeFrameReporter_FrameDropReason_REASON_DISPLAY_COMPOSITOR = 1,
+  ChromeFrameReporter_FrameDropReason_REASON_MAIN_THREAD = 2,
+  ChromeFrameReporter_FrameDropReason_REASON_CLIENT_COMPOSITOR = 3,
+};
+enum ChromeFrameReporter_ScrollState : int {
+  ChromeFrameReporter_ScrollState_SCROLL_NONE = 0,
+  ChromeFrameReporter_ScrollState_SCROLL_MAIN_THREAD = 1,
+  ChromeFrameReporter_ScrollState_SCROLL_COMPOSITOR_THREAD = 2,
+  ChromeFrameReporter_ScrollState_SCROLL_UNKNOWN = 3,
+};
+enum ChromeFrameReporter_FrameType : int {
+  ChromeFrameReporter_FrameType_FORKED = 0,
+  ChromeFrameReporter_FrameType_BACKFILL = 1,
+};
+
+class PERFETTO_EXPORT_COMPONENT ChromeFrameReporter : public ::protozero::CppMessageObj {
+ public:
+  using State = ChromeFrameReporter_State;
+  static constexpr auto STATE_NO_UPDATE_DESIRED = ChromeFrameReporter_State_STATE_NO_UPDATE_DESIRED;
+  static constexpr auto STATE_PRESENTED_ALL = ChromeFrameReporter_State_STATE_PRESENTED_ALL;
+  static constexpr auto STATE_PRESENTED_PARTIAL = ChromeFrameReporter_State_STATE_PRESENTED_PARTIAL;
+  static constexpr auto STATE_DROPPED = ChromeFrameReporter_State_STATE_DROPPED;
+  static constexpr auto State_MIN = ChromeFrameReporter_State_STATE_NO_UPDATE_DESIRED;
+  static constexpr auto State_MAX = ChromeFrameReporter_State_STATE_DROPPED;
+  using FrameDropReason = ChromeFrameReporter_FrameDropReason;
+  static constexpr auto REASON_UNSPECIFIED = ChromeFrameReporter_FrameDropReason_REASON_UNSPECIFIED;
+  static constexpr auto REASON_DISPLAY_COMPOSITOR = ChromeFrameReporter_FrameDropReason_REASON_DISPLAY_COMPOSITOR;
+  static constexpr auto REASON_MAIN_THREAD = ChromeFrameReporter_FrameDropReason_REASON_MAIN_THREAD;
+  static constexpr auto REASON_CLIENT_COMPOSITOR = ChromeFrameReporter_FrameDropReason_REASON_CLIENT_COMPOSITOR;
+  static constexpr auto FrameDropReason_MIN = ChromeFrameReporter_FrameDropReason_REASON_UNSPECIFIED;
+  static constexpr auto FrameDropReason_MAX = ChromeFrameReporter_FrameDropReason_REASON_CLIENT_COMPOSITOR;
+  using ScrollState = ChromeFrameReporter_ScrollState;
+  static constexpr auto SCROLL_NONE = ChromeFrameReporter_ScrollState_SCROLL_NONE;
+  static constexpr auto SCROLL_MAIN_THREAD = ChromeFrameReporter_ScrollState_SCROLL_MAIN_THREAD;
+  static constexpr auto SCROLL_COMPOSITOR_THREAD = ChromeFrameReporter_ScrollState_SCROLL_COMPOSITOR_THREAD;
+  static constexpr auto SCROLL_UNKNOWN = ChromeFrameReporter_ScrollState_SCROLL_UNKNOWN;
+  static constexpr auto ScrollState_MIN = ChromeFrameReporter_ScrollState_SCROLL_NONE;
+  static constexpr auto ScrollState_MAX = ChromeFrameReporter_ScrollState_SCROLL_UNKNOWN;
+  using FrameType = ChromeFrameReporter_FrameType;
+  static constexpr auto FORKED = ChromeFrameReporter_FrameType_FORKED;
+  static constexpr auto BACKFILL = ChromeFrameReporter_FrameType_BACKFILL;
+  static constexpr auto FrameType_MIN = ChromeFrameReporter_FrameType_FORKED;
+  static constexpr auto FrameType_MAX = ChromeFrameReporter_FrameType_BACKFILL;
+  enum FieldNumbers {
+    kStateFieldNumber = 1,
+    kReasonFieldNumber = 2,
+    kFrameSourceFieldNumber = 3,
+    kFrameSequenceFieldNumber = 4,
+    kAffectsSmoothnessFieldNumber = 5,
+    kScrollStateFieldNumber = 6,
+    kHasMainAnimationFieldNumber = 7,
+    kHasCompositorAnimationFieldNumber = 8,
+    kHasSmoothInputMainFieldNumber = 9,
+    kHasMissingContentFieldNumber = 10,
+    kLayerTreeHostIdFieldNumber = 11,
+    kHasHighLatencyFieldNumber = 12,
+    kFrameTypeFieldNumber = 13,
+    kHighLatencyContributionStageFieldNumber = 14,
+  };
+
+  ChromeFrameReporter();
+  ~ChromeFrameReporter() override;
+  ChromeFrameReporter(ChromeFrameReporter&&) noexcept;
+  ChromeFrameReporter& operator=(ChromeFrameReporter&&);
+  ChromeFrameReporter(const ChromeFrameReporter&);
+  ChromeFrameReporter& operator=(const ChromeFrameReporter&);
+  bool operator==(const ChromeFrameReporter&) const;
+  bool operator!=(const ChromeFrameReporter& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_state() const { return _has_field_[1]; }
+  ChromeFrameReporter_State state() const { return state_; }
+  void set_state(ChromeFrameReporter_State value) { state_ = value; _has_field_.set(1); }
+
+  bool has_reason() const { return _has_field_[2]; }
+  ChromeFrameReporter_FrameDropReason reason() const { return reason_; }
+  void set_reason(ChromeFrameReporter_FrameDropReason value) { reason_ = value; _has_field_.set(2); }
+
+  bool has_frame_source() const { return _has_field_[3]; }
+  uint64_t frame_source() const { return frame_source_; }
+  void set_frame_source(uint64_t value) { frame_source_ = value; _has_field_.set(3); }
+
+  bool has_frame_sequence() const { return _has_field_[4]; }
+  uint64_t frame_sequence() const { return frame_sequence_; }
+  void set_frame_sequence(uint64_t value) { frame_sequence_ = value; _has_field_.set(4); }
+
+  bool has_affects_smoothness() const { return _has_field_[5]; }
+  bool affects_smoothness() const { return affects_smoothness_; }
+  void set_affects_smoothness(bool value) { affects_smoothness_ = value; _has_field_.set(5); }
+
+  bool has_scroll_state() const { return _has_field_[6]; }
+  ChromeFrameReporter_ScrollState scroll_state() const { return scroll_state_; }
+  void set_scroll_state(ChromeFrameReporter_ScrollState value) { scroll_state_ = value; _has_field_.set(6); }
+
+  bool has_has_main_animation() const { return _has_field_[7]; }
+  bool has_main_animation() const { return has_main_animation_; }
+  void set_has_main_animation(bool value) { has_main_animation_ = value; _has_field_.set(7); }
+
+  bool has_has_compositor_animation() const { return _has_field_[8]; }
+  bool has_compositor_animation() const { return has_compositor_animation_; }
+  void set_has_compositor_animation(bool value) { has_compositor_animation_ = value; _has_field_.set(8); }
+
+  bool has_has_smooth_input_main() const { return _has_field_[9]; }
+  bool has_smooth_input_main() const { return has_smooth_input_main_; }
+  void set_has_smooth_input_main(bool value) { has_smooth_input_main_ = value; _has_field_.set(9); }
+
+  bool has_has_missing_content() const { return _has_field_[10]; }
+  bool has_missing_content() const { return has_missing_content_; }
+  void set_has_missing_content(bool value) { has_missing_content_ = value; _has_field_.set(10); }
+
+  bool has_layer_tree_host_id() const { return _has_field_[11]; }
+  uint64_t layer_tree_host_id() const { return layer_tree_host_id_; }
+  void set_layer_tree_host_id(uint64_t value) { layer_tree_host_id_ = value; _has_field_.set(11); }
+
+  bool has_has_high_latency() const { return _has_field_[12]; }
+  bool has_high_latency() const { return has_high_latency_; }
+  void set_has_high_latency(bool value) { has_high_latency_ = value; _has_field_.set(12); }
+
+  bool has_frame_type() const { return _has_field_[13]; }
+  ChromeFrameReporter_FrameType frame_type() const { return frame_type_; }
+  void set_frame_type(ChromeFrameReporter_FrameType value) { frame_type_ = value; _has_field_.set(13); }
+
+  const std::vector<std::string>& high_latency_contribution_stage() const { return high_latency_contribution_stage_; }
+  std::vector<std::string>* mutable_high_latency_contribution_stage() { return &high_latency_contribution_stage_; }
+  int high_latency_contribution_stage_size() const { return static_cast<int>(high_latency_contribution_stage_.size()); }
+  void clear_high_latency_contribution_stage() { high_latency_contribution_stage_.clear(); }
+  void add_high_latency_contribution_stage(std::string value) { high_latency_contribution_stage_.emplace_back(value); }
+  std::string* add_high_latency_contribution_stage() { high_latency_contribution_stage_.emplace_back(); return &high_latency_contribution_stage_.back(); }
+
+ private:
+  ChromeFrameReporter_State state_{};
+  ChromeFrameReporter_FrameDropReason reason_{};
+  uint64_t frame_source_{};
+  uint64_t frame_sequence_{};
+  bool affects_smoothness_{};
+  ChromeFrameReporter_ScrollState scroll_state_{};
+  bool has_main_animation_{};
+  bool has_compositor_animation_{};
+  bool has_smooth_input_main_{};
+  bool has_missing_content_{};
+  uint64_t layer_tree_host_id_{};
+  bool has_high_latency_{};
+  ChromeFrameReporter_FrameType frame_type_{};
+  std::vector<std::string> high_latency_contribution_stage_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<15> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_FRAME_REPORTER_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_histogram_sample.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_HISTOGRAM_SAMPLE_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_HISTOGRAM_SAMPLE_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ChromeHistogramSample;
+class HistogramName;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT ChromeHistogramSample : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kNameHashFieldNumber = 1,
+    kNameFieldNumber = 2,
+    kSampleFieldNumber = 3,
+    kNameIidFieldNumber = 4,
+  };
+
+  ChromeHistogramSample();
+  ~ChromeHistogramSample() override;
+  ChromeHistogramSample(ChromeHistogramSample&&) noexcept;
+  ChromeHistogramSample& operator=(ChromeHistogramSample&&);
+  ChromeHistogramSample(const ChromeHistogramSample&);
+  ChromeHistogramSample& operator=(const ChromeHistogramSample&);
+  bool operator==(const ChromeHistogramSample&) const;
+  bool operator!=(const ChromeHistogramSample& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name_hash() const { return _has_field_[1]; }
+  uint64_t name_hash() const { return name_hash_; }
+  void set_name_hash(uint64_t value) { name_hash_ = value; _has_field_.set(1); }
+
+  bool has_name() const { return _has_field_[2]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
+
+  bool has_sample() const { return _has_field_[3]; }
+  int64_t sample() const { return sample_; }
+  void set_sample(int64_t value) { sample_ = value; _has_field_.set(3); }
+
+  bool has_name_iid() const { return _has_field_[4]; }
+  uint64_t name_iid() const { return name_iid_; }
+  void set_name_iid(uint64_t value) { name_iid_ = value; _has_field_.set(4); }
+
+ private:
+  uint64_t name_hash_{};
+  std::string name_{};
+  int64_t sample_{};
+  uint64_t name_iid_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<5> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT HistogramName : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kIidFieldNumber = 1,
+    kNameFieldNumber = 2,
+  };
+
+  HistogramName();
+  ~HistogramName() override;
+  HistogramName(HistogramName&&) noexcept;
+  HistogramName& operator=(HistogramName&&);
+  HistogramName(const HistogramName&);
+  HistogramName& operator=(const HistogramName&);
+  bool operator==(const HistogramName&) const;
+  bool operator!=(const HistogramName& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_iid() const { return _has_field_[1]; }
+  uint64_t iid() const { return iid_; }
+  void set_iid(uint64_t value) { iid_ = value; _has_field_.set(1); }
+
+  bool has_name() const { return _has_field_[2]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
+
+ private:
+  uint64_t iid_{};
+  std::string name_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_HISTOGRAM_SAMPLE_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_keyed_service.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_KEYED_SERVICE_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_KEYED_SERVICE_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ChromeKeyedService;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT ChromeKeyedService : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kNameFieldNumber = 1,
+  };
+
+  ChromeKeyedService();
+  ~ChromeKeyedService() override;
+  ChromeKeyedService(ChromeKeyedService&&) noexcept;
+  ChromeKeyedService& operator=(ChromeKeyedService&&);
+  ChromeKeyedService(const ChromeKeyedService&);
+  ChromeKeyedService& operator=(const ChromeKeyedService&);
+  bool operator==(const ChromeKeyedService&) const;
+  bool operator!=(const ChromeKeyedService& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name() const { return _has_field_[1]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
+
+ private:
+  std::string name_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_KEYED_SERVICE_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_latency_info.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LATENCY_INFO_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LATENCY_INFO_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ChromeLatencyInfo;
+class ChromeLatencyInfo_ComponentInfo;
+enum ChromeLatencyInfo_Step : int;
+enum ChromeLatencyInfo_LatencyComponentType : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum ChromeLatencyInfo_Step : int {
+  ChromeLatencyInfo_Step_STEP_UNSPECIFIED = 0,
+  ChromeLatencyInfo_Step_STEP_SEND_INPUT_EVENT_UI = 3,
+  ChromeLatencyInfo_Step_STEP_HANDLE_INPUT_EVENT_IMPL = 5,
+  ChromeLatencyInfo_Step_STEP_DID_HANDLE_INPUT_AND_OVERSCROLL = 8,
+  ChromeLatencyInfo_Step_STEP_HANDLE_INPUT_EVENT_MAIN = 4,
+  ChromeLatencyInfo_Step_STEP_MAIN_THREAD_SCROLL_UPDATE = 2,
+  ChromeLatencyInfo_Step_STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT = 1,
+  ChromeLatencyInfo_Step_STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL = 9,
+  ChromeLatencyInfo_Step_STEP_HANDLED_INPUT_EVENT_IMPL = 10,
+  ChromeLatencyInfo_Step_STEP_SWAP_BUFFERS = 6,
+  ChromeLatencyInfo_Step_STEP_DRAW_AND_SWAP = 7,
+  ChromeLatencyInfo_Step_STEP_FINISHED_SWAP_BUFFERS = 11,
+};
+enum ChromeLatencyInfo_LatencyComponentType : int {
+  ChromeLatencyInfo_LatencyComponentType_COMPONENT_UNSPECIFIED = 0,
+  ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_BEGIN_RWH = 1,
+  ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL = 2,
+  ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL = 3,
+  ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_ORIGINAL = 4,
+  ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_UI = 5,
+  ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERER_MAIN = 6,
+  ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN = 7,
+  ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL = 8,
+  ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_LAST_EVENT = 9,
+  ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_ACK_RWH = 10,
+  ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERER_SWAP = 11,
+  ChromeLatencyInfo_LatencyComponentType_COMPONENT_DISPLAY_COMPOSITOR_RECEIVED_FRAME = 12,
+  ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_GPU_SWAP_BUFFER = 13,
+  ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_FRAME_SWAP = 14,
+};
+
+class PERFETTO_EXPORT_COMPONENT ChromeLatencyInfo : public ::protozero::CppMessageObj {
+ public:
+  using ComponentInfo = ChromeLatencyInfo_ComponentInfo;
+  using Step = ChromeLatencyInfo_Step;
+  static constexpr auto STEP_UNSPECIFIED = ChromeLatencyInfo_Step_STEP_UNSPECIFIED;
+  static constexpr auto STEP_SEND_INPUT_EVENT_UI = ChromeLatencyInfo_Step_STEP_SEND_INPUT_EVENT_UI;
+  static constexpr auto STEP_HANDLE_INPUT_EVENT_IMPL = ChromeLatencyInfo_Step_STEP_HANDLE_INPUT_EVENT_IMPL;
+  static constexpr auto STEP_DID_HANDLE_INPUT_AND_OVERSCROLL = ChromeLatencyInfo_Step_STEP_DID_HANDLE_INPUT_AND_OVERSCROLL;
+  static constexpr auto STEP_HANDLE_INPUT_EVENT_MAIN = ChromeLatencyInfo_Step_STEP_HANDLE_INPUT_EVENT_MAIN;
+  static constexpr auto STEP_MAIN_THREAD_SCROLL_UPDATE = ChromeLatencyInfo_Step_STEP_MAIN_THREAD_SCROLL_UPDATE;
+  static constexpr auto STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT = ChromeLatencyInfo_Step_STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT;
+  static constexpr auto STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL = ChromeLatencyInfo_Step_STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL;
+  static constexpr auto STEP_HANDLED_INPUT_EVENT_IMPL = ChromeLatencyInfo_Step_STEP_HANDLED_INPUT_EVENT_IMPL;
+  static constexpr auto STEP_SWAP_BUFFERS = ChromeLatencyInfo_Step_STEP_SWAP_BUFFERS;
+  static constexpr auto STEP_DRAW_AND_SWAP = ChromeLatencyInfo_Step_STEP_DRAW_AND_SWAP;
+  static constexpr auto STEP_FINISHED_SWAP_BUFFERS = ChromeLatencyInfo_Step_STEP_FINISHED_SWAP_BUFFERS;
+  static constexpr auto Step_MIN = ChromeLatencyInfo_Step_STEP_UNSPECIFIED;
+  static constexpr auto Step_MAX = ChromeLatencyInfo_Step_STEP_FINISHED_SWAP_BUFFERS;
+  using LatencyComponentType = ChromeLatencyInfo_LatencyComponentType;
+  static constexpr auto COMPONENT_UNSPECIFIED = ChromeLatencyInfo_LatencyComponentType_COMPONENT_UNSPECIFIED;
+  static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_BEGIN_RWH = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_BEGIN_RWH;
+  static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL;
+  static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL;
+  static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_ORIGINAL = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_ORIGINAL;
+  static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_UI = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_UI;
+  static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_RENDERER_MAIN = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERER_MAIN;
+  static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN;
+  static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL;
+  static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_LAST_EVENT = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_LAST_EVENT;
+  static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_ACK_RWH = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_ACK_RWH;
+  static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_RENDERER_SWAP = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERER_SWAP;
+  static constexpr auto COMPONENT_DISPLAY_COMPOSITOR_RECEIVED_FRAME = ChromeLatencyInfo_LatencyComponentType_COMPONENT_DISPLAY_COMPOSITOR_RECEIVED_FRAME;
+  static constexpr auto COMPONENT_INPUT_EVENT_GPU_SWAP_BUFFER = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_GPU_SWAP_BUFFER;
+  static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_FRAME_SWAP = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_FRAME_SWAP;
+  static constexpr auto LatencyComponentType_MIN = ChromeLatencyInfo_LatencyComponentType_COMPONENT_UNSPECIFIED;
+  static constexpr auto LatencyComponentType_MAX = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_FRAME_SWAP;
+  enum FieldNumbers {
+    kTraceIdFieldNumber = 1,
+    kStepFieldNumber = 2,
+    kFrameTreeNodeIdFieldNumber = 3,
+    kComponentInfoFieldNumber = 4,
+    kIsCoalescedFieldNumber = 5,
+    kGestureScrollIdFieldNumber = 6,
+    kTouchIdFieldNumber = 7,
+  };
+
+  ChromeLatencyInfo();
+  ~ChromeLatencyInfo() override;
+  ChromeLatencyInfo(ChromeLatencyInfo&&) noexcept;
+  ChromeLatencyInfo& operator=(ChromeLatencyInfo&&);
+  ChromeLatencyInfo(const ChromeLatencyInfo&);
+  ChromeLatencyInfo& operator=(const ChromeLatencyInfo&);
+  bool operator==(const ChromeLatencyInfo&) const;
+  bool operator!=(const ChromeLatencyInfo& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_trace_id() const { return _has_field_[1]; }
+  int64_t trace_id() const { return trace_id_; }
+  void set_trace_id(int64_t value) { trace_id_ = value; _has_field_.set(1); }
+
+  bool has_step() const { return _has_field_[2]; }
+  ChromeLatencyInfo_Step step() const { return step_; }
+  void set_step(ChromeLatencyInfo_Step value) { step_ = value; _has_field_.set(2); }
+
+  bool has_frame_tree_node_id() const { return _has_field_[3]; }
+  int32_t frame_tree_node_id() const { return frame_tree_node_id_; }
+  void set_frame_tree_node_id(int32_t value) { frame_tree_node_id_ = value; _has_field_.set(3); }
+
+  const std::vector<ChromeLatencyInfo_ComponentInfo>& component_info() const { return component_info_; }
+  std::vector<ChromeLatencyInfo_ComponentInfo>* mutable_component_info() { return &component_info_; }
+  int component_info_size() const;
+  void clear_component_info();
+  ChromeLatencyInfo_ComponentInfo* add_component_info();
+
+  bool has_is_coalesced() const { return _has_field_[5]; }
+  bool is_coalesced() const { return is_coalesced_; }
+  void set_is_coalesced(bool value) { is_coalesced_ = value; _has_field_.set(5); }
+
+  bool has_gesture_scroll_id() const { return _has_field_[6]; }
+  int64_t gesture_scroll_id() const { return gesture_scroll_id_; }
+  void set_gesture_scroll_id(int64_t value) { gesture_scroll_id_ = value; _has_field_.set(6); }
+
+  bool has_touch_id() const { return _has_field_[7]; }
+  int64_t touch_id() const { return touch_id_; }
+  void set_touch_id(int64_t value) { touch_id_ = value; _has_field_.set(7); }
+
+ private:
+  int64_t trace_id_{};
+  ChromeLatencyInfo_Step step_{};
+  int32_t frame_tree_node_id_{};
+  std::vector<ChromeLatencyInfo_ComponentInfo> component_info_;
+  bool is_coalesced_{};
+  int64_t gesture_scroll_id_{};
+  int64_t touch_id_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<8> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT ChromeLatencyInfo_ComponentInfo : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kComponentTypeFieldNumber = 1,
+    kTimeUsFieldNumber = 2,
+  };
+
+  ChromeLatencyInfo_ComponentInfo();
+  ~ChromeLatencyInfo_ComponentInfo() override;
+  ChromeLatencyInfo_ComponentInfo(ChromeLatencyInfo_ComponentInfo&&) noexcept;
+  ChromeLatencyInfo_ComponentInfo& operator=(ChromeLatencyInfo_ComponentInfo&&);
+  ChromeLatencyInfo_ComponentInfo(const ChromeLatencyInfo_ComponentInfo&);
+  ChromeLatencyInfo_ComponentInfo& operator=(const ChromeLatencyInfo_ComponentInfo&);
+  bool operator==(const ChromeLatencyInfo_ComponentInfo&) const;
+  bool operator!=(const ChromeLatencyInfo_ComponentInfo& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_component_type() const { return _has_field_[1]; }
+  ChromeLatencyInfo_LatencyComponentType component_type() const { return component_type_; }
+  void set_component_type(ChromeLatencyInfo_LatencyComponentType value) { component_type_ = value; _has_field_.set(1); }
+
+  bool has_time_us() const { return _has_field_[2]; }
+  uint64_t time_us() const { return time_us_; }
+  void set_time_us(uint64_t value) { time_us_ = value; _has_field_.set(2); }
+
+ private:
+  ChromeLatencyInfo_LatencyComponentType component_type_{};
+  uint64_t time_us_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LATENCY_INFO_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_legacy_ipc.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LEGACY_IPC_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LEGACY_IPC_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ChromeLegacyIpc;
+enum ChromeLegacyIpc_MessageClass : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum ChromeLegacyIpc_MessageClass : int {
+  ChromeLegacyIpc_MessageClass_CLASS_UNSPECIFIED = 0,
+  ChromeLegacyIpc_MessageClass_CLASS_AUTOMATION = 1,
+  ChromeLegacyIpc_MessageClass_CLASS_FRAME = 2,
+  ChromeLegacyIpc_MessageClass_CLASS_PAGE = 3,
+  ChromeLegacyIpc_MessageClass_CLASS_VIEW = 4,
+  ChromeLegacyIpc_MessageClass_CLASS_WIDGET = 5,
+  ChromeLegacyIpc_MessageClass_CLASS_INPUT = 6,
+  ChromeLegacyIpc_MessageClass_CLASS_TEST = 7,
+  ChromeLegacyIpc_MessageClass_CLASS_WORKER = 8,
+  ChromeLegacyIpc_MessageClass_CLASS_NACL = 9,
+  ChromeLegacyIpc_MessageClass_CLASS_GPU_CHANNEL = 10,
+  ChromeLegacyIpc_MessageClass_CLASS_MEDIA = 11,
+  ChromeLegacyIpc_MessageClass_CLASS_PPAPI = 12,
+  ChromeLegacyIpc_MessageClass_CLASS_CHROME = 13,
+  ChromeLegacyIpc_MessageClass_CLASS_DRAG = 14,
+  ChromeLegacyIpc_MessageClass_CLASS_PRINT = 15,
+  ChromeLegacyIpc_MessageClass_CLASS_EXTENSION = 16,
+  ChromeLegacyIpc_MessageClass_CLASS_TEXT_INPUT_CLIENT = 17,
+  ChromeLegacyIpc_MessageClass_CLASS_BLINK_TEST = 18,
+  ChromeLegacyIpc_MessageClass_CLASS_ACCESSIBILITY = 19,
+  ChromeLegacyIpc_MessageClass_CLASS_PRERENDER = 20,
+  ChromeLegacyIpc_MessageClass_CLASS_CHROMOTING = 21,
+  ChromeLegacyIpc_MessageClass_CLASS_BROWSER_PLUGIN = 22,
+  ChromeLegacyIpc_MessageClass_CLASS_ANDROID_WEB_VIEW = 23,
+  ChromeLegacyIpc_MessageClass_CLASS_NACL_HOST = 24,
+  ChromeLegacyIpc_MessageClass_CLASS_ENCRYPTED_MEDIA = 25,
+  ChromeLegacyIpc_MessageClass_CLASS_CAST = 26,
+  ChromeLegacyIpc_MessageClass_CLASS_GIN_JAVA_BRIDGE = 27,
+  ChromeLegacyIpc_MessageClass_CLASS_CHROME_UTILITY_PRINTING = 28,
+  ChromeLegacyIpc_MessageClass_CLASS_OZONE_GPU = 29,
+  ChromeLegacyIpc_MessageClass_CLASS_WEB_TEST = 30,
+  ChromeLegacyIpc_MessageClass_CLASS_NETWORK_HINTS = 31,
+  ChromeLegacyIpc_MessageClass_CLASS_EXTENSIONS_GUEST_VIEW = 32,
+  ChromeLegacyIpc_MessageClass_CLASS_GUEST_VIEW = 33,
+  ChromeLegacyIpc_MessageClass_CLASS_MEDIA_PLAYER_DELEGATE = 34,
+  ChromeLegacyIpc_MessageClass_CLASS_EXTENSION_WORKER = 35,
+  ChromeLegacyIpc_MessageClass_CLASS_SUBRESOURCE_FILTER = 36,
+  ChromeLegacyIpc_MessageClass_CLASS_UNFREEZABLE_FRAME = 37,
+};
+
+class PERFETTO_EXPORT_COMPONENT ChromeLegacyIpc : public ::protozero::CppMessageObj {
+ public:
+  using MessageClass = ChromeLegacyIpc_MessageClass;
+  static constexpr auto CLASS_UNSPECIFIED = ChromeLegacyIpc_MessageClass_CLASS_UNSPECIFIED;
+  static constexpr auto CLASS_AUTOMATION = ChromeLegacyIpc_MessageClass_CLASS_AUTOMATION;
+  static constexpr auto CLASS_FRAME = ChromeLegacyIpc_MessageClass_CLASS_FRAME;
+  static constexpr auto CLASS_PAGE = ChromeLegacyIpc_MessageClass_CLASS_PAGE;
+  static constexpr auto CLASS_VIEW = ChromeLegacyIpc_MessageClass_CLASS_VIEW;
+  static constexpr auto CLASS_WIDGET = ChromeLegacyIpc_MessageClass_CLASS_WIDGET;
+  static constexpr auto CLASS_INPUT = ChromeLegacyIpc_MessageClass_CLASS_INPUT;
+  static constexpr auto CLASS_TEST = ChromeLegacyIpc_MessageClass_CLASS_TEST;
+  static constexpr auto CLASS_WORKER = ChromeLegacyIpc_MessageClass_CLASS_WORKER;
+  static constexpr auto CLASS_NACL = ChromeLegacyIpc_MessageClass_CLASS_NACL;
+  static constexpr auto CLASS_GPU_CHANNEL = ChromeLegacyIpc_MessageClass_CLASS_GPU_CHANNEL;
+  static constexpr auto CLASS_MEDIA = ChromeLegacyIpc_MessageClass_CLASS_MEDIA;
+  static constexpr auto CLASS_PPAPI = ChromeLegacyIpc_MessageClass_CLASS_PPAPI;
+  static constexpr auto CLASS_CHROME = ChromeLegacyIpc_MessageClass_CLASS_CHROME;
+  static constexpr auto CLASS_DRAG = ChromeLegacyIpc_MessageClass_CLASS_DRAG;
+  static constexpr auto CLASS_PRINT = ChromeLegacyIpc_MessageClass_CLASS_PRINT;
+  static constexpr auto CLASS_EXTENSION = ChromeLegacyIpc_MessageClass_CLASS_EXTENSION;
+  static constexpr auto CLASS_TEXT_INPUT_CLIENT = ChromeLegacyIpc_MessageClass_CLASS_TEXT_INPUT_CLIENT;
+  static constexpr auto CLASS_BLINK_TEST = ChromeLegacyIpc_MessageClass_CLASS_BLINK_TEST;
+  static constexpr auto CLASS_ACCESSIBILITY = ChromeLegacyIpc_MessageClass_CLASS_ACCESSIBILITY;
+  static constexpr auto CLASS_PRERENDER = ChromeLegacyIpc_MessageClass_CLASS_PRERENDER;
+  static constexpr auto CLASS_CHROMOTING = ChromeLegacyIpc_MessageClass_CLASS_CHROMOTING;
+  static constexpr auto CLASS_BROWSER_PLUGIN = ChromeLegacyIpc_MessageClass_CLASS_BROWSER_PLUGIN;
+  static constexpr auto CLASS_ANDROID_WEB_VIEW = ChromeLegacyIpc_MessageClass_CLASS_ANDROID_WEB_VIEW;
+  static constexpr auto CLASS_NACL_HOST = ChromeLegacyIpc_MessageClass_CLASS_NACL_HOST;
+  static constexpr auto CLASS_ENCRYPTED_MEDIA = ChromeLegacyIpc_MessageClass_CLASS_ENCRYPTED_MEDIA;
+  static constexpr auto CLASS_CAST = ChromeLegacyIpc_MessageClass_CLASS_CAST;
+  static constexpr auto CLASS_GIN_JAVA_BRIDGE = ChromeLegacyIpc_MessageClass_CLASS_GIN_JAVA_BRIDGE;
+  static constexpr auto CLASS_CHROME_UTILITY_PRINTING = ChromeLegacyIpc_MessageClass_CLASS_CHROME_UTILITY_PRINTING;
+  static constexpr auto CLASS_OZONE_GPU = ChromeLegacyIpc_MessageClass_CLASS_OZONE_GPU;
+  static constexpr auto CLASS_WEB_TEST = ChromeLegacyIpc_MessageClass_CLASS_WEB_TEST;
+  static constexpr auto CLASS_NETWORK_HINTS = ChromeLegacyIpc_MessageClass_CLASS_NETWORK_HINTS;
+  static constexpr auto CLASS_EXTENSIONS_GUEST_VIEW = ChromeLegacyIpc_MessageClass_CLASS_EXTENSIONS_GUEST_VIEW;
+  static constexpr auto CLASS_GUEST_VIEW = ChromeLegacyIpc_MessageClass_CLASS_GUEST_VIEW;
+  static constexpr auto CLASS_MEDIA_PLAYER_DELEGATE = ChromeLegacyIpc_MessageClass_CLASS_MEDIA_PLAYER_DELEGATE;
+  static constexpr auto CLASS_EXTENSION_WORKER = ChromeLegacyIpc_MessageClass_CLASS_EXTENSION_WORKER;
+  static constexpr auto CLASS_SUBRESOURCE_FILTER = ChromeLegacyIpc_MessageClass_CLASS_SUBRESOURCE_FILTER;
+  static constexpr auto CLASS_UNFREEZABLE_FRAME = ChromeLegacyIpc_MessageClass_CLASS_UNFREEZABLE_FRAME;
+  static constexpr auto MessageClass_MIN = ChromeLegacyIpc_MessageClass_CLASS_UNSPECIFIED;
+  static constexpr auto MessageClass_MAX = ChromeLegacyIpc_MessageClass_CLASS_UNFREEZABLE_FRAME;
+  enum FieldNumbers {
+    kMessageClassFieldNumber = 1,
+    kMessageLineFieldNumber = 2,
+  };
+
+  ChromeLegacyIpc();
+  ~ChromeLegacyIpc() override;
+  ChromeLegacyIpc(ChromeLegacyIpc&&) noexcept;
+  ChromeLegacyIpc& operator=(ChromeLegacyIpc&&);
+  ChromeLegacyIpc(const ChromeLegacyIpc&);
+  ChromeLegacyIpc& operator=(const ChromeLegacyIpc&);
+  bool operator==(const ChromeLegacyIpc&) const;
+  bool operator!=(const ChromeLegacyIpc& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_message_class() const { return _has_field_[1]; }
+  ChromeLegacyIpc_MessageClass message_class() const { return message_class_; }
+  void set_message_class(ChromeLegacyIpc_MessageClass value) { message_class_ = value; _has_field_.set(1); }
+
+  bool has_message_line() const { return _has_field_[2]; }
+  uint32_t message_line() const { return message_line_; }
+  void set_message_line(uint32_t value) { message_line_ = value; _has_field_.set(2); }
+
+ private:
+  ChromeLegacyIpc_MessageClass message_class_{};
+  uint32_t message_line_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LEGACY_IPC_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_message_pump.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_MESSAGE_PUMP_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_MESSAGE_PUMP_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ChromeMessagePump;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT ChromeMessagePump : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kSentMessagesInQueueFieldNumber = 1,
+    kIoHandlerLocationIidFieldNumber = 2,
+  };
+
+  ChromeMessagePump();
+  ~ChromeMessagePump() override;
+  ChromeMessagePump(ChromeMessagePump&&) noexcept;
+  ChromeMessagePump& operator=(ChromeMessagePump&&);
+  ChromeMessagePump(const ChromeMessagePump&);
+  ChromeMessagePump& operator=(const ChromeMessagePump&);
+  bool operator==(const ChromeMessagePump&) const;
+  bool operator!=(const ChromeMessagePump& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_sent_messages_in_queue() const { return _has_field_[1]; }
+  bool sent_messages_in_queue() const { return sent_messages_in_queue_; }
+  void set_sent_messages_in_queue(bool value) { sent_messages_in_queue_ = value; _has_field_.set(1); }
+
+  bool has_io_handler_location_iid() const { return _has_field_[2]; }
+  uint64_t io_handler_location_iid() const { return io_handler_location_iid_; }
+  void set_io_handler_location_iid(uint64_t value) { io_handler_location_iid_ = value; _has_field_.set(2); }
+
+ private:
+  bool sent_messages_in_queue_{};
+  uint64_t io_handler_location_iid_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_MESSAGE_PUMP_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_mojo_event_info.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_MOJO_EVENT_INFO_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_MOJO_EVENT_INFO_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ChromeMojoEventInfo;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT ChromeMojoEventInfo : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kWatcherNotifyInterfaceTagFieldNumber = 1,
+    kIpcHashFieldNumber = 2,
+    kMojoInterfaceTagFieldNumber = 3,
+    kMojoInterfaceMethodIidFieldNumber = 4,
+    kIsReplyFieldNumber = 5,
+    kPayloadSizeFieldNumber = 6,
+    kDataNumBytesFieldNumber = 7,
+  };
+
+  ChromeMojoEventInfo();
+  ~ChromeMojoEventInfo() override;
+  ChromeMojoEventInfo(ChromeMojoEventInfo&&) noexcept;
+  ChromeMojoEventInfo& operator=(ChromeMojoEventInfo&&);
+  ChromeMojoEventInfo(const ChromeMojoEventInfo&);
+  ChromeMojoEventInfo& operator=(const ChromeMojoEventInfo&);
+  bool operator==(const ChromeMojoEventInfo&) const;
+  bool operator!=(const ChromeMojoEventInfo& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_watcher_notify_interface_tag() const { return _has_field_[1]; }
+  const std::string& watcher_notify_interface_tag() const { return watcher_notify_interface_tag_; }
+  void set_watcher_notify_interface_tag(const std::string& value) { watcher_notify_interface_tag_ = value; _has_field_.set(1); }
+
+  bool has_ipc_hash() const { return _has_field_[2]; }
+  uint32_t ipc_hash() const { return ipc_hash_; }
+  void set_ipc_hash(uint32_t value) { ipc_hash_ = value; _has_field_.set(2); }
+
+  bool has_mojo_interface_tag() const { return _has_field_[3]; }
+  const std::string& mojo_interface_tag() const { return mojo_interface_tag_; }
+  void set_mojo_interface_tag(const std::string& value) { mojo_interface_tag_ = value; _has_field_.set(3); }
+
+  bool has_mojo_interface_method_iid() const { return _has_field_[4]; }
+  uint64_t mojo_interface_method_iid() const { return mojo_interface_method_iid_; }
+  void set_mojo_interface_method_iid(uint64_t value) { mojo_interface_method_iid_ = value; _has_field_.set(4); }
+
+  bool has_is_reply() const { return _has_field_[5]; }
+  bool is_reply() const { return is_reply_; }
+  void set_is_reply(bool value) { is_reply_ = value; _has_field_.set(5); }
+
+  bool has_payload_size() const { return _has_field_[6]; }
+  uint64_t payload_size() const { return payload_size_; }
+  void set_payload_size(uint64_t value) { payload_size_ = value; _has_field_.set(6); }
+
+  bool has_data_num_bytes() const { return _has_field_[7]; }
+  uint64_t data_num_bytes() const { return data_num_bytes_; }
+  void set_data_num_bytes(uint64_t value) { data_num_bytes_ = value; _has_field_.set(7); }
+
+ private:
+  std::string watcher_notify_interface_tag_{};
+  uint32_t ipc_hash_{};
+  std::string mojo_interface_tag_{};
+  uint64_t mojo_interface_method_iid_{};
+  bool is_reply_{};
+  uint64_t payload_size_{};
+  uint64_t data_num_bytes_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<8> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_MOJO_EVENT_INFO_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_process_descriptor.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_PROCESS_DESCRIPTOR_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_PROCESS_DESCRIPTOR_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ChromeProcessDescriptor;
+enum ChromeProcessDescriptor_ProcessType : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum ChromeProcessDescriptor_ProcessType : int {
+  ChromeProcessDescriptor_ProcessType_PROCESS_UNSPECIFIED = 0,
+  ChromeProcessDescriptor_ProcessType_PROCESS_BROWSER = 1,
+  ChromeProcessDescriptor_ProcessType_PROCESS_RENDERER = 2,
+  ChromeProcessDescriptor_ProcessType_PROCESS_UTILITY = 3,
+  ChromeProcessDescriptor_ProcessType_PROCESS_ZYGOTE = 4,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SANDBOX_HELPER = 5,
+  ChromeProcessDescriptor_ProcessType_PROCESS_GPU = 6,
+  ChromeProcessDescriptor_ProcessType_PROCESS_PPAPI_PLUGIN = 7,
+  ChromeProcessDescriptor_ProcessType_PROCESS_PPAPI_BROKER = 8,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_NETWORK = 9,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_TRACING = 10,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_STORAGE = 11,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_AUDIO = 12,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_DATA_DECODER = 13,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_UTIL_WIN = 14,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PROXY_RESOLVER = 15,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_CDM = 16,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_VIDEO_CAPTURE = 17,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_UNZIPPER = 18,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_MIRRORING = 19,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_FILEPATCHER = 20,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_TTS = 21,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PRINTING = 22,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_QUARANTINE = 23,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_CROS_LOCALSEARCH = 24,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_CROS_ASSISTANT_AUDIO_DECODER = 25,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_FILEUTIL = 26,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PRINTCOMPOSITOR = 27,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PAINTPREVIEW = 28,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_SPEECHRECOGNITION = 29,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_XRDEVICE = 30,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_READICON = 31,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_LANGUAGEDETECTION = 32,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_SHARING = 33,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_MEDIAPARSER = 34,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_QRCODEGENERATOR = 35,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PROFILEIMPORT = 36,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_IME = 37,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_RECORDING = 38,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_SHAPEDETECTION = 39,
+  ChromeProcessDescriptor_ProcessType_PROCESS_RENDERER_EXTENSION = 40,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_MEDIA_FOUNDATION = 41,
+};
+
+class PERFETTO_EXPORT_COMPONENT ChromeProcessDescriptor : public ::protozero::CppMessageObj {
+ public:
+  using ProcessType = ChromeProcessDescriptor_ProcessType;
+  static constexpr auto PROCESS_UNSPECIFIED = ChromeProcessDescriptor_ProcessType_PROCESS_UNSPECIFIED;
+  static constexpr auto PROCESS_BROWSER = ChromeProcessDescriptor_ProcessType_PROCESS_BROWSER;
+  static constexpr auto PROCESS_RENDERER = ChromeProcessDescriptor_ProcessType_PROCESS_RENDERER;
+  static constexpr auto PROCESS_UTILITY = ChromeProcessDescriptor_ProcessType_PROCESS_UTILITY;
+  static constexpr auto PROCESS_ZYGOTE = ChromeProcessDescriptor_ProcessType_PROCESS_ZYGOTE;
+  static constexpr auto PROCESS_SANDBOX_HELPER = ChromeProcessDescriptor_ProcessType_PROCESS_SANDBOX_HELPER;
+  static constexpr auto PROCESS_GPU = ChromeProcessDescriptor_ProcessType_PROCESS_GPU;
+  static constexpr auto PROCESS_PPAPI_PLUGIN = ChromeProcessDescriptor_ProcessType_PROCESS_PPAPI_PLUGIN;
+  static constexpr auto PROCESS_PPAPI_BROKER = ChromeProcessDescriptor_ProcessType_PROCESS_PPAPI_BROKER;
+  static constexpr auto PROCESS_SERVICE_NETWORK = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_NETWORK;
+  static constexpr auto PROCESS_SERVICE_TRACING = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_TRACING;
+  static constexpr auto PROCESS_SERVICE_STORAGE = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_STORAGE;
+  static constexpr auto PROCESS_SERVICE_AUDIO = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_AUDIO;
+  static constexpr auto PROCESS_SERVICE_DATA_DECODER = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_DATA_DECODER;
+  static constexpr auto PROCESS_SERVICE_UTIL_WIN = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_UTIL_WIN;
+  static constexpr auto PROCESS_SERVICE_PROXY_RESOLVER = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PROXY_RESOLVER;
+  static constexpr auto PROCESS_SERVICE_CDM = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_CDM;
+  static constexpr auto PROCESS_SERVICE_VIDEO_CAPTURE = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_VIDEO_CAPTURE;
+  static constexpr auto PROCESS_SERVICE_UNZIPPER = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_UNZIPPER;
+  static constexpr auto PROCESS_SERVICE_MIRRORING = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_MIRRORING;
+  static constexpr auto PROCESS_SERVICE_FILEPATCHER = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_FILEPATCHER;
+  static constexpr auto PROCESS_SERVICE_TTS = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_TTS;
+  static constexpr auto PROCESS_SERVICE_PRINTING = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PRINTING;
+  static constexpr auto PROCESS_SERVICE_QUARANTINE = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_QUARANTINE;
+  static constexpr auto PROCESS_SERVICE_CROS_LOCALSEARCH = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_CROS_LOCALSEARCH;
+  static constexpr auto PROCESS_SERVICE_CROS_ASSISTANT_AUDIO_DECODER = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_CROS_ASSISTANT_AUDIO_DECODER;
+  static constexpr auto PROCESS_SERVICE_FILEUTIL = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_FILEUTIL;
+  static constexpr auto PROCESS_SERVICE_PRINTCOMPOSITOR = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PRINTCOMPOSITOR;
+  static constexpr auto PROCESS_SERVICE_PAINTPREVIEW = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PAINTPREVIEW;
+  static constexpr auto PROCESS_SERVICE_SPEECHRECOGNITION = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_SPEECHRECOGNITION;
+  static constexpr auto PROCESS_SERVICE_XRDEVICE = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_XRDEVICE;
+  static constexpr auto PROCESS_SERVICE_READICON = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_READICON;
+  static constexpr auto PROCESS_SERVICE_LANGUAGEDETECTION = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_LANGUAGEDETECTION;
+  static constexpr auto PROCESS_SERVICE_SHARING = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_SHARING;
+  static constexpr auto PROCESS_SERVICE_MEDIAPARSER = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_MEDIAPARSER;
+  static constexpr auto PROCESS_SERVICE_QRCODEGENERATOR = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_QRCODEGENERATOR;
+  static constexpr auto PROCESS_SERVICE_PROFILEIMPORT = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PROFILEIMPORT;
+  static constexpr auto PROCESS_SERVICE_IME = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_IME;
+  static constexpr auto PROCESS_SERVICE_RECORDING = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_RECORDING;
+  static constexpr auto PROCESS_SERVICE_SHAPEDETECTION = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_SHAPEDETECTION;
+  static constexpr auto PROCESS_RENDERER_EXTENSION = ChromeProcessDescriptor_ProcessType_PROCESS_RENDERER_EXTENSION;
+  static constexpr auto PROCESS_SERVICE_MEDIA_FOUNDATION = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_MEDIA_FOUNDATION;
+  static constexpr auto ProcessType_MIN = ChromeProcessDescriptor_ProcessType_PROCESS_UNSPECIFIED;
+  static constexpr auto ProcessType_MAX = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_MEDIA_FOUNDATION;
+  enum FieldNumbers {
+    kProcessTypeFieldNumber = 1,
+    kProcessPriorityFieldNumber = 2,
+    kLegacySortIndexFieldNumber = 3,
+    kHostAppPackageNameFieldNumber = 4,
+    kCrashTraceIdFieldNumber = 5,
+  };
+
+  ChromeProcessDescriptor();
+  ~ChromeProcessDescriptor() override;
+  ChromeProcessDescriptor(ChromeProcessDescriptor&&) noexcept;
+  ChromeProcessDescriptor& operator=(ChromeProcessDescriptor&&);
+  ChromeProcessDescriptor(const ChromeProcessDescriptor&);
+  ChromeProcessDescriptor& operator=(const ChromeProcessDescriptor&);
+  bool operator==(const ChromeProcessDescriptor&) const;
+  bool operator!=(const ChromeProcessDescriptor& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_process_type() const { return _has_field_[1]; }
+  ChromeProcessDescriptor_ProcessType process_type() const { return process_type_; }
+  void set_process_type(ChromeProcessDescriptor_ProcessType value) { process_type_ = value; _has_field_.set(1); }
+
+  bool has_process_priority() const { return _has_field_[2]; }
+  int32_t process_priority() const { return process_priority_; }
+  void set_process_priority(int32_t value) { process_priority_ = value; _has_field_.set(2); }
+
+  bool has_legacy_sort_index() const { return _has_field_[3]; }
+  int32_t legacy_sort_index() const { return legacy_sort_index_; }
+  void set_legacy_sort_index(int32_t value) { legacy_sort_index_ = value; _has_field_.set(3); }
+
+  bool has_host_app_package_name() const { return _has_field_[4]; }
+  const std::string& host_app_package_name() const { return host_app_package_name_; }
+  void set_host_app_package_name(const std::string& value) { host_app_package_name_ = value; _has_field_.set(4); }
+
+  bool has_crash_trace_id() const { return _has_field_[5]; }
+  uint64_t crash_trace_id() const { return crash_trace_id_; }
+  void set_crash_trace_id(uint64_t value) { crash_trace_id_ = value; _has_field_.set(5); }
+
+ private:
+  ChromeProcessDescriptor_ProcessType process_type_{};
+  int32_t process_priority_{};
+  int32_t legacy_sort_index_{};
+  std::string host_app_package_name_{};
+  uint64_t crash_trace_id_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<6> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_PROCESS_DESCRIPTOR_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_RENDERER_SCHEDULER_STATE_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_RENDERER_SCHEDULER_STATE_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ChromeRendererSchedulerState;
+enum ChromeRAILMode : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum ChromeRAILMode : int {
+  RAIL_MODE_NONE = 0,
+  RAIL_MODE_RESPONSE = 1,
+  RAIL_MODE_ANIMATION = 2,
+  RAIL_MODE_IDLE = 3,
+  RAIL_MODE_LOAD = 4,
+};
+
+class PERFETTO_EXPORT_COMPONENT ChromeRendererSchedulerState : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kRailModeFieldNumber = 1,
+    kIsBackgroundedFieldNumber = 2,
+    kIsHiddenFieldNumber = 3,
+  };
+
+  ChromeRendererSchedulerState();
+  ~ChromeRendererSchedulerState() override;
+  ChromeRendererSchedulerState(ChromeRendererSchedulerState&&) noexcept;
+  ChromeRendererSchedulerState& operator=(ChromeRendererSchedulerState&&);
+  ChromeRendererSchedulerState(const ChromeRendererSchedulerState&);
+  ChromeRendererSchedulerState& operator=(const ChromeRendererSchedulerState&);
+  bool operator==(const ChromeRendererSchedulerState&) const;
+  bool operator!=(const ChromeRendererSchedulerState& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_rail_mode() const { return _has_field_[1]; }
+  ChromeRAILMode rail_mode() const { return rail_mode_; }
+  void set_rail_mode(ChromeRAILMode value) { rail_mode_ = value; _has_field_.set(1); }
+
+  bool has_is_backgrounded() const { return _has_field_[2]; }
+  bool is_backgrounded() const { return is_backgrounded_; }
+  void set_is_backgrounded(bool value) { is_backgrounded_ = value; _has_field_.set(2); }
+
+  bool has_is_hidden() const { return _has_field_[3]; }
+  bool is_hidden() const { return is_hidden_; }
+  void set_is_hidden(bool value) { is_hidden_ = value; _has_field_.set(3); }
+
+ private:
+  ChromeRAILMode rail_mode_{};
+  bool is_backgrounded_{};
+  bool is_hidden_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_RENDERER_SCHEDULER_STATE_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_thread_descriptor.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_THREAD_DESCRIPTOR_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_THREAD_DESCRIPTOR_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ChromeThreadDescriptor;
+enum ChromeThreadDescriptor_ThreadType : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum ChromeThreadDescriptor_ThreadType : int {
+  ChromeThreadDescriptor_ThreadType_THREAD_UNSPECIFIED = 0,
+  ChromeThreadDescriptor_ThreadType_THREAD_MAIN = 1,
+  ChromeThreadDescriptor_ThreadType_THREAD_IO = 2,
+  ChromeThreadDescriptor_ThreadType_THREAD_POOL_BG_WORKER = 3,
+  ChromeThreadDescriptor_ThreadType_THREAD_POOL_FG_WORKER = 4,
+  ChromeThreadDescriptor_ThreadType_THREAD_POOL_FG_BLOCKING = 5,
+  ChromeThreadDescriptor_ThreadType_THREAD_POOL_BG_BLOCKING = 6,
+  ChromeThreadDescriptor_ThreadType_THREAD_POOL_SERVICE = 7,
+  ChromeThreadDescriptor_ThreadType_THREAD_COMPOSITOR = 8,
+  ChromeThreadDescriptor_ThreadType_THREAD_VIZ_COMPOSITOR = 9,
+  ChromeThreadDescriptor_ThreadType_THREAD_COMPOSITOR_WORKER = 10,
+  ChromeThreadDescriptor_ThreadType_THREAD_SERVICE_WORKER = 11,
+  ChromeThreadDescriptor_ThreadType_THREAD_NETWORK_SERVICE = 12,
+  ChromeThreadDescriptor_ThreadType_THREAD_CHILD_IO = 13,
+  ChromeThreadDescriptor_ThreadType_THREAD_BROWSER_IO = 14,
+  ChromeThreadDescriptor_ThreadType_THREAD_BROWSER_MAIN = 15,
+  ChromeThreadDescriptor_ThreadType_THREAD_RENDERER_MAIN = 16,
+  ChromeThreadDescriptor_ThreadType_THREAD_UTILITY_MAIN = 17,
+  ChromeThreadDescriptor_ThreadType_THREAD_GPU_MAIN = 18,
+  ChromeThreadDescriptor_ThreadType_THREAD_CACHE_BLOCKFILE = 19,
+  ChromeThreadDescriptor_ThreadType_THREAD_MEDIA = 20,
+  ChromeThreadDescriptor_ThreadType_THREAD_AUDIO_OUTPUTDEVICE = 21,
+  ChromeThreadDescriptor_ThreadType_THREAD_AUDIO_INPUTDEVICE = 22,
+  ChromeThreadDescriptor_ThreadType_THREAD_GPU_MEMORY = 23,
+  ChromeThreadDescriptor_ThreadType_THREAD_GPU_VSYNC = 24,
+  ChromeThreadDescriptor_ThreadType_THREAD_DXA_VIDEODECODER = 25,
+  ChromeThreadDescriptor_ThreadType_THREAD_BROWSER_WATCHDOG = 26,
+  ChromeThreadDescriptor_ThreadType_THREAD_WEBRTC_NETWORK = 27,
+  ChromeThreadDescriptor_ThreadType_THREAD_WINDOW_OWNER = 28,
+  ChromeThreadDescriptor_ThreadType_THREAD_WEBRTC_SIGNALING = 29,
+  ChromeThreadDescriptor_ThreadType_THREAD_WEBRTC_WORKER = 30,
+  ChromeThreadDescriptor_ThreadType_THREAD_PPAPI_MAIN = 31,
+  ChromeThreadDescriptor_ThreadType_THREAD_GPU_WATCHDOG = 32,
+  ChromeThreadDescriptor_ThreadType_THREAD_SWAPPER = 33,
+  ChromeThreadDescriptor_ThreadType_THREAD_GAMEPAD_POLLING = 34,
+  ChromeThreadDescriptor_ThreadType_THREAD_WEBCRYPTO = 35,
+  ChromeThreadDescriptor_ThreadType_THREAD_DATABASE = 36,
+  ChromeThreadDescriptor_ThreadType_THREAD_PROXYRESOLVER = 37,
+  ChromeThreadDescriptor_ThreadType_THREAD_DEVTOOLSADB = 38,
+  ChromeThreadDescriptor_ThreadType_THREAD_NETWORKCONFIGWATCHER = 39,
+  ChromeThreadDescriptor_ThreadType_THREAD_WASAPI_RENDER = 40,
+  ChromeThreadDescriptor_ThreadType_THREAD_LOADER_LOCK_SAMPLER = 41,
+  ChromeThreadDescriptor_ThreadType_THREAD_MEMORY_INFRA = 50,
+  ChromeThreadDescriptor_ThreadType_THREAD_SAMPLING_PROFILER = 51,
+};
+
+class PERFETTO_EXPORT_COMPONENT ChromeThreadDescriptor : public ::protozero::CppMessageObj {
+ public:
+  using ThreadType = ChromeThreadDescriptor_ThreadType;
+  static constexpr auto THREAD_UNSPECIFIED = ChromeThreadDescriptor_ThreadType_THREAD_UNSPECIFIED;
+  static constexpr auto THREAD_MAIN = ChromeThreadDescriptor_ThreadType_THREAD_MAIN;
+  static constexpr auto THREAD_IO = ChromeThreadDescriptor_ThreadType_THREAD_IO;
+  static constexpr auto THREAD_POOL_BG_WORKER = ChromeThreadDescriptor_ThreadType_THREAD_POOL_BG_WORKER;
+  static constexpr auto THREAD_POOL_FG_WORKER = ChromeThreadDescriptor_ThreadType_THREAD_POOL_FG_WORKER;
+  static constexpr auto THREAD_POOL_FG_BLOCKING = ChromeThreadDescriptor_ThreadType_THREAD_POOL_FG_BLOCKING;
+  static constexpr auto THREAD_POOL_BG_BLOCKING = ChromeThreadDescriptor_ThreadType_THREAD_POOL_BG_BLOCKING;
+  static constexpr auto THREAD_POOL_SERVICE = ChromeThreadDescriptor_ThreadType_THREAD_POOL_SERVICE;
+  static constexpr auto THREAD_COMPOSITOR = ChromeThreadDescriptor_ThreadType_THREAD_COMPOSITOR;
+  static constexpr auto THREAD_VIZ_COMPOSITOR = ChromeThreadDescriptor_ThreadType_THREAD_VIZ_COMPOSITOR;
+  static constexpr auto THREAD_COMPOSITOR_WORKER = ChromeThreadDescriptor_ThreadType_THREAD_COMPOSITOR_WORKER;
+  static constexpr auto THREAD_SERVICE_WORKER = ChromeThreadDescriptor_ThreadType_THREAD_SERVICE_WORKER;
+  static constexpr auto THREAD_NETWORK_SERVICE = ChromeThreadDescriptor_ThreadType_THREAD_NETWORK_SERVICE;
+  static constexpr auto THREAD_CHILD_IO = ChromeThreadDescriptor_ThreadType_THREAD_CHILD_IO;
+  static constexpr auto THREAD_BROWSER_IO = ChromeThreadDescriptor_ThreadType_THREAD_BROWSER_IO;
+  static constexpr auto THREAD_BROWSER_MAIN = ChromeThreadDescriptor_ThreadType_THREAD_BROWSER_MAIN;
+  static constexpr auto THREAD_RENDERER_MAIN = ChromeThreadDescriptor_ThreadType_THREAD_RENDERER_MAIN;
+  static constexpr auto THREAD_UTILITY_MAIN = ChromeThreadDescriptor_ThreadType_THREAD_UTILITY_MAIN;
+  static constexpr auto THREAD_GPU_MAIN = ChromeThreadDescriptor_ThreadType_THREAD_GPU_MAIN;
+  static constexpr auto THREAD_CACHE_BLOCKFILE = ChromeThreadDescriptor_ThreadType_THREAD_CACHE_BLOCKFILE;
+  static constexpr auto THREAD_MEDIA = ChromeThreadDescriptor_ThreadType_THREAD_MEDIA;
+  static constexpr auto THREAD_AUDIO_OUTPUTDEVICE = ChromeThreadDescriptor_ThreadType_THREAD_AUDIO_OUTPUTDEVICE;
+  static constexpr auto THREAD_AUDIO_INPUTDEVICE = ChromeThreadDescriptor_ThreadType_THREAD_AUDIO_INPUTDEVICE;
+  static constexpr auto THREAD_GPU_MEMORY = ChromeThreadDescriptor_ThreadType_THREAD_GPU_MEMORY;
+  static constexpr auto THREAD_GPU_VSYNC = ChromeThreadDescriptor_ThreadType_THREAD_GPU_VSYNC;
+  static constexpr auto THREAD_DXA_VIDEODECODER = ChromeThreadDescriptor_ThreadType_THREAD_DXA_VIDEODECODER;
+  static constexpr auto THREAD_BROWSER_WATCHDOG = ChromeThreadDescriptor_ThreadType_THREAD_BROWSER_WATCHDOG;
+  static constexpr auto THREAD_WEBRTC_NETWORK = ChromeThreadDescriptor_ThreadType_THREAD_WEBRTC_NETWORK;
+  static constexpr auto THREAD_WINDOW_OWNER = ChromeThreadDescriptor_ThreadType_THREAD_WINDOW_OWNER;
+  static constexpr auto THREAD_WEBRTC_SIGNALING = ChromeThreadDescriptor_ThreadType_THREAD_WEBRTC_SIGNALING;
+  static constexpr auto THREAD_WEBRTC_WORKER = ChromeThreadDescriptor_ThreadType_THREAD_WEBRTC_WORKER;
+  static constexpr auto THREAD_PPAPI_MAIN = ChromeThreadDescriptor_ThreadType_THREAD_PPAPI_MAIN;
+  static constexpr auto THREAD_GPU_WATCHDOG = ChromeThreadDescriptor_ThreadType_THREAD_GPU_WATCHDOG;
+  static constexpr auto THREAD_SWAPPER = ChromeThreadDescriptor_ThreadType_THREAD_SWAPPER;
+  static constexpr auto THREAD_GAMEPAD_POLLING = ChromeThreadDescriptor_ThreadType_THREAD_GAMEPAD_POLLING;
+  static constexpr auto THREAD_WEBCRYPTO = ChromeThreadDescriptor_ThreadType_THREAD_WEBCRYPTO;
+  static constexpr auto THREAD_DATABASE = ChromeThreadDescriptor_ThreadType_THREAD_DATABASE;
+  static constexpr auto THREAD_PROXYRESOLVER = ChromeThreadDescriptor_ThreadType_THREAD_PROXYRESOLVER;
+  static constexpr auto THREAD_DEVTOOLSADB = ChromeThreadDescriptor_ThreadType_THREAD_DEVTOOLSADB;
+  static constexpr auto THREAD_NETWORKCONFIGWATCHER = ChromeThreadDescriptor_ThreadType_THREAD_NETWORKCONFIGWATCHER;
+  static constexpr auto THREAD_WASAPI_RENDER = ChromeThreadDescriptor_ThreadType_THREAD_WASAPI_RENDER;
+  static constexpr auto THREAD_LOADER_LOCK_SAMPLER = ChromeThreadDescriptor_ThreadType_THREAD_LOADER_LOCK_SAMPLER;
+  static constexpr auto THREAD_MEMORY_INFRA = ChromeThreadDescriptor_ThreadType_THREAD_MEMORY_INFRA;
+  static constexpr auto THREAD_SAMPLING_PROFILER = ChromeThreadDescriptor_ThreadType_THREAD_SAMPLING_PROFILER;
+  static constexpr auto ThreadType_MIN = ChromeThreadDescriptor_ThreadType_THREAD_UNSPECIFIED;
+  static constexpr auto ThreadType_MAX = ChromeThreadDescriptor_ThreadType_THREAD_SAMPLING_PROFILER;
+  enum FieldNumbers {
+    kThreadTypeFieldNumber = 1,
+    kLegacySortIndexFieldNumber = 2,
+  };
+
+  ChromeThreadDescriptor();
+  ~ChromeThreadDescriptor() override;
+  ChromeThreadDescriptor(ChromeThreadDescriptor&&) noexcept;
+  ChromeThreadDescriptor& operator=(ChromeThreadDescriptor&&);
+  ChromeThreadDescriptor(const ChromeThreadDescriptor&);
+  ChromeThreadDescriptor& operator=(const ChromeThreadDescriptor&);
+  bool operator==(const ChromeThreadDescriptor&) const;
+  bool operator!=(const ChromeThreadDescriptor& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_thread_type() const { return _has_field_[1]; }
+  ChromeThreadDescriptor_ThreadType thread_type() const { return thread_type_; }
+  void set_thread_type(ChromeThreadDescriptor_ThreadType value) { thread_type_ = value; _has_field_.set(1); }
+
+  bool has_legacy_sort_index() const { return _has_field_[2]; }
+  int32_t legacy_sort_index() const { return legacy_sort_index_; }
+  void set_legacy_sort_index(int32_t value) { legacy_sort_index_ = value; _has_field_.set(2); }
+
+ private:
+  ChromeThreadDescriptor_ThreadType thread_type_{};
+  int32_t legacy_sort_index_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_THREAD_DESCRIPTOR_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_user_event.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_USER_EVENT_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_USER_EVENT_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ChromeUserEvent;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT ChromeUserEvent : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kActionFieldNumber = 1,
+    kActionHashFieldNumber = 2,
+  };
+
+  ChromeUserEvent();
+  ~ChromeUserEvent() override;
+  ChromeUserEvent(ChromeUserEvent&&) noexcept;
+  ChromeUserEvent& operator=(ChromeUserEvent&&);
+  ChromeUserEvent(const ChromeUserEvent&);
+  ChromeUserEvent& operator=(const ChromeUserEvent&);
+  bool operator==(const ChromeUserEvent&) const;
+  bool operator!=(const ChromeUserEvent& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_action() const { return _has_field_[1]; }
+  const std::string& action() const { return action_; }
+  void set_action(const std::string& value) { action_ = value; _has_field_.set(1); }
+
+  bool has_action_hash() const { return _has_field_[2]; }
+  uint64_t action_hash() const { return action_hash_; }
+  void set_action_hash(uint64_t value) { action_hash_ = value; _has_field_.set(2); }
+
+ private:
+  std::string action_{};
+  uint64_t action_hash_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_USER_EVENT_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_window_handle_event_info.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_WINDOW_HANDLE_EVENT_INFO_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_WINDOW_HANDLE_EVENT_INFO_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ChromeWindowHandleEventInfo;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT ChromeWindowHandleEventInfo : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDpiFieldNumber = 1,
+    kMessageIdFieldNumber = 2,
+    kHwndPtrFieldNumber = 3,
+  };
+
+  ChromeWindowHandleEventInfo();
+  ~ChromeWindowHandleEventInfo() override;
+  ChromeWindowHandleEventInfo(ChromeWindowHandleEventInfo&&) noexcept;
+  ChromeWindowHandleEventInfo& operator=(ChromeWindowHandleEventInfo&&);
+  ChromeWindowHandleEventInfo(const ChromeWindowHandleEventInfo&);
+  ChromeWindowHandleEventInfo& operator=(const ChromeWindowHandleEventInfo&);
+  bool operator==(const ChromeWindowHandleEventInfo&) const;
+  bool operator!=(const ChromeWindowHandleEventInfo& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_dpi() const { return _has_field_[1]; }
+  uint32_t dpi() const { return dpi_; }
+  void set_dpi(uint32_t value) { dpi_ = value; _has_field_.set(1); }
+
+  bool has_message_id() const { return _has_field_[2]; }
+  uint32_t message_id() const { return message_id_; }
+  void set_message_id(uint32_t value) { message_id_ = value; _has_field_.set(2); }
+
+  bool has_hwnd_ptr() const { return _has_field_[3]; }
+  uint64_t hwnd_ptr() const { return hwnd_ptr_; }
+  void set_hwnd_ptr(uint64_t value) { hwnd_ptr_ = value; _has_field_.set(3); }
+
+ private:
+  uint32_t dpi_{};
+  uint32_t message_id_{};
+  uint64_t hwnd_ptr_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_WINDOW_HANDLE_EVENT_INFO_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/debug_annotation.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_DEBUG_ANNOTATION_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_DEBUG_ANNOTATION_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class DebugAnnotationValueTypeName;
+class DebugAnnotationName;
+class DebugAnnotation;
+class DebugAnnotation_NestedValue;
+enum DebugAnnotation_NestedValue_NestedType : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum DebugAnnotation_NestedValue_NestedType : int {
+  DebugAnnotation_NestedValue_NestedType_UNSPECIFIED = 0,
+  DebugAnnotation_NestedValue_NestedType_DICT = 1,
+  DebugAnnotation_NestedValue_NestedType_ARRAY = 2,
+};
+
+class PERFETTO_EXPORT_COMPONENT DebugAnnotationValueTypeName : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kIidFieldNumber = 1,
+    kNameFieldNumber = 2,
+  };
+
+  DebugAnnotationValueTypeName();
+  ~DebugAnnotationValueTypeName() override;
+  DebugAnnotationValueTypeName(DebugAnnotationValueTypeName&&) noexcept;
+  DebugAnnotationValueTypeName& operator=(DebugAnnotationValueTypeName&&);
+  DebugAnnotationValueTypeName(const DebugAnnotationValueTypeName&);
+  DebugAnnotationValueTypeName& operator=(const DebugAnnotationValueTypeName&);
+  bool operator==(const DebugAnnotationValueTypeName&) const;
+  bool operator!=(const DebugAnnotationValueTypeName& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_iid() const { return _has_field_[1]; }
+  uint64_t iid() const { return iid_; }
+  void set_iid(uint64_t value) { iid_ = value; _has_field_.set(1); }
+
+  bool has_name() const { return _has_field_[2]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
+
+ private:
+  uint64_t iid_{};
+  std::string name_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT DebugAnnotationName : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kIidFieldNumber = 1,
+    kNameFieldNumber = 2,
+  };
+
+  DebugAnnotationName();
+  ~DebugAnnotationName() override;
+  DebugAnnotationName(DebugAnnotationName&&) noexcept;
+  DebugAnnotationName& operator=(DebugAnnotationName&&);
+  DebugAnnotationName(const DebugAnnotationName&);
+  DebugAnnotationName& operator=(const DebugAnnotationName&);
+  bool operator==(const DebugAnnotationName&) const;
+  bool operator!=(const DebugAnnotationName& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_iid() const { return _has_field_[1]; }
+  uint64_t iid() const { return iid_; }
+  void set_iid(uint64_t value) { iid_ = value; _has_field_.set(1); }
+
+  bool has_name() const { return _has_field_[2]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
+
+ private:
+  uint64_t iid_{};
+  std::string name_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT DebugAnnotation : public ::protozero::CppMessageObj {
+ public:
+  using NestedValue = DebugAnnotation_NestedValue;
+  enum FieldNumbers {
+    kNameIidFieldNumber = 1,
+    kNameFieldNumber = 10,
+    kBoolValueFieldNumber = 2,
+    kUintValueFieldNumber = 3,
+    kIntValueFieldNumber = 4,
+    kDoubleValueFieldNumber = 5,
+    kPointerValueFieldNumber = 7,
+    kNestedValueFieldNumber = 8,
+    kLegacyJsonValueFieldNumber = 9,
+    kStringValueFieldNumber = 6,
+    kStringValueIidFieldNumber = 17,
+    kProtoTypeNameFieldNumber = 16,
+    kProtoTypeNameIidFieldNumber = 13,
+    kProtoValueFieldNumber = 14,
+    kDictEntriesFieldNumber = 11,
+    kArrayValuesFieldNumber = 12,
+  };
+
+  DebugAnnotation();
+  ~DebugAnnotation() override;
+  DebugAnnotation(DebugAnnotation&&) noexcept;
+  DebugAnnotation& operator=(DebugAnnotation&&);
+  DebugAnnotation(const DebugAnnotation&);
+  DebugAnnotation& operator=(const DebugAnnotation&);
+  bool operator==(const DebugAnnotation&) const;
+  bool operator!=(const DebugAnnotation& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name_iid() const { return _has_field_[1]; }
+  uint64_t name_iid() const { return name_iid_; }
+  void set_name_iid(uint64_t value) { name_iid_ = value; _has_field_.set(1); }
+
+  bool has_name() const { return _has_field_[10]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(10); }
+
+  bool has_bool_value() const { return _has_field_[2]; }
+  bool bool_value() const { return bool_value_; }
+  void set_bool_value(bool value) { bool_value_ = value; _has_field_.set(2); }
+
+  bool has_uint_value() const { return _has_field_[3]; }
+  uint64_t uint_value() const { return uint_value_; }
+  void set_uint_value(uint64_t value) { uint_value_ = value; _has_field_.set(3); }
+
+  bool has_int_value() const { return _has_field_[4]; }
+  int64_t int_value() const { return int_value_; }
+  void set_int_value(int64_t value) { int_value_ = value; _has_field_.set(4); }
+
+  bool has_double_value() const { return _has_field_[5]; }
+  double double_value() const { return double_value_; }
+  void set_double_value(double value) { double_value_ = value; _has_field_.set(5); }
+
+  bool has_pointer_value() const { return _has_field_[7]; }
+  uint64_t pointer_value() const { return pointer_value_; }
+  void set_pointer_value(uint64_t value) { pointer_value_ = value; _has_field_.set(7); }
+
+  bool has_nested_value() const { return _has_field_[8]; }
+  const DebugAnnotation_NestedValue& nested_value() const { return *nested_value_; }
+  DebugAnnotation_NestedValue* mutable_nested_value() { _has_field_.set(8); return nested_value_.get(); }
+
+  bool has_legacy_json_value() const { return _has_field_[9]; }
+  const std::string& legacy_json_value() const { return legacy_json_value_; }
+  void set_legacy_json_value(const std::string& value) { legacy_json_value_ = value; _has_field_.set(9); }
+
+  bool has_string_value() const { return _has_field_[6]; }
+  const std::string& string_value() const { return string_value_; }
+  void set_string_value(const std::string& value) { string_value_ = value; _has_field_.set(6); }
+
+  bool has_string_value_iid() const { return _has_field_[17]; }
+  uint64_t string_value_iid() const { return string_value_iid_; }
+  void set_string_value_iid(uint64_t value) { string_value_iid_ = value; _has_field_.set(17); }
+
+  bool has_proto_type_name() const { return _has_field_[16]; }
+  const std::string& proto_type_name() const { return proto_type_name_; }
+  void set_proto_type_name(const std::string& value) { proto_type_name_ = value; _has_field_.set(16); }
+
+  bool has_proto_type_name_iid() const { return _has_field_[13]; }
+  uint64_t proto_type_name_iid() const { return proto_type_name_iid_; }
+  void set_proto_type_name_iid(uint64_t value) { proto_type_name_iid_ = value; _has_field_.set(13); }
+
+  bool has_proto_value() const { return _has_field_[14]; }
+  const std::string& proto_value() const { return proto_value_; }
+  void set_proto_value(const std::string& value) { proto_value_ = value; _has_field_.set(14); }
+  void set_proto_value(const void* p, size_t s) { proto_value_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(14); }
+
+  const std::vector<DebugAnnotation>& dict_entries() const { return dict_entries_; }
+  std::vector<DebugAnnotation>* mutable_dict_entries() { return &dict_entries_; }
+  int dict_entries_size() const;
+  void clear_dict_entries();
+  DebugAnnotation* add_dict_entries();
+
+  const std::vector<DebugAnnotation>& array_values() const { return array_values_; }
+  std::vector<DebugAnnotation>* mutable_array_values() { return &array_values_; }
+  int array_values_size() const;
+  void clear_array_values();
+  DebugAnnotation* add_array_values();
+
+ private:
+  uint64_t name_iid_{};
+  std::string name_{};
+  bool bool_value_{};
+  uint64_t uint_value_{};
+  int64_t int_value_{};
+  double double_value_{};
+  uint64_t pointer_value_{};
+  ::protozero::CopyablePtr<DebugAnnotation_NestedValue> nested_value_;
+  std::string legacy_json_value_{};
+  std::string string_value_{};
+  uint64_t string_value_iid_{};
+  std::string proto_type_name_{};
+  uint64_t proto_type_name_iid_{};
+  std::string proto_value_{};
+  std::vector<DebugAnnotation> dict_entries_;
+  std::vector<DebugAnnotation> array_values_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<18> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT DebugAnnotation_NestedValue : public ::protozero::CppMessageObj {
+ public:
+  using NestedType = DebugAnnotation_NestedValue_NestedType;
+  static constexpr auto UNSPECIFIED = DebugAnnotation_NestedValue_NestedType_UNSPECIFIED;
+  static constexpr auto DICT = DebugAnnotation_NestedValue_NestedType_DICT;
+  static constexpr auto ARRAY = DebugAnnotation_NestedValue_NestedType_ARRAY;
+  static constexpr auto NestedType_MIN = DebugAnnotation_NestedValue_NestedType_UNSPECIFIED;
+  static constexpr auto NestedType_MAX = DebugAnnotation_NestedValue_NestedType_ARRAY;
+  enum FieldNumbers {
+    kNestedTypeFieldNumber = 1,
+    kDictKeysFieldNumber = 2,
+    kDictValuesFieldNumber = 3,
+    kArrayValuesFieldNumber = 4,
+    kIntValueFieldNumber = 5,
+    kDoubleValueFieldNumber = 6,
+    kBoolValueFieldNumber = 7,
+    kStringValueFieldNumber = 8,
+  };
+
+  DebugAnnotation_NestedValue();
+  ~DebugAnnotation_NestedValue() override;
+  DebugAnnotation_NestedValue(DebugAnnotation_NestedValue&&) noexcept;
+  DebugAnnotation_NestedValue& operator=(DebugAnnotation_NestedValue&&);
+  DebugAnnotation_NestedValue(const DebugAnnotation_NestedValue&);
+  DebugAnnotation_NestedValue& operator=(const DebugAnnotation_NestedValue&);
+  bool operator==(const DebugAnnotation_NestedValue&) const;
+  bool operator!=(const DebugAnnotation_NestedValue& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_nested_type() const { return _has_field_[1]; }
+  DebugAnnotation_NestedValue_NestedType nested_type() const { return nested_type_; }
+  void set_nested_type(DebugAnnotation_NestedValue_NestedType value) { nested_type_ = value; _has_field_.set(1); }
+
+  const std::vector<std::string>& dict_keys() const { return dict_keys_; }
+  std::vector<std::string>* mutable_dict_keys() { return &dict_keys_; }
+  int dict_keys_size() const { return static_cast<int>(dict_keys_.size()); }
+  void clear_dict_keys() { dict_keys_.clear(); }
+  void add_dict_keys(std::string value) { dict_keys_.emplace_back(value); }
+  std::string* add_dict_keys() { dict_keys_.emplace_back(); return &dict_keys_.back(); }
+
+  const std::vector<DebugAnnotation_NestedValue>& dict_values() const { return dict_values_; }
+  std::vector<DebugAnnotation_NestedValue>* mutable_dict_values() { return &dict_values_; }
+  int dict_values_size() const;
+  void clear_dict_values();
+  DebugAnnotation_NestedValue* add_dict_values();
+
+  const std::vector<DebugAnnotation_NestedValue>& array_values() const { return array_values_; }
+  std::vector<DebugAnnotation_NestedValue>* mutable_array_values() { return &array_values_; }
+  int array_values_size() const;
+  void clear_array_values();
+  DebugAnnotation_NestedValue* add_array_values();
+
+  bool has_int_value() const { return _has_field_[5]; }
+  int64_t int_value() const { return int_value_; }
+  void set_int_value(int64_t value) { int_value_ = value; _has_field_.set(5); }
+
+  bool has_double_value() const { return _has_field_[6]; }
+  double double_value() const { return double_value_; }
+  void set_double_value(double value) { double_value_ = value; _has_field_.set(6); }
+
+  bool has_bool_value() const { return _has_field_[7]; }
+  bool bool_value() const { return bool_value_; }
+  void set_bool_value(bool value) { bool_value_ = value; _has_field_.set(7); }
+
+  bool has_string_value() const { return _has_field_[8]; }
+  const std::string& string_value() const { return string_value_; }
+  void set_string_value(const std::string& value) { string_value_ = value; _has_field_.set(8); }
+
+ private:
+  DebugAnnotation_NestedValue_NestedType nested_type_{};
+  std::vector<std::string> dict_keys_;
+  std::vector<DebugAnnotation_NestedValue> dict_values_;
+  std::vector<DebugAnnotation_NestedValue> array_values_;
+  int64_t int_value_{};
+  double double_value_{};
+  bool bool_value_{};
+  std::string string_value_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<9> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_DEBUG_ANNOTATION_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/log_message.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_LOG_MESSAGE_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_LOG_MESSAGE_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class LogMessageBody;
+class LogMessage;
+enum LogMessage_Priority : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum LogMessage_Priority : int {
+  LogMessage_Priority_PRIO_UNSPECIFIED = 0,
+  LogMessage_Priority_PRIO_UNUSED = 1,
+  LogMessage_Priority_PRIO_VERBOSE = 2,
+  LogMessage_Priority_PRIO_DEBUG = 3,
+  LogMessage_Priority_PRIO_INFO = 4,
+  LogMessage_Priority_PRIO_WARN = 5,
+  LogMessage_Priority_PRIO_ERROR = 6,
+  LogMessage_Priority_PRIO_FATAL = 7,
+};
+
+class PERFETTO_EXPORT_COMPONENT LogMessageBody : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kIidFieldNumber = 1,
+    kBodyFieldNumber = 2,
+  };
+
+  LogMessageBody();
+  ~LogMessageBody() override;
+  LogMessageBody(LogMessageBody&&) noexcept;
+  LogMessageBody& operator=(LogMessageBody&&);
+  LogMessageBody(const LogMessageBody&);
+  LogMessageBody& operator=(const LogMessageBody&);
+  bool operator==(const LogMessageBody&) const;
+  bool operator!=(const LogMessageBody& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_iid() const { return _has_field_[1]; }
+  uint64_t iid() const { return iid_; }
+  void set_iid(uint64_t value) { iid_ = value; _has_field_.set(1); }
+
+  bool has_body() const { return _has_field_[2]; }
+  const std::string& body() const { return body_; }
+  void set_body(const std::string& value) { body_ = value; _has_field_.set(2); }
+
+ private:
+  uint64_t iid_{};
+  std::string body_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT LogMessage : public ::protozero::CppMessageObj {
+ public:
+  using Priority = LogMessage_Priority;
+  static constexpr auto PRIO_UNSPECIFIED = LogMessage_Priority_PRIO_UNSPECIFIED;
+  static constexpr auto PRIO_UNUSED = LogMessage_Priority_PRIO_UNUSED;
+  static constexpr auto PRIO_VERBOSE = LogMessage_Priority_PRIO_VERBOSE;
+  static constexpr auto PRIO_DEBUG = LogMessage_Priority_PRIO_DEBUG;
+  static constexpr auto PRIO_INFO = LogMessage_Priority_PRIO_INFO;
+  static constexpr auto PRIO_WARN = LogMessage_Priority_PRIO_WARN;
+  static constexpr auto PRIO_ERROR = LogMessage_Priority_PRIO_ERROR;
+  static constexpr auto PRIO_FATAL = LogMessage_Priority_PRIO_FATAL;
+  static constexpr auto Priority_MIN = LogMessage_Priority_PRIO_UNSPECIFIED;
+  static constexpr auto Priority_MAX = LogMessage_Priority_PRIO_FATAL;
+  enum FieldNumbers {
+    kSourceLocationIidFieldNumber = 1,
+    kBodyIidFieldNumber = 2,
+    kPrioFieldNumber = 3,
+  };
+
+  LogMessage();
+  ~LogMessage() override;
+  LogMessage(LogMessage&&) noexcept;
+  LogMessage& operator=(LogMessage&&);
+  LogMessage(const LogMessage&);
+  LogMessage& operator=(const LogMessage&);
+  bool operator==(const LogMessage&) const;
+  bool operator!=(const LogMessage& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_source_location_iid() const { return _has_field_[1]; }
+  uint64_t source_location_iid() const { return source_location_iid_; }
+  void set_source_location_iid(uint64_t value) { source_location_iid_ = value; _has_field_.set(1); }
+
+  bool has_body_iid() const { return _has_field_[2]; }
+  uint64_t body_iid() const { return body_iid_; }
+  void set_body_iid(uint64_t value) { body_iid_ = value; _has_field_.set(2); }
+
+  bool has_prio() const { return _has_field_[3]; }
+  LogMessage_Priority prio() const { return prio_; }
+  void set_prio(LogMessage_Priority value) { prio_ = value; _has_field_.set(3); }
+
+ private:
+  uint64_t source_location_iid_{};
+  uint64_t body_iid_{};
+  LogMessage_Priority prio_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_LOG_MESSAGE_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/pixel_modem.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_PIXEL_MODEM_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_PIXEL_MODEM_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class PixelModemEventInsight;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT PixelModemEventInsight : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDetokenizedMessageFieldNumber = 1,
+  };
+
+  PixelModemEventInsight();
+  ~PixelModemEventInsight() override;
+  PixelModemEventInsight(PixelModemEventInsight&&) noexcept;
+  PixelModemEventInsight& operator=(PixelModemEventInsight&&);
+  PixelModemEventInsight(const PixelModemEventInsight&);
+  PixelModemEventInsight& operator=(const PixelModemEventInsight&);
+  bool operator==(const PixelModemEventInsight&) const;
+  bool operator!=(const PixelModemEventInsight& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_detokenized_message() const { return _has_field_[1]; }
+  const std::string& detokenized_message() const { return detokenized_message_; }
+  void set_detokenized_message(const std::string& value) { detokenized_message_ = value; _has_field_.set(1); }
+
+ private:
+  std::string detokenized_message_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_PIXEL_MODEM_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/process_descriptor.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_PROCESS_DESCRIPTOR_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_PROCESS_DESCRIPTOR_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ProcessDescriptor;
+enum ProcessDescriptor_ChromeProcessType : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum ProcessDescriptor_ChromeProcessType : int {
+  ProcessDescriptor_ChromeProcessType_PROCESS_UNSPECIFIED = 0,
+  ProcessDescriptor_ChromeProcessType_PROCESS_BROWSER = 1,
+  ProcessDescriptor_ChromeProcessType_PROCESS_RENDERER = 2,
+  ProcessDescriptor_ChromeProcessType_PROCESS_UTILITY = 3,
+  ProcessDescriptor_ChromeProcessType_PROCESS_ZYGOTE = 4,
+  ProcessDescriptor_ChromeProcessType_PROCESS_SANDBOX_HELPER = 5,
+  ProcessDescriptor_ChromeProcessType_PROCESS_GPU = 6,
+  ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_PLUGIN = 7,
+  ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_BROKER = 8,
+};
+
+class PERFETTO_EXPORT_COMPONENT ProcessDescriptor : public ::protozero::CppMessageObj {
+ public:
+  using ChromeProcessType = ProcessDescriptor_ChromeProcessType;
+  static constexpr auto PROCESS_UNSPECIFIED = ProcessDescriptor_ChromeProcessType_PROCESS_UNSPECIFIED;
+  static constexpr auto PROCESS_BROWSER = ProcessDescriptor_ChromeProcessType_PROCESS_BROWSER;
+  static constexpr auto PROCESS_RENDERER = ProcessDescriptor_ChromeProcessType_PROCESS_RENDERER;
+  static constexpr auto PROCESS_UTILITY = ProcessDescriptor_ChromeProcessType_PROCESS_UTILITY;
+  static constexpr auto PROCESS_ZYGOTE = ProcessDescriptor_ChromeProcessType_PROCESS_ZYGOTE;
+  static constexpr auto PROCESS_SANDBOX_HELPER = ProcessDescriptor_ChromeProcessType_PROCESS_SANDBOX_HELPER;
+  static constexpr auto PROCESS_GPU = ProcessDescriptor_ChromeProcessType_PROCESS_GPU;
+  static constexpr auto PROCESS_PPAPI_PLUGIN = ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_PLUGIN;
+  static constexpr auto PROCESS_PPAPI_BROKER = ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_BROKER;
+  static constexpr auto ChromeProcessType_MIN = ProcessDescriptor_ChromeProcessType_PROCESS_UNSPECIFIED;
+  static constexpr auto ChromeProcessType_MAX = ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_BROKER;
+  enum FieldNumbers {
+    kPidFieldNumber = 1,
+    kCmdlineFieldNumber = 2,
+    kProcessNameFieldNumber = 6,
+    kProcessPriorityFieldNumber = 5,
+    kStartTimestampNsFieldNumber = 7,
+    kChromeProcessTypeFieldNumber = 4,
+    kLegacySortIndexFieldNumber = 3,
+    kProcessLabelsFieldNumber = 8,
+  };
+
+  ProcessDescriptor();
+  ~ProcessDescriptor() override;
+  ProcessDescriptor(ProcessDescriptor&&) noexcept;
+  ProcessDescriptor& operator=(ProcessDescriptor&&);
+  ProcessDescriptor(const ProcessDescriptor&);
+  ProcessDescriptor& operator=(const ProcessDescriptor&);
+  bool operator==(const ProcessDescriptor&) const;
+  bool operator!=(const ProcessDescriptor& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_pid() const { return _has_field_[1]; }
+  int32_t pid() const { return pid_; }
+  void set_pid(int32_t value) { pid_ = value; _has_field_.set(1); }
+
+  const std::vector<std::string>& cmdline() const { return cmdline_; }
+  std::vector<std::string>* mutable_cmdline() { return &cmdline_; }
+  int cmdline_size() const { return static_cast<int>(cmdline_.size()); }
+  void clear_cmdline() { cmdline_.clear(); }
+  void add_cmdline(std::string value) { cmdline_.emplace_back(value); }
+  std::string* add_cmdline() { cmdline_.emplace_back(); return &cmdline_.back(); }
+
+  bool has_process_name() const { return _has_field_[6]; }
+  const std::string& process_name() const { return process_name_; }
+  void set_process_name(const std::string& value) { process_name_ = value; _has_field_.set(6); }
+
+  bool has_process_priority() const { return _has_field_[5]; }
+  int32_t process_priority() const { return process_priority_; }
+  void set_process_priority(int32_t value) { process_priority_ = value; _has_field_.set(5); }
+
+  bool has_start_timestamp_ns() const { return _has_field_[7]; }
+  int64_t start_timestamp_ns() const { return start_timestamp_ns_; }
+  void set_start_timestamp_ns(int64_t value) { start_timestamp_ns_ = value; _has_field_.set(7); }
+
+  bool has_chrome_process_type() const { return _has_field_[4]; }
+  ProcessDescriptor_ChromeProcessType chrome_process_type() const { return chrome_process_type_; }
+  void set_chrome_process_type(ProcessDescriptor_ChromeProcessType value) { chrome_process_type_ = value; _has_field_.set(4); }
+
+  bool has_legacy_sort_index() const { return _has_field_[3]; }
+  int32_t legacy_sort_index() const { return legacy_sort_index_; }
+  void set_legacy_sort_index(int32_t value) { legacy_sort_index_ = value; _has_field_.set(3); }
+
+  const std::vector<std::string>& process_labels() const { return process_labels_; }
+  std::vector<std::string>* mutable_process_labels() { return &process_labels_; }
+  int process_labels_size() const { return static_cast<int>(process_labels_.size()); }
+  void clear_process_labels() { process_labels_.clear(); }
+  void add_process_labels(std::string value) { process_labels_.emplace_back(value); }
+  std::string* add_process_labels() { process_labels_.emplace_back(); return &process_labels_.back(); }
+
+ private:
+  int32_t pid_{};
+  std::vector<std::string> cmdline_;
+  std::string process_name_{};
+  int32_t process_priority_{};
+  int64_t start_timestamp_ns_{};
+  ProcessDescriptor_ChromeProcessType chrome_process_type_{};
+  int32_t legacy_sort_index_{};
+  std::vector<std::string> process_labels_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<9> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_PROCESS_DESCRIPTOR_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/range_of_interest.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_RANGE_OF_INTEREST_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_RANGE_OF_INTEREST_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class TrackEventRangeOfInterest;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT TrackEventRangeOfInterest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kStartUsFieldNumber = 1,
+  };
+
+  TrackEventRangeOfInterest();
+  ~TrackEventRangeOfInterest() override;
+  TrackEventRangeOfInterest(TrackEventRangeOfInterest&&) noexcept;
+  TrackEventRangeOfInterest& operator=(TrackEventRangeOfInterest&&);
+  TrackEventRangeOfInterest(const TrackEventRangeOfInterest&);
+  TrackEventRangeOfInterest& operator=(const TrackEventRangeOfInterest&);
+  bool operator==(const TrackEventRangeOfInterest&) const;
+  bool operator!=(const TrackEventRangeOfInterest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_start_us() const { return _has_field_[1]; }
+  int64_t start_us() const { return start_us_; }
+  void set_start_us(int64_t value) { start_us_ = value; _has_field_.set(1); }
+
+ private:
+  int64_t start_us_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_RANGE_OF_INTEREST_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/screenshot.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_SCREENSHOT_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_SCREENSHOT_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class Screenshot;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT Screenshot : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kJpgImageFieldNumber = 1,
+  };
+
+  Screenshot();
+  ~Screenshot() override;
+  Screenshot(Screenshot&&) noexcept;
+  Screenshot& operator=(Screenshot&&);
+  Screenshot(const Screenshot&);
+  Screenshot& operator=(const Screenshot&);
+  bool operator==(const Screenshot&) const;
+  bool operator!=(const Screenshot& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_jpg_image() const { return _has_field_[1]; }
+  const std::string& jpg_image() const { return jpg_image_; }
+  void set_jpg_image(const std::string& value) { jpg_image_ = value; _has_field_.set(1); }
+  void set_jpg_image(const void* p, size_t s) { jpg_image_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(1); }
+
+ private:
+  std::string jpg_image_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_SCREENSHOT_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/source_location.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_SOURCE_LOCATION_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_SOURCE_LOCATION_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class SourceLocation;
+class UnsymbolizedSourceLocation;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT SourceLocation : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kIidFieldNumber = 1,
+    kFileNameFieldNumber = 2,
+    kFunctionNameFieldNumber = 3,
+    kLineNumberFieldNumber = 4,
+  };
+
+  SourceLocation();
+  ~SourceLocation() override;
+  SourceLocation(SourceLocation&&) noexcept;
+  SourceLocation& operator=(SourceLocation&&);
+  SourceLocation(const SourceLocation&);
+  SourceLocation& operator=(const SourceLocation&);
+  bool operator==(const SourceLocation&) const;
+  bool operator!=(const SourceLocation& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_iid() const { return _has_field_[1]; }
+  uint64_t iid() const { return iid_; }
+  void set_iid(uint64_t value) { iid_ = value; _has_field_.set(1); }
+
+  bool has_file_name() const { return _has_field_[2]; }
+  const std::string& file_name() const { return file_name_; }
+  void set_file_name(const std::string& value) { file_name_ = value; _has_field_.set(2); }
+
+  bool has_function_name() const { return _has_field_[3]; }
+  const std::string& function_name() const { return function_name_; }
+  void set_function_name(const std::string& value) { function_name_ = value; _has_field_.set(3); }
+
+  bool has_line_number() const { return _has_field_[4]; }
+  uint32_t line_number() const { return line_number_; }
+  void set_line_number(uint32_t value) { line_number_ = value; _has_field_.set(4); }
+
+ private:
+  uint64_t iid_{};
+  std::string file_name_{};
+  std::string function_name_{};
+  uint32_t line_number_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<5> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT UnsymbolizedSourceLocation : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kIidFieldNumber = 1,
+    kMappingIdFieldNumber = 2,
+    kRelPcFieldNumber = 3,
+  };
+
+  UnsymbolizedSourceLocation();
+  ~UnsymbolizedSourceLocation() override;
+  UnsymbolizedSourceLocation(UnsymbolizedSourceLocation&&) noexcept;
+  UnsymbolizedSourceLocation& operator=(UnsymbolizedSourceLocation&&);
+  UnsymbolizedSourceLocation(const UnsymbolizedSourceLocation&);
+  UnsymbolizedSourceLocation& operator=(const UnsymbolizedSourceLocation&);
+  bool operator==(const UnsymbolizedSourceLocation&) const;
+  bool operator!=(const UnsymbolizedSourceLocation& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_iid() const { return _has_field_[1]; }
+  uint64_t iid() const { return iid_; }
+  void set_iid(uint64_t value) { iid_ = value; _has_field_.set(1); }
+
+  bool has_mapping_id() const { return _has_field_[2]; }
+  uint64_t mapping_id() const { return mapping_id_; }
+  void set_mapping_id(uint64_t value) { mapping_id_ = value; _has_field_.set(2); }
+
+  bool has_rel_pc() const { return _has_field_[3]; }
+  uint64_t rel_pc() const { return rel_pc_; }
+  void set_rel_pc(uint64_t value) { rel_pc_ = value; _has_field_.set(3); }
+
+ private:
+  uint64_t iid_{};
+  uint64_t mapping_id_{};
+  uint64_t rel_pc_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_SOURCE_LOCATION_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/task_execution.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TASK_EXECUTION_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TASK_EXECUTION_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class TaskExecution;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT TaskExecution : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kPostedFromIidFieldNumber = 1,
+  };
+
+  TaskExecution();
+  ~TaskExecution() override;
+  TaskExecution(TaskExecution&&) noexcept;
+  TaskExecution& operator=(TaskExecution&&);
+  TaskExecution(const TaskExecution&);
+  TaskExecution& operator=(const TaskExecution&);
+  bool operator==(const TaskExecution&) const;
+  bool operator!=(const TaskExecution& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_posted_from_iid() const { return _has_field_[1]; }
+  uint64_t posted_from_iid() const { return posted_from_iid_; }
+  void set_posted_from_iid(uint64_t value) { posted_from_iid_ = value; _has_field_.set(1); }
+
+ private:
+  uint64_t posted_from_iid_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TASK_EXECUTION_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/thread_descriptor.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_THREAD_DESCRIPTOR_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_THREAD_DESCRIPTOR_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ThreadDescriptor;
+enum ThreadDescriptor_ChromeThreadType : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum ThreadDescriptor_ChromeThreadType : int {
+  ThreadDescriptor_ChromeThreadType_CHROME_THREAD_UNSPECIFIED = 0,
+  ThreadDescriptor_ChromeThreadType_CHROME_THREAD_MAIN = 1,
+  ThreadDescriptor_ChromeThreadType_CHROME_THREAD_IO = 2,
+  ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_BG_WORKER = 3,
+  ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_FG_WORKER = 4,
+  ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_FB_BLOCKING = 5,
+  ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_BG_BLOCKING = 6,
+  ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_SERVICE = 7,
+  ThreadDescriptor_ChromeThreadType_CHROME_THREAD_COMPOSITOR = 8,
+  ThreadDescriptor_ChromeThreadType_CHROME_THREAD_VIZ_COMPOSITOR = 9,
+  ThreadDescriptor_ChromeThreadType_CHROME_THREAD_COMPOSITOR_WORKER = 10,
+  ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SERVICE_WORKER = 11,
+  ThreadDescriptor_ChromeThreadType_CHROME_THREAD_MEMORY_INFRA = 50,
+  ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SAMPLING_PROFILER = 51,
+};
+
+class PERFETTO_EXPORT_COMPONENT ThreadDescriptor : public ::protozero::CppMessageObj {
+ public:
+  using ChromeThreadType = ThreadDescriptor_ChromeThreadType;
+  static constexpr auto CHROME_THREAD_UNSPECIFIED = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_UNSPECIFIED;
+  static constexpr auto CHROME_THREAD_MAIN = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_MAIN;
+  static constexpr auto CHROME_THREAD_IO = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_IO;
+  static constexpr auto CHROME_THREAD_POOL_BG_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_BG_WORKER;
+  static constexpr auto CHROME_THREAD_POOL_FG_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_FG_WORKER;
+  static constexpr auto CHROME_THREAD_POOL_FB_BLOCKING = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_FB_BLOCKING;
+  static constexpr auto CHROME_THREAD_POOL_BG_BLOCKING = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_BG_BLOCKING;
+  static constexpr auto CHROME_THREAD_POOL_SERVICE = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_SERVICE;
+  static constexpr auto CHROME_THREAD_COMPOSITOR = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_COMPOSITOR;
+  static constexpr auto CHROME_THREAD_VIZ_COMPOSITOR = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_VIZ_COMPOSITOR;
+  static constexpr auto CHROME_THREAD_COMPOSITOR_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_COMPOSITOR_WORKER;
+  static constexpr auto CHROME_THREAD_SERVICE_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SERVICE_WORKER;
+  static constexpr auto CHROME_THREAD_MEMORY_INFRA = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_MEMORY_INFRA;
+  static constexpr auto CHROME_THREAD_SAMPLING_PROFILER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SAMPLING_PROFILER;
+  static constexpr auto ChromeThreadType_MIN = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_UNSPECIFIED;
+  static constexpr auto ChromeThreadType_MAX = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SAMPLING_PROFILER;
+  enum FieldNumbers {
+    kPidFieldNumber = 1,
+    kTidFieldNumber = 2,
+    kThreadNameFieldNumber = 5,
+    kChromeThreadTypeFieldNumber = 4,
+    kReferenceTimestampUsFieldNumber = 6,
+    kReferenceThreadTimeUsFieldNumber = 7,
+    kReferenceThreadInstructionCountFieldNumber = 8,
+    kLegacySortIndexFieldNumber = 3,
+  };
+
+  ThreadDescriptor();
+  ~ThreadDescriptor() override;
+  ThreadDescriptor(ThreadDescriptor&&) noexcept;
+  ThreadDescriptor& operator=(ThreadDescriptor&&);
+  ThreadDescriptor(const ThreadDescriptor&);
+  ThreadDescriptor& operator=(const ThreadDescriptor&);
+  bool operator==(const ThreadDescriptor&) const;
+  bool operator!=(const ThreadDescriptor& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_pid() const { return _has_field_[1]; }
+  int32_t pid() const { return pid_; }
+  void set_pid(int32_t value) { pid_ = value; _has_field_.set(1); }
+
+  bool has_tid() const { return _has_field_[2]; }
+  int32_t tid() const { return tid_; }
+  void set_tid(int32_t value) { tid_ = value; _has_field_.set(2); }
+
+  bool has_thread_name() const { return _has_field_[5]; }
+  const std::string& thread_name() const { return thread_name_; }
+  void set_thread_name(const std::string& value) { thread_name_ = value; _has_field_.set(5); }
+
+  bool has_chrome_thread_type() const { return _has_field_[4]; }
+  ThreadDescriptor_ChromeThreadType chrome_thread_type() const { return chrome_thread_type_; }
+  void set_chrome_thread_type(ThreadDescriptor_ChromeThreadType value) { chrome_thread_type_ = value; _has_field_.set(4); }
+
+  bool has_reference_timestamp_us() const { return _has_field_[6]; }
+  int64_t reference_timestamp_us() const { return reference_timestamp_us_; }
+  void set_reference_timestamp_us(int64_t value) { reference_timestamp_us_ = value; _has_field_.set(6); }
+
+  bool has_reference_thread_time_us() const { return _has_field_[7]; }
+  int64_t reference_thread_time_us() const { return reference_thread_time_us_; }
+  void set_reference_thread_time_us(int64_t value) { reference_thread_time_us_ = value; _has_field_.set(7); }
+
+  bool has_reference_thread_instruction_count() const { return _has_field_[8]; }
+  int64_t reference_thread_instruction_count() const { return reference_thread_instruction_count_; }
+  void set_reference_thread_instruction_count(int64_t value) { reference_thread_instruction_count_ = value; _has_field_.set(8); }
+
+  bool has_legacy_sort_index() const { return _has_field_[3]; }
+  int32_t legacy_sort_index() const { return legacy_sort_index_; }
+  void set_legacy_sort_index(int32_t value) { legacy_sort_index_ = value; _has_field_.set(3); }
+
+ private:
+  int32_t pid_{};
+  int32_t tid_{};
+  std::string thread_name_{};
+  ThreadDescriptor_ChromeThreadType chrome_thread_type_{};
+  int64_t reference_timestamp_us_{};
+  int64_t reference_thread_time_us_{};
+  int64_t reference_thread_instruction_count_{};
+  int32_t legacy_sort_index_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<9> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_THREAD_DESCRIPTOR_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/track_event.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TRACK_EVENT_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TRACK_EVENT_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class EventName;
+class EventCategory;
+class TrackEventDefaults;
+class TrackEvent;
+class TrackEvent_LegacyEvent;
+class ChromeMojoEventInfo;
+class ChromeMessagePump;
+class SourceLocation;
+class PixelModemEventInsight;
+class Screenshot;
+class ChromeActiveProcesses;
+class ChromeContentSettingsEventInfo;
+class ChromeWindowHandleEventInfo;
+class ChromeRendererSchedulerState;
+class ChromeApplicationStateInfo;
+class ChromeFrameReporter;
+class ChromeLatencyInfo;
+class ChromeLatencyInfo_ComponentInfo;
+class ChromeHistogramSample;
+class ChromeLegacyIpc;
+class ChromeKeyedService;
+class ChromeUserEvent;
+class ChromeCompositorSchedulerState;
+class CompositorTimingHistory;
+class BeginFrameSourceState;
+class BeginFrameArgs;
+class BeginFrameObserverState;
+class BeginImplFrameArgs;
+class BeginImplFrameArgs_TimestampsInUs;
+class ChromeCompositorStateMachine;
+class ChromeCompositorStateMachine_MinorState;
+class ChromeCompositorStateMachine_MajorState;
+class LogMessage;
+class TaskExecution;
+class DebugAnnotation;
+class DebugAnnotation_NestedValue;
+enum TrackEvent_Type : int;
+enum TrackEvent_LegacyEvent_FlowDirection : int;
+enum TrackEvent_LegacyEvent_InstantEventScope : int;
+enum ChromeRAILMode : int;
+enum ChromeApplicationStateInfo_ChromeApplicationState : int;
+enum ChromeFrameReporter_State : int;
+enum ChromeFrameReporter_FrameDropReason : int;
+enum ChromeFrameReporter_ScrollState : int;
+enum ChromeFrameReporter_FrameType : int;
+enum ChromeLatencyInfo_Step : int;
+enum ChromeLatencyInfo_LatencyComponentType : int;
+enum ChromeLegacyIpc_MessageClass : int;
+enum ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode : int;
+enum ChromeCompositorSchedulerAction : int;
+enum BeginFrameArgs_BeginFrameArgsType : int;
+enum BeginImplFrameArgs_State : int;
+enum ChromeCompositorStateMachine_MinorState_TreePriority : int;
+enum ChromeCompositorStateMachine_MinorState_ScrollHandlerState : int;
+enum ChromeCompositorStateMachine_MajorState_BeginImplFrameState : int;
+enum ChromeCompositorStateMachine_MajorState_BeginMainFrameState : int;
+enum ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState : int;
+enum ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState : int;
+enum LogMessage_Priority : int;
+enum DebugAnnotation_NestedValue_NestedType : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum TrackEvent_Type : int {
+  TrackEvent_Type_TYPE_UNSPECIFIED = 0,
+  TrackEvent_Type_TYPE_SLICE_BEGIN = 1,
+  TrackEvent_Type_TYPE_SLICE_END = 2,
+  TrackEvent_Type_TYPE_INSTANT = 3,
+  TrackEvent_Type_TYPE_COUNTER = 4,
+};
+enum TrackEvent_LegacyEvent_FlowDirection : int {
+  TrackEvent_LegacyEvent_FlowDirection_FLOW_UNSPECIFIED = 0,
+  TrackEvent_LegacyEvent_FlowDirection_FLOW_IN = 1,
+  TrackEvent_LegacyEvent_FlowDirection_FLOW_OUT = 2,
+  TrackEvent_LegacyEvent_FlowDirection_FLOW_INOUT = 3,
+};
+enum TrackEvent_LegacyEvent_InstantEventScope : int {
+  TrackEvent_LegacyEvent_InstantEventScope_SCOPE_UNSPECIFIED = 0,
+  TrackEvent_LegacyEvent_InstantEventScope_SCOPE_GLOBAL = 1,
+  TrackEvent_LegacyEvent_InstantEventScope_SCOPE_PROCESS = 2,
+  TrackEvent_LegacyEvent_InstantEventScope_SCOPE_THREAD = 3,
+};
+
+class PERFETTO_EXPORT_COMPONENT EventName : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kIidFieldNumber = 1,
+    kNameFieldNumber = 2,
+  };
+
+  EventName();
+  ~EventName() override;
+  EventName(EventName&&) noexcept;
+  EventName& operator=(EventName&&);
+  EventName(const EventName&);
+  EventName& operator=(const EventName&);
+  bool operator==(const EventName&) const;
+  bool operator!=(const EventName& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_iid() const { return _has_field_[1]; }
+  uint64_t iid() const { return iid_; }
+  void set_iid(uint64_t value) { iid_ = value; _has_field_.set(1); }
+
+  bool has_name() const { return _has_field_[2]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
+
+ private:
+  uint64_t iid_{};
+  std::string name_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT EventCategory : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kIidFieldNumber = 1,
+    kNameFieldNumber = 2,
+  };
+
+  EventCategory();
+  ~EventCategory() override;
+  EventCategory(EventCategory&&) noexcept;
+  EventCategory& operator=(EventCategory&&);
+  EventCategory(const EventCategory&);
+  EventCategory& operator=(const EventCategory&);
+  bool operator==(const EventCategory&) const;
+  bool operator!=(const EventCategory& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_iid() const { return _has_field_[1]; }
+  uint64_t iid() const { return iid_; }
+  void set_iid(uint64_t value) { iid_ = value; _has_field_.set(1); }
+
+  bool has_name() const { return _has_field_[2]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
+
+ private:
+  uint64_t iid_{};
+  std::string name_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TrackEventDefaults : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kTrackUuidFieldNumber = 11,
+    kExtraCounterTrackUuidsFieldNumber = 31,
+    kExtraDoubleCounterTrackUuidsFieldNumber = 45,
+  };
+
+  TrackEventDefaults();
+  ~TrackEventDefaults() override;
+  TrackEventDefaults(TrackEventDefaults&&) noexcept;
+  TrackEventDefaults& operator=(TrackEventDefaults&&);
+  TrackEventDefaults(const TrackEventDefaults&);
+  TrackEventDefaults& operator=(const TrackEventDefaults&);
+  bool operator==(const TrackEventDefaults&) const;
+  bool operator!=(const TrackEventDefaults& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_track_uuid() const { return _has_field_[11]; }
+  uint64_t track_uuid() const { return track_uuid_; }
+  void set_track_uuid(uint64_t value) { track_uuid_ = value; _has_field_.set(11); }
+
+  const std::vector<uint64_t>& extra_counter_track_uuids() const { return extra_counter_track_uuids_; }
+  std::vector<uint64_t>* mutable_extra_counter_track_uuids() { return &extra_counter_track_uuids_; }
+  int extra_counter_track_uuids_size() const { return static_cast<int>(extra_counter_track_uuids_.size()); }
+  void clear_extra_counter_track_uuids() { extra_counter_track_uuids_.clear(); }
+  void add_extra_counter_track_uuids(uint64_t value) { extra_counter_track_uuids_.emplace_back(value); }
+  uint64_t* add_extra_counter_track_uuids() { extra_counter_track_uuids_.emplace_back(); return &extra_counter_track_uuids_.back(); }
+
+  const std::vector<uint64_t>& extra_double_counter_track_uuids() const { return extra_double_counter_track_uuids_; }
+  std::vector<uint64_t>* mutable_extra_double_counter_track_uuids() { return &extra_double_counter_track_uuids_; }
+  int extra_double_counter_track_uuids_size() const { return static_cast<int>(extra_double_counter_track_uuids_.size()); }
+  void clear_extra_double_counter_track_uuids() { extra_double_counter_track_uuids_.clear(); }
+  void add_extra_double_counter_track_uuids(uint64_t value) { extra_double_counter_track_uuids_.emplace_back(value); }
+  uint64_t* add_extra_double_counter_track_uuids() { extra_double_counter_track_uuids_.emplace_back(); return &extra_double_counter_track_uuids_.back(); }
+
+ private:
+  uint64_t track_uuid_{};
+  std::vector<uint64_t> extra_counter_track_uuids_;
+  std::vector<uint64_t> extra_double_counter_track_uuids_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<46> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TrackEvent : public ::protozero::CppMessageObj {
+ public:
+  using LegacyEvent = TrackEvent_LegacyEvent;
+  using Type = TrackEvent_Type;
+  static constexpr auto TYPE_UNSPECIFIED = TrackEvent_Type_TYPE_UNSPECIFIED;
+  static constexpr auto TYPE_SLICE_BEGIN = TrackEvent_Type_TYPE_SLICE_BEGIN;
+  static constexpr auto TYPE_SLICE_END = TrackEvent_Type_TYPE_SLICE_END;
+  static constexpr auto TYPE_INSTANT = TrackEvent_Type_TYPE_INSTANT;
+  static constexpr auto TYPE_COUNTER = TrackEvent_Type_TYPE_COUNTER;
+  static constexpr auto Type_MIN = TrackEvent_Type_TYPE_UNSPECIFIED;
+  static constexpr auto Type_MAX = TrackEvent_Type_TYPE_COUNTER;
+  enum FieldNumbers {
+    kCategoryIidsFieldNumber = 3,
+    kCategoriesFieldNumber = 22,
+    kNameIidFieldNumber = 10,
+    kNameFieldNumber = 23,
+    kTypeFieldNumber = 9,
+    kTrackUuidFieldNumber = 11,
+    kCounterValueFieldNumber = 30,
+    kDoubleCounterValueFieldNumber = 44,
+    kExtraCounterTrackUuidsFieldNumber = 31,
+    kExtraCounterValuesFieldNumber = 12,
+    kExtraDoubleCounterTrackUuidsFieldNumber = 45,
+    kExtraDoubleCounterValuesFieldNumber = 46,
+    kFlowIdsOldFieldNumber = 36,
+    kFlowIdsFieldNumber = 47,
+    kTerminatingFlowIdsOldFieldNumber = 42,
+    kTerminatingFlowIdsFieldNumber = 48,
+    kDebugAnnotationsFieldNumber = 4,
+    kTaskExecutionFieldNumber = 5,
+    kLogMessageFieldNumber = 21,
+    kCcSchedulerStateFieldNumber = 24,
+    kChromeUserEventFieldNumber = 25,
+    kChromeKeyedServiceFieldNumber = 26,
+    kChromeLegacyIpcFieldNumber = 27,
+    kChromeHistogramSampleFieldNumber = 28,
+    kChromeLatencyInfoFieldNumber = 29,
+    kChromeFrameReporterFieldNumber = 32,
+    kChromeApplicationStateInfoFieldNumber = 39,
+    kChromeRendererSchedulerStateFieldNumber = 40,
+    kChromeWindowHandleEventInfoFieldNumber = 41,
+    kChromeContentSettingsEventInfoFieldNumber = 43,
+    kChromeActiveProcessesFieldNumber = 49,
+    kScreenshotFieldNumber = 50,
+    kPixelModemEventInsightFieldNumber = 51,
+    kSourceLocationFieldNumber = 33,
+    kSourceLocationIidFieldNumber = 34,
+    kChromeMessagePumpFieldNumber = 35,
+    kChromeMojoEventInfoFieldNumber = 38,
+    kTimestampDeltaUsFieldNumber = 1,
+    kTimestampAbsoluteUsFieldNumber = 16,
+    kThreadTimeDeltaUsFieldNumber = 2,
+    kThreadTimeAbsoluteUsFieldNumber = 17,
+    kThreadInstructionCountDeltaFieldNumber = 8,
+    kThreadInstructionCountAbsoluteFieldNumber = 20,
+    kLegacyEventFieldNumber = 6,
+  };
+
+  TrackEvent();
+  ~TrackEvent() override;
+  TrackEvent(TrackEvent&&) noexcept;
+  TrackEvent& operator=(TrackEvent&&);
+  TrackEvent(const TrackEvent&);
+  TrackEvent& operator=(const TrackEvent&);
+  bool operator==(const TrackEvent&) const;
+  bool operator!=(const TrackEvent& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<uint64_t>& category_iids() const { return category_iids_; }
+  std::vector<uint64_t>* mutable_category_iids() { return &category_iids_; }
+  int category_iids_size() const { return static_cast<int>(category_iids_.size()); }
+  void clear_category_iids() { category_iids_.clear(); }
+  void add_category_iids(uint64_t value) { category_iids_.emplace_back(value); }
+  uint64_t* add_category_iids() { category_iids_.emplace_back(); return &category_iids_.back(); }
+
+  const std::vector<std::string>& categories() const { return categories_; }
+  std::vector<std::string>* mutable_categories() { return &categories_; }
+  int categories_size() const { return static_cast<int>(categories_.size()); }
+  void clear_categories() { categories_.clear(); }
+  void add_categories(std::string value) { categories_.emplace_back(value); }
+  std::string* add_categories() { categories_.emplace_back(); return &categories_.back(); }
+
+  bool has_name_iid() const { return _has_field_[10]; }
+  uint64_t name_iid() const { return name_iid_; }
+  void set_name_iid(uint64_t value) { name_iid_ = value; _has_field_.set(10); }
+
+  bool has_name() const { return _has_field_[23]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(23); }
+
+  bool has_type() const { return _has_field_[9]; }
+  TrackEvent_Type type() const { return type_; }
+  void set_type(TrackEvent_Type value) { type_ = value; _has_field_.set(9); }
+
+  bool has_track_uuid() const { return _has_field_[11]; }
+  uint64_t track_uuid() const { return track_uuid_; }
+  void set_track_uuid(uint64_t value) { track_uuid_ = value; _has_field_.set(11); }
+
+  bool has_counter_value() const { return _has_field_[30]; }
+  int64_t counter_value() const { return counter_value_; }
+  void set_counter_value(int64_t value) { counter_value_ = value; _has_field_.set(30); }
+
+  bool has_double_counter_value() const { return _has_field_[44]; }
+  double double_counter_value() const { return double_counter_value_; }
+  void set_double_counter_value(double value) { double_counter_value_ = value; _has_field_.set(44); }
+
+  const std::vector<uint64_t>& extra_counter_track_uuids() const { return extra_counter_track_uuids_; }
+  std::vector<uint64_t>* mutable_extra_counter_track_uuids() { return &extra_counter_track_uuids_; }
+  int extra_counter_track_uuids_size() const { return static_cast<int>(extra_counter_track_uuids_.size()); }
+  void clear_extra_counter_track_uuids() { extra_counter_track_uuids_.clear(); }
+  void add_extra_counter_track_uuids(uint64_t value) { extra_counter_track_uuids_.emplace_back(value); }
+  uint64_t* add_extra_counter_track_uuids() { extra_counter_track_uuids_.emplace_back(); return &extra_counter_track_uuids_.back(); }
+
+  const std::vector<int64_t>& extra_counter_values() const { return extra_counter_values_; }
+  std::vector<int64_t>* mutable_extra_counter_values() { return &extra_counter_values_; }
+  int extra_counter_values_size() const { return static_cast<int>(extra_counter_values_.size()); }
+  void clear_extra_counter_values() { extra_counter_values_.clear(); }
+  void add_extra_counter_values(int64_t value) { extra_counter_values_.emplace_back(value); }
+  int64_t* add_extra_counter_values() { extra_counter_values_.emplace_back(); return &extra_counter_values_.back(); }
+
+  const std::vector<uint64_t>& extra_double_counter_track_uuids() const { return extra_double_counter_track_uuids_; }
+  std::vector<uint64_t>* mutable_extra_double_counter_track_uuids() { return &extra_double_counter_track_uuids_; }
+  int extra_double_counter_track_uuids_size() const { return static_cast<int>(extra_double_counter_track_uuids_.size()); }
+  void clear_extra_double_counter_track_uuids() { extra_double_counter_track_uuids_.clear(); }
+  void add_extra_double_counter_track_uuids(uint64_t value) { extra_double_counter_track_uuids_.emplace_back(value); }
+  uint64_t* add_extra_double_counter_track_uuids() { extra_double_counter_track_uuids_.emplace_back(); return &extra_double_counter_track_uuids_.back(); }
+
+  const std::vector<double>& extra_double_counter_values() const { return extra_double_counter_values_; }
+  std::vector<double>* mutable_extra_double_counter_values() { return &extra_double_counter_values_; }
+  int extra_double_counter_values_size() const { return static_cast<int>(extra_double_counter_values_.size()); }
+  void clear_extra_double_counter_values() { extra_double_counter_values_.clear(); }
+  void add_extra_double_counter_values(double value) { extra_double_counter_values_.emplace_back(value); }
+  double* add_extra_double_counter_values() { extra_double_counter_values_.emplace_back(); return &extra_double_counter_values_.back(); }
+
+  const std::vector<uint64_t>& flow_ids_old() const { return flow_ids_old_; }
+  std::vector<uint64_t>* mutable_flow_ids_old() { return &flow_ids_old_; }
+  int flow_ids_old_size() const { return static_cast<int>(flow_ids_old_.size()); }
+  void clear_flow_ids_old() { flow_ids_old_.clear(); }
+  void add_flow_ids_old(uint64_t value) { flow_ids_old_.emplace_back(value); }
+  uint64_t* add_flow_ids_old() { flow_ids_old_.emplace_back(); return &flow_ids_old_.back(); }
+
+  const std::vector<uint64_t>& flow_ids() const { return flow_ids_; }
+  std::vector<uint64_t>* mutable_flow_ids() { return &flow_ids_; }
+  int flow_ids_size() const { return static_cast<int>(flow_ids_.size()); }
+  void clear_flow_ids() { flow_ids_.clear(); }
+  void add_flow_ids(uint64_t value) { flow_ids_.emplace_back(value); }
+  uint64_t* add_flow_ids() { flow_ids_.emplace_back(); return &flow_ids_.back(); }
+
+  const std::vector<uint64_t>& terminating_flow_ids_old() const { return terminating_flow_ids_old_; }
+  std::vector<uint64_t>* mutable_terminating_flow_ids_old() { return &terminating_flow_ids_old_; }
+  int terminating_flow_ids_old_size() const { return static_cast<int>(terminating_flow_ids_old_.size()); }
+  void clear_terminating_flow_ids_old() { terminating_flow_ids_old_.clear(); }
+  void add_terminating_flow_ids_old(uint64_t value) { terminating_flow_ids_old_.emplace_back(value); }
+  uint64_t* add_terminating_flow_ids_old() { terminating_flow_ids_old_.emplace_back(); return &terminating_flow_ids_old_.back(); }
+
+  const std::vector<uint64_t>& terminating_flow_ids() const { return terminating_flow_ids_; }
+  std::vector<uint64_t>* mutable_terminating_flow_ids() { return &terminating_flow_ids_; }
+  int terminating_flow_ids_size() const { return static_cast<int>(terminating_flow_ids_.size()); }
+  void clear_terminating_flow_ids() { terminating_flow_ids_.clear(); }
+  void add_terminating_flow_ids(uint64_t value) { terminating_flow_ids_.emplace_back(value); }
+  uint64_t* add_terminating_flow_ids() { terminating_flow_ids_.emplace_back(); return &terminating_flow_ids_.back(); }
+
+  const std::vector<DebugAnnotation>& debug_annotations() const { return debug_annotations_; }
+  std::vector<DebugAnnotation>* mutable_debug_annotations() { return &debug_annotations_; }
+  int debug_annotations_size() const;
+  void clear_debug_annotations();
+  DebugAnnotation* add_debug_annotations();
+
+  bool has_task_execution() const { return _has_field_[5]; }
+  const TaskExecution& task_execution() const { return *task_execution_; }
+  TaskExecution* mutable_task_execution() { _has_field_.set(5); return task_execution_.get(); }
+
+  bool has_log_message() const { return _has_field_[21]; }
+  const LogMessage& log_message() const { return *log_message_; }
+  LogMessage* mutable_log_message() { _has_field_.set(21); return log_message_.get(); }
+
+  bool has_cc_scheduler_state() const { return _has_field_[24]; }
+  const ChromeCompositorSchedulerState& cc_scheduler_state() const { return *cc_scheduler_state_; }
+  ChromeCompositorSchedulerState* mutable_cc_scheduler_state() { _has_field_.set(24); return cc_scheduler_state_.get(); }
+
+  bool has_chrome_user_event() const { return _has_field_[25]; }
+  const ChromeUserEvent& chrome_user_event() const { return *chrome_user_event_; }
+  ChromeUserEvent* mutable_chrome_user_event() { _has_field_.set(25); return chrome_user_event_.get(); }
+
+  bool has_chrome_keyed_service() const { return _has_field_[26]; }
+  const ChromeKeyedService& chrome_keyed_service() const { return *chrome_keyed_service_; }
+  ChromeKeyedService* mutable_chrome_keyed_service() { _has_field_.set(26); return chrome_keyed_service_.get(); }
+
+  bool has_chrome_legacy_ipc() const { return _has_field_[27]; }
+  const ChromeLegacyIpc& chrome_legacy_ipc() const { return *chrome_legacy_ipc_; }
+  ChromeLegacyIpc* mutable_chrome_legacy_ipc() { _has_field_.set(27); return chrome_legacy_ipc_.get(); }
+
+  bool has_chrome_histogram_sample() const { return _has_field_[28]; }
+  const ChromeHistogramSample& chrome_histogram_sample() const { return *chrome_histogram_sample_; }
+  ChromeHistogramSample* mutable_chrome_histogram_sample() { _has_field_.set(28); return chrome_histogram_sample_.get(); }
+
+  bool has_chrome_latency_info() const { return _has_field_[29]; }
+  const ChromeLatencyInfo& chrome_latency_info() const { return *chrome_latency_info_; }
+  ChromeLatencyInfo* mutable_chrome_latency_info() { _has_field_.set(29); return chrome_latency_info_.get(); }
+
+  bool has_chrome_frame_reporter() const { return _has_field_[32]; }
+  const ChromeFrameReporter& chrome_frame_reporter() const { return *chrome_frame_reporter_; }
+  ChromeFrameReporter* mutable_chrome_frame_reporter() { _has_field_.set(32); return chrome_frame_reporter_.get(); }
+
+  bool has_chrome_application_state_info() const { return _has_field_[39]; }
+  const ChromeApplicationStateInfo& chrome_application_state_info() const { return *chrome_application_state_info_; }
+  ChromeApplicationStateInfo* mutable_chrome_application_state_info() { _has_field_.set(39); return chrome_application_state_info_.get(); }
+
+  bool has_chrome_renderer_scheduler_state() const { return _has_field_[40]; }
+  const ChromeRendererSchedulerState& chrome_renderer_scheduler_state() const { return *chrome_renderer_scheduler_state_; }
+  ChromeRendererSchedulerState* mutable_chrome_renderer_scheduler_state() { _has_field_.set(40); return chrome_renderer_scheduler_state_.get(); }
+
+  bool has_chrome_window_handle_event_info() const { return _has_field_[41]; }
+  const ChromeWindowHandleEventInfo& chrome_window_handle_event_info() const { return *chrome_window_handle_event_info_; }
+  ChromeWindowHandleEventInfo* mutable_chrome_window_handle_event_info() { _has_field_.set(41); return chrome_window_handle_event_info_.get(); }
+
+  bool has_chrome_content_settings_event_info() const { return _has_field_[43]; }
+  const ChromeContentSettingsEventInfo& chrome_content_settings_event_info() const { return *chrome_content_settings_event_info_; }
+  ChromeContentSettingsEventInfo* mutable_chrome_content_settings_event_info() { _has_field_.set(43); return chrome_content_settings_event_info_.get(); }
+
+  bool has_chrome_active_processes() const { return _has_field_[49]; }
+  const ChromeActiveProcesses& chrome_active_processes() const { return *chrome_active_processes_; }
+  ChromeActiveProcesses* mutable_chrome_active_processes() { _has_field_.set(49); return chrome_active_processes_.get(); }
+
+  bool has_screenshot() const { return _has_field_[50]; }
+  const Screenshot& screenshot() const { return *screenshot_; }
+  Screenshot* mutable_screenshot() { _has_field_.set(50); return screenshot_.get(); }
+
+  bool has_pixel_modem_event_insight() const { return _has_field_[51]; }
+  const PixelModemEventInsight& pixel_modem_event_insight() const { return *pixel_modem_event_insight_; }
+  PixelModemEventInsight* mutable_pixel_modem_event_insight() { _has_field_.set(51); return pixel_modem_event_insight_.get(); }
+
+  bool has_source_location() const { return _has_field_[33]; }
+  const SourceLocation& source_location() const { return *source_location_; }
+  SourceLocation* mutable_source_location() { _has_field_.set(33); return source_location_.get(); }
+
+  bool has_source_location_iid() const { return _has_field_[34]; }
+  uint64_t source_location_iid() const { return source_location_iid_; }
+  void set_source_location_iid(uint64_t value) { source_location_iid_ = value; _has_field_.set(34); }
+
+  bool has_chrome_message_pump() const { return _has_field_[35]; }
+  const ChromeMessagePump& chrome_message_pump() const { return *chrome_message_pump_; }
+  ChromeMessagePump* mutable_chrome_message_pump() { _has_field_.set(35); return chrome_message_pump_.get(); }
+
+  bool has_chrome_mojo_event_info() const { return _has_field_[38]; }
+  const ChromeMojoEventInfo& chrome_mojo_event_info() const { return *chrome_mojo_event_info_; }
+  ChromeMojoEventInfo* mutable_chrome_mojo_event_info() { _has_field_.set(38); return chrome_mojo_event_info_.get(); }
+
+  bool has_timestamp_delta_us() const { return _has_field_[1]; }
+  int64_t timestamp_delta_us() const { return timestamp_delta_us_; }
+  void set_timestamp_delta_us(int64_t value) { timestamp_delta_us_ = value; _has_field_.set(1); }
+
+  bool has_timestamp_absolute_us() const { return _has_field_[16]; }
+  int64_t timestamp_absolute_us() const { return timestamp_absolute_us_; }
+  void set_timestamp_absolute_us(int64_t value) { timestamp_absolute_us_ = value; _has_field_.set(16); }
+
+  bool has_thread_time_delta_us() const { return _has_field_[2]; }
+  int64_t thread_time_delta_us() const { return thread_time_delta_us_; }
+  void set_thread_time_delta_us(int64_t value) { thread_time_delta_us_ = value; _has_field_.set(2); }
+
+  bool has_thread_time_absolute_us() const { return _has_field_[17]; }
+  int64_t thread_time_absolute_us() const { return thread_time_absolute_us_; }
+  void set_thread_time_absolute_us(int64_t value) { thread_time_absolute_us_ = value; _has_field_.set(17); }
+
+  bool has_thread_instruction_count_delta() const { return _has_field_[8]; }
+  int64_t thread_instruction_count_delta() const { return thread_instruction_count_delta_; }
+  void set_thread_instruction_count_delta(int64_t value) { thread_instruction_count_delta_ = value; _has_field_.set(8); }
+
+  bool has_thread_instruction_count_absolute() const { return _has_field_[20]; }
+  int64_t thread_instruction_count_absolute() const { return thread_instruction_count_absolute_; }
+  void set_thread_instruction_count_absolute(int64_t value) { thread_instruction_count_absolute_ = value; _has_field_.set(20); }
+
+  bool has_legacy_event() const { return _has_field_[6]; }
+  const TrackEvent_LegacyEvent& legacy_event() const { return *legacy_event_; }
+  TrackEvent_LegacyEvent* mutable_legacy_event() { _has_field_.set(6); return legacy_event_.get(); }
+
+ private:
+  std::vector<uint64_t> category_iids_;
+  std::vector<std::string> categories_;
+  uint64_t name_iid_{};
+  std::string name_{};
+  TrackEvent_Type type_{};
+  uint64_t track_uuid_{};
+  int64_t counter_value_{};
+  double double_counter_value_{};
+  std::vector<uint64_t> extra_counter_track_uuids_;
+  std::vector<int64_t> extra_counter_values_;
+  std::vector<uint64_t> extra_double_counter_track_uuids_;
+  std::vector<double> extra_double_counter_values_;
+  std::vector<uint64_t> flow_ids_old_;
+  std::vector<uint64_t> flow_ids_;
+  std::vector<uint64_t> terminating_flow_ids_old_;
+  std::vector<uint64_t> terminating_flow_ids_;
+  std::vector<DebugAnnotation> debug_annotations_;
+  ::protozero::CopyablePtr<TaskExecution> task_execution_;
+  ::protozero::CopyablePtr<LogMessage> log_message_;
+  ::protozero::CopyablePtr<ChromeCompositorSchedulerState> cc_scheduler_state_;
+  ::protozero::CopyablePtr<ChromeUserEvent> chrome_user_event_;
+  ::protozero::CopyablePtr<ChromeKeyedService> chrome_keyed_service_;
+  ::protozero::CopyablePtr<ChromeLegacyIpc> chrome_legacy_ipc_;
+  ::protozero::CopyablePtr<ChromeHistogramSample> chrome_histogram_sample_;
+  ::protozero::CopyablePtr<ChromeLatencyInfo> chrome_latency_info_;
+  ::protozero::CopyablePtr<ChromeFrameReporter> chrome_frame_reporter_;
+  ::protozero::CopyablePtr<ChromeApplicationStateInfo> chrome_application_state_info_;
+  ::protozero::CopyablePtr<ChromeRendererSchedulerState> chrome_renderer_scheduler_state_;
+  ::protozero::CopyablePtr<ChromeWindowHandleEventInfo> chrome_window_handle_event_info_;
+  ::protozero::CopyablePtr<ChromeContentSettingsEventInfo> chrome_content_settings_event_info_;
+  ::protozero::CopyablePtr<ChromeActiveProcesses> chrome_active_processes_;
+  ::protozero::CopyablePtr<Screenshot> screenshot_;
+  ::protozero::CopyablePtr<PixelModemEventInsight> pixel_modem_event_insight_;
+  ::protozero::CopyablePtr<SourceLocation> source_location_;
+  uint64_t source_location_iid_{};
+  ::protozero::CopyablePtr<ChromeMessagePump> chrome_message_pump_;
+  ::protozero::CopyablePtr<ChromeMojoEventInfo> chrome_mojo_event_info_;
+  int64_t timestamp_delta_us_{};
+  int64_t timestamp_absolute_us_{};
+  int64_t thread_time_delta_us_{};
+  int64_t thread_time_absolute_us_{};
+  int64_t thread_instruction_count_delta_{};
+  int64_t thread_instruction_count_absolute_{};
+  ::protozero::CopyablePtr<TrackEvent_LegacyEvent> legacy_event_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<52> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TrackEvent_LegacyEvent : public ::protozero::CppMessageObj {
+ public:
+  using FlowDirection = TrackEvent_LegacyEvent_FlowDirection;
+  static constexpr auto FLOW_UNSPECIFIED = TrackEvent_LegacyEvent_FlowDirection_FLOW_UNSPECIFIED;
+  static constexpr auto FLOW_IN = TrackEvent_LegacyEvent_FlowDirection_FLOW_IN;
+  static constexpr auto FLOW_OUT = TrackEvent_LegacyEvent_FlowDirection_FLOW_OUT;
+  static constexpr auto FLOW_INOUT = TrackEvent_LegacyEvent_FlowDirection_FLOW_INOUT;
+  static constexpr auto FlowDirection_MIN = TrackEvent_LegacyEvent_FlowDirection_FLOW_UNSPECIFIED;
+  static constexpr auto FlowDirection_MAX = TrackEvent_LegacyEvent_FlowDirection_FLOW_INOUT;
+  using InstantEventScope = TrackEvent_LegacyEvent_InstantEventScope;
+  static constexpr auto SCOPE_UNSPECIFIED = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_UNSPECIFIED;
+  static constexpr auto SCOPE_GLOBAL = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_GLOBAL;
+  static constexpr auto SCOPE_PROCESS = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_PROCESS;
+  static constexpr auto SCOPE_THREAD = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_THREAD;
+  static constexpr auto InstantEventScope_MIN = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_UNSPECIFIED;
+  static constexpr auto InstantEventScope_MAX = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_THREAD;
+  enum FieldNumbers {
+    kNameIidFieldNumber = 1,
+    kPhaseFieldNumber = 2,
+    kDurationUsFieldNumber = 3,
+    kThreadDurationUsFieldNumber = 4,
+    kThreadInstructionDeltaFieldNumber = 15,
+    kUnscopedIdFieldNumber = 6,
+    kLocalIdFieldNumber = 10,
+    kGlobalIdFieldNumber = 11,
+    kIdScopeFieldNumber = 7,
+    kUseAsyncTtsFieldNumber = 9,
+    kBindIdFieldNumber = 8,
+    kBindToEnclosingFieldNumber = 12,
+    kFlowDirectionFieldNumber = 13,
+    kInstantEventScopeFieldNumber = 14,
+    kPidOverrideFieldNumber = 18,
+    kTidOverrideFieldNumber = 19,
+  };
+
+  TrackEvent_LegacyEvent();
+  ~TrackEvent_LegacyEvent() override;
+  TrackEvent_LegacyEvent(TrackEvent_LegacyEvent&&) noexcept;
+  TrackEvent_LegacyEvent& operator=(TrackEvent_LegacyEvent&&);
+  TrackEvent_LegacyEvent(const TrackEvent_LegacyEvent&);
+  TrackEvent_LegacyEvent& operator=(const TrackEvent_LegacyEvent&);
+  bool operator==(const TrackEvent_LegacyEvent&) const;
+  bool operator!=(const TrackEvent_LegacyEvent& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name_iid() const { return _has_field_[1]; }
+  uint64_t name_iid() const { return name_iid_; }
+  void set_name_iid(uint64_t value) { name_iid_ = value; _has_field_.set(1); }
+
+  bool has_phase() const { return _has_field_[2]; }
+  int32_t phase() const { return phase_; }
+  void set_phase(int32_t value) { phase_ = value; _has_field_.set(2); }
+
+  bool has_duration_us() const { return _has_field_[3]; }
+  int64_t duration_us() const { return duration_us_; }
+  void set_duration_us(int64_t value) { duration_us_ = value; _has_field_.set(3); }
+
+  bool has_thread_duration_us() const { return _has_field_[4]; }
+  int64_t thread_duration_us() const { return thread_duration_us_; }
+  void set_thread_duration_us(int64_t value) { thread_duration_us_ = value; _has_field_.set(4); }
+
+  bool has_thread_instruction_delta() const { return _has_field_[15]; }
+  int64_t thread_instruction_delta() const { return thread_instruction_delta_; }
+  void set_thread_instruction_delta(int64_t value) { thread_instruction_delta_ = value; _has_field_.set(15); }
+
+  bool has_unscoped_id() const { return _has_field_[6]; }
+  uint64_t unscoped_id() const { return unscoped_id_; }
+  void set_unscoped_id(uint64_t value) { unscoped_id_ = value; _has_field_.set(6); }
+
+  bool has_local_id() const { return _has_field_[10]; }
+  uint64_t local_id() const { return local_id_; }
+  void set_local_id(uint64_t value) { local_id_ = value; _has_field_.set(10); }
+
+  bool has_global_id() const { return _has_field_[11]; }
+  uint64_t global_id() const { return global_id_; }
+  void set_global_id(uint64_t value) { global_id_ = value; _has_field_.set(11); }
+
+  bool has_id_scope() const { return _has_field_[7]; }
+  const std::string& id_scope() const { return id_scope_; }
+  void set_id_scope(const std::string& value) { id_scope_ = value; _has_field_.set(7); }
+
+  bool has_use_async_tts() const { return _has_field_[9]; }
+  bool use_async_tts() const { return use_async_tts_; }
+  void set_use_async_tts(bool value) { use_async_tts_ = value; _has_field_.set(9); }
+
+  bool has_bind_id() const { return _has_field_[8]; }
+  uint64_t bind_id() const { return bind_id_; }
+  void set_bind_id(uint64_t value) { bind_id_ = value; _has_field_.set(8); }
+
+  bool has_bind_to_enclosing() const { return _has_field_[12]; }
+  bool bind_to_enclosing() const { return bind_to_enclosing_; }
+  void set_bind_to_enclosing(bool value) { bind_to_enclosing_ = value; _has_field_.set(12); }
+
+  bool has_flow_direction() const { return _has_field_[13]; }
+  TrackEvent_LegacyEvent_FlowDirection flow_direction() const { return flow_direction_; }
+  void set_flow_direction(TrackEvent_LegacyEvent_FlowDirection value) { flow_direction_ = value; _has_field_.set(13); }
+
+  bool has_instant_event_scope() const { return _has_field_[14]; }
+  TrackEvent_LegacyEvent_InstantEventScope instant_event_scope() const { return instant_event_scope_; }
+  void set_instant_event_scope(TrackEvent_LegacyEvent_InstantEventScope value) { instant_event_scope_ = value; _has_field_.set(14); }
+
+  bool has_pid_override() const { return _has_field_[18]; }
+  int32_t pid_override() const { return pid_override_; }
+  void set_pid_override(int32_t value) { pid_override_ = value; _has_field_.set(18); }
+
+  bool has_tid_override() const { return _has_field_[19]; }
+  int32_t tid_override() const { return tid_override_; }
+  void set_tid_override(int32_t value) { tid_override_ = value; _has_field_.set(19); }
+
+ private:
+  uint64_t name_iid_{};
+  int32_t phase_{};
+  int64_t duration_us_{};
+  int64_t thread_duration_us_{};
+  int64_t thread_instruction_delta_{};
+  uint64_t unscoped_id_{};
+  uint64_t local_id_{};
+  uint64_t global_id_{};
+  std::string id_scope_{};
+  bool use_async_tts_{};
+  uint64_t bind_id_{};
+  bool bind_to_enclosing_{};
+  TrackEvent_LegacyEvent_FlowDirection flow_direction_{};
+  TrackEvent_LegacyEvent_InstantEventScope instant_event_scope_{};
+  int32_t pid_override_{};
+  int32_t tid_override_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<20> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TRACK_EVENT_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/ipc/consumer_port.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_CONSUMER_PORT_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_CONSUMER_PORT_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class CloneSessionResponse;
+class CloneSessionRequest;
+class SaveTraceForBugreportResponse;
+class SaveTraceForBugreportRequest;
+class QueryCapabilitiesResponse;
+class TracingServiceCapabilities;
+class QueryCapabilitiesRequest;
+class QueryServiceStateResponse;
+class TracingServiceState;
+class TracingServiceState_TracingSession;
+class TracingServiceState_DataSource;
+class DataSourceDescriptor;
+class TracingServiceState_Producer;
+class QueryServiceStateRequest;
+class ObserveEventsResponse;
+class ObservableEvents;
+class ObservableEvents_CloneTriggerHit;
+class ObservableEvents_DataSourceInstanceStateChange;
+class ObserveEventsRequest;
+class GetTraceStatsResponse;
+class TraceStats;
+class TraceStats_FilterStats;
+class TraceStats_WriterStats;
+class TraceStats_BufferStats;
+class GetTraceStatsRequest;
+class AttachResponse;
+class TraceConfig;
+class TraceConfig_CmdTraceStartDelay;
+class TraceConfig_AndroidReportConfig;
+class TraceConfig_TraceFilter;
+class TraceConfig_TraceFilter_StringFilterChain;
+class TraceConfig_TraceFilter_StringFilterRule;
+class TraceConfig_IncidentReportConfig;
+class TraceConfig_IncrementalStateConfig;
+class TraceConfig_TriggerConfig;
+class TraceConfig_TriggerConfig_Trigger;
+class TraceConfig_GuardrailOverrides;
+class TraceConfig_StatsdMetadata;
+class TraceConfig_ProducerConfig;
+class TraceConfig_BuiltinDataSource;
+class TraceConfig_DataSource;
+class DataSourceConfig;
+class TestConfig;
+class TestConfig_DummyFields;
+class InterceptorConfig;
+class ConsoleConfig;
+class ChromeConfig;
+class SystemInfoConfig;
+class TraceConfig_BufferConfig;
+class AttachRequest;
+class DetachResponse;
+class DetachRequest;
+class FlushResponse;
+class FlushRequest;
+class FreeBuffersResponse;
+class FreeBuffersRequest;
+class ReadBuffersResponse;
+class ReadBuffersResponse_Slice;
+class ReadBuffersRequest;
+class DisableTracingResponse;
+class DisableTracingRequest;
+class ChangeTraceConfigResponse;
+class ChangeTraceConfigRequest;
+class StartTracingResponse;
+class StartTracingRequest;
+class EnableTracingResponse;
+class EnableTracingRequest;
+enum ObservableEvents_Type : int;
+enum ObservableEvents_DataSourceInstanceState : int;
+enum TraceStats_FinalFlushOutcome : int;
+enum TraceConfig_LockdownModeOperation : int;
+enum TraceConfig_CompressionType : int;
+enum TraceConfig_StatsdLogging : int;
+enum TraceConfig_TraceFilter_StringFilterPolicy : int;
+enum TraceConfig_TriggerConfig_TriggerMode : int;
+enum BuiltinClock : int;
+enum DataSourceConfig_SessionInitiator : int;
+enum ConsoleConfig_Output : int;
+enum ChromeConfig_ClientPriority : int;
+enum TraceConfig_BufferConfig_FillPolicy : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT CloneSessionResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kSuccessFieldNumber = 1,
+    kErrorFieldNumber = 2,
+    kUuidMsbFieldNumber = 3,
+    kUuidLsbFieldNumber = 4,
+  };
+
+  CloneSessionResponse();
+  ~CloneSessionResponse() override;
+  CloneSessionResponse(CloneSessionResponse&&) noexcept;
+  CloneSessionResponse& operator=(CloneSessionResponse&&);
+  CloneSessionResponse(const CloneSessionResponse&);
+  CloneSessionResponse& operator=(const CloneSessionResponse&);
+  bool operator==(const CloneSessionResponse&) const;
+  bool operator!=(const CloneSessionResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_success() const { return _has_field_[1]; }
+  bool success() const { return success_; }
+  void set_success(bool value) { success_ = value; _has_field_.set(1); }
+
+  bool has_error() const { return _has_field_[2]; }
+  const std::string& error() const { return error_; }
+  void set_error(const std::string& value) { error_ = value; _has_field_.set(2); }
+
+  bool has_uuid_msb() const { return _has_field_[3]; }
+  int64_t uuid_msb() const { return uuid_msb_; }
+  void set_uuid_msb(int64_t value) { uuid_msb_ = value; _has_field_.set(3); }
+
+  bool has_uuid_lsb() const { return _has_field_[4]; }
+  int64_t uuid_lsb() const { return uuid_lsb_; }
+  void set_uuid_lsb(int64_t value) { uuid_lsb_ = value; _has_field_.set(4); }
+
+ private:
+  bool success_{};
+  std::string error_{};
+  int64_t uuid_msb_{};
+  int64_t uuid_lsb_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<5> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT CloneSessionRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kSessionIdFieldNumber = 1,
+    kSkipTraceFilterFieldNumber = 2,
+    kForBugreportFieldNumber = 3,
+  };
+
+  CloneSessionRequest();
+  ~CloneSessionRequest() override;
+  CloneSessionRequest(CloneSessionRequest&&) noexcept;
+  CloneSessionRequest& operator=(CloneSessionRequest&&);
+  CloneSessionRequest(const CloneSessionRequest&);
+  CloneSessionRequest& operator=(const CloneSessionRequest&);
+  bool operator==(const CloneSessionRequest&) const;
+  bool operator!=(const CloneSessionRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_session_id() const { return _has_field_[1]; }
+  uint64_t session_id() const { return session_id_; }
+  void set_session_id(uint64_t value) { session_id_ = value; _has_field_.set(1); }
+
+  bool has_skip_trace_filter() const { return _has_field_[2]; }
+  bool skip_trace_filter() const { return skip_trace_filter_; }
+  void set_skip_trace_filter(bool value) { skip_trace_filter_ = value; _has_field_.set(2); }
+
+  bool has_for_bugreport() const { return _has_field_[3]; }
+  bool for_bugreport() const { return for_bugreport_; }
+  void set_for_bugreport(bool value) { for_bugreport_ = value; _has_field_.set(3); }
+
+ private:
+  uint64_t session_id_{};
+  bool skip_trace_filter_{};
+  bool for_bugreport_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT SaveTraceForBugreportResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kSuccessFieldNumber = 1,
+    kMsgFieldNumber = 2,
+  };
+
+  SaveTraceForBugreportResponse();
+  ~SaveTraceForBugreportResponse() override;
+  SaveTraceForBugreportResponse(SaveTraceForBugreportResponse&&) noexcept;
+  SaveTraceForBugreportResponse& operator=(SaveTraceForBugreportResponse&&);
+  SaveTraceForBugreportResponse(const SaveTraceForBugreportResponse&);
+  SaveTraceForBugreportResponse& operator=(const SaveTraceForBugreportResponse&);
+  bool operator==(const SaveTraceForBugreportResponse&) const;
+  bool operator!=(const SaveTraceForBugreportResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_success() const { return _has_field_[1]; }
+  bool success() const { return success_; }
+  void set_success(bool value) { success_ = value; _has_field_.set(1); }
+
+  bool has_msg() const { return _has_field_[2]; }
+  const std::string& msg() const { return msg_; }
+  void set_msg(const std::string& value) { msg_ = value; _has_field_.set(2); }
+
+ private:
+  bool success_{};
+  std::string msg_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT SaveTraceForBugreportRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  SaveTraceForBugreportRequest();
+  ~SaveTraceForBugreportRequest() override;
+  SaveTraceForBugreportRequest(SaveTraceForBugreportRequest&&) noexcept;
+  SaveTraceForBugreportRequest& operator=(SaveTraceForBugreportRequest&&);
+  SaveTraceForBugreportRequest(const SaveTraceForBugreportRequest&);
+  SaveTraceForBugreportRequest& operator=(const SaveTraceForBugreportRequest&);
+  bool operator==(const SaveTraceForBugreportRequest&) const;
+  bool operator!=(const SaveTraceForBugreportRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT QueryCapabilitiesResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kCapabilitiesFieldNumber = 1,
+  };
+
+  QueryCapabilitiesResponse();
+  ~QueryCapabilitiesResponse() override;
+  QueryCapabilitiesResponse(QueryCapabilitiesResponse&&) noexcept;
+  QueryCapabilitiesResponse& operator=(QueryCapabilitiesResponse&&);
+  QueryCapabilitiesResponse(const QueryCapabilitiesResponse&);
+  QueryCapabilitiesResponse& operator=(const QueryCapabilitiesResponse&);
+  bool operator==(const QueryCapabilitiesResponse&) const;
+  bool operator!=(const QueryCapabilitiesResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_capabilities() const { return _has_field_[1]; }
+  const TracingServiceCapabilities& capabilities() const { return *capabilities_; }
+  TracingServiceCapabilities* mutable_capabilities() { _has_field_.set(1); return capabilities_.get(); }
+
+ private:
+  ::protozero::CopyablePtr<TracingServiceCapabilities> capabilities_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT QueryCapabilitiesRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  QueryCapabilitiesRequest();
+  ~QueryCapabilitiesRequest() override;
+  QueryCapabilitiesRequest(QueryCapabilitiesRequest&&) noexcept;
+  QueryCapabilitiesRequest& operator=(QueryCapabilitiesRequest&&);
+  QueryCapabilitiesRequest(const QueryCapabilitiesRequest&);
+  QueryCapabilitiesRequest& operator=(const QueryCapabilitiesRequest&);
+  bool operator==(const QueryCapabilitiesRequest&) const;
+  bool operator!=(const QueryCapabilitiesRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT QueryServiceStateResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kServiceStateFieldNumber = 1,
+  };
+
+  QueryServiceStateResponse();
+  ~QueryServiceStateResponse() override;
+  QueryServiceStateResponse(QueryServiceStateResponse&&) noexcept;
+  QueryServiceStateResponse& operator=(QueryServiceStateResponse&&);
+  QueryServiceStateResponse(const QueryServiceStateResponse&);
+  QueryServiceStateResponse& operator=(const QueryServiceStateResponse&);
+  bool operator==(const QueryServiceStateResponse&) const;
+  bool operator!=(const QueryServiceStateResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_service_state() const { return _has_field_[1]; }
+  const TracingServiceState& service_state() const { return *service_state_; }
+  TracingServiceState* mutable_service_state() { _has_field_.set(1); return service_state_.get(); }
+
+ private:
+  ::protozero::CopyablePtr<TracingServiceState> service_state_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT QueryServiceStateRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kSessionsOnlyFieldNumber = 1,
+  };
+
+  QueryServiceStateRequest();
+  ~QueryServiceStateRequest() override;
+  QueryServiceStateRequest(QueryServiceStateRequest&&) noexcept;
+  QueryServiceStateRequest& operator=(QueryServiceStateRequest&&);
+  QueryServiceStateRequest(const QueryServiceStateRequest&);
+  QueryServiceStateRequest& operator=(const QueryServiceStateRequest&);
+  bool operator==(const QueryServiceStateRequest&) const;
+  bool operator!=(const QueryServiceStateRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_sessions_only() const { return _has_field_[1]; }
+  bool sessions_only() const { return sessions_only_; }
+  void set_sessions_only(bool value) { sessions_only_ = value; _has_field_.set(1); }
+
+ private:
+  bool sessions_only_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT ObserveEventsResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kEventsFieldNumber = 1,
+  };
+
+  ObserveEventsResponse();
+  ~ObserveEventsResponse() override;
+  ObserveEventsResponse(ObserveEventsResponse&&) noexcept;
+  ObserveEventsResponse& operator=(ObserveEventsResponse&&);
+  ObserveEventsResponse(const ObserveEventsResponse&);
+  ObserveEventsResponse& operator=(const ObserveEventsResponse&);
+  bool operator==(const ObserveEventsResponse&) const;
+  bool operator!=(const ObserveEventsResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_events() const { return _has_field_[1]; }
+  const ObservableEvents& events() const { return *events_; }
+  ObservableEvents* mutable_events() { _has_field_.set(1); return events_.get(); }
+
+ private:
+  ::protozero::CopyablePtr<ObservableEvents> events_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT ObserveEventsRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kEventsToObserveFieldNumber = 1,
+  };
+
+  ObserveEventsRequest();
+  ~ObserveEventsRequest() override;
+  ObserveEventsRequest(ObserveEventsRequest&&) noexcept;
+  ObserveEventsRequest& operator=(ObserveEventsRequest&&);
+  ObserveEventsRequest(const ObserveEventsRequest&);
+  ObserveEventsRequest& operator=(const ObserveEventsRequest&);
+  bool operator==(const ObserveEventsRequest&) const;
+  bool operator!=(const ObserveEventsRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<ObservableEvents_Type>& events_to_observe() const { return events_to_observe_; }
+  std::vector<ObservableEvents_Type>* mutable_events_to_observe() { return &events_to_observe_; }
+  int events_to_observe_size() const { return static_cast<int>(events_to_observe_.size()); }
+  void clear_events_to_observe() { events_to_observe_.clear(); }
+  void add_events_to_observe(ObservableEvents_Type value) { events_to_observe_.emplace_back(value); }
+  ObservableEvents_Type* add_events_to_observe() { events_to_observe_.emplace_back(); return &events_to_observe_.back(); }
+
+ private:
+  std::vector<ObservableEvents_Type> events_to_observe_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT GetTraceStatsResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kTraceStatsFieldNumber = 1,
+  };
+
+  GetTraceStatsResponse();
+  ~GetTraceStatsResponse() override;
+  GetTraceStatsResponse(GetTraceStatsResponse&&) noexcept;
+  GetTraceStatsResponse& operator=(GetTraceStatsResponse&&);
+  GetTraceStatsResponse(const GetTraceStatsResponse&);
+  GetTraceStatsResponse& operator=(const GetTraceStatsResponse&);
+  bool operator==(const GetTraceStatsResponse&) const;
+  bool operator!=(const GetTraceStatsResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_trace_stats() const { return _has_field_[1]; }
+  const TraceStats& trace_stats() const { return *trace_stats_; }
+  TraceStats* mutable_trace_stats() { _has_field_.set(1); return trace_stats_.get(); }
+
+ private:
+  ::protozero::CopyablePtr<TraceStats> trace_stats_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT GetTraceStatsRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  GetTraceStatsRequest();
+  ~GetTraceStatsRequest() override;
+  GetTraceStatsRequest(GetTraceStatsRequest&&) noexcept;
+  GetTraceStatsRequest& operator=(GetTraceStatsRequest&&);
+  GetTraceStatsRequest(const GetTraceStatsRequest&);
+  GetTraceStatsRequest& operator=(const GetTraceStatsRequest&);
+  bool operator==(const GetTraceStatsRequest&) const;
+  bool operator!=(const GetTraceStatsRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT AttachResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kTraceConfigFieldNumber = 1,
+  };
+
+  AttachResponse();
+  ~AttachResponse() override;
+  AttachResponse(AttachResponse&&) noexcept;
+  AttachResponse& operator=(AttachResponse&&);
+  AttachResponse(const AttachResponse&);
+  AttachResponse& operator=(const AttachResponse&);
+  bool operator==(const AttachResponse&) const;
+  bool operator!=(const AttachResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_trace_config() const { return _has_field_[1]; }
+  const TraceConfig& trace_config() const { return *trace_config_; }
+  TraceConfig* mutable_trace_config() { _has_field_.set(1); return trace_config_.get(); }
+
+ private:
+  ::protozero::CopyablePtr<TraceConfig> trace_config_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT AttachRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kKeyFieldNumber = 1,
+  };
+
+  AttachRequest();
+  ~AttachRequest() override;
+  AttachRequest(AttachRequest&&) noexcept;
+  AttachRequest& operator=(AttachRequest&&);
+  AttachRequest(const AttachRequest&);
+  AttachRequest& operator=(const AttachRequest&);
+  bool operator==(const AttachRequest&) const;
+  bool operator!=(const AttachRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_key() const { return _has_field_[1]; }
+  const std::string& key() const { return key_; }
+  void set_key(const std::string& value) { key_ = value; _has_field_.set(1); }
+
+ private:
+  std::string key_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT DetachResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  DetachResponse();
+  ~DetachResponse() override;
+  DetachResponse(DetachResponse&&) noexcept;
+  DetachResponse& operator=(DetachResponse&&);
+  DetachResponse(const DetachResponse&);
+  DetachResponse& operator=(const DetachResponse&);
+  bool operator==(const DetachResponse&) const;
+  bool operator!=(const DetachResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT DetachRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kKeyFieldNumber = 1,
+  };
+
+  DetachRequest();
+  ~DetachRequest() override;
+  DetachRequest(DetachRequest&&) noexcept;
+  DetachRequest& operator=(DetachRequest&&);
+  DetachRequest(const DetachRequest&);
+  DetachRequest& operator=(const DetachRequest&);
+  bool operator==(const DetachRequest&) const;
+  bool operator!=(const DetachRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_key() const { return _has_field_[1]; }
+  const std::string& key() const { return key_; }
+  void set_key(const std::string& value) { key_ = value; _has_field_.set(1); }
+
+ private:
+  std::string key_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT FlushResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  FlushResponse();
+  ~FlushResponse() override;
+  FlushResponse(FlushResponse&&) noexcept;
+  FlushResponse& operator=(FlushResponse&&);
+  FlushResponse(const FlushResponse&);
+  FlushResponse& operator=(const FlushResponse&);
+  bool operator==(const FlushResponse&) const;
+  bool operator!=(const FlushResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT FlushRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kTimeoutMsFieldNumber = 1,
+    kFlagsFieldNumber = 2,
+  };
+
+  FlushRequest();
+  ~FlushRequest() override;
+  FlushRequest(FlushRequest&&) noexcept;
+  FlushRequest& operator=(FlushRequest&&);
+  FlushRequest(const FlushRequest&);
+  FlushRequest& operator=(const FlushRequest&);
+  bool operator==(const FlushRequest&) const;
+  bool operator!=(const FlushRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_timeout_ms() const { return _has_field_[1]; }
+  uint32_t timeout_ms() const { return timeout_ms_; }
+  void set_timeout_ms(uint32_t value) { timeout_ms_ = value; _has_field_.set(1); }
+
+  bool has_flags() const { return _has_field_[2]; }
+  uint64_t flags() const { return flags_; }
+  void set_flags(uint64_t value) { flags_ = value; _has_field_.set(2); }
+
+ private:
+  uint32_t timeout_ms_{};
+  uint64_t flags_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT FreeBuffersResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  FreeBuffersResponse();
+  ~FreeBuffersResponse() override;
+  FreeBuffersResponse(FreeBuffersResponse&&) noexcept;
+  FreeBuffersResponse& operator=(FreeBuffersResponse&&);
+  FreeBuffersResponse(const FreeBuffersResponse&);
+  FreeBuffersResponse& operator=(const FreeBuffersResponse&);
+  bool operator==(const FreeBuffersResponse&) const;
+  bool operator!=(const FreeBuffersResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT FreeBuffersRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kBufferIdsFieldNumber = 1,
+  };
+
+  FreeBuffersRequest();
+  ~FreeBuffersRequest() override;
+  FreeBuffersRequest(FreeBuffersRequest&&) noexcept;
+  FreeBuffersRequest& operator=(FreeBuffersRequest&&);
+  FreeBuffersRequest(const FreeBuffersRequest&);
+  FreeBuffersRequest& operator=(const FreeBuffersRequest&);
+  bool operator==(const FreeBuffersRequest&) const;
+  bool operator!=(const FreeBuffersRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<uint32_t>& buffer_ids() const { return buffer_ids_; }
+  std::vector<uint32_t>* mutable_buffer_ids() { return &buffer_ids_; }
+  int buffer_ids_size() const { return static_cast<int>(buffer_ids_.size()); }
+  void clear_buffer_ids() { buffer_ids_.clear(); }
+  void add_buffer_ids(uint32_t value) { buffer_ids_.emplace_back(value); }
+  uint32_t* add_buffer_ids() { buffer_ids_.emplace_back(); return &buffer_ids_.back(); }
+
+ private:
+  std::vector<uint32_t> buffer_ids_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT ReadBuffersResponse : public ::protozero::CppMessageObj {
+ public:
+  using Slice = ReadBuffersResponse_Slice;
+  enum FieldNumbers {
+    kSlicesFieldNumber = 2,
+  };
+
+  ReadBuffersResponse();
+  ~ReadBuffersResponse() override;
+  ReadBuffersResponse(ReadBuffersResponse&&) noexcept;
+  ReadBuffersResponse& operator=(ReadBuffersResponse&&);
+  ReadBuffersResponse(const ReadBuffersResponse&);
+  ReadBuffersResponse& operator=(const ReadBuffersResponse&);
+  bool operator==(const ReadBuffersResponse&) const;
+  bool operator!=(const ReadBuffersResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<ReadBuffersResponse_Slice>& slices() const { return slices_; }
+  std::vector<ReadBuffersResponse_Slice>* mutable_slices() { return &slices_; }
+  int slices_size() const;
+  void clear_slices();
+  ReadBuffersResponse_Slice* add_slices();
+
+ private:
+  std::vector<ReadBuffersResponse_Slice> slices_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT ReadBuffersResponse_Slice : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDataFieldNumber = 1,
+    kLastSliceForPacketFieldNumber = 2,
+  };
+
+  ReadBuffersResponse_Slice();
+  ~ReadBuffersResponse_Slice() override;
+  ReadBuffersResponse_Slice(ReadBuffersResponse_Slice&&) noexcept;
+  ReadBuffersResponse_Slice& operator=(ReadBuffersResponse_Slice&&);
+  ReadBuffersResponse_Slice(const ReadBuffersResponse_Slice&);
+  ReadBuffersResponse_Slice& operator=(const ReadBuffersResponse_Slice&);
+  bool operator==(const ReadBuffersResponse_Slice&) const;
+  bool operator!=(const ReadBuffersResponse_Slice& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_data() const { return _has_field_[1]; }
+  const std::string& data() const { return data_; }
+  void set_data(const std::string& value) { data_ = value; _has_field_.set(1); }
+  void set_data(const void* p, size_t s) { data_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(1); }
+
+  bool has_last_slice_for_packet() const { return _has_field_[2]; }
+  bool last_slice_for_packet() const { return last_slice_for_packet_; }
+  void set_last_slice_for_packet(bool value) { last_slice_for_packet_ = value; _has_field_.set(2); }
+
+ private:
+  std::string data_{};
+  bool last_slice_for_packet_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT ReadBuffersRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  ReadBuffersRequest();
+  ~ReadBuffersRequest() override;
+  ReadBuffersRequest(ReadBuffersRequest&&) noexcept;
+  ReadBuffersRequest& operator=(ReadBuffersRequest&&);
+  ReadBuffersRequest(const ReadBuffersRequest&);
+  ReadBuffersRequest& operator=(const ReadBuffersRequest&);
+  bool operator==(const ReadBuffersRequest&) const;
+  bool operator!=(const ReadBuffersRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT DisableTracingResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  DisableTracingResponse();
+  ~DisableTracingResponse() override;
+  DisableTracingResponse(DisableTracingResponse&&) noexcept;
+  DisableTracingResponse& operator=(DisableTracingResponse&&);
+  DisableTracingResponse(const DisableTracingResponse&);
+  DisableTracingResponse& operator=(const DisableTracingResponse&);
+  bool operator==(const DisableTracingResponse&) const;
+  bool operator!=(const DisableTracingResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT DisableTracingRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  DisableTracingRequest();
+  ~DisableTracingRequest() override;
+  DisableTracingRequest(DisableTracingRequest&&) noexcept;
+  DisableTracingRequest& operator=(DisableTracingRequest&&);
+  DisableTracingRequest(const DisableTracingRequest&);
+  DisableTracingRequest& operator=(const DisableTracingRequest&);
+  bool operator==(const DisableTracingRequest&) const;
+  bool operator!=(const DisableTracingRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT ChangeTraceConfigResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  ChangeTraceConfigResponse();
+  ~ChangeTraceConfigResponse() override;
+  ChangeTraceConfigResponse(ChangeTraceConfigResponse&&) noexcept;
+  ChangeTraceConfigResponse& operator=(ChangeTraceConfigResponse&&);
+  ChangeTraceConfigResponse(const ChangeTraceConfigResponse&);
+  ChangeTraceConfigResponse& operator=(const ChangeTraceConfigResponse&);
+  bool operator==(const ChangeTraceConfigResponse&) const;
+  bool operator!=(const ChangeTraceConfigResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT ChangeTraceConfigRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kTraceConfigFieldNumber = 1,
+  };
+
+  ChangeTraceConfigRequest();
+  ~ChangeTraceConfigRequest() override;
+  ChangeTraceConfigRequest(ChangeTraceConfigRequest&&) noexcept;
+  ChangeTraceConfigRequest& operator=(ChangeTraceConfigRequest&&);
+  ChangeTraceConfigRequest(const ChangeTraceConfigRequest&);
+  ChangeTraceConfigRequest& operator=(const ChangeTraceConfigRequest&);
+  bool operator==(const ChangeTraceConfigRequest&) const;
+  bool operator!=(const ChangeTraceConfigRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_trace_config() const { return _has_field_[1]; }
+  const TraceConfig& trace_config() const { return *trace_config_; }
+  TraceConfig* mutable_trace_config() { _has_field_.set(1); return trace_config_.get(); }
+
+ private:
+  ::protozero::CopyablePtr<TraceConfig> trace_config_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT StartTracingResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  StartTracingResponse();
+  ~StartTracingResponse() override;
+  StartTracingResponse(StartTracingResponse&&) noexcept;
+  StartTracingResponse& operator=(StartTracingResponse&&);
+  StartTracingResponse(const StartTracingResponse&);
+  StartTracingResponse& operator=(const StartTracingResponse&);
+  bool operator==(const StartTracingResponse&) const;
+  bool operator!=(const StartTracingResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT StartTracingRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  StartTracingRequest();
+  ~StartTracingRequest() override;
+  StartTracingRequest(StartTracingRequest&&) noexcept;
+  StartTracingRequest& operator=(StartTracingRequest&&);
+  StartTracingRequest(const StartTracingRequest&);
+  StartTracingRequest& operator=(const StartTracingRequest&);
+  bool operator==(const StartTracingRequest&) const;
+  bool operator!=(const StartTracingRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT EnableTracingResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDisabledFieldNumber = 1,
+    kErrorFieldNumber = 3,
+  };
+
+  EnableTracingResponse();
+  ~EnableTracingResponse() override;
+  EnableTracingResponse(EnableTracingResponse&&) noexcept;
+  EnableTracingResponse& operator=(EnableTracingResponse&&);
+  EnableTracingResponse(const EnableTracingResponse&);
+  EnableTracingResponse& operator=(const EnableTracingResponse&);
+  bool operator==(const EnableTracingResponse&) const;
+  bool operator!=(const EnableTracingResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_disabled() const { return _has_field_[1]; }
+  bool disabled() const { return disabled_; }
+  void set_disabled(bool value) { disabled_ = value; _has_field_.set(1); }
+
+  bool has_error() const { return _has_field_[3]; }
+  const std::string& error() const { return error_; }
+  void set_error(const std::string& value) { error_ = value; _has_field_.set(3); }
+
+ private:
+  bool disabled_{};
+  std::string error_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT EnableTracingRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kTraceConfigFieldNumber = 1,
+    kAttachNotificationOnlyFieldNumber = 2,
+  };
+
+  EnableTracingRequest();
+  ~EnableTracingRequest() override;
+  EnableTracingRequest(EnableTracingRequest&&) noexcept;
+  EnableTracingRequest& operator=(EnableTracingRequest&&);
+  EnableTracingRequest(const EnableTracingRequest&);
+  EnableTracingRequest& operator=(const EnableTracingRequest&);
+  bool operator==(const EnableTracingRequest&) const;
+  bool operator!=(const EnableTracingRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_trace_config() const { return _has_field_[1]; }
+  const TraceConfig& trace_config() const { return *trace_config_; }
+  TraceConfig* mutable_trace_config() { _has_field_.set(1); return trace_config_.get(); }
+
+  bool has_attach_notification_only() const { return _has_field_[2]; }
+  bool attach_notification_only() const { return attach_notification_only_; }
+  void set_attach_notification_only(bool value) { attach_notification_only_ = value; _has_field_.set(2); }
+
+ private:
+  ::protozero::CopyablePtr<TraceConfig> trace_config_;
+  bool attach_notification_only_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_CONSUMER_PORT_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/ipc/producer_port.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_PRODUCER_PORT_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_PRODUCER_PORT_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class SyncResponse;
+class SyncRequest;
+class GetAsyncCommandResponse;
+class GetAsyncCommandResponse_ClearIncrementalState;
+class GetAsyncCommandResponse_Flush;
+class GetAsyncCommandResponse_StopDataSource;
+class GetAsyncCommandResponse_StartDataSource;
+class DataSourceConfig;
+class TestConfig;
+class TestConfig_DummyFields;
+class InterceptorConfig;
+class ConsoleConfig;
+class ChromeConfig;
+class SystemInfoConfig;
+class GetAsyncCommandResponse_SetupDataSource;
+class GetAsyncCommandResponse_SetupTracing;
+class GetAsyncCommandRequest;
+class ActivateTriggersResponse;
+class ActivateTriggersRequest;
+class NotifyDataSourceStoppedResponse;
+class NotifyDataSourceStoppedRequest;
+class NotifyDataSourceStartedResponse;
+class NotifyDataSourceStartedRequest;
+class CommitDataResponse;
+class UnregisterTraceWriterResponse;
+class UnregisterTraceWriterRequest;
+class RegisterTraceWriterResponse;
+class RegisterTraceWriterRequest;
+class UnregisterDataSourceResponse;
+class UnregisterDataSourceRequest;
+class UpdateDataSourceResponse;
+class UpdateDataSourceRequest;
+class DataSourceDescriptor;
+class RegisterDataSourceResponse;
+class RegisterDataSourceRequest;
+class InitializeConnectionResponse;
+class InitializeConnectionRequest;
+enum DataSourceConfig_SessionInitiator : int;
+enum ConsoleConfig_Output : int;
+enum ChromeConfig_ClientPriority : int;
+enum InitializeConnectionRequest_ProducerSMBScrapingMode : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum InitializeConnectionRequest_ProducerSMBScrapingMode : int {
+  InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_UNSPECIFIED = 0,
+  InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_ENABLED = 1,
+  InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_DISABLED = 2,
+};
+
+class PERFETTO_EXPORT_COMPONENT SyncResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  SyncResponse();
+  ~SyncResponse() override;
+  SyncResponse(SyncResponse&&) noexcept;
+  SyncResponse& operator=(SyncResponse&&);
+  SyncResponse(const SyncResponse&);
+  SyncResponse& operator=(const SyncResponse&);
+  bool operator==(const SyncResponse&) const;
+  bool operator!=(const SyncResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT SyncRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  SyncRequest();
+  ~SyncRequest() override;
+  SyncRequest(SyncRequest&&) noexcept;
+  SyncRequest& operator=(SyncRequest&&);
+  SyncRequest(const SyncRequest&);
+  SyncRequest& operator=(const SyncRequest&);
+  bool operator==(const SyncRequest&) const;
+  bool operator!=(const SyncRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT GetAsyncCommandResponse : public ::protozero::CppMessageObj {
+ public:
+  using SetupDataSource = GetAsyncCommandResponse_SetupDataSource;
+  using StartDataSource = GetAsyncCommandResponse_StartDataSource;
+  using StopDataSource = GetAsyncCommandResponse_StopDataSource;
+  using SetupTracing = GetAsyncCommandResponse_SetupTracing;
+  using Flush = GetAsyncCommandResponse_Flush;
+  using ClearIncrementalState = GetAsyncCommandResponse_ClearIncrementalState;
+  enum FieldNumbers {
+    kSetupTracingFieldNumber = 3,
+    kSetupDataSourceFieldNumber = 6,
+    kStartDataSourceFieldNumber = 1,
+    kStopDataSourceFieldNumber = 2,
+    kFlushFieldNumber = 5,
+    kClearIncrementalStateFieldNumber = 7,
+  };
+
+  GetAsyncCommandResponse();
+  ~GetAsyncCommandResponse() override;
+  GetAsyncCommandResponse(GetAsyncCommandResponse&&) noexcept;
+  GetAsyncCommandResponse& operator=(GetAsyncCommandResponse&&);
+  GetAsyncCommandResponse(const GetAsyncCommandResponse&);
+  GetAsyncCommandResponse& operator=(const GetAsyncCommandResponse&);
+  bool operator==(const GetAsyncCommandResponse&) const;
+  bool operator!=(const GetAsyncCommandResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_setup_tracing() const { return _has_field_[3]; }
+  const GetAsyncCommandResponse_SetupTracing& setup_tracing() const { return *setup_tracing_; }
+  GetAsyncCommandResponse_SetupTracing* mutable_setup_tracing() { _has_field_.set(3); return setup_tracing_.get(); }
+
+  bool has_setup_data_source() const { return _has_field_[6]; }
+  const GetAsyncCommandResponse_SetupDataSource& setup_data_source() const { return *setup_data_source_; }
+  GetAsyncCommandResponse_SetupDataSource* mutable_setup_data_source() { _has_field_.set(6); return setup_data_source_.get(); }
+
+  bool has_start_data_source() const { return _has_field_[1]; }
+  const GetAsyncCommandResponse_StartDataSource& start_data_source() const { return *start_data_source_; }
+  GetAsyncCommandResponse_StartDataSource* mutable_start_data_source() { _has_field_.set(1); return start_data_source_.get(); }
+
+  bool has_stop_data_source() const { return _has_field_[2]; }
+  const GetAsyncCommandResponse_StopDataSource& stop_data_source() const { return *stop_data_source_; }
+  GetAsyncCommandResponse_StopDataSource* mutable_stop_data_source() { _has_field_.set(2); return stop_data_source_.get(); }
+
+  bool has_flush() const { return _has_field_[5]; }
+  const GetAsyncCommandResponse_Flush& flush() const { return *flush_; }
+  GetAsyncCommandResponse_Flush* mutable_flush() { _has_field_.set(5); return flush_.get(); }
+
+  bool has_clear_incremental_state() const { return _has_field_[7]; }
+  const GetAsyncCommandResponse_ClearIncrementalState& clear_incremental_state() const { return *clear_incremental_state_; }
+  GetAsyncCommandResponse_ClearIncrementalState* mutable_clear_incremental_state() { _has_field_.set(7); return clear_incremental_state_.get(); }
+
+ private:
+  ::protozero::CopyablePtr<GetAsyncCommandResponse_SetupTracing> setup_tracing_;
+  ::protozero::CopyablePtr<GetAsyncCommandResponse_SetupDataSource> setup_data_source_;
+  ::protozero::CopyablePtr<GetAsyncCommandResponse_StartDataSource> start_data_source_;
+  ::protozero::CopyablePtr<GetAsyncCommandResponse_StopDataSource> stop_data_source_;
+  ::protozero::CopyablePtr<GetAsyncCommandResponse_Flush> flush_;
+  ::protozero::CopyablePtr<GetAsyncCommandResponse_ClearIncrementalState> clear_incremental_state_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<8> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT GetAsyncCommandResponse_ClearIncrementalState : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDataSourceIdsFieldNumber = 1,
+  };
+
+  GetAsyncCommandResponse_ClearIncrementalState();
+  ~GetAsyncCommandResponse_ClearIncrementalState() override;
+  GetAsyncCommandResponse_ClearIncrementalState(GetAsyncCommandResponse_ClearIncrementalState&&) noexcept;
+  GetAsyncCommandResponse_ClearIncrementalState& operator=(GetAsyncCommandResponse_ClearIncrementalState&&);
+  GetAsyncCommandResponse_ClearIncrementalState(const GetAsyncCommandResponse_ClearIncrementalState&);
+  GetAsyncCommandResponse_ClearIncrementalState& operator=(const GetAsyncCommandResponse_ClearIncrementalState&);
+  bool operator==(const GetAsyncCommandResponse_ClearIncrementalState&) const;
+  bool operator!=(const GetAsyncCommandResponse_ClearIncrementalState& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<uint64_t>& data_source_ids() const { return data_source_ids_; }
+  std::vector<uint64_t>* mutable_data_source_ids() { return &data_source_ids_; }
+  int data_source_ids_size() const { return static_cast<int>(data_source_ids_.size()); }
+  void clear_data_source_ids() { data_source_ids_.clear(); }
+  void add_data_source_ids(uint64_t value) { data_source_ids_.emplace_back(value); }
+  uint64_t* add_data_source_ids() { data_source_ids_.emplace_back(); return &data_source_ids_.back(); }
+
+ private:
+  std::vector<uint64_t> data_source_ids_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT GetAsyncCommandResponse_Flush : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDataSourceIdsFieldNumber = 1,
+    kRequestIdFieldNumber = 2,
+    kFlagsFieldNumber = 3,
+  };
+
+  GetAsyncCommandResponse_Flush();
+  ~GetAsyncCommandResponse_Flush() override;
+  GetAsyncCommandResponse_Flush(GetAsyncCommandResponse_Flush&&) noexcept;
+  GetAsyncCommandResponse_Flush& operator=(GetAsyncCommandResponse_Flush&&);
+  GetAsyncCommandResponse_Flush(const GetAsyncCommandResponse_Flush&);
+  GetAsyncCommandResponse_Flush& operator=(const GetAsyncCommandResponse_Flush&);
+  bool operator==(const GetAsyncCommandResponse_Flush&) const;
+  bool operator!=(const GetAsyncCommandResponse_Flush& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<uint64_t>& data_source_ids() const { return data_source_ids_; }
+  std::vector<uint64_t>* mutable_data_source_ids() { return &data_source_ids_; }
+  int data_source_ids_size() const { return static_cast<int>(data_source_ids_.size()); }
+  void clear_data_source_ids() { data_source_ids_.clear(); }
+  void add_data_source_ids(uint64_t value) { data_source_ids_.emplace_back(value); }
+  uint64_t* add_data_source_ids() { data_source_ids_.emplace_back(); return &data_source_ids_.back(); }
+
+  bool has_request_id() const { return _has_field_[2]; }
+  uint64_t request_id() const { return request_id_; }
+  void set_request_id(uint64_t value) { request_id_ = value; _has_field_.set(2); }
+
+  bool has_flags() const { return _has_field_[3]; }
+  uint64_t flags() const { return flags_; }
+  void set_flags(uint64_t value) { flags_ = value; _has_field_.set(3); }
+
+ private:
+  std::vector<uint64_t> data_source_ids_;
+  uint64_t request_id_{};
+  uint64_t flags_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT GetAsyncCommandResponse_StopDataSource : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kInstanceIdFieldNumber = 1,
+  };
+
+  GetAsyncCommandResponse_StopDataSource();
+  ~GetAsyncCommandResponse_StopDataSource() override;
+  GetAsyncCommandResponse_StopDataSource(GetAsyncCommandResponse_StopDataSource&&) noexcept;
+  GetAsyncCommandResponse_StopDataSource& operator=(GetAsyncCommandResponse_StopDataSource&&);
+  GetAsyncCommandResponse_StopDataSource(const GetAsyncCommandResponse_StopDataSource&);
+  GetAsyncCommandResponse_StopDataSource& operator=(const GetAsyncCommandResponse_StopDataSource&);
+  bool operator==(const GetAsyncCommandResponse_StopDataSource&) const;
+  bool operator!=(const GetAsyncCommandResponse_StopDataSource& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_instance_id() const { return _has_field_[1]; }
+  uint64_t instance_id() const { return instance_id_; }
+  void set_instance_id(uint64_t value) { instance_id_ = value; _has_field_.set(1); }
+
+ private:
+  uint64_t instance_id_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT GetAsyncCommandResponse_StartDataSource : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kNewInstanceIdFieldNumber = 1,
+    kConfigFieldNumber = 2,
+  };
+
+  GetAsyncCommandResponse_StartDataSource();
+  ~GetAsyncCommandResponse_StartDataSource() override;
+  GetAsyncCommandResponse_StartDataSource(GetAsyncCommandResponse_StartDataSource&&) noexcept;
+  GetAsyncCommandResponse_StartDataSource& operator=(GetAsyncCommandResponse_StartDataSource&&);
+  GetAsyncCommandResponse_StartDataSource(const GetAsyncCommandResponse_StartDataSource&);
+  GetAsyncCommandResponse_StartDataSource& operator=(const GetAsyncCommandResponse_StartDataSource&);
+  bool operator==(const GetAsyncCommandResponse_StartDataSource&) const;
+  bool operator!=(const GetAsyncCommandResponse_StartDataSource& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_new_instance_id() const { return _has_field_[1]; }
+  uint64_t new_instance_id() const { return new_instance_id_; }
+  void set_new_instance_id(uint64_t value) { new_instance_id_ = value; _has_field_.set(1); }
+
+  bool has_config() const { return _has_field_[2]; }
+  const DataSourceConfig& config() const { return *config_; }
+  DataSourceConfig* mutable_config() { _has_field_.set(2); return config_.get(); }
+
+ private:
+  uint64_t new_instance_id_{};
+  ::protozero::CopyablePtr<DataSourceConfig> config_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT GetAsyncCommandResponse_SetupDataSource : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kNewInstanceIdFieldNumber = 1,
+    kConfigFieldNumber = 2,
+  };
+
+  GetAsyncCommandResponse_SetupDataSource();
+  ~GetAsyncCommandResponse_SetupDataSource() override;
+  GetAsyncCommandResponse_SetupDataSource(GetAsyncCommandResponse_SetupDataSource&&) noexcept;
+  GetAsyncCommandResponse_SetupDataSource& operator=(GetAsyncCommandResponse_SetupDataSource&&);
+  GetAsyncCommandResponse_SetupDataSource(const GetAsyncCommandResponse_SetupDataSource&);
+  GetAsyncCommandResponse_SetupDataSource& operator=(const GetAsyncCommandResponse_SetupDataSource&);
+  bool operator==(const GetAsyncCommandResponse_SetupDataSource&) const;
+  bool operator!=(const GetAsyncCommandResponse_SetupDataSource& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_new_instance_id() const { return _has_field_[1]; }
+  uint64_t new_instance_id() const { return new_instance_id_; }
+  void set_new_instance_id(uint64_t value) { new_instance_id_ = value; _has_field_.set(1); }
+
+  bool has_config() const { return _has_field_[2]; }
+  const DataSourceConfig& config() const { return *config_; }
+  DataSourceConfig* mutable_config() { _has_field_.set(2); return config_.get(); }
+
+ private:
+  uint64_t new_instance_id_{};
+  ::protozero::CopyablePtr<DataSourceConfig> config_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT GetAsyncCommandResponse_SetupTracing : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kSharedBufferPageSizeKbFieldNumber = 1,
+    kShmKeyWindowsFieldNumber = 2,
+  };
+
+  GetAsyncCommandResponse_SetupTracing();
+  ~GetAsyncCommandResponse_SetupTracing() override;
+  GetAsyncCommandResponse_SetupTracing(GetAsyncCommandResponse_SetupTracing&&) noexcept;
+  GetAsyncCommandResponse_SetupTracing& operator=(GetAsyncCommandResponse_SetupTracing&&);
+  GetAsyncCommandResponse_SetupTracing(const GetAsyncCommandResponse_SetupTracing&);
+  GetAsyncCommandResponse_SetupTracing& operator=(const GetAsyncCommandResponse_SetupTracing&);
+  bool operator==(const GetAsyncCommandResponse_SetupTracing&) const;
+  bool operator!=(const GetAsyncCommandResponse_SetupTracing& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_shared_buffer_page_size_kb() const { return _has_field_[1]; }
+  uint32_t shared_buffer_page_size_kb() const { return shared_buffer_page_size_kb_; }
+  void set_shared_buffer_page_size_kb(uint32_t value) { shared_buffer_page_size_kb_ = value; _has_field_.set(1); }
+
+  bool has_shm_key_windows() const { return _has_field_[2]; }
+  const std::string& shm_key_windows() const { return shm_key_windows_; }
+  void set_shm_key_windows(const std::string& value) { shm_key_windows_ = value; _has_field_.set(2); }
+
+ private:
+  uint32_t shared_buffer_page_size_kb_{};
+  std::string shm_key_windows_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT GetAsyncCommandRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  GetAsyncCommandRequest();
+  ~GetAsyncCommandRequest() override;
+  GetAsyncCommandRequest(GetAsyncCommandRequest&&) noexcept;
+  GetAsyncCommandRequest& operator=(GetAsyncCommandRequest&&);
+  GetAsyncCommandRequest(const GetAsyncCommandRequest&);
+  GetAsyncCommandRequest& operator=(const GetAsyncCommandRequest&);
+  bool operator==(const GetAsyncCommandRequest&) const;
+  bool operator!=(const GetAsyncCommandRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT ActivateTriggersResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  ActivateTriggersResponse();
+  ~ActivateTriggersResponse() override;
+  ActivateTriggersResponse(ActivateTriggersResponse&&) noexcept;
+  ActivateTriggersResponse& operator=(ActivateTriggersResponse&&);
+  ActivateTriggersResponse(const ActivateTriggersResponse&);
+  ActivateTriggersResponse& operator=(const ActivateTriggersResponse&);
+  bool operator==(const ActivateTriggersResponse&) const;
+  bool operator!=(const ActivateTriggersResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT ActivateTriggersRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kTriggerNamesFieldNumber = 1,
+  };
+
+  ActivateTriggersRequest();
+  ~ActivateTriggersRequest() override;
+  ActivateTriggersRequest(ActivateTriggersRequest&&) noexcept;
+  ActivateTriggersRequest& operator=(ActivateTriggersRequest&&);
+  ActivateTriggersRequest(const ActivateTriggersRequest&);
+  ActivateTriggersRequest& operator=(const ActivateTriggersRequest&);
+  bool operator==(const ActivateTriggersRequest&) const;
+  bool operator!=(const ActivateTriggersRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<std::string>& trigger_names() const { return trigger_names_; }
+  std::vector<std::string>* mutable_trigger_names() { return &trigger_names_; }
+  int trigger_names_size() const { return static_cast<int>(trigger_names_.size()); }
+  void clear_trigger_names() { trigger_names_.clear(); }
+  void add_trigger_names(std::string value) { trigger_names_.emplace_back(value); }
+  std::string* add_trigger_names() { trigger_names_.emplace_back(); return &trigger_names_.back(); }
+
+ private:
+  std::vector<std::string> trigger_names_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT NotifyDataSourceStoppedResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  NotifyDataSourceStoppedResponse();
+  ~NotifyDataSourceStoppedResponse() override;
+  NotifyDataSourceStoppedResponse(NotifyDataSourceStoppedResponse&&) noexcept;
+  NotifyDataSourceStoppedResponse& operator=(NotifyDataSourceStoppedResponse&&);
+  NotifyDataSourceStoppedResponse(const NotifyDataSourceStoppedResponse&);
+  NotifyDataSourceStoppedResponse& operator=(const NotifyDataSourceStoppedResponse&);
+  bool operator==(const NotifyDataSourceStoppedResponse&) const;
+  bool operator!=(const NotifyDataSourceStoppedResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT NotifyDataSourceStoppedRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDataSourceIdFieldNumber = 1,
+  };
+
+  NotifyDataSourceStoppedRequest();
+  ~NotifyDataSourceStoppedRequest() override;
+  NotifyDataSourceStoppedRequest(NotifyDataSourceStoppedRequest&&) noexcept;
+  NotifyDataSourceStoppedRequest& operator=(NotifyDataSourceStoppedRequest&&);
+  NotifyDataSourceStoppedRequest(const NotifyDataSourceStoppedRequest&);
+  NotifyDataSourceStoppedRequest& operator=(const NotifyDataSourceStoppedRequest&);
+  bool operator==(const NotifyDataSourceStoppedRequest&) const;
+  bool operator!=(const NotifyDataSourceStoppedRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_data_source_id() const { return _has_field_[1]; }
+  uint64_t data_source_id() const { return data_source_id_; }
+  void set_data_source_id(uint64_t value) { data_source_id_ = value; _has_field_.set(1); }
+
+ private:
+  uint64_t data_source_id_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT NotifyDataSourceStartedResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  NotifyDataSourceStartedResponse();
+  ~NotifyDataSourceStartedResponse() override;
+  NotifyDataSourceStartedResponse(NotifyDataSourceStartedResponse&&) noexcept;
+  NotifyDataSourceStartedResponse& operator=(NotifyDataSourceStartedResponse&&);
+  NotifyDataSourceStartedResponse(const NotifyDataSourceStartedResponse&);
+  NotifyDataSourceStartedResponse& operator=(const NotifyDataSourceStartedResponse&);
+  bool operator==(const NotifyDataSourceStartedResponse&) const;
+  bool operator!=(const NotifyDataSourceStartedResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT NotifyDataSourceStartedRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDataSourceIdFieldNumber = 1,
+  };
+
+  NotifyDataSourceStartedRequest();
+  ~NotifyDataSourceStartedRequest() override;
+  NotifyDataSourceStartedRequest(NotifyDataSourceStartedRequest&&) noexcept;
+  NotifyDataSourceStartedRequest& operator=(NotifyDataSourceStartedRequest&&);
+  NotifyDataSourceStartedRequest(const NotifyDataSourceStartedRequest&);
+  NotifyDataSourceStartedRequest& operator=(const NotifyDataSourceStartedRequest&);
+  bool operator==(const NotifyDataSourceStartedRequest&) const;
+  bool operator!=(const NotifyDataSourceStartedRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_data_source_id() const { return _has_field_[1]; }
+  uint64_t data_source_id() const { return data_source_id_; }
+  void set_data_source_id(uint64_t value) { data_source_id_ = value; _has_field_.set(1); }
+
+ private:
+  uint64_t data_source_id_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT CommitDataResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  CommitDataResponse();
+  ~CommitDataResponse() override;
+  CommitDataResponse(CommitDataResponse&&) noexcept;
+  CommitDataResponse& operator=(CommitDataResponse&&);
+  CommitDataResponse(const CommitDataResponse&);
+  CommitDataResponse& operator=(const CommitDataResponse&);
+  bool operator==(const CommitDataResponse&) const;
+  bool operator!=(const CommitDataResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT UnregisterTraceWriterResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  UnregisterTraceWriterResponse();
+  ~UnregisterTraceWriterResponse() override;
+  UnregisterTraceWriterResponse(UnregisterTraceWriterResponse&&) noexcept;
+  UnregisterTraceWriterResponse& operator=(UnregisterTraceWriterResponse&&);
+  UnregisterTraceWriterResponse(const UnregisterTraceWriterResponse&);
+  UnregisterTraceWriterResponse& operator=(const UnregisterTraceWriterResponse&);
+  bool operator==(const UnregisterTraceWriterResponse&) const;
+  bool operator!=(const UnregisterTraceWriterResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT UnregisterTraceWriterRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kTraceWriterIdFieldNumber = 1,
+  };
+
+  UnregisterTraceWriterRequest();
+  ~UnregisterTraceWriterRequest() override;
+  UnregisterTraceWriterRequest(UnregisterTraceWriterRequest&&) noexcept;
+  UnregisterTraceWriterRequest& operator=(UnregisterTraceWriterRequest&&);
+  UnregisterTraceWriterRequest(const UnregisterTraceWriterRequest&);
+  UnregisterTraceWriterRequest& operator=(const UnregisterTraceWriterRequest&);
+  bool operator==(const UnregisterTraceWriterRequest&) const;
+  bool operator!=(const UnregisterTraceWriterRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_trace_writer_id() const { return _has_field_[1]; }
+  uint32_t trace_writer_id() const { return trace_writer_id_; }
+  void set_trace_writer_id(uint32_t value) { trace_writer_id_ = value; _has_field_.set(1); }
+
+ private:
+  uint32_t trace_writer_id_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT RegisterTraceWriterResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  RegisterTraceWriterResponse();
+  ~RegisterTraceWriterResponse() override;
+  RegisterTraceWriterResponse(RegisterTraceWriterResponse&&) noexcept;
+  RegisterTraceWriterResponse& operator=(RegisterTraceWriterResponse&&);
+  RegisterTraceWriterResponse(const RegisterTraceWriterResponse&);
+  RegisterTraceWriterResponse& operator=(const RegisterTraceWriterResponse&);
+  bool operator==(const RegisterTraceWriterResponse&) const;
+  bool operator!=(const RegisterTraceWriterResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT RegisterTraceWriterRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kTraceWriterIdFieldNumber = 1,
+    kTargetBufferFieldNumber = 2,
+  };
+
+  RegisterTraceWriterRequest();
+  ~RegisterTraceWriterRequest() override;
+  RegisterTraceWriterRequest(RegisterTraceWriterRequest&&) noexcept;
+  RegisterTraceWriterRequest& operator=(RegisterTraceWriterRequest&&);
+  RegisterTraceWriterRequest(const RegisterTraceWriterRequest&);
+  RegisterTraceWriterRequest& operator=(const RegisterTraceWriterRequest&);
+  bool operator==(const RegisterTraceWriterRequest&) const;
+  bool operator!=(const RegisterTraceWriterRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_trace_writer_id() const { return _has_field_[1]; }
+  uint32_t trace_writer_id() const { return trace_writer_id_; }
+  void set_trace_writer_id(uint32_t value) { trace_writer_id_ = value; _has_field_.set(1); }
+
+  bool has_target_buffer() const { return _has_field_[2]; }
+  uint32_t target_buffer() const { return target_buffer_; }
+  void set_target_buffer(uint32_t value) { target_buffer_ = value; _has_field_.set(2); }
+
+ private:
+  uint32_t trace_writer_id_{};
+  uint32_t target_buffer_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT UnregisterDataSourceResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  UnregisterDataSourceResponse();
+  ~UnregisterDataSourceResponse() override;
+  UnregisterDataSourceResponse(UnregisterDataSourceResponse&&) noexcept;
+  UnregisterDataSourceResponse& operator=(UnregisterDataSourceResponse&&);
+  UnregisterDataSourceResponse(const UnregisterDataSourceResponse&);
+  UnregisterDataSourceResponse& operator=(const UnregisterDataSourceResponse&);
+  bool operator==(const UnregisterDataSourceResponse&) const;
+  bool operator!=(const UnregisterDataSourceResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT UnregisterDataSourceRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDataSourceNameFieldNumber = 1,
+  };
+
+  UnregisterDataSourceRequest();
+  ~UnregisterDataSourceRequest() override;
+  UnregisterDataSourceRequest(UnregisterDataSourceRequest&&) noexcept;
+  UnregisterDataSourceRequest& operator=(UnregisterDataSourceRequest&&);
+  UnregisterDataSourceRequest(const UnregisterDataSourceRequest&);
+  UnregisterDataSourceRequest& operator=(const UnregisterDataSourceRequest&);
+  bool operator==(const UnregisterDataSourceRequest&) const;
+  bool operator!=(const UnregisterDataSourceRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_data_source_name() const { return _has_field_[1]; }
+  const std::string& data_source_name() const { return data_source_name_; }
+  void set_data_source_name(const std::string& value) { data_source_name_ = value; _has_field_.set(1); }
+
+ private:
+  std::string data_source_name_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT UpdateDataSourceResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  UpdateDataSourceResponse();
+  ~UpdateDataSourceResponse() override;
+  UpdateDataSourceResponse(UpdateDataSourceResponse&&) noexcept;
+  UpdateDataSourceResponse& operator=(UpdateDataSourceResponse&&);
+  UpdateDataSourceResponse(const UpdateDataSourceResponse&);
+  UpdateDataSourceResponse& operator=(const UpdateDataSourceResponse&);
+  bool operator==(const UpdateDataSourceResponse&) const;
+  bool operator!=(const UpdateDataSourceResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT UpdateDataSourceRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDataSourceDescriptorFieldNumber = 1,
+  };
+
+  UpdateDataSourceRequest();
+  ~UpdateDataSourceRequest() override;
+  UpdateDataSourceRequest(UpdateDataSourceRequest&&) noexcept;
+  UpdateDataSourceRequest& operator=(UpdateDataSourceRequest&&);
+  UpdateDataSourceRequest(const UpdateDataSourceRequest&);
+  UpdateDataSourceRequest& operator=(const UpdateDataSourceRequest&);
+  bool operator==(const UpdateDataSourceRequest&) const;
+  bool operator!=(const UpdateDataSourceRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_data_source_descriptor() const { return _has_field_[1]; }
+  const DataSourceDescriptor& data_source_descriptor() const { return *data_source_descriptor_; }
+  DataSourceDescriptor* mutable_data_source_descriptor() { _has_field_.set(1); return data_source_descriptor_.get(); }
+
+ private:
+  ::protozero::CopyablePtr<DataSourceDescriptor> data_source_descriptor_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT RegisterDataSourceResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kErrorFieldNumber = 1,
+  };
+
+  RegisterDataSourceResponse();
+  ~RegisterDataSourceResponse() override;
+  RegisterDataSourceResponse(RegisterDataSourceResponse&&) noexcept;
+  RegisterDataSourceResponse& operator=(RegisterDataSourceResponse&&);
+  RegisterDataSourceResponse(const RegisterDataSourceResponse&);
+  RegisterDataSourceResponse& operator=(const RegisterDataSourceResponse&);
+  bool operator==(const RegisterDataSourceResponse&) const;
+  bool operator!=(const RegisterDataSourceResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_error() const { return _has_field_[1]; }
+  const std::string& error() const { return error_; }
+  void set_error(const std::string& value) { error_ = value; _has_field_.set(1); }
+
+ private:
+  std::string error_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT RegisterDataSourceRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDataSourceDescriptorFieldNumber = 1,
+  };
+
+  RegisterDataSourceRequest();
+  ~RegisterDataSourceRequest() override;
+  RegisterDataSourceRequest(RegisterDataSourceRequest&&) noexcept;
+  RegisterDataSourceRequest& operator=(RegisterDataSourceRequest&&);
+  RegisterDataSourceRequest(const RegisterDataSourceRequest&);
+  RegisterDataSourceRequest& operator=(const RegisterDataSourceRequest&);
+  bool operator==(const RegisterDataSourceRequest&) const;
+  bool operator!=(const RegisterDataSourceRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_data_source_descriptor() const { return _has_field_[1]; }
+  const DataSourceDescriptor& data_source_descriptor() const { return *data_source_descriptor_; }
+  DataSourceDescriptor* mutable_data_source_descriptor() { _has_field_.set(1); return data_source_descriptor_.get(); }
+
+ private:
+  ::protozero::CopyablePtr<DataSourceDescriptor> data_source_descriptor_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT InitializeConnectionResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kUsingShmemProvidedByProducerFieldNumber = 1,
+    kDirectSmbPatchingSupportedFieldNumber = 2,
+    kUseShmemEmulationFieldNumber = 3,
+  };
+
+  InitializeConnectionResponse();
+  ~InitializeConnectionResponse() override;
+  InitializeConnectionResponse(InitializeConnectionResponse&&) noexcept;
+  InitializeConnectionResponse& operator=(InitializeConnectionResponse&&);
+  InitializeConnectionResponse(const InitializeConnectionResponse&);
+  InitializeConnectionResponse& operator=(const InitializeConnectionResponse&);
+  bool operator==(const InitializeConnectionResponse&) const;
+  bool operator!=(const InitializeConnectionResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_using_shmem_provided_by_producer() const { return _has_field_[1]; }
+  bool using_shmem_provided_by_producer() const { return using_shmem_provided_by_producer_; }
+  void set_using_shmem_provided_by_producer(bool value) { using_shmem_provided_by_producer_ = value; _has_field_.set(1); }
+
+  bool has_direct_smb_patching_supported() const { return _has_field_[2]; }
+  bool direct_smb_patching_supported() const { return direct_smb_patching_supported_; }
+  void set_direct_smb_patching_supported(bool value) { direct_smb_patching_supported_ = value; _has_field_.set(2); }
+
+  bool has_use_shmem_emulation() const { return _has_field_[3]; }
+  bool use_shmem_emulation() const { return use_shmem_emulation_; }
+  void set_use_shmem_emulation(bool value) { use_shmem_emulation_ = value; _has_field_.set(3); }
+
+ private:
+  bool using_shmem_provided_by_producer_{};
+  bool direct_smb_patching_supported_{};
+  bool use_shmem_emulation_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT InitializeConnectionRequest : public ::protozero::CppMessageObj {
+ public:
+  using ProducerSMBScrapingMode = InitializeConnectionRequest_ProducerSMBScrapingMode;
+  static constexpr auto SMB_SCRAPING_UNSPECIFIED = InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_UNSPECIFIED;
+  static constexpr auto SMB_SCRAPING_ENABLED = InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_ENABLED;
+  static constexpr auto SMB_SCRAPING_DISABLED = InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_DISABLED;
+  static constexpr auto ProducerSMBScrapingMode_MIN = InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_UNSPECIFIED;
+  static constexpr auto ProducerSMBScrapingMode_MAX = InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_DISABLED;
+  enum FieldNumbers {
+    kSharedMemoryPageSizeHintBytesFieldNumber = 1,
+    kSharedMemorySizeHintBytesFieldNumber = 2,
+    kProducerNameFieldNumber = 3,
+    kSmbScrapingModeFieldNumber = 4,
+    kProducerProvidedShmemFieldNumber = 6,
+    kSdkVersionFieldNumber = 8,
+    kShmKeyWindowsFieldNumber = 7,
+  };
+
+  InitializeConnectionRequest();
+  ~InitializeConnectionRequest() override;
+  InitializeConnectionRequest(InitializeConnectionRequest&&) noexcept;
+  InitializeConnectionRequest& operator=(InitializeConnectionRequest&&);
+  InitializeConnectionRequest(const InitializeConnectionRequest&);
+  InitializeConnectionRequest& operator=(const InitializeConnectionRequest&);
+  bool operator==(const InitializeConnectionRequest&) const;
+  bool operator!=(const InitializeConnectionRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_shared_memory_page_size_hint_bytes() const { return _has_field_[1]; }
+  uint32_t shared_memory_page_size_hint_bytes() const { return shared_memory_page_size_hint_bytes_; }
+  void set_shared_memory_page_size_hint_bytes(uint32_t value) { shared_memory_page_size_hint_bytes_ = value; _has_field_.set(1); }
+
+  bool has_shared_memory_size_hint_bytes() const { return _has_field_[2]; }
+  uint32_t shared_memory_size_hint_bytes() const { return shared_memory_size_hint_bytes_; }
+  void set_shared_memory_size_hint_bytes(uint32_t value) { shared_memory_size_hint_bytes_ = value; _has_field_.set(2); }
+
+  bool has_producer_name() const { return _has_field_[3]; }
+  const std::string& producer_name() const { return producer_name_; }
+  void set_producer_name(const std::string& value) { producer_name_ = value; _has_field_.set(3); }
+
+  bool has_smb_scraping_mode() const { return _has_field_[4]; }
+  InitializeConnectionRequest_ProducerSMBScrapingMode smb_scraping_mode() const { return smb_scraping_mode_; }
+  void set_smb_scraping_mode(InitializeConnectionRequest_ProducerSMBScrapingMode value) { smb_scraping_mode_ = value; _has_field_.set(4); }
+
+  bool has_producer_provided_shmem() const { return _has_field_[6]; }
+  bool producer_provided_shmem() const { return producer_provided_shmem_; }
+  void set_producer_provided_shmem(bool value) { producer_provided_shmem_ = value; _has_field_.set(6); }
+
+  bool has_sdk_version() const { return _has_field_[8]; }
+  const std::string& sdk_version() const { return sdk_version_; }
+  void set_sdk_version(const std::string& value) { sdk_version_ = value; _has_field_.set(8); }
+
+  bool has_shm_key_windows() const { return _has_field_[7]; }
+  const std::string& shm_key_windows() const { return shm_key_windows_; }
+  void set_shm_key_windows(const std::string& value) { shm_key_windows_ = value; _has_field_.set(7); }
+
+ private:
+  uint32_t shared_memory_page_size_hint_bytes_{};
+  uint32_t shared_memory_size_hint_bytes_{};
+  std::string producer_name_{};
+  InitializeConnectionRequest_ProducerSMBScrapingMode smb_scraping_mode_{};
+  bool producer_provided_shmem_{};
+  std::string sdk_version_{};
+  std::string shm_key_windows_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<9> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_PRODUCER_PORT_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/ipc/relay_port.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_RELAY_PORT_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_RELAY_PORT_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class SyncClockResponse;
+class SyncClockRequest;
+class SyncClockRequest_Clock;
+enum SyncClockRequest_Phase : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum SyncClockRequest_Phase : int {
+  SyncClockRequest_Phase_PING = 1,
+  SyncClockRequest_Phase_UPDATE = 2,
+};
+
+class PERFETTO_EXPORT_COMPONENT SyncClockResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  SyncClockResponse();
+  ~SyncClockResponse() override;
+  SyncClockResponse(SyncClockResponse&&) noexcept;
+  SyncClockResponse& operator=(SyncClockResponse&&);
+  SyncClockResponse(const SyncClockResponse&);
+  SyncClockResponse& operator=(const SyncClockResponse&);
+  bool operator==(const SyncClockResponse&) const;
+  bool operator!=(const SyncClockResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT SyncClockRequest : public ::protozero::CppMessageObj {
+ public:
+  using Clock = SyncClockRequest_Clock;
+  using Phase = SyncClockRequest_Phase;
+  static constexpr auto PING = SyncClockRequest_Phase_PING;
+  static constexpr auto UPDATE = SyncClockRequest_Phase_UPDATE;
+  static constexpr auto Phase_MIN = SyncClockRequest_Phase_PING;
+  static constexpr auto Phase_MAX = SyncClockRequest_Phase_UPDATE;
+  enum FieldNumbers {
+    kPhaseFieldNumber = 1,
+    kClocksFieldNumber = 2,
+  };
+
+  SyncClockRequest();
+  ~SyncClockRequest() override;
+  SyncClockRequest(SyncClockRequest&&) noexcept;
+  SyncClockRequest& operator=(SyncClockRequest&&);
+  SyncClockRequest(const SyncClockRequest&);
+  SyncClockRequest& operator=(const SyncClockRequest&);
+  bool operator==(const SyncClockRequest&) const;
+  bool operator!=(const SyncClockRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_phase() const { return _has_field_[1]; }
+  SyncClockRequest_Phase phase() const { return phase_; }
+  void set_phase(SyncClockRequest_Phase value) { phase_ = value; _has_field_.set(1); }
+
+  const std::vector<SyncClockRequest_Clock>& clocks() const { return clocks_; }
+  std::vector<SyncClockRequest_Clock>* mutable_clocks() { return &clocks_; }
+  int clocks_size() const;
+  void clear_clocks();
+  SyncClockRequest_Clock* add_clocks();
+
+ private:
+  SyncClockRequest_Phase phase_{};
+  std::vector<SyncClockRequest_Clock> clocks_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT SyncClockRequest_Clock : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kClockIdFieldNumber = 1,
+    kTimestampFieldNumber = 2,
+  };
+
+  SyncClockRequest_Clock();
+  ~SyncClockRequest_Clock() override;
+  SyncClockRequest_Clock(SyncClockRequest_Clock&&) noexcept;
+  SyncClockRequest_Clock& operator=(SyncClockRequest_Clock&&);
+  SyncClockRequest_Clock(const SyncClockRequest_Clock&);
+  SyncClockRequest_Clock& operator=(const SyncClockRequest_Clock&);
+  bool operator==(const SyncClockRequest_Clock&) const;
+  bool operator!=(const SyncClockRequest_Clock& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_clock_id() const { return _has_field_[1]; }
+  uint32_t clock_id() const { return clock_id_; }
+  void set_clock_id(uint32_t value) { clock_id_ = value; _has_field_.set(1); }
+
+  bool has_timestamp() const { return _has_field_[2]; }
+  uint64_t timestamp() const { return timestamp_; }
+  void set_timestamp(uint64_t value) { timestamp_ = value; _has_field_.set(2); }
+
+ private:
+  uint32_t clock_id_{};
+  uint64_t timestamp_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_RELAY_PORT_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/ipc/wire_protocol.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_WIRE_PROTOCOL_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_WIRE_PROTOCOL_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class IPCFrame;
+class IPCFrame_SetPeerIdentity;
+class IPCFrame_RequestError;
+class IPCFrame_InvokeMethodReply;
+class IPCFrame_InvokeMethod;
+class IPCFrame_BindServiceReply;
+class IPCFrame_BindServiceReply_MethodInfo;
+class IPCFrame_BindService;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT IPCFrame : public ::protozero::CppMessageObj {
+ public:
+  using BindService = IPCFrame_BindService;
+  using BindServiceReply = IPCFrame_BindServiceReply;
+  using InvokeMethod = IPCFrame_InvokeMethod;
+  using InvokeMethodReply = IPCFrame_InvokeMethodReply;
+  using RequestError = IPCFrame_RequestError;
+  using SetPeerIdentity = IPCFrame_SetPeerIdentity;
+  enum FieldNumbers {
+    kRequestIdFieldNumber = 2,
+    kMsgBindServiceFieldNumber = 3,
+    kMsgBindServiceReplyFieldNumber = 4,
+    kMsgInvokeMethodFieldNumber = 5,
+    kMsgInvokeMethodReplyFieldNumber = 6,
+    kMsgRequestErrorFieldNumber = 7,
+    kSetPeerIdentityFieldNumber = 8,
+    kDataForTestingFieldNumber = 1,
+  };
+
+  IPCFrame();
+  ~IPCFrame() override;
+  IPCFrame(IPCFrame&&) noexcept;
+  IPCFrame& operator=(IPCFrame&&);
+  IPCFrame(const IPCFrame&);
+  IPCFrame& operator=(const IPCFrame&);
+  bool operator==(const IPCFrame&) const;
+  bool operator!=(const IPCFrame& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_request_id() const { return _has_field_[2]; }
+  uint64_t request_id() const { return request_id_; }
+  void set_request_id(uint64_t value) { request_id_ = value; _has_field_.set(2); }
+
+  bool has_msg_bind_service() const { return _has_field_[3]; }
+  const IPCFrame_BindService& msg_bind_service() const { return *msg_bind_service_; }
+  IPCFrame_BindService* mutable_msg_bind_service() { _has_field_.set(3); return msg_bind_service_.get(); }
+
+  bool has_msg_bind_service_reply() const { return _has_field_[4]; }
+  const IPCFrame_BindServiceReply& msg_bind_service_reply() const { return *msg_bind_service_reply_; }
+  IPCFrame_BindServiceReply* mutable_msg_bind_service_reply() { _has_field_.set(4); return msg_bind_service_reply_.get(); }
+
+  bool has_msg_invoke_method() const { return _has_field_[5]; }
+  const IPCFrame_InvokeMethod& msg_invoke_method() const { return *msg_invoke_method_; }
+  IPCFrame_InvokeMethod* mutable_msg_invoke_method() { _has_field_.set(5); return msg_invoke_method_.get(); }
+
+  bool has_msg_invoke_method_reply() const { return _has_field_[6]; }
+  const IPCFrame_InvokeMethodReply& msg_invoke_method_reply() const { return *msg_invoke_method_reply_; }
+  IPCFrame_InvokeMethodReply* mutable_msg_invoke_method_reply() { _has_field_.set(6); return msg_invoke_method_reply_.get(); }
+
+  bool has_msg_request_error() const { return _has_field_[7]; }
+  const IPCFrame_RequestError& msg_request_error() const { return *msg_request_error_; }
+  IPCFrame_RequestError* mutable_msg_request_error() { _has_field_.set(7); return msg_request_error_.get(); }
+
+  bool has_set_peer_identity() const { return _has_field_[8]; }
+  const IPCFrame_SetPeerIdentity& set_peer_identity() const { return *set_peer_identity_; }
+  IPCFrame_SetPeerIdentity* mutable_set_peer_identity() { _has_field_.set(8); return set_peer_identity_.get(); }
+
+  const std::vector<std::string>& data_for_testing() const { return data_for_testing_; }
+  std::vector<std::string>* mutable_data_for_testing() { return &data_for_testing_; }
+  int data_for_testing_size() const { return static_cast<int>(data_for_testing_.size()); }
+  void clear_data_for_testing() { data_for_testing_.clear(); }
+  void add_data_for_testing(std::string value) { data_for_testing_.emplace_back(value); }
+  std::string* add_data_for_testing() { data_for_testing_.emplace_back(); return &data_for_testing_.back(); }
+
+ private:
+  uint64_t request_id_{};
+  ::protozero::CopyablePtr<IPCFrame_BindService> msg_bind_service_;
+  ::protozero::CopyablePtr<IPCFrame_BindServiceReply> msg_bind_service_reply_;
+  ::protozero::CopyablePtr<IPCFrame_InvokeMethod> msg_invoke_method_;
+  ::protozero::CopyablePtr<IPCFrame_InvokeMethodReply> msg_invoke_method_reply_;
+  ::protozero::CopyablePtr<IPCFrame_RequestError> msg_request_error_;
+  ::protozero::CopyablePtr<IPCFrame_SetPeerIdentity> set_peer_identity_;
+  std::vector<std::string> data_for_testing_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<9> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT IPCFrame_SetPeerIdentity : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kPidFieldNumber = 1,
+    kUidFieldNumber = 2,
+    kMachineIdHintFieldNumber = 3,
+  };
+
+  IPCFrame_SetPeerIdentity();
+  ~IPCFrame_SetPeerIdentity() override;
+  IPCFrame_SetPeerIdentity(IPCFrame_SetPeerIdentity&&) noexcept;
+  IPCFrame_SetPeerIdentity& operator=(IPCFrame_SetPeerIdentity&&);
+  IPCFrame_SetPeerIdentity(const IPCFrame_SetPeerIdentity&);
+  IPCFrame_SetPeerIdentity& operator=(const IPCFrame_SetPeerIdentity&);
+  bool operator==(const IPCFrame_SetPeerIdentity&) const;
+  bool operator!=(const IPCFrame_SetPeerIdentity& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_pid() const { return _has_field_[1]; }
+  int32_t pid() const { return pid_; }
+  void set_pid(int32_t value) { pid_ = value; _has_field_.set(1); }
+
+  bool has_uid() const { return _has_field_[2]; }
+  int32_t uid() const { return uid_; }
+  void set_uid(int32_t value) { uid_ = value; _has_field_.set(2); }
+
+  bool has_machine_id_hint() const { return _has_field_[3]; }
+  const std::string& machine_id_hint() const { return machine_id_hint_; }
+  void set_machine_id_hint(const std::string& value) { machine_id_hint_ = value; _has_field_.set(3); }
+
+ private:
+  int32_t pid_{};
+  int32_t uid_{};
+  std::string machine_id_hint_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT IPCFrame_RequestError : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kErrorFieldNumber = 1,
+  };
+
+  IPCFrame_RequestError();
+  ~IPCFrame_RequestError() override;
+  IPCFrame_RequestError(IPCFrame_RequestError&&) noexcept;
+  IPCFrame_RequestError& operator=(IPCFrame_RequestError&&);
+  IPCFrame_RequestError(const IPCFrame_RequestError&);
+  IPCFrame_RequestError& operator=(const IPCFrame_RequestError&);
+  bool operator==(const IPCFrame_RequestError&) const;
+  bool operator!=(const IPCFrame_RequestError& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_error() const { return _has_field_[1]; }
+  const std::string& error() const { return error_; }
+  void set_error(const std::string& value) { error_ = value; _has_field_.set(1); }
+
+ private:
+  std::string error_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT IPCFrame_InvokeMethodReply : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kSuccessFieldNumber = 1,
+    kHasMoreFieldNumber = 2,
+    kReplyProtoFieldNumber = 3,
+  };
+
+  IPCFrame_InvokeMethodReply();
+  ~IPCFrame_InvokeMethodReply() override;
+  IPCFrame_InvokeMethodReply(IPCFrame_InvokeMethodReply&&) noexcept;
+  IPCFrame_InvokeMethodReply& operator=(IPCFrame_InvokeMethodReply&&);
+  IPCFrame_InvokeMethodReply(const IPCFrame_InvokeMethodReply&);
+  IPCFrame_InvokeMethodReply& operator=(const IPCFrame_InvokeMethodReply&);
+  bool operator==(const IPCFrame_InvokeMethodReply&) const;
+  bool operator!=(const IPCFrame_InvokeMethodReply& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_success() const { return _has_field_[1]; }
+  bool success() const { return success_; }
+  void set_success(bool value) { success_ = value; _has_field_.set(1); }
+
+  bool has_has_more() const { return _has_field_[2]; }
+  bool has_more() const { return has_more_; }
+  void set_has_more(bool value) { has_more_ = value; _has_field_.set(2); }
+
+  bool has_reply_proto() const { return _has_field_[3]; }
+  const std::string& reply_proto() const { return reply_proto_; }
+  void set_reply_proto(const std::string& value) { reply_proto_ = value; _has_field_.set(3); }
+  void set_reply_proto(const void* p, size_t s) { reply_proto_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(3); }
+
+ private:
+  bool success_{};
+  bool has_more_{};
+  std::string reply_proto_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT IPCFrame_InvokeMethod : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kServiceIdFieldNumber = 1,
+    kMethodIdFieldNumber = 2,
+    kArgsProtoFieldNumber = 3,
+    kDropReplyFieldNumber = 4,
+  };
+
+  IPCFrame_InvokeMethod();
+  ~IPCFrame_InvokeMethod() override;
+  IPCFrame_InvokeMethod(IPCFrame_InvokeMethod&&) noexcept;
+  IPCFrame_InvokeMethod& operator=(IPCFrame_InvokeMethod&&);
+  IPCFrame_InvokeMethod(const IPCFrame_InvokeMethod&);
+  IPCFrame_InvokeMethod& operator=(const IPCFrame_InvokeMethod&);
+  bool operator==(const IPCFrame_InvokeMethod&) const;
+  bool operator!=(const IPCFrame_InvokeMethod& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_service_id() const { return _has_field_[1]; }
+  uint32_t service_id() const { return service_id_; }
+  void set_service_id(uint32_t value) { service_id_ = value; _has_field_.set(1); }
+
+  bool has_method_id() const { return _has_field_[2]; }
+  uint32_t method_id() const { return method_id_; }
+  void set_method_id(uint32_t value) { method_id_ = value; _has_field_.set(2); }
+
+  bool has_args_proto() const { return _has_field_[3]; }
+  const std::string& args_proto() const { return args_proto_; }
+  void set_args_proto(const std::string& value) { args_proto_ = value; _has_field_.set(3); }
+  void set_args_proto(const void* p, size_t s) { args_proto_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(3); }
+
+  bool has_drop_reply() const { return _has_field_[4]; }
+  bool drop_reply() const { return drop_reply_; }
+  void set_drop_reply(bool value) { drop_reply_ = value; _has_field_.set(4); }
+
+ private:
+  uint32_t service_id_{};
+  uint32_t method_id_{};
+  std::string args_proto_{};
+  bool drop_reply_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<5> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT IPCFrame_BindServiceReply : public ::protozero::CppMessageObj {
+ public:
+  using MethodInfo = IPCFrame_BindServiceReply_MethodInfo;
+  enum FieldNumbers {
+    kSuccessFieldNumber = 1,
+    kServiceIdFieldNumber = 2,
+    kMethodsFieldNumber = 3,
+  };
+
+  IPCFrame_BindServiceReply();
+  ~IPCFrame_BindServiceReply() override;
+  IPCFrame_BindServiceReply(IPCFrame_BindServiceReply&&) noexcept;
+  IPCFrame_BindServiceReply& operator=(IPCFrame_BindServiceReply&&);
+  IPCFrame_BindServiceReply(const IPCFrame_BindServiceReply&);
+  IPCFrame_BindServiceReply& operator=(const IPCFrame_BindServiceReply&);
+  bool operator==(const IPCFrame_BindServiceReply&) const;
+  bool operator!=(const IPCFrame_BindServiceReply& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_success() const { return _has_field_[1]; }
+  bool success() const { return success_; }
+  void set_success(bool value) { success_ = value; _has_field_.set(1); }
+
+  bool has_service_id() const { return _has_field_[2]; }
+  uint32_t service_id() const { return service_id_; }
+  void set_service_id(uint32_t value) { service_id_ = value; _has_field_.set(2); }
+
+  const std::vector<IPCFrame_BindServiceReply_MethodInfo>& methods() const { return methods_; }
+  std::vector<IPCFrame_BindServiceReply_MethodInfo>* mutable_methods() { return &methods_; }
+  int methods_size() const;
+  void clear_methods();
+  IPCFrame_BindServiceReply_MethodInfo* add_methods();
+
+ private:
+  bool success_{};
+  uint32_t service_id_{};
+  std::vector<IPCFrame_BindServiceReply_MethodInfo> methods_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT IPCFrame_BindServiceReply_MethodInfo : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kIdFieldNumber = 1,
+    kNameFieldNumber = 2,
+  };
+
+  IPCFrame_BindServiceReply_MethodInfo();
+  ~IPCFrame_BindServiceReply_MethodInfo() override;
+  IPCFrame_BindServiceReply_MethodInfo(IPCFrame_BindServiceReply_MethodInfo&&) noexcept;
+  IPCFrame_BindServiceReply_MethodInfo& operator=(IPCFrame_BindServiceReply_MethodInfo&&);
+  IPCFrame_BindServiceReply_MethodInfo(const IPCFrame_BindServiceReply_MethodInfo&);
+  IPCFrame_BindServiceReply_MethodInfo& operator=(const IPCFrame_BindServiceReply_MethodInfo&);
+  bool operator==(const IPCFrame_BindServiceReply_MethodInfo&) const;
+  bool operator!=(const IPCFrame_BindServiceReply_MethodInfo& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_id() const { return _has_field_[1]; }
+  uint32_t id() const { return id_; }
+  void set_id(uint32_t value) { id_ = value; _has_field_.set(1); }
+
+  bool has_name() const { return _has_field_[2]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
+
+ private:
+  uint32_t id_{};
+  std::string name_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT IPCFrame_BindService : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kServiceNameFieldNumber = 1,
+  };
+
+  IPCFrame_BindService();
+  ~IPCFrame_BindService() override;
+  IPCFrame_BindService(IPCFrame_BindService&&) noexcept;
+  IPCFrame_BindService& operator=(IPCFrame_BindService&&);
+  IPCFrame_BindService(const IPCFrame_BindService&);
+  IPCFrame_BindService& operator=(const IPCFrame_BindService&);
+  bool operator==(const IPCFrame_BindService&) const;
+  bool operator!=(const IPCFrame_BindService& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_service_name() const { return _has_field_[1]; }
+  const std::string& service_name() const { return service_name_; }
+  void set_service_name(const std::string& value) { service_name_ = value; _has_field_.set(1); }
+
+ private:
+  std::string service_name_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_WIRE_PROTOCOL_PROTO_CPP_H_
+// gen_amalgamated begin header: include/perfetto/protozero/gen_field_helpers.h
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_PROTOZERO_GEN_FIELD_HELPERS_H_
+#define INCLUDE_PERFETTO_PROTOZERO_GEN_FIELD_HELPERS_H_
+
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+
+namespace protozero {
+namespace internal {
+namespace gen_helpers {
+
+// This file implements some helpers used by the protobuf generated code in the
+// .gen.cc files.
+//
+// The .gen.cc generated protobuf implementation (as opposed to the .pbzero.h
+// implementation) is not zero-copy and is not supposed to be used in fast
+// paths, so most of these helpers are designed to reduce binary size.
+
+void DeserializeString(const protozero::Field& field, std::string* dst);
+
+// Read packed repeated elements (serialized as `wire_type`) from `field` into
+// the `*dst` vector. Returns false if some bytes of `field` could not be
+// interpreted correctly as `wire_type`.
+template <proto_utils::ProtoWireType wire_type, typename CppType>
+bool DeserializePackedRepeated(const protozero::Field& field,
+                               std::vector<CppType>* dst) {
+  bool parse_error = false;
+  for (::protozero::PackedRepeatedFieldIterator<wire_type, CppType> rep(
+           field.data(), field.size(), &parse_error);
+       rep; ++rep) {
+    dst->emplace_back(*rep);
+  }
+  return !parse_error;
+}
+
+extern template bool
+DeserializePackedRepeated<proto_utils::ProtoWireType::kVarInt, uint64_t>(
+    const protozero::Field& field,
+    std::vector<uint64_t>* dst);
+
+extern template bool
+DeserializePackedRepeated<proto_utils::ProtoWireType::kVarInt, int64_t>(
+    const protozero::Field& field,
+    std::vector<int64_t>* dst);
+
+extern template bool
+DeserializePackedRepeated<proto_utils::ProtoWireType::kVarInt, uint32_t>(
+    const protozero::Field& field,
+    std::vector<uint32_t>* dst);
+
+extern template bool
+DeserializePackedRepeated<proto_utils::ProtoWireType::kVarInt, int32_t>(
+    const protozero::Field& field,
+    std::vector<int32_t>* dst);
+
+// Serializers for different type of fields
+
+void SerializeTinyVarInt(uint32_t field_id, bool value, Message* msg);
+
+template <typename T>
+void SerializeExtendedVarInt(uint32_t field_id, T value, Message* msg) {
+  msg->AppendVarInt(field_id, value);
+}
+
+extern template void SerializeExtendedVarInt<uint64_t>(uint32_t field_id,
+                                                       uint64_t value,
+                                                       Message* msg);
+
+extern template void SerializeExtendedVarInt<uint32_t>(uint32_t field_id,
+                                                       uint32_t value,
+                                                       Message* msg);
+
+template <typename T>
+void SerializeVarInt(uint32_t field_id, T value, Message* msg) {
+  SerializeExtendedVarInt(
+      field_id, proto_utils::ExtendValueForVarIntSerialization(value), msg);
+}
+
+template <typename T>
+void SerializeSignedVarInt(uint32_t field_id, T value, Message* msg) {
+  SerializeVarInt(field_id, proto_utils::ZigZagEncode(value), msg);
+}
+
+template <typename T>
+void SerializeFixed(uint32_t field_id, T value, Message* msg) {
+  msg->AppendFixed(field_id, value);
+}
+
+extern template void SerializeFixed<double>(uint32_t field_id,
+                                            double value,
+                                            Message* msg);
+
+extern template void SerializeFixed<float>(uint32_t field_id,
+                                           float value,
+                                           Message* msg);
+
+extern template void SerializeFixed<uint64_t>(uint32_t field_id,
+                                              uint64_t value,
+                                              Message* msg);
+
+extern template void SerializeFixed<int64_t>(uint32_t field_id,
+                                             int64_t value,
+                                             Message* msg);
+
+extern template void SerializeFixed<uint32_t>(uint32_t field_id,
+                                              uint32_t value,
+                                              Message* msg);
+
+extern template void SerializeFixed<int32_t>(uint32_t field_id,
+                                             int32_t value,
+                                             Message* msg);
+
+void SerializeString(uint32_t field_id, const std::string& value, Message* msg);
+
+void SerializeUnknownFields(const std::string& unknown_fields, Message* msg);
+
+// Wrapper around HeapBuffered that avoids inlining.
+class MessageSerializer {
+ public:
+  MessageSerializer();
+  ~MessageSerializer();
+
+  Message* get() { return msg_.get(); }
+  std::vector<uint8_t> SerializeAsArray();
+  std::string SerializeAsString();
+
+ private:
+  HeapBuffered<Message> msg_;
+};
+
+// Wrapper about operator==() which reduces the binary size of generated protos.
+// This is needed because std::string's operator== is inlined aggressively (even
+// when optimizing for size). Having this layer of indirection with removes the
+// overhead.
+template <typename T>
+bool EqualsField(const T& a, const T& b) {
+  return a == b;
+}
+extern template bool EqualsField<std::string>(const std::string&,
+                                              const std::string&);
+
+}  // namespace gen_helpers
+}  // namespace internal
+}  // namespace protozero
+
+#endif  // INCLUDE_PERFETTO_PROTOZERO_GEN_FIELD_HELPERS_H_
+// gen_amalgamated begin header: include/perfetto/protozero/scattered_stream_null_delegate.h
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_PROTOZERO_SCATTERED_STREAM_NULL_DELEGATE_H_
+#define INCLUDE_PERFETTO_PROTOZERO_SCATTERED_STREAM_NULL_DELEGATE_H_
+
+#include <memory>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/contiguous_memory_range.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
+
+namespace protozero {
+
+class PERFETTO_EXPORT_COMPONENT ScatteredStreamWriterNullDelegate
+    : public ScatteredStreamWriter::Delegate {
+ public:
+  explicit ScatteredStreamWriterNullDelegate(size_t chunk_size);
+  ~ScatteredStreamWriterNullDelegate() override;
+
+  // protozero::ScatteredStreamWriter::Delegate implementation.
+  ContiguousMemoryRange GetNewBuffer() override;
+
+ private:
+  const size_t chunk_size_;
+  std::unique_ptr<uint8_t[]> chunk_;
+};
+
+}  // namespace protozero
+
+#endif  // INCLUDE_PERFETTO_PROTOZERO_SCATTERED_STREAM_NULL_DELEGATE_H_
+// gen_amalgamated begin header: include/perfetto/protozero/static_buffer.h
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INCLUDE_PERFETTO_PROTOZERO_STATIC_BUFFER_H_
+#define INCLUDE_PERFETTO_PROTOZERO_STATIC_BUFFER_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/root_message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
+
+namespace protozero {
+
+class Message;
+
+// A simple implementation of ScatteredStreamWriter::Delegate backed by a
+// fixed-size buffer. It doesn't support expansion. The caller needs to ensure
+// to never write more than the size of the buffer. Will CHECK() otherwise.
+class PERFETTO_EXPORT_COMPONENT StaticBufferDelegate
+    : public ScatteredStreamWriter::Delegate {
+ public:
+  StaticBufferDelegate(uint8_t* buf, size_t len) : range_{buf, buf + len} {}
+  ~StaticBufferDelegate() override;
+
+  // ScatteredStreamWriter::Delegate implementation.
+  ContiguousMemoryRange GetNewBuffer() override;
+
+  ContiguousMemoryRange const range_;
+  bool get_new_buffer_called_once_ = false;
+};
+
+// Helper function to create protozero messages backed by a fixed-size buffer
+// in one line. You can write:
+//   protozero::Static<protozero::MyMessage> msg(buf.data(), buf.size());
+//   msg->set_stuff(...);
+//   size_t bytes_encoded = msg.Finalize();
+template <typename T /* protozero::Message */>
+class StaticBuffered {
+ public:
+  StaticBuffered(void* buf, size_t len)
+      : delegate_(reinterpret_cast<uint8_t*>(buf), len), writer_(&delegate_) {
+    msg_.Reset(&writer_);
+  }
+
+  // This can't be neither copied nor moved because Message hands out pointers
+  // to itself when creating submessages.
+  StaticBuffered(const StaticBuffered&) = delete;
+  StaticBuffered& operator=(const StaticBuffered&) = delete;
+  StaticBuffered(StaticBuffered&&) = delete;
+  StaticBuffered& operator=(StaticBuffered&&) = delete;
+
+  T* get() { return &msg_; }
+  T* operator->() { return &msg_; }
+
+  // The lack of a size() method is deliberate. It's to prevent that one
+  // accidentally calls size() before Finalize().
+
+  // Returns the number of encoded bytes (<= the size passed in the ctor).
+  size_t Finalize() {
+    msg_.Finalize();
+    return static_cast<size_t>(writer_.write_ptr() - delegate_.range_.begin);
+  }
+
+ private:
+  StaticBufferDelegate delegate_;
+  ScatteredStreamWriter writer_;
+  RootMessage<T> msg_;
+};
+
+// Helper function to create stack-based protozero messages in one line.
+// You can write:
+//   protozero::StackBuffered<protozero::MyMessage, 16> msg;
+//   msg->set_stuff(...);
+//   size_t bytes_encoded = msg.Finalize();
+template <typename T /* protozero::Message */, size_t N>
+class StackBuffered : public StaticBuffered<T> {
+ public:
+  StackBuffered() : StaticBuffered<T>(&buf_[0], N) {}
+
+ private:
+  uint8_t buf_[N];  // Deliberately not initialized.
+};
+
+}  // namespace protozero
+
+#endif  // INCLUDE_PERFETTO_PROTOZERO_STATIC_BUFFER_H_
+
